@exxatdesignux/ui 0.5.11 → 0.5.12
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/CHANGELOG.md +26 -0
- package/bin/cli.mjs +70 -1
- package/bin/init.mjs +18 -4
- package/bin/sync-extras.mjs +28 -4
- package/consumer-extras/README.md +41 -5
- package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
- package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
- package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
- package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
- package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
- package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
- package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
- package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
- package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
- package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
- package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
- package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
- package/consumer-extras/patterns/command-menu-pattern.md +2 -2
- package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
- package/consumer-extras/patterns/jobs/README.md +1 -1
- package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
- package/consumer-extras/scripts/dev-guard.mjs +156 -0
- package/consumer-extras/templates/README.md +23 -0
- package/consumer-extras/templates/handoff.md +190 -0
- package/package.json +2 -2
- package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
- package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
- package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
- package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
- package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
- package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
- package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
- package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
- package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
- package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
- package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
- package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
- package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
- package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
- package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
- package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
- package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
- package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
- package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
- package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
- package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
- package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
- package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
- package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
- package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
- package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
- package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
- package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
- package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
- package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
- package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
- package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
- package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
- package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
- package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
- package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
- package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
- package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
- package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
- package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
- package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
- package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
- package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
- package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
- package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
- package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
- package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
- package/{template → template-vite}/components/command-menu.tsx +1 -1
- package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
- package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
- package/{template → template-vite}/components/library-client.tsx +1 -1
- package/{template → template-vite}/components/library-hub-client.tsx +2 -2
- package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/library-table.tsx +35 -27
- package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
- package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
- package/{template → template-vite}/components/settings-client.tsx +1 -1
- package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
- package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
- package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
- package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
- package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
- package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
- package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
- package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
- package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
- package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
- package/template-vite/index.html +49 -0
- package/template-vite/lib/next-compat.tsx +98 -0
- package/{template → template-vite}/package.json +15 -27
- package/template-vite/scripts/port-next-imports.mjs +70 -0
- package/template-vite/src/App.tsx +103 -0
- package/template-vite/src/main.tsx +50 -0
- package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
- package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
- package/template-vite/src/pages/_not-found.tsx +17 -0
- package/template-vite/src/pages/dashboard.tsx +48 -0
- package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
- package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
- package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
- package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
- package/template-vite/src/routes.tsx +72 -0
- package/{template/app → template-vite/src/styles}/globals.css +6 -2
- package/{template → template-vite}/tsconfig.json +5 -14
- package/template-vite/vite.config.ts +52 -0
- package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
- package/template/.agents/skills/shadcn/SKILL.md +0 -242
- package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
- package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/template/.agents/skills/shadcn/cli.md +0 -257
- package/template/.agents/skills/shadcn/customization.md +0 -202
- package/template/.agents/skills/shadcn/evals/evals.json +0 -47
- package/template/.agents/skills/shadcn/mcp.md +0 -94
- package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
- package/template/.agents/skills/shadcn/rules/composition.md +0 -195
- package/template/.agents/skills/shadcn/rules/forms.md +0 -192
- package/template/.agents/skills/shadcn/rules/icons.md +0 -101
- package/template/.agents/skills/shadcn/rules/styling.md +0 -162
- package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
- package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
- package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
- package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
- package/template/.nvmrc +0 -1
- package/template/.prettierignore +0 -7
- package/template/Logo/Exxat_Prism.svg +0 -39
- package/template/Logo/Exxat_one.svg +0 -36
- package/template/app/(app)/dashboard/loading.tsx +0 -18
- package/template/app/(app)/dashboard/page.tsx +0 -36
- package/template/app/(app)/layout.tsx +0 -77
- package/template/app/global-error.tsx +0 -63
- package/template/app/layout.tsx +0 -133
- package/template/app/page.tsx +0 -9
- package/template/docs/HANDBOOK.md +0 -187
- package/template/docs/blueprints/README.md +0 -86
- package/template/docs/blueprints/_template.md +0 -91
- package/template/docs/blueprints/board-card.md +0 -123
- package/template/docs/blueprints/data-table.md +0 -139
- package/template/docs/blueprints/key-metrics.md +0 -128
- package/template/docs/blueprints/list-page-template.md +0 -123
- package/template/docs/blueprints/page-header.md +0 -130
- package/template/docs/card-vs-rows-pattern.md +0 -36
- package/template/docs/collaboration-access-pattern.md +0 -116
- package/template/docs/command-menu-pattern.md +0 -45
- package/template/docs/component-selection-guide.md +0 -224
- package/template/docs/components-audit-2026-05.md +0 -158
- package/template/docs/consumer-upgrade-checklist.md +0 -52
- package/template/docs/data-views-pattern.md +0 -185
- package/template/docs/drawer-vs-dialog-pattern.md +0 -50
- package/template/docs/glossary.md +0 -59
- package/template/docs/hub-supported-views-pattern.md +0 -53
- package/template/docs/jobs/README.md +0 -59
- package/template/docs/jobs/record-detail.md +0 -177
- package/template/docs/kpi-flat-band-pattern.md +0 -57
- package/template/docs/kpi-strip-max-four-pattern.md +0 -30
- package/template/docs/kpi-trend-pattern.md +0 -58
- package/template/docs/large-dataset-strategy.md +0 -155
- package/template/docs/library-hub-header-pattern.md +0 -25
- package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
- package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
- package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
- package/template/docs/migrations/README.md +0 -100
- package/template/docs/migrations/_template.md +0 -64
- package/template/docs/modern-saas-patterns.md +0 -165
- package/template/docs/perf-memory-pattern.md +0 -206
- package/template/docs/reference-implementations.md +0 -153
- package/template/docs/shell-surface-elevation-pattern.md +0 -52
- package/template/docs/token-taxonomy.md +0 -416
- package/template/docs/voice-and-tone.md +0 -262
- package/template/ecosystem.config.cjs +0 -32
- package/template/next.config.mjs +0 -216
- package/template/postcss.config.mjs +0 -8
- package/template/public/favicon/favicon.ico +0 -0
- package/template/tests/setup.ts +0 -26
- package/template/vitest.config.ts +0 -18
- /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
- /package/{template → template-vite}/.prettierrc +0 -0
- /package/{template → template-vite}/AGENTS.md +0 -0
- /package/{template → template-vite}/README.md +0 -0
- /package/{template → template-vite}/components/.gitkeep +0 -0
- /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
- /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
- /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
- /package/{template → template-vite}/components/charts-overview.tsx +0 -0
- /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
- /package/{template → template-vite}/components/columns-client.tsx +0 -0
- /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
- /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
- /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
- /package/{template → template-vite}/components/data-table/index.tsx +0 -0
- /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
- /package/{template → template-vite}/components/data-table/types.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
- /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
- /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
- /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
- /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
- /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
- /package/{template → template-vite}/components/data-views/index.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
- /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
- /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
- /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
- /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
- /package/{template → template-vite}/components/export-drawer.tsx +0 -0
- /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
- /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
- /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
- /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
- /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
- /package/{template → template-vite}/components/key-metrics.tsx +0 -0
- /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
- /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
- /package/{template → template-vite}/components/library-board-view.tsx +0 -0
- /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
- /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
- /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
- /package/{template → template-vite}/components/library-page-header.tsx +0 -0
- /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
- /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
- /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/index.ts +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
- /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
- /package/{template → template-vite}/components/page-header.tsx +0 -0
- /package/{template → template-vite}/components/product-switcher.tsx +0 -0
- /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
- /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
- /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/index.ts +0 -0
- /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
- /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
- /package/{template → template-vite}/components/site-header.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
- /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/index.ts +0 -0
- /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
- /package/{template → template-vite}/components/table-properties/types.ts +0 -0
- /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
- /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
- /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
- /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
- /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
- /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
- /package/{template → template-vite}/components/theme-provider.tsx +0 -0
- /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
- /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
- /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
- /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
- /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
- /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
- /package/{template → template-vite}/components/ui/badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/banner.tsx +0 -0
- /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
- /package/{template → template-vite}/components/ui/button.tsx +0 -0
- /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
- /package/{template → template-vite}/components/ui/card.tsx +0 -0
- /package/{template → template-vite}/components/ui/chart.tsx +0 -0
- /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
- /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
- /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
- /package/{template → template-vite}/components/ui/command.tsx +0 -0
- /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
- /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
- /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
- /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
- /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
- /package/{template → template-vite}/components/ui/field.tsx +0 -0
- /package/{template → template-vite}/components/ui/form.tsx +0 -0
- /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
- /package/{template → template-vite}/components/ui/input.tsx +0 -0
- /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
- /package/{template → template-vite}/components/ui/label.tsx +0 -0
- /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
- /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
- /package/{template → template-vite}/components/ui/popover.tsx +0 -0
- /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
- /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
- /package/{template → template-vite}/components/ui/select.tsx +0 -0
- /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
- /package/{template → template-vite}/components/ui/separator.tsx +0 -0
- /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
- /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
- /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
- /package/{template → template-vite}/components/ui/slider.tsx +0 -0
- /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
- /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
- /package/{template → template-vite}/components/ui/table.tsx +0 -0
- /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
- /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
- /package/{template → template-vite}/components/ui/tip.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
- /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
- /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
- /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
- /package/{template → template-vite}/components.json +0 -0
- /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
- /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
- /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
- /package/{template → template-vite}/contexts/product-context.tsx +0 -0
- /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
- /package/{template → template-vite}/eslint.config.mjs +0 -0
- /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
- /package/{template → template-vite}/hooks/.gitkeep +0 -0
- /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
- /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
- /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
- /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
- /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
- /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
- /package/{template → template-vite}/lib/.gitkeep +0 -0
- /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
- /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
- /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
- /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
- /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
- /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
- /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
- /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
- /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
- /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
- /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
- /package/{template → template-vite}/lib/data-list-view.ts +0 -0
- /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
- /package/{template → template-vite}/lib/date-filter.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
- /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
- /package/{template → template-vite}/lib/dev-log.ts +0 -0
- /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
- /package/{template → template-vite}/lib/editable-target.ts +0 -0
- /package/{template → template-vite}/lib/exxat-palette.json +0 -0
- /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
- /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
- /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
- /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
- /package/{template → template-vite}/lib/library-authoring.ts +0 -0
- /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
- /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
- /package/{template → template-vite}/lib/library-nav.ts +0 -0
- /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
- /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
- /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
- /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
- /package/{template → template-vite}/lib/logo-dev.ts +0 -0
- /package/{template → template-vite}/lib/mailto.ts +0 -0
- /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
- /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
- /package/{template → template-vite}/lib/mock/library.ts +0 -0
- /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
- /package/{template → template-vite}/lib/motion-ui.ts +0 -0
- /package/{template → template-vite}/lib/product-brand.ts +0 -0
- /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
- /package/{template → template-vite}/lib/row-height.ts +0 -0
- /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
- /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
- /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
- /package/{template → template-vite}/lib/utils.test.ts +0 -0
- /package/{template → template-vite}/lib/utils.ts +0 -0
- /package/{template → template-vite}/public/.gitkeep +0 -0
- /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
- /package/{template → template-vite}/public/avatars/user.svg +0 -0
- /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
- /package/{template/app → template-vite/public}/favicon.ico +0 -0
- /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
- /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
- /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
- /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
- /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
- /package/{template → template-vite}/skills-lock.json +0 -0
- /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
- /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
- /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
- /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
- /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
- /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
- /package/{template → template-vite}/stores/app-store.ts +0 -0
- /package/{template → template-vite}/types/react-payment-inputs.d.ts +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exxat-senior-ux
|
|
3
|
+
description: >-
|
|
4
|
+
Make the agent behave like a senior UX designer — STOP before writing
|
|
5
|
+
code, understand the problem, study how modern SaaS solves the same job,
|
|
6
|
+
propose a design brief, WAIT for user go-ahead, then build. Load FIRST
|
|
7
|
+
on ANY task that decides what a surface should be — create, build, design,
|
|
8
|
+
rebuild, redesign, replace, redo, refresh, modernize, re-imagine, "make a
|
|
9
|
+
new version", "instead of what we have", "from scratch" — for any page,
|
|
10
|
+
route, hub, detail view, wizard, settings section, dashboard, dialog,
|
|
11
|
+
sheet, drawer, panel, layout, or significant component. Also load when
|
|
12
|
+
the user attaches a screenshot / mockup / Figma link and asks to build
|
|
13
|
+
it. Load BEFORE opening AGENTS.md, blueprints, or any other DS doc.
|
|
14
|
+
user-invocable: true
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Exxat DS — senior UX (read this BEFORE you design)
|
|
18
|
+
|
|
19
|
+
You are not a typing assistant. You are a senior product designer with 10+
|
|
20
|
+
years across modern SaaS (Linear, Notion, Stripe, Figma, Vercel-class
|
|
21
|
+
products). You design for the **user's job**, not the user's words.
|
|
22
|
+
|
|
23
|
+
## When to load this skill
|
|
24
|
+
|
|
25
|
+
Load on **any task that decides what a surface should be** — whether the
|
|
26
|
+
surface exists today or not. The user's verb is the strongest signal:
|
|
27
|
+
|
|
28
|
+
| Phrase in the prompt | Load? |
|
|
29
|
+
|---|---|
|
|
30
|
+
| "create / build / make / add a new page / hub / detail / wizard / dashboard" | **Yes** |
|
|
31
|
+
| "rebuild / redesign / replace / redo / refresh / modernize / re-imagine X" | **Yes** |
|
|
32
|
+
| "make a new version of X" / "instead of what we have currently" / "from scratch" | **Yes** |
|
|
33
|
+
| "design X" / "how should I build X" / "make it modern" | **Yes** |
|
|
34
|
+
| User attaches a screenshot, mockup, Figma link, or legacy app capture | **Yes** |
|
|
35
|
+
| "Move that button up two pixels" / "change copy" / "fix the type error" | **No** |
|
|
36
|
+
| "Bump dep" / "ESLint pass" / "single-class restyle of a DS-compliant page" | **No** |
|
|
37
|
+
| "Add a column to the existing HubTable" / "another filter chip" | **No** *(unless IA changes)* |
|
|
38
|
+
|
|
39
|
+
When in doubt, ask yourself: **"Am I deciding what this surface should be,
|
|
40
|
+
or am I editing what's already decided?"** Decide → load. Edit → don't.
|
|
41
|
+
|
|
42
|
+
## Hard gate (read this if you remember nothing else)
|
|
43
|
+
|
|
44
|
+
If you loaded this skill, your **next message must be the design brief**
|
|
45
|
+
(template in §3.1). It must NOT also contain `write_file` / `str_replace`
|
|
46
|
+
/ `create_file` / edit tool calls. End the turn after the brief with
|
|
47
|
+
"Ready to build — confirm or edit." The user's reply is your green light.
|
|
48
|
+
|
|
49
|
+
Silence, a thumbs-up, or "ok" all count as confirmation. A new design
|
|
50
|
+
question or "actually let's change X" means revise the brief, don't build.
|
|
51
|
+
|
|
52
|
+
## Mindset (5 lines, memorize)
|
|
53
|
+
|
|
54
|
+
1. **Problem before solution.** A prompt is a symptom. The job is the disease.
|
|
55
|
+
2. **Recognition before invention.** Modern products converged for a reason —
|
|
56
|
+
start from what users already know.
|
|
57
|
+
3. **One job per surface.** A screen that tries to do three things does none.
|
|
58
|
+
4. **Push back, don't transcribe.** Challenge vague briefs, solution-shaped
|
|
59
|
+
prompts, feature stacking, pixel-copies.
|
|
60
|
+
5. **The DS is the vocabulary, not the design.** Composition is the means;
|
|
61
|
+
clarity for the user is the end.
|
|
62
|
+
|
|
63
|
+
## The five-step protocol (mandatory on any surface decision)
|
|
64
|
+
|
|
65
|
+
The five steps are **sequential checkpoints**, not a single turn. Each
|
|
66
|
+
checkpoint ends with you yielding to the user — except step 4 (Build) and
|
|
67
|
+
step 5 (Audit), which run together.
|
|
68
|
+
|
|
69
|
+
### 1. Discovery — ask, infer, or state assumptions
|
|
70
|
+
|
|
71
|
+
Output a **design brief in chat** BEFORE writing files. Ask 1–3 questions
|
|
72
|
+
only if the answer materially changes the design — otherwise state
|
|
73
|
+
assumptions and proceed.
|
|
74
|
+
|
|
75
|
+
Use the **question bank by surface type** in
|
|
76
|
+
`.cursor/rules/exxat-ux-discovery-protocol.mdc`.
|
|
77
|
+
|
|
78
|
+
If the user said "no questions, build it", still output the brief + your
|
|
79
|
+
assumptions.
|
|
80
|
+
|
|
81
|
+
### 2. Research — recognize the pattern, don't reinvent
|
|
82
|
+
|
|
83
|
+
Run research **before posting the brief in step 3**, so the brief can name
|
|
84
|
+
specific references. (See research methods below.)
|
|
85
|
+
|
|
86
|
+
### 3. Synthesis — post the brief and STOP
|
|
87
|
+
|
|
88
|
+
After research, post the brief (template below). **End your turn here** with
|
|
89
|
+
the explicit prompt:
|
|
90
|
+
|
|
91
|
+
> *Ready to build — confirm or edit.*
|
|
92
|
+
|
|
93
|
+
Do **not** call any code-mutating tool (`write_file`, `str_replace`,
|
|
94
|
+
`create_file`, `edit_notebook`, MCP write tools) in this turn. The user's
|
|
95
|
+
next message is your green light.
|
|
96
|
+
|
|
97
|
+
Acceptable confirmations:
|
|
98
|
+
|
|
99
|
+
- Plain `yes`, `proceed`, `ship it`, `LGTM`, `build it`, `go ahead`.
|
|
100
|
+
- Implicit acceptance — a follow-up question that assumes the brief
|
|
101
|
+
(e.g. "and add a section for X").
|
|
102
|
+
- Silence followed by a new design question — treat as accepted.
|
|
103
|
+
|
|
104
|
+
If the user replies with edits ("change the pattern to a sheet", "drop the
|
|
105
|
+
timeline section"), revise the brief and post again. Only build after a
|
|
106
|
+
confirmed brief.
|
|
107
|
+
|
|
108
|
+
### Research methods (used inside step 2)
|
|
109
|
+
|
|
110
|
+
1. Check this repo first — does a canonical reference solve the same **job**?
|
|
111
|
+
See `apps/web/docs/jobs/`.
|
|
112
|
+
2. If unfamiliar, call **Mobbin** `search_screens` for the **job type**
|
|
113
|
+
("record detail", "triage list", "compose flow") — not the domain.
|
|
114
|
+
3. For 2026 conventions, **WebSearch** (e.g. "Linear issue detail 2026",
|
|
115
|
+
"Notion property panel pattern").
|
|
116
|
+
4. Read `apps/web/docs/modern-saas-patterns.md` for the canon you're working
|
|
117
|
+
against — content-first chrome, command palette, inline editing,
|
|
118
|
+
optimistic UI, side-panel detail, density layers, type-first hierarchy,
|
|
119
|
+
activity timeline, AI as sidecar.
|
|
120
|
+
5. Extract **patterns** (IA, hierarchy, action placement), never pixels
|
|
121
|
+
(`exxat-no-image-pixel-copy.mdc`).
|
|
122
|
+
|
|
123
|
+
### 3.1 Brief template (copy verbatim into chat)
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Problem: <one sentence — the user's pain, not the feature>
|
|
127
|
+
User & frequency: <persona, daily/weekly/occasional, expertise>
|
|
128
|
+
Job-to-be-done: <the decision or action this enables>
|
|
129
|
+
Pattern: <route | sheet | dialog | inline> + IA shape
|
|
130
|
+
Reference (repo): <file path>
|
|
131
|
+
Reference (modern): <product 1 + Mx codes>, <product 2 + Mx codes>
|
|
132
|
+
Principles applied: <list of Pxx from exxat-ux-principles>
|
|
133
|
+
Deviations: <principle + reason, or "none">
|
|
134
|
+
Out of scope: <what this surface intentionally does not do>
|
|
135
|
+
Open questions: <max 2; ideally 0>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
End the turn with: *Ready to build — confirm or edit.*
|
|
139
|
+
|
|
140
|
+
### 4. Build — compose, don't invent
|
|
141
|
+
|
|
142
|
+
- Use DS primitives (see `exxat-token-economy/SKILL.md` §1 + §3).
|
|
143
|
+
- Apply principles from `exxat-ux-principles.mdc`.
|
|
144
|
+
- When you break a principle, **say so in chat** with the one-sentence
|
|
145
|
+
reason. If you can't articulate it, you shouldn't be breaking it.
|
|
146
|
+
|
|
147
|
+
### 5. Audit — self-review like a senior would
|
|
148
|
+
|
|
149
|
+
Before declaring done, answer yes/no/N/A:
|
|
150
|
+
|
|
151
|
+
- [ ] One H1, no duplicated identity (e.g. name in breadcrumb + title + body).
|
|
152
|
+
- [ ] Primary action findable in < 2 seconds.
|
|
153
|
+
- [ ] Exactly one filled primary CTA per surface; others outline / ghost.
|
|
154
|
+
- [ ] Way-back is provided **once** (breadcrumb OR back affordance, not both).
|
|
155
|
+
- [ ] Status signals visible without scrolling.
|
|
156
|
+
- [ ] Empty / error / loading states all designed (not afterthoughts).
|
|
157
|
+
- [ ] Keyboard: every action reachable; Enter / Esc behave as expected.
|
|
158
|
+
- [ ] Accessibility: contrast ≥ 4.5:1, focus ring visible, target ≥ 24×24,
|
|
159
|
+
tooltips on icon-only.
|
|
160
|
+
- [ ] Voice: empty-state and button copy match `docs/voice-and-tone.md`.
|
|
161
|
+
- [ ] Modern: no `toast()`, no Vaul, no full-width tab bar, no legacy
|
|
162
|
+
pixel-copy, no two filled CTAs.
|
|
163
|
+
|
|
164
|
+
If any answer is **no**, fix before responding.
|
|
165
|
+
|
|
166
|
+
## When to ask vs assume
|
|
167
|
+
|
|
168
|
+
| Situation | Do |
|
|
169
|
+
|-----------|----|
|
|
170
|
+
| Brief is vague ("make it nice", "modern", "clean") | Ask **1 sharp question** that finds the underlying job |
|
|
171
|
+
| Solution-shaped prompt ("add a tab for X") | Ask what job that tab serves; offer 1 alternative |
|
|
172
|
+
| User said "like our other admin pages" | Don't ask — pick the reference, state the assumption |
|
|
173
|
+
| User attached a screenshot/mockup | Don't pixel-copy — extract IA, map to DS, state mapping |
|
|
174
|
+
| You don't recognize the job | Research (Mobbin + WebSearch), then synthesize |
|
|
175
|
+
| User explicitly said "no questions, build it" | Build, but still output the brief + assumptions |
|
|
176
|
+
|
|
177
|
+
## Push back when
|
|
178
|
+
|
|
179
|
+
- Prompt would produce 2+ filled CTAs, duplicate identity, hidden status, or
|
|
180
|
+
the way-back duplicated.
|
|
181
|
+
- User wants to pixel-copy a competitor (extract pattern instead).
|
|
182
|
+
- User wants a new shared primitive without 2+ proven use cases.
|
|
183
|
+
- User wants `toast()` for product feedback (use banners / inline / dialog).
|
|
184
|
+
- User wants `vaul` (use `Sheet`).
|
|
185
|
+
- A "feature list" prompt has no underlying job — ask: "What decision does
|
|
186
|
+
this enable?"
|
|
187
|
+
|
|
188
|
+
Be polite, unambiguous, brief: *"I'd suggest X because Y — okay to proceed
|
|
189
|
+
that way?"*
|
|
190
|
+
|
|
191
|
+
## See also
|
|
192
|
+
|
|
193
|
+
- `.cursor/rules/exxat-ux-discovery-protocol.mdc` — brief-before-code gate
|
|
194
|
+
- `.cursor/rules/exxat-ux-principles.mdc` — principles + when to break
|
|
195
|
+
- `apps/web/docs/modern-saas-patterns.md` — what "modern" means here
|
|
196
|
+
- `apps/web/docs/jobs/` — canonical references per job type
|
|
197
|
+
- `.cursor/skills/exxat-token-economy/SKILL.md` — minimum files + scaffolds
|
|
198
|
+
- `.cursor/rules/exxat-no-image-pixel-copy.mdc` — IA from screenshots only
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: exxat-token-economy
|
|
3
|
+
description: >-
|
|
4
|
+
Cut AI token usage by ~50% on Exxat DS work — task → minimum-file-set table,
|
|
5
|
+
five-question pre-flight that catches the top rule violations before
|
|
6
|
+
generation, canonical primitive aliases (no grep needed), tiny scaffolds
|
|
7
|
+
for hub client / column def / KPI item, and a deny-list of files the
|
|
8
|
+
assistant should NOT open. Read this BEFORE opening any other DS doc.
|
|
9
|
+
user-invocable: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Exxat DS — token economy (read this first)
|
|
13
|
+
|
|
14
|
+
**Why this exists.** Every other DS skill / rule / pattern doc is a deep dive on
|
|
15
|
+
one concern. When the user just wants to build a screen, the assistant tends to:
|
|
16
|
+
|
|
17
|
+
1. Re-read `AGENTS.md` (~80 KB) on every turn.
|
|
18
|
+
2. `grep` to "find the Button" when the import path is already known.
|
|
19
|
+
3. Regenerate hub scaffolding it could copy from a reference page.
|
|
20
|
+
4. Read 6 rule files speculatively when only 2 apply.
|
|
21
|
+
5. Re-explain "we use HubTable because…" in 200 tokens.
|
|
22
|
+
|
|
23
|
+
This skill is the **pre-flight** for any DS work. Read it first; load other docs
|
|
24
|
+
only when this skill explicitly points to one. **Target: ≥ 50% fewer input
|
|
25
|
+
tokens per design turn vs. the naive "open AGENTS.md and grep" loop.**
|
|
26
|
+
|
|
27
|
+
## When to use this skill
|
|
28
|
+
|
|
29
|
+
- **First** turn of any new DS feature, hub, or design change.
|
|
30
|
+
- Any time the assistant is about to open `AGENTS.md` or a `*-pattern.md` doc — read this skill instead and follow §1's file-set table.
|
|
31
|
+
- Whenever the user complains about cost, latency, or "you keep re-reading the same files".
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## §1 — Task → minimum file set
|
|
36
|
+
|
|
37
|
+
Open **only** these files. Skip everything else unless one of these files cites it.
|
|
38
|
+
|
|
39
|
+
| Task | Read (minimum) | Skip (do not open) |
|
|
40
|
+
|------|----------------|--------------------|
|
|
41
|
+
| **Build a new hub page** (table + KPIs + view tabs) | `apps/web/components/library-table.tsx` + `library-client.tsx`, `exxat-hub-supported-views.mdc` (or `hub-supported-views-pattern.md`) | `AGENTS.md`, `hub-table.tsx` source, all `*-pattern.md` |
|
|
42
|
+
| **Add a column / cell pattern** | `apps/web/components/columns-showcase.tsx` (the live catalog) | `data-table/index.tsx`, the whole `types.ts` |
|
|
43
|
+
| **Add a board / kanban view** | `apps/web/components/placements-board-card.tsx`, `exxat-board-cards.mdc` only | All other rules |
|
|
44
|
+
| **Add a KPI strip** | `docs/exxat-ds/handbook/reference-implementations.md` § KPI flat band, `exxat-kpi-max-four.mdc`, `exxat-kpi-trends.mdc` | `key-metrics.tsx` source |
|
|
45
|
+
| **Write empty-state / error / button copy** | `docs/exxat-ds/handbook/voice-and-tone.md` | All rules |
|
|
46
|
+
| **Theme / token tweak** | `apps/web/app/globals.css`, `packages/ui/tokens/hooks-index.json` | All pattern docs |
|
|
47
|
+
| **Status chip color/icon** | `apps/web/lib/list-status-badges.ts` | Accessibility rule (already covered by the map) |
|
|
48
|
+
| **Bug fix** | `rg` for the symbol, read only the matching file | Everything else |
|
|
49
|
+
| **Architectural change** (only when the user explicitly says so) | `AGENTS.md`, `HANDBOOK.md` | — |
|
|
50
|
+
|
|
51
|
+
**Heuristic.** If a file is over 25 KB and you're not modifying that exact file,
|
|
52
|
+
don't read it. Use this skill body + the reference page in `columns-showcase.tsx`
|
|
53
|
+
instead.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## §2 — Five-question pre-flight (before you generate code)
|
|
58
|
+
|
|
59
|
+
Answer **yes / no / N/A** to each. A **no** means re-plan; you'll save a regeneration cycle.
|
|
60
|
+
|
|
61
|
+
1. **`HubTable`, not raw `<table>`?** — every hub-style grid in `ListPageTemplate.renderContent` uses `HubTable<TRow>` from `@/components/data-views`. Filters + Properties drawer + view-type tiles + bulk actions come free.
|
|
62
|
+
2. **`view` + `onViewChange` plumbed?** — if the page has view tabs, pass both through `client → table → drawer toolbar → TablePropertiesDrawer`. Otherwise the drawer ships table-only copy on a Board tab.
|
|
63
|
+
3. **Color + icon on every status chip?** — `ListHubStatusBadge` + a tint from `lib/list-status-badges.ts` + an FA icon. Color alone fails WCAG 1.4.1.
|
|
64
|
+
4. **≤ 4 KPIs on the primary strip?** — `KEY_METRICS_KPI_COUNT_MAX = 4`. A fifth becomes a `MetricInsight` or a chart.
|
|
65
|
+
5. **No toasts for product feedback?** — use `LocalBanner` / `SystemBanner` / inline status. Toasts are reserved for build-tool messages.
|
|
66
|
+
6. **Seven views + real bodies?** — `FULL_HUB_SUPPORTED_VIEWS` on **`ListPageTemplate`** + **`HubTable`** (sync both); every allowed view has a renderer; list uses **`ListPageBoardCard`** — not `["table"]` / `PRIMARY_HUB_SUPPORTED_VIEWS` / empty `renderers={}`.
|
|
67
|
+
7. **Sheet only (no Vaul)?** — side panels use **`Sheet`**; **`vaul`** must not be in `package.json`.
|
|
68
|
+
8. **Header + tabs + table preview?** — **`PageHeader`** + DS **`Button`** variants for actions; hub views via **`ListPageTemplate`** (not full-width tabs); record tabs **`TabsList`** `w-fit`; row preview via **`HoverCard`** + shared cells — not custom popovers.
|
|
69
|
+
9. **Uploaded image ≠ spec?** — If the user attached a screenshot/mockup: extract **IA only** (labels, routes, fields); map to **`component-selection-guide`** + a **reference hub**; **MUST NOT** pixel-copy colors, sidebar chrome, tabs, or bespoke widgets — **`exxat-no-image-pixel-copy.mdc`**.
|
|
70
|
+
|
|
71
|
+
If all nine are **yes**, generate. If any is **no**, either narrow the requirements
|
|
72
|
+
with **one** clarifying question or fix the gap silently and note it in your response.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## §3 — Canonical primitive aliases (no grep needed)
|
|
77
|
+
|
|
78
|
+
When the user says "X", reach for "Y". Save the search.
|
|
79
|
+
|
|
80
|
+
### Page chrome & overlays
|
|
81
|
+
|
|
82
|
+
| User says | Use | Path |
|
|
83
|
+
|----------|-----|------|
|
|
84
|
+
| button, action, CTA | `Button` | `@/components/ui/button` |
|
|
85
|
+
| input, text field, form field | `Input`, `FormField` | `@/components/ui/{input,form}` |
|
|
86
|
+
| avatar | `AvatarInitials` | `@/components/ui/avatar` |
|
|
87
|
+
| chip, badge, status, tag | `Badge`, `ListHubStatusBadge`, `StatusBadge` | `@/components/{ui/badge,list-hub-status-badge}` |
|
|
88
|
+
| dropdown, menu, ⋯ | `DropdownMenu` family | `@/components/ui/dropdown-menu` |
|
|
89
|
+
| tooltip, hint | `Tip` (or `Tooltip`) | `@/components/ui/tip` |
|
|
90
|
+
| sheet, side panel | `Sheet` family, `ExportDrawer`, `TablePropertiesDrawer` | `@/components/ui/sheet` |
|
|
91
|
+
| dialog, modal, confirm | `Dialog` family | `@/components/ui/dialog` |
|
|
92
|
+
| table, list, grid (product data) | `HubTable` inside `ListPageTemplate` | `@/components/data-views` |
|
|
93
|
+
| KPI, metric, stat | `KeyMetrics` + `MetricItem` | `@/components/key-metrics` |
|
|
94
|
+
| board, kanban | `ListPageBoardCard`, `ListPageBoardTemplate` | `@/components/data-views/list-page-board-card` |
|
|
95
|
+
| icon | FA `<i class="fa-light fa-{name}" aria-hidden />` | (Kit script in `app/layout.tsx`) |
|
|
96
|
+
| keyboard shortcut hint | `Kbd variant="bare"` inside buttons; `tile` in tooltips | `@/components/ui/kbd` |
|
|
97
|
+
| toggle, switch | `ToggleSwitch` | `@/components/ui/toggle-switch` |
|
|
98
|
+
|
|
99
|
+
### Table cell renderers (ALL importable — do NOT re-implement)
|
|
100
|
+
|
|
101
|
+
Every cell renderer below is exported from **`@/components/data-views`** (re-exported from `apps/web/components/data-views/table-cells.tsx`). Live catalog: `apps/web/components/columns-showcase.tsx` at route `/columns`.
|
|
102
|
+
|
|
103
|
+
| User says | Use | Notes |
|
|
104
|
+
|----------|-----|-------|
|
|
105
|
+
| progress bar, % complete, weeks done | `ProgressCell` | `value`, `max?`, `tone?: "auto" \| "success" \| "warning" \| "danger" \| "info"`, `label?` |
|
|
106
|
+
| currency, money, price, cost | `CurrencyCell` | `value`, `currency?` (default USD), `locale?`, right-aligned `tabular-nums` |
|
|
107
|
+
| numeric count, attempts, downloads | `NumericCell` | `value`, `fractionDigits?`, right-aligned |
|
|
108
|
+
| rating, stars, score | `RatingCell` | `value`, `max?` (5), `showValue?` — color **and** glyph (WCAG 1.4.1) |
|
|
109
|
+
| signal bars, low/med/high, difficulty | `SignalBarsCell` | `level`, `max?` (3), `tone?`, `label` (required, accessible) |
|
|
110
|
+
| toggle, published/draft, enabled/disabled | `BooleanToggleCell` | `checked`, `onChange(next)`, `labelOn?`, `labelOff?`; stops row click propagation |
|
|
111
|
+
| attachments, files count, paperclip | `AttachmentCountCell` | `count` — muted dash on `0` |
|
|
112
|
+
| external link, source, view in new tab | `ExternalLinkCell` | `url`, `label?` — host extracted; `Tip` shows full URL |
|
|
113
|
+
| relative time, "3 hours ago", recency | `RelativeTimeCell` | `iso`, `now?` (override for deterministic snapshots) |
|
|
114
|
+
| face rail, reviewers, assignees +N | `PeopleAvatarRailCell` | `people: PersonStub[]`, `visibleMax?` (3), `size?: "sm" \| "md"`; **non-overlapping** avatars |
|
|
115
|
+
| type pill, category, kind with icon | `PillCell` | `label`, `icon?: "fa-..."` — outlined, single-line |
|
|
116
|
+
| tag list +N, keywords, labels | `TagListCell` | `tags: string[]`, `visibleMax?` (2), `formatLabel?` (default `#${tag}`) |
|
|
117
|
+
| row actions, ⋯, overflow menu | `RowActionsCell<TRow>` | `row`, `actions: RowActionDef<TRow>[]` (`label`, `icon`, `onSelect`, `variant?`, `shortcut?`, `disabled?`) |
|
|
118
|
+
|
|
119
|
+
### Out of band — only when none of the above fits
|
|
120
|
+
|
|
121
|
+
If the user asks for **anything outside this list**: first scan `columns-showcase.tsx`
|
|
122
|
+
+ the `reference-implementations.md` index — both name every existing primitive.
|
|
123
|
+
Only propose a new shared component if neither covers it AND the user has approved
|
|
124
|
+
bespoke work (`exxat-reuse-before-custom.mdc`).
|
|
125
|
+
|
|
126
|
+
**Hard rule.** Do NOT inline-implement a progress bar, currency formatter, rating,
|
|
127
|
+
relative-time, attachment chip, external link, face rail, type pill, tag list, or
|
|
128
|
+
row-actions menu inside a `ColumnDef['cell']`. Import the named cell. If you find
|
|
129
|
+
yourself writing `Intl.NumberFormat`, `<a target="_blank">`, or a `[1,2,3,4,5].map(…)` star
|
|
130
|
+
loop inside a `cell:`, stop — you're re-deriving a shipped primitive.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## §4 — Tiny scaffolds (copy verbatim, don't re-derive)
|
|
135
|
+
|
|
136
|
+
The boilerplate shapes you'd otherwise regenerate.
|
|
137
|
+
|
|
138
|
+
### Hub client (replace `Entity`, KPIs, columns)
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
"use client"
|
|
142
|
+
import * as React from "react"
|
|
143
|
+
import { PrimaryPageTemplate } from "@/components/templates/primary-page-template"
|
|
144
|
+
import { PageHeader } from "@/components/page-header"
|
|
145
|
+
import { KeyMetrics, type MetricItem } from "@/components/key-metrics"
|
|
146
|
+
import { ListPageTemplate, type ViewTab, HubTable } from "@/components/data-views"
|
|
147
|
+
|
|
148
|
+
import { FULL_HUB_SUPPORTED_VIEWS } from "@/lib/data-list-view-registry"
|
|
149
|
+
|
|
150
|
+
const ENTITY_TABS: ViewTab[] = [{ id: "all", label: "All", viewType: "table", icon: "fa-table", filterId: "all" }]
|
|
151
|
+
/** Seven views (Library parity) unless product documents a narrower list in lib/entity-supported-views.ts */
|
|
152
|
+
const ENTITY_SUPPORTED_VIEWS = FULL_HUB_SUPPORTED_VIEWS
|
|
153
|
+
|
|
154
|
+
export function EntityClient({ rows }) {
|
|
155
|
+
const [tabs, setTabs] = React.useState<ViewTab[]>(ENTITY_TABS)
|
|
156
|
+
const [activeTabId, setActiveTabId] = React.useState(ENTITY_TABS[0].id)
|
|
157
|
+
return (
|
|
158
|
+
<PrimaryPageTemplate siteHeader={{ title: "Entity" }}>
|
|
159
|
+
<ListPageTemplate
|
|
160
|
+
defaultTabs={ENTITY_TABS} tabs={tabs} onTabsChange={setTabs}
|
|
161
|
+
activeTabId={activeTabId} onActiveTabChange={setActiveTabId}
|
|
162
|
+
supportedViewTypes={ENTITY_SUPPORTED_VIEWS}
|
|
163
|
+
getTabCount={() => rows.length}
|
|
164
|
+
header={<PageHeader title="Entity" subtitle="…" />}
|
|
165
|
+
metrics={<KeyMetrics variant="flat" metrics={ENTITY_KPIS} showHeader={false} metricsSingleRow />}
|
|
166
|
+
renderContent={(tab, updateTab) => (
|
|
167
|
+
<HubTable rows={rows} columns={useColumns()}
|
|
168
|
+
view={tab.viewType} onViewChange={v => updateTab({ viewType: v })}
|
|
169
|
+
supportedViewTypes={ENTITY_SUPPORTED_VIEWS}
|
|
170
|
+
hubLabel="Entity" lifecycleTabLabel="Entity"
|
|
171
|
+
getRowId={r => r.id} getRowSelectionLabel={r => r.name}
|
|
172
|
+
defaultSort={{ key: "name", dir: "asc" }}
|
|
173
|
+
renderListRow={row => /* ListPageBoardCard layout="row" — copy library-table.tsx */}
|
|
174
|
+
renderers={{
|
|
175
|
+
/* board-with-toolbar, dashboard-with-toolbar, folder/panel/tree — see library-table.tsx or tokens-hub-auxiliary-views.tsx */
|
|
176
|
+
}}
|
|
177
|
+
/>
|
|
178
|
+
)}
|
|
179
|
+
/>
|
|
180
|
+
</PrimaryPageTemplate>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `MetricItem` shape (KPI strip cell)
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
{ id: "active", label: "Active", value: 142, delta: "+8 vs last week",
|
|
189
|
+
trend: "up", trendPolarity: "higher_is_better",
|
|
190
|
+
metricVariant: "hero", description: "currently in placement" }
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
- `trend: "neutral"` + empty `delta` → no trend chip renders. Don't fake a `+0`.
|
|
194
|
+
- `trendPolarity: "lower_is_better"` for error counts, defects, overdue.
|
|
195
|
+
- `metricVariant: "hero"` for **one** cell per strip — the headline number.
|
|
196
|
+
- Max **4 cells**.
|
|
197
|
+
|
|
198
|
+
### `ColumnDef<TRow>` shape
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
{ key: "name", label: "Name", width: 240, minWidth: 180,
|
|
202
|
+
defaultPin: "left", sortable: true, sortKey: "name",
|
|
203
|
+
filter: { type: "text", icon: "fa-user", operators: ["contains"] },
|
|
204
|
+
cell: row => <span className="truncate">{row.name}</span> }
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
- `key: "select"` + `defaultPin: "left"` + `lockPin: true` → checkbox column.
|
|
208
|
+
- `key: "actions"` + `defaultPin: "right"` + `lockPin: true` → ⋯ overflow column.
|
|
209
|
+
- `filter: { type: "select", options }` for categorical columns.
|
|
210
|
+
|
|
211
|
+
### Default `cell:` should call a named primitive
|
|
212
|
+
|
|
213
|
+
The right `cell:` body for the common patterns is **one import + one component**, not an inline JSX block:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
import { ProgressCell, CurrencyCell, RatingCell, BooleanToggleCell,
|
|
217
|
+
RelativeTimeCell, AttachmentCountCell, ExternalLinkCell,
|
|
218
|
+
PeopleAvatarRailCell, PillCell, TagListCell, NumericCell,
|
|
219
|
+
RowActionsCell, type RowActionDef } from "@/components/data-views"
|
|
220
|
+
|
|
221
|
+
// Examples — cell:'s body is one call.
|
|
222
|
+
cell: row => <ProgressCell value={row.completion} />
|
|
223
|
+
cell: row => <CurrencyCell value={row.cost} />
|
|
224
|
+
cell: row => <RatingCell value={row.rating} />
|
|
225
|
+
cell: row => <BooleanToggleCell checked={row.published} onChange={next => onTogglePublished(row, next)} />
|
|
226
|
+
cell: row => <RelativeTimeCell iso={row.lastActivityAt} />
|
|
227
|
+
cell: row => <AttachmentCountCell count={row.attachmentCount} />
|
|
228
|
+
cell: row => <ExternalLinkCell url={row.sourceUrl} />
|
|
229
|
+
cell: row => <PeopleAvatarRailCell people={row.reviewers} />
|
|
230
|
+
cell: row => <PillCell label={TYPE_LABEL[row.type]} icon={TYPE_ICON[row.type]} />
|
|
231
|
+
cell: row => <TagListCell tags={row.tags} />
|
|
232
|
+
cell: row => <NumericCell value={row.attempts} />
|
|
233
|
+
cell: row => <RowActionsCell row={row} actions={ROW_ACTIONS} />
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
If `cell:` exceeds **one line** for any pattern above, you're re-deriving — go back and import.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## §5 — Deny list (do NOT open unless asked)
|
|
241
|
+
|
|
242
|
+
Treat these as expensive — skip unless the user explicitly names them or this skill points to them:
|
|
243
|
+
|
|
244
|
+
- `AGENTS.md` — only when the task is "change the architecture or the rules themselves".
|
|
245
|
+
- `packages/ui/src/components/data-views/hub-table.tsx` — the API is documented; don't read the implementation.
|
|
246
|
+
- `apps/web/.next/`, `.turbo/`, `node_modules/` — never.
|
|
247
|
+
- All 29 `.cursor/rules/exxat-*.mdc` at once — §1 already points to the 1-2 that apply.
|
|
248
|
+
- Test files (`*.test.*`, `__tests__/`) — irrelevant for design.
|
|
249
|
+
- Build configs (`tsup.config.ts`, `next.config.ts`, `turbo.json`) — irrelevant for design.
|
|
250
|
+
- `packages/ui/tokens/hooks-index.json` (~163 KB) — only when the task is a token rename / audit.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## §6 — When to ask vs. when to assume
|
|
255
|
+
|
|
256
|
+
One clarifying question costs ~50 tokens. A wrong implementation costs hundreds (read, generate, user feedback, regenerate). Ask when:
|
|
257
|
+
|
|
258
|
+
1. The task name is ambiguous between two patterns (e.g. "add a panel" → drawer or split panel?).
|
|
259
|
+
2. Two existing reference hubs handle the same concern differently (use the user's existing precedent if they have one).
|
|
260
|
+
3. The user mentions a screen that doesn't have a clear primitive in §3.
|
|
261
|
+
|
|
262
|
+
Don't ask when:
|
|
263
|
+
|
|
264
|
+
- The user has cited a specific file or component — go.
|
|
265
|
+
- The pre-flight (§2) all answers yes — go.
|
|
266
|
+
- The task fits exactly one row in §1's task map — go.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## §7 — Output discipline (your turn budget)
|
|
271
|
+
|
|
272
|
+
Your **response** also costs tokens. Keep it lean:
|
|
273
|
+
|
|
274
|
+
- **No "let me explain the design system" preambles.** The user has the package installed; they know.
|
|
275
|
+
- **No reading-aloud of file paths.** Cite with `code` ticks; don't re-narrate.
|
|
276
|
+
- **No restating the prompt.** Jump straight to the action.
|
|
277
|
+
- **Group tool calls in parallel** when independent (reading 3 files = 1 message, not 3).
|
|
278
|
+
- **Stop generating** as soon as the pre-flight (§2) says you have what you need. Don't gold-plate.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## See also
|
|
283
|
+
|
|
284
|
+
- **Handbook** — `docs/exxat-ds/handbook/HANDBOOK.md` (5 principles + how-to-build-a-hub)
|
|
285
|
+
- **Reference implementations** — `docs/exxat-ds/handbook/reference-implementations.md` (find the file to copy)
|
|
286
|
+
- **Voice & tone** — `docs/exxat-ds/handbook/voice-and-tone.md` (user-facing copy)
|
|
287
|
+
- **Cell patterns catalog** — `apps/web/components/columns-showcase.tsx` (live at `/columns`)
|