@julianoczkowski/create-trimble-app 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -0
- package/bin/create-trimble-app.js +9 -0
- package/package.json +67 -0
- package/src/cli.js +134 -0
- package/src/frameworks.js +28 -0
- package/src/scaffold.js +209 -0
- package/src/utils/file.js +47 -0
- package/src/utils/git.js +140 -0
- package/src/utils/install.js +25 -0
- package/src/utils/logger.js +124 -0
- package/templates/angular/.cursor/commands/remove-dev-content.md +394 -0
- package/templates/angular/.cursor/mcp.json +13 -0
- package/templates/angular/.cursor/rules/modus-angular-20.mdc +82 -0
- package/templates/angular/.cursor/rules/modus-angular-accordion-state-management-short.mdc +45 -0
- package/templates/angular/.cursor/rules/modus-angular-accordion-state-management.mdc +322 -0
- package/templates/angular/.cursor/rules/modus-angular-best-practices.mdc +472 -0
- package/templates/angular/.cursor/rules/modus-angular-border-usage-short.mdc +48 -0
- package/templates/angular/.cursor/rules/modus-angular-border-usage.mdc +286 -0
- package/templates/angular/.cursor/rules/modus-angular-button-group-usage-short.mdc +47 -0
- package/templates/angular/.cursor/rules/modus-angular-button-group-usage.mdc +263 -0
- package/templates/angular/.cursor/rules/modus-angular-checkbox-value-inversion-short.mdc +36 -0
- package/templates/angular/.cursor/rules/modus-angular-checkbox-value-inversion.mdc +92 -0
- package/templates/angular/.cursor/rules/modus-angular-chrome-devtools-testing-short.mdc +34 -0
- package/templates/angular/.cursor/rules/modus-angular-chrome-devtools-testing.mdc +185 -0
- package/templates/angular/.cursor/rules/modus-angular-color-usage-short.mdc +56 -0
- package/templates/angular/.cursor/rules/modus-angular-color-usage.mdc +208 -0
- package/templates/angular/.cursor/rules/modus-angular-components-reference.mdc +114 -0
- package/templates/angular/.cursor/rules/modus-angular-design-system.mdc +273 -0
- package/templates/angular/.cursor/rules/modus-angular-development-workflow-short.mdc +43 -0
- package/templates/angular/.cursor/rules/modus-angular-development-workflow.mdc +145 -0
- package/templates/angular/.cursor/rules/modus-angular-essentials.mdc +272 -0
- package/templates/angular/.cursor/rules/modus-angular-forms-validation-short.mdc +56 -0
- package/templates/angular/.cursor/rules/modus-angular-forms-validation.mdc +124 -0
- package/templates/angular/.cursor/rules/modus-angular-icon-names.mdc +70 -0
- package/templates/angular/.cursor/rules/modus-angular-icons-short.mdc +40 -0
- package/templates/angular/.cursor/rules/modus-angular-icons.mdc +137 -0
- package/templates/angular/.cursor/rules/modus-angular-implementation-guides-short.mdc +36 -0
- package/templates/angular/.cursor/rules/modus-angular-implementation-guides.mdc +301 -0
- package/templates/angular/.cursor/rules/modus-angular-integration-short.mdc +60 -0
- package/templates/angular/.cursor/rules/modus-angular-integration.mdc +1096 -0
- package/templates/angular/.cursor/rules/modus-angular-master.mdc +164 -0
- package/templates/angular/.cursor/rules/modus-angular-modal-usage-short.mdc +51 -0
- package/templates/angular/.cursor/rules/modus-angular-modal-usage.mdc +115 -0
- package/templates/angular/.cursor/rules/modus-angular-navbar-usage-short.mdc +49 -0
- package/templates/angular/.cursor/rules/modus-angular-navbar-usage.mdc +146 -0
- package/templates/angular/.cursor/rules/modus-angular-no-emojis.mdc +66 -0
- package/templates/angular/.cursor/rules/modus-angular-opacity-utilities-short.mdc +43 -0
- package/templates/angular/.cursor/rules/modus-angular-opacity-utilities.mdc +160 -0
- package/templates/angular/.cursor/rules/modus-angular-select-vs-dropdown-menu-short.mdc +51 -0
- package/templates/angular/.cursor/rules/modus-angular-select-vs-dropdown-menu.mdc +83 -0
- package/templates/angular/.cursor/rules/modus-angular-semantic-html-short.mdc +36 -0
- package/templates/angular/.cursor/rules/modus-angular-semantic-html.mdc +81 -0
- package/templates/angular/.cursor/rules/modus-angular-side-navigation-usage-short.mdc +50 -0
- package/templates/angular/.cursor/rules/modus-angular-side-navigation-usage.mdc +136 -0
- package/templates/angular/.cursor/rules/modus-angular-table-usage-short.mdc +52 -0
- package/templates/angular/.cursor/rules/modus-angular-table-usage.mdc +151 -0
- package/templates/angular/.cursor/rules/modus-angular-tailwind-usage-short.mdc +44 -0
- package/templates/angular/.cursor/rules/modus-angular-tailwind-usage.mdc +242 -0
- package/templates/angular/.cursor/rules/modus-angular-themes-short.mdc +54 -0
- package/templates/angular/.cursor/rules/modus-angular-themes.mdc +222 -0
- package/templates/angular/.cursor/rules/modus-angular-utility-panel-usage-short.mdc +52 -0
- package/templates/angular/.cursor/rules/modus-angular-utility-panel-usage.mdc +130 -0
- package/templates/angular/.cursor/rules/ux/gestalt-laws-detailed.mdc +514 -0
- package/templates/angular/.cursor/rules/ux/ux-ui-foundations.mdc +235 -0
- package/templates/angular/.cursor/skills/run-lint-checks/SKILL.md +169 -0
- package/templates/angular/.editorconfig +17 -0
- package/templates/angular/.github/dependabot.yml +19 -0
- package/templates/angular/.github/workflows/a11y-check.yml +135 -0
- package/templates/angular/.github/workflows/ci.yml +44 -0
- package/templates/angular/.husky/pre-commit +32 -0
- package/templates/angular/.postcssrc.json +5 -0
- package/templates/angular/.vscode/extensions.json +4 -0
- package/templates/angular/.vscode/launch.json +20 -0
- package/templates/angular/.vscode/tasks.json +42 -0
- package/templates/angular/CLAUDE.md +148 -0
- package/templates/angular/README.md +92 -0
- package/templates/angular/amplify.yml +25 -0
- package/templates/angular/angular.json +106 -0
- package/templates/angular/data/modusIcons.ts +861 -0
- package/templates/angular/package-lock.json +11030 -0
- package/templates/angular/package.json +66 -0
- package/templates/angular/public/angular-icon.svg +12 -0
- package/templates/angular/public/favicon.ico +0 -0
- package/templates/angular/public/modus-icons.css +49 -0
- package/templates/angular/public/vite.svg +1 -0
- package/templates/angular/scripts/README.md +410 -0
- package/templates/angular/scripts/check-border-violations.js +352 -0
- package/templates/angular/scripts/check-icon-names.js +402 -0
- package/templates/angular/scripts/check-inline-styles.js +292 -0
- package/templates/angular/scripts/check-modus-colors.js +282 -0
- package/templates/angular/scripts/check-modus-icons.js +263 -0
- package/templates/angular/scripts/check-opacity-utilities.js +426 -0
- package/templates/angular/scripts/check-semantic-html.js +452 -0
- package/templates/angular/scripts/check-typescript.js +109 -0
- package/templates/angular/src/app/app.config.ts +29 -0
- package/templates/angular/src/app/app.css +0 -0
- package/templates/angular/src/app/app.html +4 -0
- package/templates/angular/src/app/app.routes.ts +351 -0
- package/templates/angular/src/app/app.spec.ts +27 -0
- package/templates/angular/src/app/app.ts +47 -0
- package/templates/angular/src/app/components/README.md +77 -0
- package/templates/angular/src/app/components/index.ts +53 -0
- package/templates/angular/src/app/components/modus-accordion.component.ts +50 -0
- package/templates/angular/src/app/components/modus-alert.component.ts +133 -0
- package/templates/angular/src/app/components/modus-autocomplete.component.ts +262 -0
- package/templates/angular/src/app/components/modus-avatar.component.ts +75 -0
- package/templates/angular/src/app/components/modus-badge.component.ts +84 -0
- package/templates/angular/src/app/components/modus-breadcrumbs.component.ts +65 -0
- package/templates/angular/src/app/components/modus-button-group.component.ts +82 -0
- package/templates/angular/src/app/components/modus-button.component.ts +292 -0
- package/templates/angular/src/app/components/modus-card.component.ts +73 -0
- package/templates/angular/src/app/components/modus-checkbox.component.ts +117 -0
- package/templates/angular/src/app/components/modus-chip.component.ts +97 -0
- package/templates/angular/src/app/components/modus-collapse.component.ts +118 -0
- package/templates/angular/src/app/components/modus-date.component.ts +165 -0
- package/templates/angular/src/app/components/modus-dropdown-menu.component.ts +108 -0
- package/templates/angular/src/app/components/modus-file-dropzone.component.ts +121 -0
- package/templates/angular/src/app/components/modus-handle.component.ts +96 -0
- package/templates/angular/src/app/components/modus-icon.component.ts +81 -0
- package/templates/angular/src/app/components/modus-input-feedback.component.ts +54 -0
- package/templates/angular/src/app/components/modus-input-label.component.ts +62 -0
- package/templates/angular/src/app/components/modus-loader.component.ts +48 -0
- package/templates/angular/src/app/components/modus-logo.component.ts +115 -0
- package/templates/angular/src/app/components/modus-menu-item.component.ts +116 -0
- package/templates/angular/src/app/components/modus-menu.component.ts +58 -0
- package/templates/angular/src/app/components/modus-modal.component.ts +70 -0
- package/templates/angular/src/app/components/modus-navbar.component.ts +303 -0
- package/templates/angular/src/app/components/modus-number-input.component.ts +174 -0
- package/templates/angular/src/app/components/modus-pagination.component.ts +74 -0
- package/templates/angular/src/app/components/modus-panel.component.ts +61 -0
- package/templates/angular/src/app/components/modus-progress.component.ts +62 -0
- package/templates/angular/src/app/components/modus-radio.component.ts +102 -0
- package/templates/angular/src/app/components/modus-rating.component.ts +80 -0
- package/templates/angular/src/app/components/modus-select.component.ts +131 -0
- package/templates/angular/src/app/components/modus-side-navigation.component.ts +90 -0
- package/templates/angular/src/app/components/modus-skeleton.component.ts +54 -0
- package/templates/angular/src/app/components/modus-slider.component.ts +132 -0
- package/templates/angular/src/app/components/modus-stepper.component.ts +65 -0
- package/templates/angular/src/app/components/modus-switch.component.ts +118 -0
- package/templates/angular/src/app/components/modus-table.component.ts +204 -0
- package/templates/angular/src/app/components/modus-tabs.component.ts +82 -0
- package/templates/angular/src/app/components/modus-text-input.component.ts +221 -0
- package/templates/angular/src/app/components/modus-textarea.component.ts +168 -0
- package/templates/angular/src/app/components/modus-theme-switcher.component.ts +45 -0
- package/templates/angular/src/app/components/modus-time-input.component.ts +172 -0
- package/templates/angular/src/app/components/modus-toast.component.ts +63 -0
- package/templates/angular/src/app/components/modus-toolbar.component.ts +43 -0
- package/templates/angular/src/app/components/modus-tooltip.component.ts +83 -0
- package/templates/angular/src/app/components/modus-typography.component.ts +79 -0
- package/templates/angular/src/app/components/modus-utility-panel.component.ts +275 -0
- package/templates/angular/src/app/components/theme-demo.component.ts +1242 -0
- package/templates/angular/src/app/data/component-demos.ts +360 -0
- package/templates/angular/src/app/data/modus-icons.ts +806 -0
- package/templates/angular/src/app/demos/accordion/accordion-demo.component.ts +212 -0
- package/templates/angular/src/app/demos/alert/alert-demo.component.ts +108 -0
- package/templates/angular/src/app/demos/autocomplete/autocomplete-demo.component.ts +174 -0
- package/templates/angular/src/app/demos/avatar/avatar-demo.component.ts +149 -0
- package/templates/angular/src/app/demos/badge/badge-demo.component.ts +148 -0
- package/templates/angular/src/app/demos/breadcrumbs/breadcrumbs-demo.component.ts +96 -0
- package/templates/angular/src/app/demos/button/button-demo.component.ts +256 -0
- package/templates/angular/src/app/demos/button-group/button-group-demo.component.ts +215 -0
- package/templates/angular/src/app/demos/card/card-demo.component.ts +180 -0
- package/templates/angular/src/app/demos/checkbox/checkbox-demo.component.ts +71 -0
- package/templates/angular/src/app/demos/chip/chip-demo.component.ts +183 -0
- package/templates/angular/src/app/demos/date/date-demo.component.ts +193 -0
- package/templates/angular/src/app/demos/dropdown/dropdown-demo.component.ts +196 -0
- package/templates/angular/src/app/demos/file-dropzone/file-dropzone-demo.component.ts +176 -0
- package/templates/angular/src/app/demos/handle/handle-demo.component.ts +265 -0
- package/templates/angular/src/app/demos/icon/icon-demo.component.ts +65 -0
- package/templates/angular/src/app/demos/input-feedback/input-feedback-demo.component.ts +189 -0
- package/templates/angular/src/app/demos/input-label/input-label-demo.component.ts +330 -0
- package/templates/angular/src/app/demos/loader/loader-demo.component.ts +143 -0
- package/templates/angular/src/app/demos/logo/logo-demo.component.ts +191 -0
- package/templates/angular/src/app/demos/menu/menu-demo.component.ts +72 -0
- package/templates/angular/src/app/demos/modal/modal-demo.component.ts +278 -0
- package/templates/angular/src/app/demos/navbar/navbar-demo.component.ts +135 -0
- package/templates/angular/src/app/demos/number-input/number-input-demo.component.ts +175 -0
- package/templates/angular/src/app/demos/pagination/pagination-demo.component.ts +134 -0
- package/templates/angular/src/app/demos/panel/panel-demo.component.ts +235 -0
- package/templates/angular/src/app/demos/progress/progress-demo.component.ts +169 -0
- package/templates/angular/src/app/demos/radio/radio-demo.component.ts +161 -0
- package/templates/angular/src/app/demos/rating/rating-demo.component.ts +97 -0
- package/templates/angular/src/app/demos/select/select-demo.component.ts +107 -0
- package/templates/angular/src/app/demos/shared/demo-example-clean.component.ts +41 -0
- package/templates/angular/src/app/demos/shared/demo-example.component.ts +42 -0
- package/templates/angular/src/app/demos/shared/demo-page.component.ts +97 -0
- package/templates/angular/src/app/demos/shared/index.ts +3 -0
- package/templates/angular/src/app/demos/side-navigation/side-navigation-demo.component.ts +524 -0
- package/templates/angular/src/app/demos/skeleton/skeleton-demo.component.ts +112 -0
- package/templates/angular/src/app/demos/slider/slider-demo.component.ts +76 -0
- package/templates/angular/src/app/demos/stepper/stepper-demo.component.ts +79 -0
- package/templates/angular/src/app/demos/switch/switch-demo.component.ts +113 -0
- package/templates/angular/src/app/demos/table/table-demo.component.ts +405 -0
- package/templates/angular/src/app/demos/tabs/tabs-demo.component.ts +318 -0
- package/templates/angular/src/app/demos/text-input/text-input-demo.component.ts +160 -0
- package/templates/angular/src/app/demos/textarea/textarea-demo.component.ts +95 -0
- package/templates/angular/src/app/demos/theme-switcher/theme-switcher-demo.component.ts +38 -0
- package/templates/angular/src/app/demos/time-input/time-input-demo.component.ts +130 -0
- package/templates/angular/src/app/demos/toast/toast-demo.component.ts +258 -0
- package/templates/angular/src/app/demos/toolbar/toolbar-demo.component.ts +54 -0
- package/templates/angular/src/app/demos/tooltip/tooltip-demo.component.ts +163 -0
- package/templates/angular/src/app/demos/utility-panel/utility-panel-demo.component.ts +197 -0
- package/templates/angular/src/app/dev/dev-config.ts +119 -0
- package/templates/angular/src/app/dev/dev-panel/dev-panel.component.ts +215 -0
- package/templates/angular/src/app/dev/dev-panel.service.ts +63 -0
- package/templates/angular/src/app/dev/index.ts +8 -0
- package/templates/angular/src/app/dev/theme-switcher-dropdown/theme-switcher-dropdown.component.ts +134 -0
- package/templates/angular/src/app/dev-pages/color-palette/color-palette.component.ts +229 -0
- package/templates/angular/src/app/dev-pages/components-gallery/components-gallery.component.ts +486 -0
- package/templates/angular/src/app/dev-pages/icons/icons.component.ts +149 -0
- package/templates/angular/src/app/pages/home/home.component.ts +251 -0
- package/templates/angular/src/app/services/README.md +57 -0
- package/templates/angular/src/app/services/theme.service.ts +163 -0
- package/templates/angular/src/environments/environment.development.ts +8 -0
- package/templates/angular/src/environments/environment.ts +8 -0
- package/templates/angular/src/index.html +14 -0
- package/templates/angular/src/main.ts +6 -0
- package/templates/angular/src/styles.css +1328 -0
- package/templates/angular/tsconfig.app.json +15 -0
- package/templates/angular/tsconfig.json +35 -0
- package/templates/angular/tsconfig.spec.json +14 -0
- package/templates/config.json +23 -0
- package/templates/react/.cursor/commands/remove-dev-content.md +311 -0
- package/templates/react/.cursor/mcp.json +13 -0
- package/templates/react/.cursor/rules/README.md +240 -0
- package/templates/react/.cursor/rules/border-usage-guidelines-short.mdc +22 -0
- package/templates/react/.cursor/rules/border-usage-guidelines.mdc +380 -0
- package/templates/react/.cursor/rules/chrome-devtools-testing-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/development-workflow-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/development-workflow-react.mdc +292 -0
- package/templates/react/.cursor/rules/implementation-guides-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/implementation-guides-react.mdc +446 -0
- package/templates/react/.cursor/rules/modus-accordion-state-management-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-accordion-state-management-react.mdc +445 -0
- package/templates/react/.cursor/rules/modus-button-group-usage-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-button-group-usage-react.mdc +117 -0
- package/templates/react/.cursor/rules/modus-checkbox-value-inversion-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-checkbox-value-inversion-react.mdc +492 -0
- package/templates/react/.cursor/rules/modus-color-usage-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-color-usage-react.mdc +420 -0
- package/templates/react/.cursor/rules/modus-components-reference.mdc +366 -0
- package/templates/react/.cursor/rules/modus-icon-names.mdc +63 -0
- package/templates/react/.cursor/rules/modus-icons-react-short.mdc +24 -0
- package/templates/react/.cursor/rules/modus-icons-react.mdc +402 -0
- package/templates/react/.cursor/rules/modus-modal-implementation-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-modal-implementation-react.mdc +831 -0
- package/templates/react/.cursor/rules/modus-navbar-side-navigation-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-navbar-side-navigation-react.mdc +247 -0
- package/templates/react/.cursor/rules/modus-no-emojis-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-opacity-utilities-react-short.mdc +70 -0
- package/templates/react/.cursor/rules/modus-opacity-utilities-react.mdc +208 -0
- package/templates/react/.cursor/rules/modus-react-best-practices-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-react-best-practices.mdc +508 -0
- package/templates/react/.cursor/rules/modus-react-essentials.mdc +209 -0
- package/templates/react/.cursor/rules/modus-react-integration-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-react-integration.mdc +509 -0
- package/templates/react/.cursor/rules/modus-react-key-warnings-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-react-key-warnings.mdc +805 -0
- package/templates/react/.cursor/rules/modus-react-master.mdc +160 -0
- package/templates/react/.cursor/rules/modus-select-vs-dropdown-menu-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-select-vs-dropdown-menu-react.mdc +442 -0
- package/templates/react/.cursor/rules/modus-semantic-html-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-semantic-html-react.mdc +427 -0
- package/templates/react/.cursor/rules/modus-tailwind-usage-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-tailwind-usage-react.mdc +642 -0
- package/templates/react/.cursor/rules/modus-themes-react-short.mdc +23 -0
- package/templates/react/.cursor/rules/modus-themes-react.mdc +506 -0
- package/templates/react/.cursor/rules/ux/gestalt-laws-detailed.mdc +456 -0
- package/templates/react/.cursor/rules/ux/ux-ui-foundations.mdc +211 -0
- package/templates/react/.cursor/skills/create-modus-form-component/SKILL.md +518 -0
- package/templates/react/.cursor/skills/create-modus-wrapper-component/SKILL.md +252 -0
- package/templates/react/.cursor/skills/fix-modus-component-event-issues/SKILL.md +345 -0
- package/templates/react/.cursor/skills/handle-modus-checkbox-value-bug/SKILL.md +202 -0
- package/templates/react/.cursor/skills/implement-modus-modal-with-refs/SKILL.md +386 -0
- package/templates/react/.cursor/skills/integrate-modus-icons/SKILL.md +300 -0
- package/templates/react/.cursor/skills/run-lint-checks/SKILL.md +235 -0
- package/templates/react/.cursor/skills/set-up-modus-event-listeners/SKILL.md +284 -0
- package/templates/react/.cursor/skills/style-modus-components-with-tailwind/SKILL.md +382 -0
- package/templates/react/.env.development +3 -0
- package/templates/react/.env.production +3 -0
- package/templates/react/.github/CODEOWNERS +28 -0
- package/templates/react/.github/ISSUE_TEMPLATE/bug_report.yml +176 -0
- package/templates/react/.github/ISSUE_TEMPLATE/config.yml +20 -0
- package/templates/react/.github/ISSUE_TEMPLATE/documentation.yml +115 -0
- package/templates/react/.github/ISSUE_TEMPLATE/feature_request.yml +171 -0
- package/templates/react/.github/ISSUE_TEMPLATE/question.yml +139 -0
- package/templates/react/.github/copilot-instructions.md +80 -0
- package/templates/react/.github/instructions/components.instructions.md +82 -0
- package/templates/react/.github/instructions/demos.instructions.md +82 -0
- package/templates/react/.github/instructions/pages.instructions.md +76 -0
- package/templates/react/.github/instructions/styles.instructions.md +77 -0
- package/templates/react/.github/instructions/typescript.instructions.md +101 -0
- package/templates/react/.github/pull_request_template.md +188 -0
- package/templates/react/.github/workflows/ci.yml +43 -0
- package/templates/react/.github/workflows/claude-code-review.yml +44 -0
- package/templates/react/.github/workflows/claude.yml +50 -0
- package/templates/react/.husky/pre-commit +28 -0
- package/templates/react/.vscode/extensions.json +8 -0
- package/templates/react/CLAUDE.md +119 -0
- package/templates/react/CODE_OF_CONDUCT.md +79 -0
- package/templates/react/CONTRIBUTING.md +65 -0
- package/templates/react/LICENSE +21 -0
- package/templates/react/README.md +728 -0
- package/templates/react/SECURITY.md +50 -0
- package/templates/react/eslint.config.js +23 -0
- package/templates/react/index.html +13 -0
- package/templates/react/package-lock.json +5209 -0
- package/templates/react/package.json +49 -0
- package/templates/react/postcss.config.js +6 -0
- package/templates/react/public/react.svg +1 -0
- package/templates/react/public/vite.svg +1 -0
- package/templates/react/readme_assets/getting_started_header.png +0 -0
- package/templates/react/readme_assets/hero.png +0 -0
- package/templates/react/readme_assets/modus_comp.png +0 -0
- package/templates/react/readme_assets/modus_figma_mcp.png +0 -0
- package/templates/react/readme_assets/teaser_comp.gif +0 -0
- package/templates/react/scripts/README.md +343 -0
- package/templates/react/scripts/check-border-violations.js +483 -0
- package/templates/react/scripts/check-icon-names.js +486 -0
- package/templates/react/scripts/check-inline-styles.js +364 -0
- package/templates/react/scripts/check-modus-colors.js +247 -0
- package/templates/react/scripts/check-modus-icons.js +256 -0
- package/templates/react/scripts/check-opacity-utilities.js +481 -0
- package/templates/react/scripts/check-semantic-html.js +476 -0
- package/templates/react/scripts/check-typescript.js +109 -0
- package/templates/react/src/App.css +42 -0
- package/templates/react/src/App.tsx +54 -0
- package/templates/react/src/assets/react.svg +1 -0
- package/templates/react/src/components/DemoExample.tsx +61 -0
- package/templates/react/src/components/DemoPage.tsx +81 -0
- package/templates/react/src/components/ModusAccordion.tsx +89 -0
- package/templates/react/src/components/ModusAlert.tsx +85 -0
- package/templates/react/src/components/ModusAutocomplete.tsx +207 -0
- package/templates/react/src/components/ModusAvatar.tsx +50 -0
- package/templates/react/src/components/ModusBadge.tsx +82 -0
- package/templates/react/src/components/ModusBreadcrumbs.tsx +75 -0
- package/templates/react/src/components/ModusButton.tsx +244 -0
- package/templates/react/src/components/ModusButtonGroup.tsx +91 -0
- package/templates/react/src/components/ModusCard.tsx +70 -0
- package/templates/react/src/components/ModusCheckbox.tsx +168 -0
- package/templates/react/src/components/ModusChip.tsx +93 -0
- package/templates/react/src/components/ModusDate.tsx +154 -0
- package/templates/react/src/components/ModusDropdownMenu.tsx +148 -0
- package/templates/react/src/components/ModusFileDropzone.tsx +140 -0
- package/templates/react/src/components/ModusHandle.tsx +101 -0
- package/templates/react/src/components/ModusIcon.tsx +49 -0
- package/templates/react/src/components/ModusInputFeedback.tsx +52 -0
- package/templates/react/src/components/ModusInputLabel.tsx +50 -0
- package/templates/react/src/components/ModusLoader.tsx +42 -0
- package/templates/react/src/components/ModusLogo.tsx +102 -0
- package/templates/react/src/components/ModusMenu.tsx +119 -0
- package/templates/react/src/components/ModusMenuItem.tsx +86 -0
- package/templates/react/src/components/ModusModal.tsx +145 -0
- package/templates/react/src/components/ModusNavbar.tsx +504 -0
- package/templates/react/src/components/ModusNumberInput.tsx +230 -0
- package/templates/react/src/components/ModusPagination.tsx +94 -0
- package/templates/react/src/components/ModusPanel.tsx +92 -0
- package/templates/react/src/components/ModusProgress.tsx +70 -0
- package/templates/react/src/components/ModusProvider.tsx +18 -0
- package/templates/react/src/components/ModusRadio.tsx +114 -0
- package/templates/react/src/components/ModusRating.tsx +108 -0
- package/templates/react/src/components/ModusSelect.tsx +171 -0
- package/templates/react/src/components/ModusSideNavigation.tsx +149 -0
- package/templates/react/src/components/ModusSkeleton.tsx +42 -0
- package/templates/react/src/components/ModusSlider.tsx +128 -0
- package/templates/react/src/components/ModusStepper.tsx +85 -0
- package/templates/react/src/components/ModusSwitch.tsx +130 -0
- package/templates/react/src/components/ModusTable.tsx +309 -0
- package/templates/react/src/components/ModusTabs.tsx +114 -0
- package/templates/react/src/components/ModusTextInput.tsx +179 -0
- package/templates/react/src/components/ModusTextarea.tsx +164 -0
- package/templates/react/src/components/ModusThemeSwitcher.tsx +58 -0
- package/templates/react/src/components/ModusTimeInput.tsx +176 -0
- package/templates/react/src/components/ModusToast.tsx +207 -0
- package/templates/react/src/components/ModusToolbar.tsx +70 -0
- package/templates/react/src/components/ModusTooltip.tsx +97 -0
- package/templates/react/src/components/ModusUtilityPanel.tsx +198 -0
- package/templates/react/src/components/ThemeSwitcherDropdown.tsx +117 -0
- package/templates/react/src/components/ThemeToggleSimple.tsx +157 -0
- package/templates/react/src/config/routes.ts +196 -0
- package/templates/react/src/contexts/ThemeContext.tsx +81 -0
- package/templates/react/src/contexts/ThemeContextData.tsx +89 -0
- package/templates/react/src/data/modusIcons.ts +865 -0
- package/templates/react/src/demos/accordion-demo/page.tsx +236 -0
- package/templates/react/src/demos/alert-demo/page.tsx +94 -0
- package/templates/react/src/demos/autocomplete-demo/page.tsx +166 -0
- package/templates/react/src/demos/avatar-demo/page.tsx +135 -0
- package/templates/react/src/demos/badge-demo/page.tsx +174 -0
- package/templates/react/src/demos/breadcrumbs-demo/page.tsx +88 -0
- package/templates/react/src/demos/button-demo/page.tsx +261 -0
- package/templates/react/src/demos/button-group-demo/page.tsx +231 -0
- package/templates/react/src/demos/card-demo/page.tsx +241 -0
- package/templates/react/src/demos/checkbox-demo/page.tsx +79 -0
- package/templates/react/src/demos/chip-demo/page.tsx +197 -0
- package/templates/react/src/demos/date-demo/page.tsx +179 -0
- package/templates/react/src/demos/dropdown-demo/page.tsx +150 -0
- package/templates/react/src/demos/file-dropzone-demo/page.tsx +186 -0
- package/templates/react/src/demos/handle-demo/page.tsx +313 -0
- package/templates/react/src/demos/icon-demo/page.tsx +72 -0
- package/templates/react/src/demos/input-feedback-demo/page.tsx +202 -0
- package/templates/react/src/demos/input-label-demo/page.tsx +392 -0
- package/templates/react/src/demos/loader-demo/page.tsx +138 -0
- package/templates/react/src/demos/logo-demo/page.tsx +292 -0
- package/templates/react/src/demos/menu-demo/page.tsx +70 -0
- package/templates/react/src/demos/modal-demo/page.tsx +332 -0
- package/templates/react/src/demos/navbar-demo/page.tsx +141 -0
- package/templates/react/src/demos/number-input-demo/page.tsx +180 -0
- package/templates/react/src/demos/pagination-demo/page.tsx +147 -0
- package/templates/react/src/demos/panel-demo/page.tsx +376 -0
- package/templates/react/src/demos/progress-demo/page.tsx +185 -0
- package/templates/react/src/demos/radio-demo/page.tsx +242 -0
- package/templates/react/src/demos/rating-demo/page.tsx +97 -0
- package/templates/react/src/demos/select-demo/page.tsx +111 -0
- package/templates/react/src/demos/side-navigation-demo/page.tsx +775 -0
- package/templates/react/src/demos/skeleton-demo/page.tsx +107 -0
- package/templates/react/src/demos/slider-demo/page.tsx +78 -0
- package/templates/react/src/demos/stepper-demo/page.tsx +86 -0
- package/templates/react/src/demos/switch-demo/page.tsx +146 -0
- package/templates/react/src/demos/table-demo/page.tsx +489 -0
- package/templates/react/src/demos/tabs-demo/page.tsx +187 -0
- package/templates/react/src/demos/text-input-demo/page.tsx +151 -0
- package/templates/react/src/demos/textarea-demo/page.tsx +73 -0
- package/templates/react/src/demos/theme-switcher-demo/page.tsx +26 -0
- package/templates/react/src/demos/time-input-demo/page.tsx +148 -0
- package/templates/react/src/demos/toast-demo/page.tsx +302 -0
- package/templates/react/src/demos/toolbar-demo/page.tsx +49 -0
- package/templates/react/src/demos/tooltip-demo/page.tsx +209 -0
- package/templates/react/src/demos/typography-test/page.tsx +28 -0
- package/templates/react/src/demos/utility-panel-demo/page.tsx +197 -0
- package/templates/react/src/dev/DevPanel.tsx +219 -0
- package/templates/react/src/dev/DevPanelContext.ts +14 -0
- package/templates/react/src/dev/DevPanelProvider.tsx +63 -0
- package/templates/react/src/dev/DevRoutes.tsx +98 -0
- package/templates/react/src/dev/config.ts +127 -0
- package/templates/react/src/dev/index.ts +8 -0
- package/templates/react/src/dev/useDevPanel.ts +17 -0
- package/templates/react/src/dev-pages/ColorPalettePage.tsx +347 -0
- package/templates/react/src/dev-pages/ComponentsGalleryPage.tsx +489 -0
- package/templates/react/src/dev-pages/IconsPage.tsx +137 -0
- package/templates/react/src/dev-pages/index.ts +3 -0
- package/templates/react/src/hooks/useTheme.ts +15 -0
- package/templates/react/src/index.css +635 -0
- package/templates/react/src/main.tsx +14 -0
- package/templates/react/src/pages/HomePage.tsx +283 -0
- package/templates/react/src/vite-env.d.ts +9 -0
- package/templates/react/tailwind.config.js +58 -0
- package/templates/react/tsconfig.app.json +27 -0
- package/templates/react/tsconfig.json +7 -0
- package/templates/react/tsconfig.node.json +25 -0
- package/templates/react/vite.config.ts +18 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Comprehensive Gestalt Laws with real-world examples and Modus Design System integration
|
|
3
|
+
globs: ["**/*.tsx", "**/*.ts"]
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Gestalt Laws in UI Design - Detailed Implementation Guide
|
|
8
|
+
|
|
9
|
+
**Scope**: Comprehensive Gestalt Laws with Real-World Examples and Modus Design System Integration
|
|
10
|
+
|
|
11
|
+
The Gestalt Laws are fundamental principles of visual perception that explain how humans naturally organize visual elements. When applied to UI design, these laws create intuitive, user-friendly interfaces that feel natural and reduce cognitive load.
|
|
12
|
+
|
|
13
|
+
## 1. Law of Proximity
|
|
14
|
+
|
|
15
|
+
**Definition:** Elements that are close together are perceived as related or grouped together.
|
|
16
|
+
|
|
17
|
+
**Real-World Example:** In a contact list, the name, phone number, and email address for each person are grouped closely together with small gaps (`gap-2`), while each contact is separated by larger gaps (`gap-6` to `gap-8`) from other contacts.
|
|
18
|
+
|
|
19
|
+
**Implementation:**
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
// Contact list example
|
|
23
|
+
<div className="space-y-6">
|
|
24
|
+
{contacts.map((contact) => (
|
|
25
|
+
<div
|
|
26
|
+
key={contact.id}
|
|
27
|
+
className="flex items-center gap-2 p-4 bg-card border border-border rounded-lg"
|
|
28
|
+
>
|
|
29
|
+
<ModusAvatar name={contact.name} size="md" />
|
|
30
|
+
<div className="flex flex-col gap-1">
|
|
31
|
+
<div className="text-foreground font-medium">{contact.name}</div>
|
|
32
|
+
<div className="text-muted-foreground text-sm">{contact.email}</div>
|
|
33
|
+
<div className="text-muted-foreground text-sm">{contact.phone}</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
))}
|
|
37
|
+
</div>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Key Rules:**
|
|
41
|
+
|
|
42
|
+
- Use `gap-2` for related elements within a group
|
|
43
|
+
- Use `gap-6` to `gap-8` for separation between different groups
|
|
44
|
+
- Group form labels with their inputs using `gap-2`
|
|
45
|
+
- Separate different sections with `gap-6` or larger
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2. Law of Similarity
|
|
50
|
+
|
|
51
|
+
**Definition:** Elements that look similar (same color, shape, size, or style) are perceived as related or belonging to the same category.
|
|
52
|
+
|
|
53
|
+
**Real-World Example:** In a dashboard, all primary action buttons use the same `variant="primary"` style, all secondary actions use `variant="secondary"`, and all destructive actions use `variant="danger"`. This creates visual consistency that users can quickly understand.
|
|
54
|
+
|
|
55
|
+
**Implementation:**
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
// Dashboard action buttons
|
|
59
|
+
<div className="flex gap-4">
|
|
60
|
+
<ModusButton variant="primary" size="medium">Save Changes</ModusButton>
|
|
61
|
+
<ModusButton variant="secondary" size="medium">Cancel</ModusButton>
|
|
62
|
+
<ModusButton variant="danger" size="medium">Delete</ModusButton>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
// Status indicators
|
|
66
|
+
<div className="flex gap-2">
|
|
67
|
+
<ModusBadge variant="success">Active</ModusBadge>
|
|
68
|
+
<ModusBadge variant="warning">Pending</ModusBadge>
|
|
69
|
+
<ModusBadge variant="destructive">Error</ModusBadge>
|
|
70
|
+
</div>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Key Rules:**
|
|
74
|
+
|
|
75
|
+
- Same purpose = same variant, same size
|
|
76
|
+
- Use consistent color coding for status indicators
|
|
77
|
+
- Maintain visual hierarchy through consistent styling
|
|
78
|
+
- Group similar interactive elements together
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 3. Law of Common Region
|
|
83
|
+
|
|
84
|
+
**Definition:** Elements that are enclosed within the same boundary are perceived as related or grouped together.
|
|
85
|
+
|
|
86
|
+
**Real-World Example:** In an e-commerce product page, all product details (name, price, description, specifications) are contained within a single card, while customer reviews are in a separate card below. This creates clear visual separation between different types of information.
|
|
87
|
+
|
|
88
|
+
**Implementation:**
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// Product details card
|
|
92
|
+
<ModusCard className="p-6 bg-card border border-border rounded-lg">
|
|
93
|
+
<div className="space-y-4">
|
|
94
|
+
<div className="flex items-start justify-between">
|
|
95
|
+
<h1 className="text-2xl font-bold text-foreground">Product Name</h1>
|
|
96
|
+
<div className="text-3xl font-bold text-primary">$99.99</div>
|
|
97
|
+
</div>
|
|
98
|
+
<p className="text-muted-foreground">Product description goes here...</p>
|
|
99
|
+
<div className="flex gap-4">
|
|
100
|
+
<ModusButton variant="primary">Add to Cart</ModusButton>
|
|
101
|
+
<ModusButton variant="secondary">Add to Wishlist</ModusButton>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</ModusCard>
|
|
105
|
+
|
|
106
|
+
// Separate reviews card
|
|
107
|
+
<ModusCard className="p-6 bg-card border border-border rounded-lg mt-6">
|
|
108
|
+
<h2 className="text-xl font-semibold text-foreground mb-4">Customer Reviews</h2>
|
|
109
|
+
{/* Reviews content */}
|
|
110
|
+
</ModusCard>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Key Rules:**
|
|
114
|
+
|
|
115
|
+
- Use `ModusCard` with `bg-card` and `border-border` for grouping
|
|
116
|
+
- Apply consistent padding (`p-6`) within cards
|
|
117
|
+
- Use `rounded-lg` for visual containment
|
|
118
|
+
- Separate different content types into different cards
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 4. Law of Figure/Ground
|
|
123
|
+
|
|
124
|
+
**Definition:** The visual system automatically separates elements into foreground (figure) and background (ground). The figure appears to stand out from the background.
|
|
125
|
+
|
|
126
|
+
**Real-World Example:** In a modal dialog, the modal content (figure) stands out clearly against the darkened background overlay (ground). The modal appears to "float" above the page content, making it the clear focus of attention.
|
|
127
|
+
|
|
128
|
+
**Implementation:**
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
// Modal with figure/ground separation
|
|
132
|
+
<ModusModal isOpen={isOpen} onClose={onClose}>
|
|
133
|
+
<div className="bg-card border border-border rounded-lg p-6 shadow-lg">
|
|
134
|
+
<div className="text-xl font-semibold text-foreground mb-4">Confirm Action</div>
|
|
135
|
+
<div className="text-muted-foreground mb-6">Are you sure you want to delete this item?</div>
|
|
136
|
+
<div className="flex gap-4 justify-end">
|
|
137
|
+
<ModusButton variant="secondary" onClick={onClose}>Cancel</ModusButton>
|
|
138
|
+
<ModusButton variant="danger" onClick={handleDelete}>Delete</ModusButton>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</ModusModal>
|
|
142
|
+
|
|
143
|
+
// Card on background
|
|
144
|
+
<div className="bg-background min-h-screen p-6">
|
|
145
|
+
<ModusCard className="p-6 bg-card border border-border rounded-lg shadow-sm">
|
|
146
|
+
{/* Card content stands out from background */}
|
|
147
|
+
</ModusCard>
|
|
148
|
+
</div>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Key Rules:**
|
|
152
|
+
|
|
153
|
+
- Use `bg-card` over `bg-background` for figure/ground separation
|
|
154
|
+
- Apply shadows (`shadow-sm`, `shadow-lg`) to enhance separation
|
|
155
|
+
- Use borders (`border-border`) to define boundaries
|
|
156
|
+
- Ensure sufficient contrast between figure and ground
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 5. Law of Continuity
|
|
161
|
+
|
|
162
|
+
**Definition:** The eye tends to follow continuous lines, curves, or patterns, creating a sense of flow and direction.
|
|
163
|
+
|
|
164
|
+
**Real-World Example:** In a horizontal navigation menu, the eye naturally follows the line of menu items from left to right. In a form, the eye follows the vertical flow from label to input to the next label-input pair.
|
|
165
|
+
|
|
166
|
+
**Implementation:**
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
// Horizontal navigation with continuity
|
|
170
|
+
<div className="flex items-center gap-8 border-b border-border pb-4">
|
|
171
|
+
<ModusButton variant="tertiary">Home</ModusButton>
|
|
172
|
+
<ModusButton variant="tertiary">Products</ModusButton>
|
|
173
|
+
<ModusButton variant="tertiary">About</ModusButton>
|
|
174
|
+
<ModusButton variant="tertiary">Contact</ModusButton>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
// Form with vertical continuity
|
|
178
|
+
<form className="space-y-6">
|
|
179
|
+
<div className="flex flex-col gap-2">
|
|
180
|
+
<label className="text-sm font-medium text-foreground">First Name</label>
|
|
181
|
+
<ModusTextInput placeholder="Enter first name" />
|
|
182
|
+
</div>
|
|
183
|
+
<div className="flex flex-col gap-2">
|
|
184
|
+
<label className="text-sm font-medium text-foreground">Last Name</label>
|
|
185
|
+
<ModusTextInput placeholder="Enter last name" />
|
|
186
|
+
</div>
|
|
187
|
+
<div className="flex flex-col gap-2">
|
|
188
|
+
<label className="text-sm font-medium text-foreground">Email</label>
|
|
189
|
+
<ModusTextInput type="email" placeholder="Enter email" />
|
|
190
|
+
</div>
|
|
191
|
+
</form>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Key Rules:**
|
|
195
|
+
|
|
196
|
+
- Maintain alignment using `flex`, `items-start`, `justify-between`
|
|
197
|
+
- Use consistent spacing (`space-y-6`, `gap-2`) for flow
|
|
198
|
+
- Align related elements along common axes
|
|
199
|
+
- Create clear visual paths for the eye to follow
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 6. Hick's Law
|
|
204
|
+
|
|
205
|
+
**Definition:** The time it takes to make a decision increases with the number and complexity of choices available.
|
|
206
|
+
|
|
207
|
+
**Real-World Example:** A toolbar with 15 different buttons creates decision paralysis. Instead, show only the 3 most important actions (Save, Cancel, Delete) and move secondary actions to a dropdown menu or secondary toolbar.
|
|
208
|
+
|
|
209
|
+
**Implementation:**
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
// Good: Limited primary actions
|
|
213
|
+
<div className="flex items-center justify-between gap-4">
|
|
214
|
+
<div className="flex items-center gap-2">
|
|
215
|
+
<ModusIcon name="filter-list" size="md" decorative />
|
|
216
|
+
<ModusSelect placeholder="Filter by" options={filterOptions} />
|
|
217
|
+
</div>
|
|
218
|
+
<div className="flex gap-2">
|
|
219
|
+
<ModusButton variant="primary">Save</ModusButton>
|
|
220
|
+
<ModusButton variant="secondary">Cancel</ModusButton>
|
|
221
|
+
<ModusDropdownMenu>
|
|
222
|
+
<ModusButton variant="tertiary">More Actions</ModusButton>
|
|
223
|
+
{/* Additional actions in dropdown */}
|
|
224
|
+
</ModusDropdownMenu>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
// Bad: Too many choices
|
|
229
|
+
<div className="flex gap-2">
|
|
230
|
+
<ModusButton variant="primary">Save</ModusButton>
|
|
231
|
+
<ModusButton variant="secondary">Cancel</ModusButton>
|
|
232
|
+
<ModusButton variant="tertiary">Edit</ModusButton>
|
|
233
|
+
<ModusButton variant="tertiary">Copy</ModusButton>
|
|
234
|
+
<ModusButton variant="tertiary">Move</ModusButton>
|
|
235
|
+
<ModusButton variant="tertiary">Share</ModusButton>
|
|
236
|
+
<ModusButton variant="tertiary">Archive</ModusButton>
|
|
237
|
+
<ModusButton variant="danger">Delete</ModusButton>
|
|
238
|
+
</div>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Key Rules:**
|
|
242
|
+
|
|
243
|
+
- Maximum 3 visible CTAs per context
|
|
244
|
+
- Move secondary actions to dropdown menus
|
|
245
|
+
- Use progressive disclosure for complex interfaces
|
|
246
|
+
- Prioritize actions by frequency of use
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 7. Fitts's Law
|
|
251
|
+
|
|
252
|
+
**Definition:** The time required to move to a target is a function of the distance to the target and the size of the target.
|
|
253
|
+
|
|
254
|
+
**Real-World Example:** In a text editor, the "Save" button should be large and positioned near the text area where users are working. A small "Save" button in the top-right corner requires more precision and time to click.
|
|
255
|
+
|
|
256
|
+
**Implementation:**
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
// Good: Large, accessible buttons near content
|
|
260
|
+
<div className="flex flex-col gap-4">
|
|
261
|
+
<ModusTextarea
|
|
262
|
+
placeholder="Write your content here..."
|
|
263
|
+
className="min-h-32"
|
|
264
|
+
/>
|
|
265
|
+
<div className="flex gap-2">
|
|
266
|
+
<ModusButton variant="primary" size="large">Save</ModusButton>
|
|
267
|
+
<ModusButton variant="secondary" size="large">Cancel</ModusButton>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
// Good: Floating action button for primary action
|
|
272
|
+
<div className="fixed bottom-6 right-6">
|
|
273
|
+
<ModusButton
|
|
274
|
+
variant="primary"
|
|
275
|
+
size="large"
|
|
276
|
+
className="w-14 h-14 rounded-full shadow-lg"
|
|
277
|
+
>
|
|
278
|
+
<ModusIcon name="plus" size="lg" decorative />
|
|
279
|
+
</ModusButton>
|
|
280
|
+
</div>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Key Rules:**
|
|
284
|
+
|
|
285
|
+
- Keep primary CTAs near edited content
|
|
286
|
+
- Minimum 44×44px touch targets
|
|
287
|
+
- Use `size="large"` for important actions
|
|
288
|
+
- Position frequently used controls within easy reach
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 8. Serial Position Effect
|
|
293
|
+
|
|
294
|
+
**Definition:** Users best remember the first and last items in a series, with the first item having the strongest recall (primacy effect) and the last item having good recall (recency effect).
|
|
295
|
+
|
|
296
|
+
**Real-World Example:** In a navigation menu, place the most important item (like "Dashboard") first, and the least important item (like "Settings") last. In a form, put the most critical field first and the submit button last.
|
|
297
|
+
|
|
298
|
+
**Implementation:**
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
// Navigation with serial position consideration
|
|
302
|
+
<div className="flex flex-col gap-1">
|
|
303
|
+
<ModusButton variant="primary" className="justify-start">Dashboard</ModusButton>
|
|
304
|
+
<ModusButton variant="tertiary" className="justify-start">Projects</ModusButton>
|
|
305
|
+
<ModusButton variant="tertiary" className="justify-start">Tasks</ModusButton>
|
|
306
|
+
<ModusButton variant="tertiary" className="justify-start">Reports</ModusButton>
|
|
307
|
+
<ModusButton variant="tertiary" className="justify-start">Settings</ModusButton>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
// Form with serial position
|
|
311
|
+
<form className="space-y-6">
|
|
312
|
+
<div className="flex flex-col gap-2">
|
|
313
|
+
<label className="text-sm font-medium text-foreground">Email *</label>
|
|
314
|
+
<ModusTextInput type="email" required />
|
|
315
|
+
</div>
|
|
316
|
+
<div className="flex flex-col gap-2">
|
|
317
|
+
<label className="text-sm font-medium text-foreground">Password *</label>
|
|
318
|
+
<ModusTextInput type="password" required />
|
|
319
|
+
</div>
|
|
320
|
+
<div className="flex flex-col gap-2">
|
|
321
|
+
<label className="text-sm font-medium text-foreground">Confirm Password *</label>
|
|
322
|
+
<ModusTextInput type="password" required />
|
|
323
|
+
</div>
|
|
324
|
+
<div className="flex gap-4 pt-4">
|
|
325
|
+
<ModusButton variant="primary" type="submit">Create Account</ModusButton>
|
|
326
|
+
<ModusButton variant="secondary" type="button">Cancel</ModusButton>
|
|
327
|
+
</div>
|
|
328
|
+
</form>
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Key Rules:**
|
|
332
|
+
|
|
333
|
+
- Place primary actions at start or end of flow
|
|
334
|
+
- Put most important information first
|
|
335
|
+
- Position secondary actions in the middle
|
|
336
|
+
- Use visual hierarchy to reinforce importance
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 9. Law of Prägnanz (Simplicity)
|
|
341
|
+
|
|
342
|
+
**Definition:** People tend to perceive the simplest, most stable interpretation of visual elements. The mind prefers simplicity over complexity.
|
|
343
|
+
|
|
344
|
+
**Real-World Example:** A clean, minimal interface with plenty of white space is easier to understand than a cluttered interface with many borders, colors, and decorative elements. Users can focus on the content rather than being distracted by visual noise.
|
|
345
|
+
|
|
346
|
+
**Implementation:**
|
|
347
|
+
|
|
348
|
+
```tsx
|
|
349
|
+
// Good: Clean, simple design
|
|
350
|
+
<div className="bg-background min-h-screen p-6">
|
|
351
|
+
<div className="max-w-4xl mx-auto space-y-8">
|
|
352
|
+
<div className="text-center space-y-4">
|
|
353
|
+
<div className="text-4xl font-bold text-foreground">Welcome</div>
|
|
354
|
+
<div className="text-xl text-muted-foreground">Get started with your project</div>
|
|
355
|
+
</div>
|
|
356
|
+
|
|
357
|
+
<ModusCard className="p-8 bg-card border border-border rounded-lg">
|
|
358
|
+
<div className="space-y-6">
|
|
359
|
+
<div className="text-2xl font-semibold text-foreground">Create New Project</div>
|
|
360
|
+
<div className="space-y-4">
|
|
361
|
+
<ModusTextInput placeholder="Project name" />
|
|
362
|
+
<ModusTextarea placeholder="Project description" />
|
|
363
|
+
</div>
|
|
364
|
+
<div className="flex gap-4">
|
|
365
|
+
<ModusButton variant="primary">Create Project</ModusButton>
|
|
366
|
+
<ModusButton variant="secondary">Cancel</ModusButton>
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
</ModusCard>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
|
|
373
|
+
// Bad: Cluttered, complex design
|
|
374
|
+
<div className="bg-background min-h-screen p-6">
|
|
375
|
+
<div className="max-w-4xl mx-auto space-y-8">
|
|
376
|
+
<div className="text-center space-y-4 border-2 border-primary rounded-lg p-6 bg-primary/10">
|
|
377
|
+
<div className="text-4xl font-bold text-foreground">Welcome</div>
|
|
378
|
+
<div className="text-xl text-muted-foreground">Get started with your project</div>
|
|
379
|
+
</div>
|
|
380
|
+
|
|
381
|
+
<ModusCard className="p-8 bg-card border-2 border-border rounded-lg shadow-lg">
|
|
382
|
+
<div className="space-y-6 border-t border-b border-border py-4">
|
|
383
|
+
<div className="text-2xl font-semibold text-foreground">Create New Project</div>
|
|
384
|
+
<div className="space-y-4">
|
|
385
|
+
<div className="border border-border rounded p-2">
|
|
386
|
+
<ModusTextInput placeholder="Project name" />
|
|
387
|
+
</div>
|
|
388
|
+
<div className="border border-border rounded p-2">
|
|
389
|
+
<ModusTextarea placeholder="Project description" />
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
<div className="flex gap-4 border-t border-border pt-4">
|
|
393
|
+
<ModusButton variant="primary">Create Project</ModusButton>
|
|
394
|
+
<ModusButton variant="secondary">Cancel</ModusButton>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
</ModusCard>
|
|
398
|
+
</div>
|
|
399
|
+
</div>
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
**Key Rules:**
|
|
403
|
+
|
|
404
|
+
- Remove unnecessary divs, borders, or text
|
|
405
|
+
- Prefer whitespace over visual elements
|
|
406
|
+
- Use consistent spacing and alignment
|
|
407
|
+
- Focus on content hierarchy over decoration
|
|
408
|
+
- Apply the "less is more" principle
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Implementation Checklist
|
|
413
|
+
|
|
414
|
+
When applying Gestalt Laws to your UI design:
|
|
415
|
+
|
|
416
|
+
- [ ] **Proximity**: Group related elements with `gap-2`, separate groups with `gap-6`+
|
|
417
|
+
- [ ] **Similarity**: Use consistent variants and sizes for similar purposes
|
|
418
|
+
- [ ] **Common Region**: Use `ModusCard` with `bg-card` and `border-border` for grouping
|
|
419
|
+
- [ ] **Figure/Ground**: Create clear separation with `bg-card` over `bg-background`
|
|
420
|
+
- [ ] **Continuity**: Maintain alignment and flow with consistent spacing
|
|
421
|
+
- [ ] **Hick's Law**: Limit to 3 visible CTAs, use dropdowns for secondary actions
|
|
422
|
+
- [ ] **Fitts's Law**: Keep primary actions near content, use 44×44px minimum targets
|
|
423
|
+
- [ ] **Serial Position**: Place important items first and last
|
|
424
|
+
- [ ] **Prägnanz**: Remove unnecessary elements, prefer whitespace
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Real-World Application Examples
|
|
429
|
+
|
|
430
|
+
### E-commerce Product Page
|
|
431
|
+
|
|
432
|
+
- **Proximity**: Product details grouped in one card, reviews in another
|
|
433
|
+
- **Similarity**: All "Add to Cart" buttons use same variant
|
|
434
|
+
- **Common Region**: Product info contained within card boundaries
|
|
435
|
+
- **Figure/Ground**: Product card stands out from page background
|
|
436
|
+
- **Continuity**: Eye flows from image to title to price to buttons
|
|
437
|
+
- **Hick's Law**: Primary action (Add to Cart) prominent, secondary actions in dropdown
|
|
438
|
+
- **Fitts's Law**: Large, accessible "Add to Cart" button
|
|
439
|
+
- **Serial Position**: Product name first, price last in header
|
|
440
|
+
- **Prägnanz**: Clean layout with minimal visual noise
|
|
441
|
+
|
|
442
|
+
### Dashboard Interface
|
|
443
|
+
|
|
444
|
+
- **Proximity**: Related metrics grouped together
|
|
445
|
+
- **Similarity**: All status indicators use consistent badge variants
|
|
446
|
+
- **Common Region**: Each widget contained in its own card
|
|
447
|
+
- **Figure/Ground**: Widgets stand out from dashboard background
|
|
448
|
+
- **Continuity**: Consistent grid layout creates visual flow
|
|
449
|
+
- **Hick's Law**: Main actions in toolbar, secondary in menus
|
|
450
|
+
- **Fitts's Law**: Important controls large and accessible
|
|
451
|
+
- **Serial Position**: Most important widget in top-left
|
|
452
|
+
- **Prägnanz**: Clean, uncluttered dashboard design
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
This comprehensive guide provides the foundation for creating intuitive, user-friendly interfaces that follow established principles of visual perception and human-computer interaction.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: UI/UX foundations for AI agents with validated Modus 2 + Tailwind integration
|
|
3
|
+
globs: ["**/*.tsx", "**/*.ts"]
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# UI/UX Foundations for AI Agents (Validated Modus 2 + Tailwind)
|
|
8
|
+
|
|
9
|
+
**Scope**: Modus 2 React Components + Tailwind (Real Config Alignment)
|
|
10
|
+
|
|
11
|
+
> This file is grounded in your **real Modus 2 React + Tailwind setup**. It uses the exact variables, color tokens, and CSS conventions from your implementation (`--modus-wc-color-*`, `--background`, etc.).
|
|
12
|
+
|
|
13
|
+
# Foundation & Setup
|
|
14
|
+
|
|
15
|
+
## 1 Color System — From Real Tailwind Config
|
|
16
|
+
|
|
17
|
+
### Semantic Mapping
|
|
18
|
+
|
|
19
|
+
Use Tailwind tokens defined in your `tailwind.config.js`. **Do not use arbitrary colors.**
|
|
20
|
+
|
|
21
|
+
| Purpose | Tailwind Token | CSS Variable (from index.css) |
|
|
22
|
+
| ----------- | ------------------------------------------------ | ----------------------------------------------------- |
|
|
23
|
+
| Background | `bg-background` | `--background` → `var(--modus-wc-color-base-page)` |
|
|
24
|
+
| Foreground | `text-foreground` | `--foreground` → `var(--modus-wc-color-base-content)` |
|
|
25
|
+
| Card | `bg-card` | `--card` → `var(--modus-wc-color-base-100)` |
|
|
26
|
+
| Card Text | `text-card-foreground` | `--card-foreground` |
|
|
27
|
+
| Primary | `bg-primary` / `text-primary-foreground` | `--modus-wc-color-info` |
|
|
28
|
+
| Secondary | `bg-secondary` / `text-secondary-foreground` | `--modus-wc-color-base-300` |
|
|
29
|
+
| Muted | `bg-muted` / `text-muted-foreground` | `--modus-wc-color-base-200` |
|
|
30
|
+
| Accent | `bg-accent` / `text-accent-foreground` | `--modus-wc-color-info` |
|
|
31
|
+
| Destructive | `bg-destructive` / `text-destructive-foreground` | `--modus-wc-color-error` |
|
|
32
|
+
| Warning | `bg-warning` / `text-warning-foreground` | `--modus-wc-color-warning` |
|
|
33
|
+
| Success | `bg-success` / `text-success-foreground` | `--modus-wc-color-success` |
|
|
34
|
+
| Border | `border-border` | `--modus-wc-color-base-200` |
|
|
35
|
+
| Ring | `ring` | `--modus-wc-color-info` |
|
|
36
|
+
|
|
37
|
+
**Rules:**
|
|
38
|
+
|
|
39
|
+
- Never use `#hex`, RGB, or inline color CSS.
|
|
40
|
+
- All visual hierarchy comes from semantic tokens.
|
|
41
|
+
- Respect light/dark context (CSS variables auto-handle switching).
|
|
42
|
+
|
|
43
|
+
## 2 Tailwind Config Alignment
|
|
44
|
+
|
|
45
|
+
Your real config already defines the following mapping (keep as-is):
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
colors: {
|
|
49
|
+
background: 'var(--background)',
|
|
50
|
+
foreground: 'var(--foreground)',
|
|
51
|
+
card: 'var(--card)',
|
|
52
|
+
'card-foreground': 'var(--card-foreground)',
|
|
53
|
+
primary: 'var(--primary)',
|
|
54
|
+
'primary-foreground': 'var(--primary-foreground)',
|
|
55
|
+
secondary: 'var(--secondary)',
|
|
56
|
+
'secondary-foreground': 'var(--secondary-foreground)',
|
|
57
|
+
muted: 'var(--muted)',
|
|
58
|
+
'muted-foreground': 'var(--muted-foreground)',
|
|
59
|
+
accent: 'var(--accent)',
|
|
60
|
+
'accent-foreground': 'var(--accent-foreground)',
|
|
61
|
+
destructive: 'var(--destructive)',
|
|
62
|
+
'destructive-foreground': 'var(--destructive-foreground)',
|
|
63
|
+
border: 'var(--border)',
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
# Component System
|
|
68
|
+
|
|
69
|
+
## 3 Example Component System — Modus 2 React Wrappers
|
|
70
|
+
|
|
71
|
+
**REFERENCE**: For more information referance `.cursor/rules/modus-components-reference.mdc`
|
|
72
|
+
|
|
73
|
+
| Component | React Wrapper | Props | Usage Rule | | | | | |
|
|
74
|
+
| --------- | ------------------ | ------------------------------------------- | --------------------------------------------------------------------- | -------- | ---------------------- | ------ | ------- | ----------------------------------------------------- |
|
|
75
|
+
| Button | `<ModusButton />` | `variant="primary | secondary | tertiary | danger"`, `size="small | medium | large"` | One primary action per surface. Destructive uses red. |
|
|
76
|
+
| Card | `<ModusCard />` | `elevation`, `padding`, `bordered` | For grouping or sectioning. Use `bg-card` + `border-border`. | | | | | |
|
|
77
|
+
| Input | `<ModusInput />` | `label`, `error`, `disabled` | Must have a visible `<label>`. Use inline error text + ARIA bindings. | | | | | |
|
|
78
|
+
| Select | `<ModusSelect />` | `options`, `placeholder` | Never rely on placeholder as label. | | | | | |
|
|
79
|
+
| Table | `<ModusTable />` | `columns`, `data`, `sortable`, `onRowClick` | Include empty and loading states. | | | | | |
|
|
80
|
+
| Modal | `<ModusModal />` | `isOpen`, `onClose`, `title` | Trap focus. ESC closes. Max 3 actions. | | | | | |
|
|
81
|
+
| Tabs | `<ModusTabs />` | `tabs`, `activeKey`, `onChange` | Keyboard accessible. | | | | | |
|
|
82
|
+
| Tooltip | `<ModusTooltip />` | `text`, `position` | Short contextual hints only. | | | | | |
|
|
83
|
+
| Icon | `<ModusIcon />` | `name`, `size`, `color` | Follows real Modus naming (kebab-case, outlined default). | | | | | |
|
|
84
|
+
|
|
85
|
+
## 4 Iconography
|
|
86
|
+
|
|
87
|
+
**REFERENCE**: For complete icon usage guidelines see `.cursor/rules/modus-icons-react.mdc`
|
|
88
|
+
**REFERENCE**: For allowed list of Modus icon names see `.cursor/rules/modus-icon-names.mdc`
|
|
89
|
+
|
|
90
|
+
### Import (already handled globally)
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
@import url("https://cdn.jsdelivr.net/npm/@trimble-oss/modus-icons@1.17.0/dist/field-systems/fonts/modus-icons.css");
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Supported Usage Patterns
|
|
97
|
+
|
|
98
|
+
#### A) React Wrapper (preferred)
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
// Informational icon (announced by SR)
|
|
102
|
+
<ModusIcon name="user-add" size="lg" decorative={false} aria-label="Add user" />
|
|
103
|
+
|
|
104
|
+
// Decorative icon (not announced)
|
|
105
|
+
<ModusIcon name="chevron-right" size="md" decorative />
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- **Props:** `name` (kebab-case), `size`: `sm | md | lg` (mapped to Tailwind text sizes), `decorative`: boolean.
|
|
109
|
+
- **Accessibility:** If `decorative={false}`, include `aria-label`.
|
|
110
|
+
- **Do not** pass numeric pixel sizes like `{24}`.
|
|
111
|
+
|
|
112
|
+
#### B) Bare `<i>` Glyph (CDN font)
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
// Decorative icon
|
|
116
|
+
<i className="modus-icons text-lg" aria-hidden="true">user-add</i>
|
|
117
|
+
|
|
118
|
+
// Informational icon
|
|
119
|
+
<i className="modus-icons text-md" role="img" aria-label="Settings">settings</i>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- Size using Tailwind text utilities (`text-sm`, `text-md`, `text-lg`).
|
|
123
|
+
- Keep color semantic (`text-foreground`, `text-muted-foreground`, etc.).
|
|
124
|
+
|
|
125
|
+
### Rules
|
|
126
|
+
|
|
127
|
+
- Naming: **kebab-case** (`file-upload`, `user-add`).
|
|
128
|
+
- Style: outlined default; filled for active/selected states only.
|
|
129
|
+
- One icon per control.
|
|
130
|
+
- In buttons: icon left, `gap-2` between icon and label, aligned baseline.
|
|
131
|
+
|
|
132
|
+
# Design Principles
|
|
133
|
+
|
|
134
|
+
## 5 Gestalt Laws in Practice (UI Layout Rules)
|
|
135
|
+
|
|
136
|
+
**REFERENCE**: For more information referance `.cursor/rules/ux/gestalt-laws-detailed.mdc`
|
|
137
|
+
|
|
138
|
+
| Law | Implementation |
|
|
139
|
+
| ------------------- | ---------------------------------------------------------------------------- |
|
|
140
|
+
| **Proximity** | `gap-2` within a group; `gap-6`–`gap-8` between groups. |
|
|
141
|
+
| **Similarity** | Same purpose = same variant, same size. |
|
|
142
|
+
| **Common Region** | Group with `<ModusCard className="p-6 bg-card border-border rounded-lg" />`. |
|
|
143
|
+
| **Figure/Ground** | Use `bg-card` over `bg-background` with shadow or border. |
|
|
144
|
+
| **Continuity** | Maintain alignment using `flex`, `items-start`, `justify-between`. |
|
|
145
|
+
| **Hick's** | Max 3 visible CTAs per context. Overflow extra in menu. |
|
|
146
|
+
| **Fitts's** | Keep primary CTAs near edited content, 44×44px minimum. |
|
|
147
|
+
| **Serial Position** | Primary actions at start or end of flow. |
|
|
148
|
+
| **Prägnanz** | Remove unnecessary divs, borders, or text. Prefer whitespace. |
|
|
149
|
+
|
|
150
|
+
# Implementation Examples
|
|
151
|
+
|
|
152
|
+
## 6 Example Snippets
|
|
153
|
+
|
|
154
|
+
### Form Card
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<ModusCard className="bg-card border border-border rounded-lg p-6">
|
|
158
|
+
<div className="flex items-center justify-between">
|
|
159
|
+
<div className="text-foreground text-lg font-medium">Profile</div>
|
|
160
|
+
<ModusButton variant="primary">Save</ModusButton>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mt-6">
|
|
164
|
+
<div className="flex flex-col gap-2">
|
|
165
|
+
<label htmlFor="email" className="text-sm text-muted-foreground">
|
|
166
|
+
Email
|
|
167
|
+
</label>
|
|
168
|
+
<ModusInput id="email" name="email" type="email" required />
|
|
169
|
+
<div className="text-xs text-muted-foreground">
|
|
170
|
+
Used for notifications
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</ModusCard>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Toolbar
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
<div className="flex items-center justify-between gap-4 border-b border-border pb-4">
|
|
181
|
+
<div className="flex items-center gap-2">
|
|
182
|
+
<ModusIcon name="filter-list" size="md" decorative />
|
|
183
|
+
<ModusSelect placeholder="Sort by" options={sortOptions} />
|
|
184
|
+
</div>
|
|
185
|
+
<ModusButton variant="primary" icon="plus">
|
|
186
|
+
New
|
|
187
|
+
</ModusButton>
|
|
188
|
+
</div>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
# AI Guidelines
|
|
192
|
+
|
|
193
|
+
## 7 AI Output Contract
|
|
194
|
+
|
|
195
|
+
- Use `<ModusIcon size="sm|md|lg" />`, never numeric.
|
|
196
|
+
- Use `decorative` and `aria-label` correctly.
|
|
197
|
+
- Accept either `<ModusIcon>` or `<i className="modus-icons">` per context.
|
|
198
|
+
- All Tailwind utilities must use semantic tokens from config.
|
|
199
|
+
- Accessibility attributes required for all interactive elements.
|
|
200
|
+
- All motion ≤250ms; respect `prefers-reduced-motion`.
|
|
201
|
+
|
|
202
|
+
## 8 PR / QA Checklist
|
|
203
|
+
|
|
204
|
+
- [ ] All UI uses `<Modus*>` wrappers.
|
|
205
|
+
- [ ] Tailwind tokens match config.
|
|
206
|
+
- [ ] ARIA, labels, keyboard, and focus verified.
|
|
207
|
+
- [ ] Empty/loading/error states present.
|
|
208
|
+
- [ ] Only one primary CTA per surface.
|
|
209
|
+
- [ ] Spacing follows 4/8 rhythm (`gap-2`, `gap-4`, `gap-8`).
|
|
210
|
+
- [ ] Colors from real variables only (`--modus-wc-color-*`).
|
|
211
|
+
- [ ] No theme attributes; dark/light handled via root vars.
|