@exxatdesignux/ui 0.5.10 → 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.
Files changed (478) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/bin/cli.mjs +70 -1
  3. package/bin/init.mjs +18 -4
  4. package/bin/sync-extras.mjs +28 -4
  5. package/consumer-extras/README.md +41 -5
  6. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +2 -1
  7. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +5 -3
  8. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +1 -0
  9. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +1 -0
  10. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +4 -2
  11. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -0
  12. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +3 -2
  13. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +5 -3
  14. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +7 -0
  15. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +2 -1
  16. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +13 -2
  17. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +1 -0
  18. package/consumer-extras/cursor-rules/exxat-hub-supported-views.mdc +6 -4
  19. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +6 -5
  20. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +1 -0
  21. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +1 -0
  22. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +1 -0
  23. package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +2 -1
  24. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +6 -2
  25. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +2 -1
  26. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +2 -1
  27. package/consumer-extras/cursor-rules/exxat-nav-single-active.mdc +4 -3
  28. package/consumer-extras/cursor-rules/exxat-no-image-pixel-copy.mdc +25 -14
  29. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +8 -2
  30. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +1 -0
  31. package/consumer-extras/cursor-rules/exxat-no-vaul.mdc +2 -1
  32. package/consumer-extras/cursor-rules/exxat-page-header-actions.mdc +6 -4
  33. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +2 -1
  34. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -0
  35. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +2 -1
  36. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -0
  37. package/consumer-extras/cursor-rules/exxat-sidebar-shell.mdc +13 -7
  38. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +5 -3
  39. package/consumer-extras/cursor-rules/exxat-table-row-preview.mdc +1 -0
  40. package/consumer-extras/cursor-rules/exxat-tabs-chrome.mdc +6 -4
  41. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +6 -0
  42. package/consumer-extras/cursor-rules/exxat-ux-discovery-protocol.mdc +92 -12
  43. package/consumer-extras/cursor-rules/exxat-ux-principles.mdc +1 -0
  44. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +1 -1
  45. package/consumer-extras/cursor-skills/exxat-kpi-trends/SKILL.md +5 -3
  46. package/consumer-extras/cursor-skills/exxat-senior-ux/SKILL.md +70 -17
  47. package/consumer-extras/patterns/command-menu-pattern.md +2 -2
  48. package/consumer-extras/patterns/consumer-upgrade-checklist.md +1 -1
  49. package/consumer-extras/patterns/jobs/README.md +1 -1
  50. package/consumer-extras/patterns/perf-memory-pattern.md +115 -150
  51. package/consumer-extras/scripts/dev-guard.mjs +156 -0
  52. package/consumer-extras/templates/README.md +23 -0
  53. package/consumer-extras/templates/handoff.md +190 -0
  54. package/dist/hooks/use-app-theme.d.ts +1 -1
  55. package/package.json +2 -2
  56. package/{template → template-vite}/.claude/skills/exxat-ds-skill/SKILL.md +184 -23
  57. package/template-vite/.cursor/rules/exxat-accessibility.mdc +40 -0
  58. package/template-vite/.cursor/rules/exxat-board-cards.mdc +28 -0
  59. package/template-vite/.cursor/rules/exxat-breadcrumbs-no-back.mdc +22 -0
  60. package/template-vite/.cursor/rules/exxat-card-vs-list-rows.mdc +22 -0
  61. package/template-vite/.cursor/rules/exxat-centralized-list-dataset.mdc +46 -0
  62. package/template-vite/.cursor/rules/exxat-collaboration-access.mdc +33 -0
  63. package/{template → template-vite}/.cursor/rules/exxat-command-menu.mdc +5 -5
  64. package/template-vite/.cursor/rules/exxat-data-tables.mdc +47 -0
  65. package/template-vite/.cursor/rules/exxat-dedicated-search-surfaces.mdc +32 -0
  66. package/template-vite/.cursor/rules/exxat-drawer-vs-dialog.mdc +23 -0
  67. package/template-vite/.cursor/rules/exxat-ds-agents.mdc +87 -0
  68. package/template-vite/.cursor/rules/exxat-fontawesome-icons.mdc +32 -0
  69. package/template-vite/.cursor/rules/exxat-hub-supported-views.mdc +56 -0
  70. package/{template → template-vite}/.cursor/rules/exxat-kbd-shortcuts.mdc +1 -0
  71. package/template-vite/.cursor/rules/exxat-kpi-flat-band.mdc +29 -0
  72. package/template-vite/.cursor/rules/exxat-kpi-max-four.mdc +22 -0
  73. package/template-vite/.cursor/rules/exxat-kpi-trends.mdc +32 -0
  74. package/template-vite/.cursor/rules/exxat-library-hub-header.mdc +29 -0
  75. package/template-vite/.cursor/rules/exxat-list-page-connected-views.mdc +28 -0
  76. package/template-vite/.cursor/rules/exxat-list-page-view-shells.mdc +32 -0
  77. package/{template → template-vite}/.cursor/rules/exxat-mono-ids.mdc +1 -0
  78. package/template-vite/.cursor/rules/exxat-nav-single-active.mdc +32 -0
  79. package/template-vite/.cursor/rules/exxat-no-image-pixel-copy.mdc +46 -0
  80. package/template-vite/.cursor/rules/exxat-no-slds-leakage.mdc +84 -0
  81. package/{template → template-vite}/.cursor/rules/exxat-no-toast.mdc +2 -2
  82. package/template-vite/.cursor/rules/exxat-no-vaul.mdc +26 -0
  83. package/template-vite/.cursor/rules/exxat-page-header-actions.mdc +33 -0
  84. package/{template → template-vite}/.cursor/rules/exxat-page-vs-drawer.mdc +5 -3
  85. package/template-vite/.cursor/rules/exxat-person-identity-display.mdc +48 -0
  86. package/template-vite/.cursor/rules/exxat-primary-nav-secondary-panel.mdc +53 -0
  87. package/template-vite/.cursor/rules/exxat-reuse-before-custom.mdc +37 -0
  88. package/template-vite/.cursor/rules/exxat-sidebar-shell.mdc +41 -0
  89. package/template-vite/.cursor/rules/exxat-table-properties-drawer.mdc +79 -0
  90. package/template-vite/.cursor/rules/exxat-table-row-preview.mdc +25 -0
  91. package/template-vite/.cursor/rules/exxat-tabs-chrome.mdc +33 -0
  92. package/template-vite/.cursor/rules/exxat-token-discipline.mdc +109 -0
  93. package/template-vite/.cursor/rules/exxat-ux-discovery-protocol.mdc +202 -0
  94. package/template-vite/.cursor/rules/exxat-ux-principles.mdc +187 -0
  95. package/template-vite/.cursor/skills/exxat-accessibility/SKILL.md +282 -0
  96. package/template-vite/.cursor/skills/exxat-board-cards/SKILL.md +68 -0
  97. package/template-vite/.cursor/skills/exxat-card-vs-list-rows/SKILL.md +20 -0
  98. package/template-vite/.cursor/skills/exxat-centralized-list-dataset/SKILL.md +99 -0
  99. package/template-vite/.cursor/skills/exxat-collaboration-access/SKILL.md +35 -0
  100. package/template-vite/.cursor/skills/exxat-dedicated-search-surfaces/SKILL.md +45 -0
  101. package/template-vite/.cursor/skills/exxat-drawer-vs-dialog/SKILL.md +20 -0
  102. package/template-vite/.cursor/skills/exxat-ds-skill/SKILL.md +893 -0
  103. package/template-vite/.cursor/skills/exxat-ds-skill/references/accessibility.md +142 -0
  104. package/template-vite/.cursor/skills/exxat-ds-skill/references/coach-marks.md +169 -0
  105. package/template-vite/.cursor/skills/exxat-ds-skill/references/data-table-pattern.md +392 -0
  106. package/template-vite/.cursor/skills/exxat-fontawesome-icons/SKILL.md +31 -0
  107. package/template-vite/.cursor/skills/exxat-kpi-flat-band/SKILL.md +38 -0
  108. package/template-vite/.cursor/skills/exxat-kpi-max-four/SKILL.md +19 -0
  109. package/template-vite/.cursor/skills/exxat-kpi-trends/SKILL.md +29 -0
  110. package/template-vite/.cursor/skills/exxat-list-page-view-shells/SKILL.md +36 -0
  111. package/template-vite/.cursor/skills/exxat-mono-ids/SKILL.md +56 -0
  112. package/template-vite/.cursor/skills/exxat-primary-nav-secondary-panel/SKILL.md +49 -0
  113. package/template-vite/.cursor/skills/exxat-senior-ux/SKILL.md +198 -0
  114. package/template-vite/.cursor/skills/exxat-token-economy/SKILL.md +287 -0
  115. package/template-vite/.cursor/skills/exxat-ux-audit/SKILL.md +303 -0
  116. package/{template → template-vite}/components/ask-leo-sidebar.tsx +10 -8
  117. package/{template → template-vite}/components/command-menu.tsx +1 -1
  118. package/{template → template-vite}/components/data-views/library-folder-tree-branch.tsx +1 -1
  119. package/{template → template-vite}/components/dedicated-search-recents.tsx +1 -1
  120. package/{template → template-vite}/components/dedicated-search-url-composer.tsx +1 -1
  121. package/{template → template-vite}/components/library-client.tsx +1 -1
  122. package/{template → template-vite}/components/library-hub-client.tsx +2 -2
  123. package/{template → template-vite}/components/library-secondary-nav.tsx +2 -2
  124. package/{template → template-vite}/components/library-table.tsx +35 -27
  125. package/{template → template-vite}/components/new-library-item-form.tsx +1 -1
  126. package/{template → template-vite}/components/page-breadcrumb-trail.tsx +1 -1
  127. package/{template → template-vite}/components/settings-client.tsx +1 -1
  128. package/{template → template-vite}/components/sidebar/app-sidebar.tsx +2 -2
  129. package/{template → template-vite}/components/sidebar/nav-main.tsx +1 -1
  130. package/{template → template-vite}/components/sidebar/nav-user.tsx +1 -1
  131. package/{template → template-vite}/components/sidebar/secondary-nav.tsx +1 -1
  132. package/{template → template-vite}/components/system-banner-slot.tsx +1 -1
  133. package/{template → template-vite}/components/templates/discovery-hub-template.tsx +2 -2
  134. package/{template → template-vite}/components/templates/new-focus-template.tsx +1 -1
  135. package/{template → template-vite}/components/tokens-secondary-nav.tsx +2 -2
  136. package/{template → template-vite}/components/tokens-themes-client.tsx +1 -1
  137. package/{template → template-vite}/hooks/use-secondary-panel-hub-nav.ts +1 -1
  138. package/template-vite/index.html +49 -0
  139. package/template-vite/lib/next-compat.tsx +98 -0
  140. package/{template → template-vite}/package.json +15 -27
  141. package/template-vite/scripts/port-next-imports.mjs +70 -0
  142. package/template-vite/src/App.tsx +103 -0
  143. package/template-vite/src/main.tsx +50 -0
  144. package/{template/app/(app)/error.tsx → template-vite/src/pages/_error.tsx} +12 -24
  145. package/{template/app/(app)/loading.tsx → template-vite/src/pages/_loading.tsx} +4 -2
  146. package/template-vite/src/pages/_not-found.tsx +17 -0
  147. package/template-vite/src/pages/dashboard.tsx +48 -0
  148. package/{template/app/(app)/help/page.tsx → template-vite/src/pages/help.tsx} +3 -2
  149. package/{template/app/(app)/library/layout.tsx → template-vite/src/pages/library/_layout.tsx} +18 -16
  150. package/{template/app/(app)/library/all/page.tsx → template-vite/src/pages/library/all.tsx} +1 -1
  151. package/{template/app/(app)/library/new/page.tsx → template-vite/src/pages/library/new.tsx} +12 -18
  152. package/template-vite/src/routes.tsx +72 -0
  153. package/{template/app → template-vite/src/styles}/globals.css +6 -2
  154. package/{template → template-vite}/tsconfig.json +5 -14
  155. package/template-vite/vite.config.ts +52 -0
  156. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +0 -53
  157. package/template/.agents/skills/shadcn/SKILL.md +0 -242
  158. package/template/.agents/skills/shadcn/agents/openai.yml +0 -5
  159. package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  160. package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
  161. package/template/.agents/skills/shadcn/cli.md +0 -257
  162. package/template/.agents/skills/shadcn/customization.md +0 -202
  163. package/template/.agents/skills/shadcn/evals/evals.json +0 -47
  164. package/template/.agents/skills/shadcn/mcp.md +0 -94
  165. package/template/.agents/skills/shadcn/rules/base-vs-radix.md +0 -306
  166. package/template/.agents/skills/shadcn/rules/composition.md +0 -195
  167. package/template/.agents/skills/shadcn/rules/forms.md +0 -192
  168. package/template/.agents/skills/shadcn/rules/icons.md +0 -101
  169. package/template/.agents/skills/shadcn/rules/styling.md +0 -162
  170. package/template/.cursor/rules/exxat-accessibility.mdc +0 -33
  171. package/template/.cursor/rules/exxat-data-tables.mdc +0 -32
  172. package/template/.cursor/rules/exxat-ds-agents.mdc +0 -26
  173. package/template/.cursor/rules/exxat-list-page-connected-views.mdc +0 -16
  174. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +0 -40
  175. package/template/.nvmrc +0 -1
  176. package/template/.prettierignore +0 -7
  177. package/template/Logo/Exxat_Prism.svg +0 -39
  178. package/template/Logo/Exxat_one.svg +0 -36
  179. package/template/app/(app)/dashboard/loading.tsx +0 -18
  180. package/template/app/(app)/dashboard/page.tsx +0 -36
  181. package/template/app/(app)/layout.tsx +0 -77
  182. package/template/app/global-error.tsx +0 -63
  183. package/template/app/layout.tsx +0 -133
  184. package/template/app/page.tsx +0 -9
  185. package/template/docs/HANDBOOK.md +0 -187
  186. package/template/docs/blueprints/README.md +0 -86
  187. package/template/docs/blueprints/_template.md +0 -91
  188. package/template/docs/blueprints/board-card.md +0 -123
  189. package/template/docs/blueprints/data-table.md +0 -139
  190. package/template/docs/blueprints/key-metrics.md +0 -128
  191. package/template/docs/blueprints/list-page-template.md +0 -123
  192. package/template/docs/blueprints/page-header.md +0 -130
  193. package/template/docs/card-vs-rows-pattern.md +0 -36
  194. package/template/docs/collaboration-access-pattern.md +0 -116
  195. package/template/docs/command-menu-pattern.md +0 -45
  196. package/template/docs/component-selection-guide.md +0 -224
  197. package/template/docs/components-audit-2026-05.md +0 -158
  198. package/template/docs/consumer-upgrade-checklist.md +0 -52
  199. package/template/docs/data-views-pattern.md +0 -185
  200. package/template/docs/drawer-vs-dialog-pattern.md +0 -50
  201. package/template/docs/glossary.md +0 -59
  202. package/template/docs/hub-supported-views-pattern.md +0 -53
  203. package/template/docs/jobs/README.md +0 -59
  204. package/template/docs/jobs/record-detail.md +0 -177
  205. package/template/docs/kpi-flat-band-pattern.md +0 -57
  206. package/template/docs/kpi-strip-max-four-pattern.md +0 -30
  207. package/template/docs/kpi-trend-pattern.md +0 -58
  208. package/template/docs/large-dataset-strategy.md +0 -155
  209. package/template/docs/library-hub-header-pattern.md +0 -25
  210. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +0 -95
  211. package/template/docs/migrations/0002-exxat-token-namespace.md +0 -154
  212. package/template/docs/migrations/0003-globals-css-canonical.md +0 -110
  213. package/template/docs/migrations/README.md +0 -100
  214. package/template/docs/migrations/_template.md +0 -64
  215. package/template/docs/modern-saas-patterns.md +0 -165
  216. package/template/docs/perf-memory-pattern.md +0 -206
  217. package/template/docs/reference-implementations.md +0 -153
  218. package/template/docs/shell-surface-elevation-pattern.md +0 -52
  219. package/template/docs/token-taxonomy.md +0 -416
  220. package/template/docs/voice-and-tone.md +0 -262
  221. package/template/ecosystem.config.cjs +0 -32
  222. package/template/next.config.mjs +0 -216
  223. package/template/postcss.config.mjs +0 -8
  224. package/template/public/favicon/favicon.ico +0 -0
  225. package/template/tests/setup.ts +0 -26
  226. package/template/vitest.config.ts +0 -18
  227. /package/{template → template-vite}/.cursor/rules/exxat-dashboard-view-charts.mdc +0 -0
  228. /package/{template → template-vite}/.prettierrc +0 -0
  229. /package/{template → template-vite}/AGENTS.md +0 -0
  230. /package/{template → template-vite}/README.md +0 -0
  231. /package/{template → template-vite}/components/.gitkeep +0 -0
  232. /package/{template → template-vite}/components/ask-leo-composer.tsx +0 -0
  233. /package/{template → template-vite}/components/brand-color-picker.tsx +0 -0
  234. /package/{template → template-vite}/components/chart-area-interactive.tsx +0 -0
  235. /package/{template → template-vite}/components/charts-overview.tsx +0 -0
  236. /package/{template → template-vite}/components/collaboration-access-flow.tsx +0 -0
  237. /package/{template → template-vite}/components/columns-client.tsx +0 -0
  238. /package/{template → template-vite}/components/columns-showcase.tsx +0 -0
  239. /package/{template → template-vite}/components/dashboard-promo-banner.tsx +0 -0
  240. /package/{template → template-vite}/components/dashboard-quota-progress-card.tsx +0 -0
  241. /package/{template → template-vite}/components/dashboard-report-charts.tsx +0 -0
  242. /package/{template → template-vite}/components/dashboard-section-heading.tsx +0 -0
  243. /package/{template → template-vite}/components/dashboard-tabs.tsx +0 -0
  244. /package/{template → template-vite}/components/data-table/filter-date-calendar.tsx +0 -0
  245. /package/{template → template-vite}/components/data-table/filter-text-value-input.tsx +0 -0
  246. /package/{template → template-vite}/components/data-table/index.tsx +0 -0
  247. /package/{template → template-vite}/components/data-table/pagination.tsx +0 -0
  248. /package/{template → template-vite}/components/data-table/types.ts +0 -0
  249. /package/{template → template-vite}/components/data-table/use-table-state.test.ts +0 -0
  250. /package/{template → template-vite}/components/data-table/use-table-state.ts +0 -0
  251. /package/{template → template-vite}/components/data-views/board-card-primitives.tsx +0 -0
  252. /package/{template → template-vite}/components/data-views/data-row-list.tsx +0 -0
  253. /package/{template → template-vite}/components/data-views/finder-panel-view.tsx +0 -0
  254. /package/{template → template-vite}/components/data-views/folder-grid-view.tsx +0 -0
  255. /package/{template → template-vite}/components/data-views/hub-table.tsx +0 -0
  256. /package/{template → template-vite}/components/data-views/index.ts +0 -0
  257. /package/{template → template-vite}/components/data-views/list-page-board-card.tsx +0 -0
  258. /package/{template → template-vite}/components/data-views/list-page-board-template.tsx +0 -0
  259. /package/{template → template-vite}/components/data-views/list-page-connected-view-body.tsx +0 -0
  260. /package/{template → template-vite}/components/data-views/list-page-split-details-placeholder.tsx +0 -0
  261. /package/{template → template-vite}/components/data-views/list-page-split-hub-chrome.tsx +0 -0
  262. /package/{template → template-vite}/components/data-views/list-page-split-hub-tokens.ts +0 -0
  263. /package/{template → template-vite}/components/data-views/list-page-tree-column-header.tsx +0 -0
  264. /package/{template → template-vite}/components/data-views/list-page-tree-panel-shell.tsx +0 -0
  265. /package/{template → template-vite}/components/data-views/list-page-view-frame.tsx +0 -0
  266. /package/{template → template-vite}/components/data-views/os-folder-glyph.tsx +0 -0
  267. /package/{template → template-vite}/components/data-views/outline-tree-menu.tsx +0 -0
  268. /package/{template → template-vite}/components/data-views/table-cells.tsx +0 -0
  269. /package/{template → template-vite}/components/dev-chunk-load-recovery.tsx +0 -0
  270. /package/{template → template-vite}/components/export-drawer.test.tsx +0 -0
  271. /package/{template → template-vite}/components/export-drawer.tsx +0 -0
  272. /package/{template → template-vite}/components/exxat-product-logo.tsx +0 -0
  273. /package/{template → template-vite}/components/folder-details-shell.tsx +0 -0
  274. /package/{template → template-vite}/components/form-layout-01.tsx +0 -0
  275. /package/{template → template-vite}/components/hub-tree-panel-view.tsx +0 -0
  276. /package/{template → template-vite}/components/invite-collaborators-drawer.tsx +0 -0
  277. /package/{template → template-vite}/components/key-metrics-ask-leo-bridge.tsx +0 -0
  278. /package/{template → template-vite}/components/key-metrics.tsx +0 -0
  279. /package/{template → template-vite}/components/leo-insight-indicator.tsx +0 -0
  280. /package/{template → template-vite}/components/leo-typing-dots.tsx +0 -0
  281. /package/{template → template-vite}/components/library-board-view.tsx +0 -0
  282. /package/{template → template-vite}/components/library-dashboard-charts.tsx +0 -0
  283. /package/{template → template-vite}/components/library-favorite-button.tsx +0 -0
  284. /package/{template → template-vite}/components/library-new-folder-sheet.tsx +0 -0
  285. /package/{template → template-vite}/components/library-os-folder-view.tsx +0 -0
  286. /package/{template → template-vite}/components/library-page-header.tsx +0 -0
  287. /package/{template → template-vite}/components/library-panel-activator.tsx +0 -0
  288. /package/{template → template-vite}/components/list-hub-status-badge.tsx +0 -0
  289. /package/{template → template-vite}/components/list-page-dashboard-charts.tsx +0 -0
  290. /package/{template → template-vite}/components/onboarding/getting-started.tsx +0 -0
  291. /package/{template → template-vite}/components/onboarding/index.ts +0 -0
  292. /package/{template → template-vite}/components/onboarding/onboarding-01.tsx +0 -0
  293. /package/{template → template-vite}/components/onboarding/onboarding-02.tsx +0 -0
  294. /package/{template → template-vite}/components/onboarding/onboarding-03.tsx +0 -0
  295. /package/{template → template-vite}/components/onboarding/onboarding-04.tsx +0 -0
  296. /package/{template → template-vite}/components/page-header.tsx +0 -0
  297. /package/{template → template-vite}/components/product-switcher.tsx +0 -0
  298. /package/{template → template-vite}/components/product-wordmark.tsx +0 -0
  299. /package/{template → template-vite}/components/settings-appearance-card.tsx +0 -0
  300. /package/{template → template-vite}/components/settings-form-row.tsx +0 -0
  301. /package/{template → template-vite}/components/sidebar/app-sidebar-dynamic.tsx +0 -0
  302. /package/{template → template-vite}/components/sidebar/index.ts +0 -0
  303. /package/{template → template-vite}/components/sidebar/nav-documents.tsx +0 -0
  304. /package/{template → template-vite}/components/sidebar/nav-secondary.tsx +0 -0
  305. /package/{template → template-vite}/components/sidebar/secondary-panel.tsx +0 -0
  306. /package/{template → template-vite}/components/sidebar/sidebar-auto-collapse.tsx +0 -0
  307. /package/{template → template-vite}/components/sidebar/sidebar-auto-open.tsx +0 -0
  308. /package/{template → template-vite}/components/sidebar/sidebar-shell.tsx +0 -0
  309. /package/{template → template-vite}/components/site-header.tsx +0 -0
  310. /package/{template → template-vite}/components/table-properties/column-row.tsx +0 -0
  311. /package/{template → template-vite}/components/table-properties/draggable-list.ts +0 -0
  312. /package/{template → template-vite}/components/table-properties/drawer-button.tsx +0 -0
  313. /package/{template → template-vite}/components/table-properties/drawer.tsx +0 -0
  314. /package/{template → template-vite}/components/table-properties/filter-card.tsx +0 -0
  315. /package/{template → template-vite}/components/table-properties/index.ts +0 -0
  316. /package/{template → template-vite}/components/table-properties/sort-card.tsx +0 -0
  317. /package/{template → template-vite}/components/table-properties/types.ts +0 -0
  318. /package/{template → template-vite}/components/task-list-panel.tsx +0 -0
  319. /package/{template → template-vite}/components/task-priority-badge.tsx +0 -0
  320. /package/{template → template-vite}/components/templates/dedicated-search-landing-template.tsx +0 -0
  321. /package/{template → template-vite}/components/templates/dedicated-search-results-template.tsx +0 -0
  322. /package/{template → template-vite}/components/templates/list-page.tsx +0 -0
  323. /package/{template → template-vite}/components/templates/nested-secondary-panel-shell.tsx +0 -0
  324. /package/{template → template-vite}/components/templates/primary-page-template.tsx +0 -0
  325. /package/{template → template-vite}/components/templates/secondary-panel-hub-template.tsx +0 -0
  326. /package/{template → template-vite}/components/theme-color-sync.tsx +0 -0
  327. /package/{template → template-vite}/components/theme-provider.tsx +0 -0
  328. /package/{template → template-vite}/components/tinted-icon-disc.tsx +0 -0
  329. /package/{template → template-vite}/components/tokens-hub-auxiliary-views.tsx +0 -0
  330. /package/{template → template-vite}/components/tokens-themes-section.tsx +0 -0
  331. /package/{template → template-vite}/components/ui/accordion.tsx +0 -0
  332. /package/{template → template-vite}/components/ui/ai-thinking-surface.tsx +0 -0
  333. /package/{template → template-vite}/components/ui/alert-dialog.tsx +0 -0
  334. /package/{template → template-vite}/components/ui/avatar.tsx +0 -0
  335. /package/{template → template-vite}/components/ui/badge.tsx +0 -0
  336. /package/{template → template-vite}/components/ui/banner.tsx +0 -0
  337. /package/{template → template-vite}/components/ui/breadcrumb.tsx +0 -0
  338. /package/{template → template-vite}/components/ui/button.tsx +0 -0
  339. /package/{template → template-vite}/components/ui/calendar.tsx +0 -0
  340. /package/{template → template-vite}/components/ui/card.tsx +0 -0
  341. /package/{template → template-vite}/components/ui/chart.tsx +0 -0
  342. /package/{template → template-vite}/components/ui/checkbox.tsx +0 -0
  343. /package/{template → template-vite}/components/ui/coach-mark.tsx +0 -0
  344. /package/{template → template-vite}/components/ui/collapsible.tsx +0 -0
  345. /package/{template → template-vite}/components/ui/command.tsx +0 -0
  346. /package/{template → template-vite}/components/ui/context-menu.tsx +0 -0
  347. /package/{template → template-vite}/components/ui/date-picker-field.tsx +0 -0
  348. /package/{template → template-vite}/components/ui/dialog.tsx +0 -0
  349. /package/{template → template-vite}/components/ui/dot-pattern.tsx +0 -0
  350. /package/{template → template-vite}/components/ui/drag-handle-grip.tsx +0 -0
  351. /package/{template → template-vite}/components/ui/dropdown-menu.tsx +0 -0
  352. /package/{template → template-vite}/components/ui/field.tsx +0 -0
  353. /package/{template → template-vite}/components/ui/form.tsx +0 -0
  354. /package/{template → template-vite}/components/ui/hover-card.tsx +0 -0
  355. /package/{template → template-vite}/components/ui/input-group.tsx +0 -0
  356. /package/{template → template-vite}/components/ui/input-mask.tsx +0 -0
  357. /package/{template → template-vite}/components/ui/input.tsx +0 -0
  358. /package/{template → template-vite}/components/ui/kbd.tsx +0 -0
  359. /package/{template → template-vite}/components/ui/label.tsx +0 -0
  360. /package/{template → template-vite}/components/ui/leo-icon.tsx +0 -0
  361. /package/{template → template-vite}/components/ui/payment-card-fields.tsx +0 -0
  362. /package/{template → template-vite}/components/ui/popover.tsx +0 -0
  363. /package/{template → template-vite}/components/ui/radio-group.tsx +0 -0
  364. /package/{template → template-vite}/components/ui/resizable.tsx +0 -0
  365. /package/{template → template-vite}/components/ui/scroll-area.tsx +0 -0
  366. /package/{template → template-vite}/components/ui/select.tsx +0 -0
  367. /package/{template → template-vite}/components/ui/selection-tile-grid.tsx +0 -0
  368. /package/{template → template-vite}/components/ui/separator.tsx +0 -0
  369. /package/{template → template-vite}/components/ui/sheet.tsx +0 -0
  370. /package/{template → template-vite}/components/ui/sidebar.tsx +0 -0
  371. /package/{template → template-vite}/components/ui/skeleton.tsx +0 -0
  372. /package/{template → template-vite}/components/ui/slider.tsx +0 -0
  373. /package/{template → template-vite}/components/ui/sonner.tsx +0 -0
  374. /package/{template → template-vite}/components/ui/status-badge.tsx +0 -0
  375. /package/{template → template-vite}/components/ui/table.tsx +0 -0
  376. /package/{template → template-vite}/components/ui/tabs.tsx +0 -0
  377. /package/{template → template-vite}/components/ui/textarea.tsx +0 -0
  378. /package/{template → template-vite}/components/ui/tip.tsx +0 -0
  379. /package/{template → template-vite}/components/ui/toggle-group.tsx +0 -0
  380. /package/{template → template-vite}/components/ui/toggle-switch.tsx +0 -0
  381. /package/{template → template-vite}/components/ui/toggle.tsx +0 -0
  382. /package/{template → template-vite}/components/ui/tooltip.tsx +0 -0
  383. /package/{template → template-vite}/components/ui/view-segmented-control.tsx +0 -0
  384. /package/{template → template-vite}/components.json +0 -0
  385. /package/{template → template-vite}/contexts/chart-variant-context.tsx +0 -0
  386. /package/{template → template-vite}/contexts/command-menu-context.tsx +0 -0
  387. /package/{template → template-vite}/contexts/dashboard-view-context.tsx +0 -0
  388. /package/{template → template-vite}/contexts/product-context.tsx +0 -0
  389. /package/{template → template-vite}/contexts/system-banner-context.tsx +0 -0
  390. /package/{template → template-vite}/eslint.config.mjs +0 -0
  391. /package/{template → template-vite}/fontawesome-subset.manifest.json +0 -0
  392. /package/{template → template-vite}/hooks/.gitkeep +0 -0
  393. /package/{template → template-vite}/hooks/use-app-theme.ts +0 -0
  394. /package/{template → template-vite}/hooks/use-coach-mark.ts +0 -0
  395. /package/{template → template-vite}/hooks/use-location-hash.ts +0 -0
  396. /package/{template → template-vite}/hooks/use-mobile.ts +0 -0
  397. /package/{template → template-vite}/hooks/use-mod-key-label.ts +0 -0
  398. /package/{template → template-vite}/hooks/use-sidebar-reflow-zoom.ts +0 -0
  399. /package/{template → template-vite}/lib/.gitkeep +0 -0
  400. /package/{template → template-vite}/lib/ask-leo-route-context.ts +0 -0
  401. /package/{template → template-vite}/lib/chart-keyboard-selection.test.ts +0 -0
  402. /package/{template → template-vite}/lib/chart-keyboard-selection.ts +0 -0
  403. /package/{template → template-vite}/lib/chart-line-dash.ts +0 -0
  404. /package/{template → template-vite}/lib/chunk-load-error.ts +0 -0
  405. /package/{template → template-vite}/lib/coach-mark-registry.ts +0 -0
  406. /package/{template → template-vite}/lib/collaborator-access.ts +0 -0
  407. /package/{template → template-vite}/lib/command-menu-config.ts +0 -0
  408. /package/{template → template-vite}/lib/command-menu-search-data.ts +0 -0
  409. /package/{template → template-vite}/lib/conditional-rule-match.ts +0 -0
  410. /package/{template → template-vite}/lib/dashboard-customize-coach-mark.ts +0 -0
  411. /package/{template → template-vite}/lib/dashboard-layout-merge.ts +0 -0
  412. /package/{template → template-vite}/lib/data-list-display-options.ts +0 -0
  413. /package/{template → template-vite}/lib/data-list-persistence.ts +0 -0
  414. /package/{template → template-vite}/lib/data-list-view-registry.ts +0 -0
  415. /package/{template → template-vite}/lib/data-list-view-surface.ts +0 -0
  416. /package/{template → template-vite}/lib/data-list-view.ts +0 -0
  417. /package/{template → template-vite}/lib/data-view-dashboard-storage.ts +0 -0
  418. /package/{template → template-vite}/lib/date-filter.ts +0 -0
  419. /package/{template → template-vite}/lib/dedicated-search-recents.ts +0 -0
  420. /package/{template → template-vite}/lib/dedicated-search-url.ts +0 -0
  421. /package/{template → template-vite}/lib/dev-log.test.ts +0 -0
  422. /package/{template → template-vite}/lib/dev-log.ts +0 -0
  423. /package/{template → template-vite}/lib/discovery-hub.ts +0 -0
  424. /package/{template → template-vite}/lib/editable-target.ts +0 -0
  425. /package/{template → template-vite}/lib/exxat-palette.json +0 -0
  426. /package/{template → template-vite}/lib/exxat-palette.ts +0 -0
  427. /package/{template → template-vite}/lib/floating-sheet-panel.ts +0 -0
  428. /package/{template → template-vite}/lib/full-hub-supported-views.ts +0 -0
  429. /package/{template → template-vite}/lib/hub-connected-view-renderers.ts +0 -0
  430. /package/{template → template-vite}/lib/initials-from-name.ts +0 -0
  431. /package/{template → template-vite}/lib/library-authoring.ts +0 -0
  432. /package/{template → template-vite}/lib/library-dedicated-search.ts +0 -0
  433. /package/{template → template-vite}/lib/library-hub-search.ts +0 -0
  434. /package/{template → template-vite}/lib/library-nav.ts +0 -0
  435. /package/{template → template-vite}/lib/library-recent-searches.ts +0 -0
  436. /package/{template → template-vite}/lib/library-supported-views.ts +0 -0
  437. /package/{template → template-vite}/lib/list-hub-supported-views.ts +0 -0
  438. /package/{template → template-vite}/lib/list-page-table-properties.ts +0 -0
  439. /package/{template → template-vite}/lib/list-status-badges.ts +0 -0
  440. /package/{template → template-vite}/lib/logo-dev.ts +0 -0
  441. /package/{template → template-vite}/lib/mailto.ts +0 -0
  442. /package/{template → template-vite}/lib/mock/dashboard.ts +0 -0
  443. /package/{template → template-vite}/lib/mock/library-folders.ts +0 -0
  444. /package/{template → template-vite}/lib/mock/library-header-collaborators.ts +0 -0
  445. /package/{template → template-vite}/lib/mock/library-inspector.ts +0 -0
  446. /package/{template → template-vite}/lib/mock/library-kpi.ts +0 -0
  447. /package/{template → template-vite}/lib/mock/library.ts +0 -0
  448. /package/{template → template-vite}/lib/mock/navigation.tsx +0 -0
  449. /package/{template → template-vite}/lib/motion-ui.ts +0 -0
  450. /package/{template → template-vite}/lib/product-brand.ts +0 -0
  451. /package/{template → template-vite}/lib/raf-throttle.ts +0 -0
  452. /package/{template → template-vite}/lib/row-height.ts +0 -0
  453. /package/{template → template-vite}/lib/sidebar-state-cookie.ts +0 -0
  454. /package/{template → template-vite}/lib/stock-portrait.ts +0 -0
  455. /package/{template → template-vite}/lib/table-state-lifecycle.ts +0 -0
  456. /package/{template → template-vite}/lib/utils.test.ts +0 -0
  457. /package/{template → template-vite}/lib/utils.ts +0 -0
  458. /package/{template → template-vite}/public/.gitkeep +0 -0
  459. /package/{template → template-vite}/public/Illustration/Rotation.svg +0 -0
  460. /package/{template → template-vite}/public/avatars/user.svg +0 -0
  461. /package/{template/public → template-vite/public/favicon}/favicon.ico +0 -0
  462. /package/{template/app → template-vite/public}/favicon.ico +0 -0
  463. /package/{template → template-vite}/public/folders/icons8-folder-windows-11.svg +0 -0
  464. /package/{template → template-vite}/public/logos/exxat-one.svg +0 -0
  465. /package/{template → template-vite}/public/logos/exxat-prism.svg +0 -0
  466. /package/{template → template-vite}/public/mock-schools/emory.svg +0 -0
  467. /package/{template → template-vite}/public/mock-schools/rush.svg +0 -0
  468. /package/{template → template-vite}/scripts/fontawesome-subset-audit.mjs +0 -0
  469. /package/{template → template-vite}/scripts/pm2-startup-macos.sh +0 -0
  470. /package/{template → template-vite}/skills-lock.json +0 -0
  471. /package/{template/app/(app)/columns/page.tsx → template-vite/src/pages/columns.tsx} +0 -0
  472. /package/{template/app/(app)/library/find/page.tsx → template-vite/src/pages/library/find.tsx} +0 -0
  473. /package/{template/app/(app)/library/page.tsx → template-vite/src/pages/library/index.tsx} +0 -0
  474. /package/{template/app/(app)/library/list/page.tsx → template-vite/src/pages/library/list.tsx} +0 -0
  475. /package/{template/app/(app)/settings/page.tsx → template-vite/src/pages/settings.tsx} +0 -0
  476. /package/{template/app/(app)/tokens-themes/page.tsx → template-vite/src/pages/tokens-themes.tsx} +0 -0
  477. /package/{template → template-vite}/stores/app-store.ts +0 -0
  478. /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`)