@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
@@ -1,6 +1,8 @@
1
1
  ---
2
- description: ListPageTemplate — shared table state across views, mock + KPI helpers, dashboard tab
3
- alwaysApply: true
2
+ description: ListPageTemplate — shared table state across views, mock + KPI helpers, dashboard tab. Auto-attaches when editing list-page React clients.
3
+ globs: apps/web/{components,lib,app}/**/*.{tsx,ts}
4
+ alwaysApply: false
5
+ appliesTo: [react]
4
6
  ---
5
7
 
6
8
  # Exxat DS — list page connected views
@@ -16,9 +18,11 @@ alwaysApply: true
16
18
  5. **List hub metrics strip** — Prefer **`KeyMetrics variant="flat"`** on **`ListPageTemplate`** **`metrics`** slot (transparent band, brand glow only) — **`docs/kpi-flat-band-pattern.md`**, **`.cursor/rules/exxat-kpi-flat-band.mdc`**.
17
19
  6. **MUST NOT** ship “not wired” / “switch to table” placeholders for list/board/dashboard when the stack supports those views.
18
20
  7. **MUST NOT** add a **primary nav** destination that is only placeholder copy with no **`ListPageTemplate`** hub, mock rows, and wired views — see **`apps/web/AGENTS.md` §4.1** (no empty hubs).
21
+ 8. **Add view parity** — Use **`FULL_HUB_SUPPORTED_VIEWS`** (default) and implement **all seven** views with real bodies — **`.cursor/rules/exxat-hub-supported-views.mdc`**. List rows **MUST** use **`ListPageBoardCard`** (`library-table.tsx`), not bare title + id lines.
19
22
 
20
23
  ## See also
21
24
 
22
25
  - **`.cursor/rules/exxat-centralized-list-dataset.mdc`** — single **`tableState.rows`** source for every hub view, inspectors, and **`TablePropertiesDrawer`** on the same **`DataTable`**.
23
26
  - **Centered view bodies + reusable shells:** **`apps/web/AGENTS.md` §4.5**, **`.cursor/rules/exxat-list-page-view-shells.mdc`**, **`ListPageViewFrame`** in **`components/data-views/list-page-view-frame.tsx`**.
24
27
  - **Flat KPI band:** **`docs/kpi-flat-band-pattern.md`**, **`.cursor/rules/exxat-kpi-flat-band.mdc`**.
28
+ - **Hub supported views:** **`docs/hub-supported-views-pattern.md`**, **`.cursor/rules/exxat-hub-supported-views.mdc`**.
@@ -2,6 +2,7 @@
2
2
  description: Exxat DS — centered reusable shells for list-page views (not page-specific markup)
3
3
  globs: apps/web/components/**/*.tsx
4
4
  alwaysApply: false
5
+ appliesTo: [react]
5
6
  ---
6
7
 
7
8
  # Exxat DS — list-page view shells (centered, reusable)
@@ -21,7 +22,7 @@ Domain logic (columns, tiles, folder trees) stays in **`*-table.tsx` / `*-client
21
22
  ## MUST NOT
22
23
 
23
24
  - Wrap **`DataTable`** (or its outer toolbar shell) in **`ListPageViewFrame`** if that **duplicates** horizontal inset already applied by **`DataTable`** / **`DataTableToolbar`** — see **`AGENTS.md` §5** (double indent).
24
- - Ship **view-only** layout classes only inside **`app/(app)/.../page.tsx`** for a hub that other entities will mirror — belong in **`data-views/`** or **`templates/`**.
25
+ - Ship **view-only** layout classes only inside **`src/views/<route>.tsx`** (or any route entry) for a hub that other entities will mirror — belong in **`data-views/`** or **`templates/`**.
25
26
 
26
27
  ## See also
27
28
 
@@ -2,6 +2,7 @@
2
2
  description: Exxat DS — monospace typography for record IDs, question IDs, and other system identifiers
3
3
  globs: apps/web/**/*.tsx
4
4
  alwaysApply: false
5
+ appliesTo: [react]
5
6
  ---
6
7
 
7
8
  # Exxat DS — monospace IDs
@@ -16,7 +17,7 @@ Use this when rendering **system identifiers** — values a user copies, searche
16
17
 
17
18
  ## SHOULD
18
19
 
19
- - Match existing hubs: **`library-table.tsx`**, **`library-list-view.tsx`**, **`new-library-item-form.tsx`** (header subtitle), **`sites-table.tsx`** (`row.id`).
20
+ - Match existing hubs: **`library-table.tsx`**, **`columns-showcase.tsx`** (mono record IDs in the showcase row), **`new-library-item-form.tsx`** (header subtitle).
20
21
  - Prefer **`truncate`** / **`min-w-0`** on mono IDs in tight layouts so long tokens do not blow out columns.
21
22
 
22
23
  ## MUST NOT
@@ -2,6 +2,7 @@
2
2
  description: Sidebar and secondary nav — exactly one active item per route (longest path match)
3
3
  globs: "**/app-sidebar.tsx,**/secondary-nav.tsx,**/navigation.tsx,**/lib/nav-active.ts"
4
4
  alwaysApply: false
5
+ appliesTo: [react]
5
6
  ---
6
7
 
7
8
  # Exxat DS — single active nav item (MUST)
@@ -17,7 +18,7 @@ Only **one** primary sidebar row, collapsible child, or secondary-panel link may
17
18
  2. **Never** mark a nav item active with bare `pathname === href` or `pathname.startsWith(href + "/")` when other nav targets share that prefix (e.g. `/dashboard` vs `/dashboard/students`).
18
19
  3. **Hash disambiguation** — when multiple items share the same path (e.g. `/settings` vs `/settings#appearance`), use `buildNavHashClaims` so the no-fragment row defers to the hash-specific row.
19
20
  4. **Collapsible parents** — when any child is active, the **parent** row stays visually neutral in the expanded sidebar; only the child gets `data-active` (icon rail may still highlight the parent — see `isCollapsibleParentMenuButtonActive` in `app-sidebar.tsx`).
20
- 5. **Keep `ListPageTemplate.supportedViewTypes` and `HubTable.supportedViewTypes` in sync** on the same hub — do not pass `supportedViewTypes={["table"]}` on a primary hub unless that hub truly implements only table.
21
+ 5. **Keep `ListPageTemplate.supportedViewTypes` and `HubTable.supportedViewTypes` in sync** on the same hub — default **`FULL_HUB_SUPPORTED_VIEWS`** (seven views). See **`exxat-hub-supported-views.mdc`** for renderer requirements.
21
22
 
22
23
  ## MUST NOT
23
24
 
@@ -27,5 +28,5 @@ Only **one** primary sidebar row, collapsible child, or secondary-panel link may
27
28
  ## Reference
28
29
 
29
30
  - `packages/ui/src/lib/nav-active.ts`
30
- - `packages/ui/template/components/sidebar/app-sidebar.tsx`
31
- - `packages/ui/template/components/sidebar/secondary-nav.tsx`
31
+ - `packages/ui/template-vite/components/sidebar/app-sidebar.tsx`
32
+ - `packages/ui/template-vite/components/sidebar/secondary-nav.tsx`
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Uploaded screenshots/mockups are IA reference only — map to Exxat DS patterns; never pixel-copy
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — uploaded images are not the implementation spec
@@ -11,25 +12,35 @@ When the user attaches a **screenshot**, **mockup**, **Figma export**, **legacy
11
12
 
12
13
  ## Allowed to take from an image (content / IA)
13
14
 
14
- - **Screen purpose**, **nav labels**, **routes**, **fields**, **columns**, **KPIs**, **actions**, **statuses**
15
- - **Icon suffix** (Font Awesome) still use **`fa-light` / `fa-solid`** DS pairing
16
- - **Workflow intent** — export, invite, row detail, etc.
15
+ - **Screen purpose** list hub, detail record, settings, search, etc.
16
+ - **Nav labels**, **section grouping**, **route slugs**, **field names**, **column headers**
17
+ - **Data the user cares about** — which KPIs, filters, actions, statuses exist
18
+ - **Icon choice** (Font Awesome suffix) when obvious — still use **`fa-light` / `fa-solid`** DS pairing
19
+ - **Workflow** — e.g. “export from ⋯”, “row opens profile”, “invite from header”
17
20
 
18
21
  ## MUST NOT copy from an image (visual / stack)
19
22
 
20
- - **Hex / RGB colors**, rainbow section text, custom sidebar washes, bespoke pills
21
- - **Shell forks** — sidebar, header, list toolbar, tabs that bypass DS components
22
- - **Bespoke widgets** when DS primitives exist — raw tables, custom popovers, Vaul, full-width tabs
23
- - **Pixel implementation “because it’s in the picture”** without citing a **DS pattern + reference hub**
23
+ - **Hex / RGB colors**, per-section rainbow text, custom sidebar washes, one-off pill shapes
24
+ - **Layout chrome** that duplicates DS shell — sidebar, **`SiteHeader`**, **`PageHeader`**, **`ListPageTemplate`** toolbar, tab bars
25
+ - **Bespoke components** when a DS primitive exists — raw `<table>`, custom popovers, hand-built buttons, full-width tabs, Vaul drawers
26
+ - **Forking shared files** (`app-sidebar.tsx`, `sidebar.tsx`, `globals.css`) to match a legacy product
27
+ - **Implementing “because it’s in the picture”** without naming the **DS pattern + reference file** you are using
24
28
 
25
- ## REQUIRED workflow (before UI code)
29
+ ## REQUIRED workflow (before writing UI code)
26
30
 
27
- 1. Classify via **`component-selection-guide`** + **`blueprints/`**
28
- 2. Pick **`reference-implementations`** hub
29
- 3. State mapping (screenDS composition)
30
- 4. Build with **`AGENTS.md`** + topic rules
31
- 5. Image vs DS conflict **DS wins**; ask one question only for true business gaps
31
+ 1. **Classify the screen** — use **`docs/component-selection-guide.md`** + **`docs/blueprints/`** (list page, page header, data table, dedicated search, …).
32
+ 2. **Pick a reference hub** — **`docs/reference-implementations.md`** (Placements, Team, Library, Compliance, …).
33
+ 3. **State the mapping** (briefly in your reply): e.g. “Students roster **`ListPageTemplate`** + **`HubTable`** like Team; nav rows → **`lib/mock/navigation.tsx`** only; sidebar chrome unchanged.”
34
+ 4. **Implement with DS components + tokens** — **`AGENTS.md`**, **`exxat-ds-agents.mdc`**, topic rules (`exxat-tabs-chrome`, `exxat-page-header-actions`, `exxat-sidebar-shell`, …).
35
+ 5. **If the image conflicts with DS** follow DS; ask **one** clarifying question only when the **business requirement** (not pixels) cannot be met with existing patterns.
36
+
37
+ ## Consumer apps
38
+
39
+ - Product UI lives in the **customer repo** with **`@exxatdesignux/ui`** — not by restyling the DS monorepo to match uploads.
40
+ - After upgrade, run **`exxat-ui sync-extras`** so this rule and siblings stay on disk.
32
41
 
33
42
  ## See also
34
43
 
35
- - **`exxat-reuse-before-custom.mdc`**, **`exxat-sidebar-shell.mdc`**, **`exxat-token-economy`** §2
44
+ - **`exxat-reuse-before-custom.mdc`** compose before inventing
45
+ - **`exxat-sidebar-shell.mdc`** — sidebar-specific anti-patterns
46
+ - **`exxat-token-economy`** skill §2 — pre-flight includes image discipline
@@ -1,3 +1,9 @@
1
+ ---
2
+ description: No Salesforce SLDS leakage — never copy slds-* classes, lightning-* elements, SLDS token names, or synthetic-shadow assumptions into Exxat DS code.
3
+ alwaysApply: true
4
+ appliesTo: [universal]
5
+ ---
6
+
1
7
  # Exxat DS — no SLDS leakage
2
8
 
3
9
  **Context:** Some agents have access to other repos, including the **Salesforce
@@ -23,7 +29,7 @@ codebase into **`apps/web`** or **`packages/ui`**.
23
29
  Exxat compositions in `apps/web/components/`.
24
30
  3. **Synthetic-shadow assumptions** — Do **not** call `template.querySelector`,
25
31
  `slds-color-scheme_dark`, `shadowRoot === null` checks, or anything that
26
- only makes sense under Salesforce synthetic shadow. The Next.js app uses
32
+ only makes sense under Salesforce synthetic shadow. The Vite + React app uses
27
33
  the real DOM + Radix portals.
28
34
  4. **SLDS styling-hook vars** — Do **not** use SLDS custom properties
29
35
  (`--slds-g-color-surface-*`, `--slds-g-color-on-surface-*`,
@@ -67,7 +73,7 @@ silently breaks:
67
73
  - **Accessibility** — SLDS 1 contrast ratios differ from Exxat's WCAG 2.1 AA
68
74
  targets; mixing them produces unverifiable composites.
69
75
  - **Bundling** — Importing `@salesforce-ux/design-system` would balloon the
70
- Next.js bundle and pull in classic SLDS that we explicitly chose not to use.
76
+ Vite bundle and pull in classic SLDS that we explicitly chose not to use.
71
77
 
72
78
  ## See also
73
79
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS — do not use toast / sonner / transient snackbars for product messaging.
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — no toast
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS — no Vaul Drawer primitive; side panels use Sheet only
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — no Vaul
@@ -22,4 +23,4 @@ After upgrading to **`@exxatdesignux/ui@0.5.3`**, remove **`vaul`** from the app
22
23
  ## See also
23
24
 
24
25
  - **`.cursor/rules/exxat-drawer-vs-dialog.mdc`**
25
- - **`docs/exxat-ds/patterns/drawer-vs-dialog-pattern.md`**
26
+ - **`apps/web/docs/drawer-vs-dialog-pattern.md`**
@@ -1,11 +1,13 @@
1
1
  ---
2
- description: Exxat DS — PageHeader actions slot; View as / overflow / primary CTA patterns
3
- alwaysApply: true
2
+ description: Exxat DS — PageHeader actions slot; View as / overflow / primary CTA patterns. Auto-attaches when editing React PageHeader callsites; the universal "one filled primary" rule lives in P3 of exxat-ux-principles.
3
+ globs: apps/web/{components,app}/**/*.{tsx,ts}
4
+ alwaysApply: false
5
+ appliesTo: [react]
4
6
  ---
5
7
 
6
8
  # Exxat DS — page header actions
7
9
 
8
- **Blueprint:** `docs/exxat-ds/handbook/HANDBOOK.md` + `node_modules/@exxatdesignux/ui/template/docs/blueprints/page-header.md`
10
+ **Blueprint:** `apps/web/docs/blueprints/page-header.md`
9
11
 
10
12
  ## Anatomy (actions slot only)
11
13
 
@@ -28,4 +30,4 @@ alwaysApply: true
28
30
 
29
31
  ## Reference
30
32
 
31
- - **`docs/exxat-ds/handbook/reference-implementations.md`**
33
+ - `components/library-page-header.tsx`, Placements/Team header patterns in **`apps/web/docs/reference-implementations.md`**
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS — when to use a drawer vs a new page for actions and auxiliary UI.
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — page vs drawer
@@ -14,7 +15,7 @@ alwaysApply: true
14
15
  ## Product examples (this repo)
15
16
 
16
17
  - **Drawer-appropriate:** `TablePropertiesDrawer`, `ExportDrawer`, lightweight panels that supplement a hub.
17
- - **Page-appropriate:** Full placement or settings flows that are the main task, multi-screen wizards.
18
+ - **Page-appropriate:** Full settings flows, multi-step record-creation wizards (e.g. `new-library-item-form.tsx`), or any task that is itself the user's primary intent.
18
19
 
19
20
  ## Authoritative detail
20
21
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS — avatar + name + email when showing a person; omit email in dense contexts (e.g. board cards).
3
3
  alwaysApply: false
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — person identity (name + email)
@@ -2,6 +2,7 @@
2
2
  description: Primary sidebar item opens nested SecondaryPanel (Library pattern)
3
3
  globs: apps/web/components/**/*.tsx
4
4
  alwaysApply: false
5
+ appliesTo: [react]
5
6
  ---
6
7
 
7
8
  # Exxat DS — primary nav → secondary panel
@@ -15,7 +16,7 @@ Some hubs expose **scoped navigation** (All / My / tree / filters) in a **nested
15
16
  1. **`NavLinkItem`** — On the **primary** row that should drive the panel, set **`secondaryPanel`** to a **stable string id** (e.g. **`"library"`**). Keep **`url`** pointing at the **hub route**.
16
17
  2. **`SecondaryPanel` registry** — In **`components/secondary-panel.tsx`**, add **`PANELS[id]`** → component that renders **panel chrome** (title, optional search) + **your secondary nav** list. **MUST** keep ids in sync with **`NAV_PRIMARY`**.
17
18
  3. **Auto-open on route** — The hub **`client`** (or layout slot) **MUST** mount **`*PanelActivator`** that calls **`useAutoPanel(id)`** with the **same id**, so deep links and first visit open the panel while the route is mounted (e.g. **`LibraryPanelActivator`** + **`beforeSiteHeader`** on **`LibraryClient`**).
18
- 4. **Same-route reopen** — **`AppSidebar`** already calls **`openPanel(secondaryPanel)`** when the user clicks the primary item **again** while already on that **`url`** (prevents no-op navigation). Secondary nav rows that stay on the same path **SHOULD** call **`openPanel`** on click where **Next.js `Link`** would not fire (same **`href`**).
19
+ 4. **Same-route reopen** — **`AppSidebar`** already calls **`openPanel(secondaryPanel)`** when the user clicks the primary item **again** while already on that **`url`** (prevents no-op navigation). Secondary nav rows that stay on the same path **SHOULD** call **`openPanel`** on click where **`react-router-dom` `Link`** would not fire (same **`to`**).
19
20
 
20
21
  ## Surface elevation (brand chrome)
21
22
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS — prefer centralized reusable components; ask the user before new bespoke primitives.
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — reuse before custom
@@ -2,6 +2,7 @@
2
2
  description: Application sidebar — DS shell only; legacy screenshots are IA reference, not visual spec
3
3
  globs: "**/app-sidebar.tsx,**/navigation*.tsx,**/lib/mock/navigation.tsx,**/lib/*-navigation.tsx"
4
4
  alwaysApply: false
5
+ appliesTo: [react]
5
6
  ---
6
7
 
7
8
  # Exxat DS — application sidebar shell (MUST)
@@ -23,13 +24,18 @@ Customer / legacy app **screenshots** may show **what links exist** — not **ho
23
24
 
24
25
  ## MUST — DS sidebar chrome
25
26
 
26
- 1. **Shell:** **`AppSidebar`** + **`SidebarMenuButton`** / **`SidebarGroup`** / **`SidebarGroupLabel`** from **`@exxatdesignux/ui`**. Reference: **`AGENTS.md` §9.1**, **`exxat-ds-skill` §3.1–§3.2**.
27
- 2. **Typography:** Row labels **`text-sidebar-foreground`**. Section headings **`SidebarGroupLabel`** + **`text-sidebar-section-label`**.
28
- 3. **Active state:** **`SidebarMenuButton` `isActive`** only one active row in expanded rail; collapsible parent neutral when child active.
29
- 4. **Icons:** **`fa-light`** / **`fa-solid`** on icons — do **not** recolor labels per module.
30
- 5. **Nav data:** Extend **`lib/mock/navigation.tsx`** (or imported mock). **MUST NOT** paste legacy sidebar components from customer repos.
31
- 6. **Consumer products:** Build in a **separate repo** with **`@exxatdesignux/ui`** — not DS monorepo sidebar forks.
27
+ 1. **Shell:** **`AppSidebar`** + **`SidebarMenuButton`** / **`SidebarGroup`** / **`SidebarGroupLabel`** from **`@exxatdesignux/ui`** (or app shims). Reference: **`apps/web/components/sidebar/app-sidebar.tsx`**, **`AGENTS.md` §9.1**, **`exxat-ds-skill` §3.1–§3.2**.
28
+ 2. **Typography:** Row labels **`text-sidebar-foreground`** (default from `SidebarMenuButton`). Section headings **`SidebarGroupLabel`** + **`text-sidebar-section-label`** — not rainbow section body text.
29
+ 3. **Active state:** Pass **`isActive`** into **`SidebarMenuButton`** only. Expanded rail: **one** active row (`data-active` background pill + ring from DS). Collapsible parent stays **neutral** when a child is active. Icon rail: parent icon may light up when any child is active.
30
+ 4. **Icons:** **`fa-light`** idle / **`fa-solid`** active on the **icon** only — do **not** recolor the label per module.
31
+ 5. **Nav data:** Add or extend **`lib/mock/navigation.tsx`** (or a file it imports). **MUST NOT** paste a full legacy sidebar component from a customer repo into **`apps/web`**.
32
+ 6. **Consumer products:** Prism / customer hubs belong in a **separate consumer repo** with **`@exxatdesignux/ui`** — not product-specific rewrites of the DS monorepo sidebar.
33
+
34
+ ## Reference (canonical visual)
35
+
36
+ - **`apps/web/components/sidebar/app-sidebar.tsx`** + **`lib/mock/navigation.tsx`**
37
+ - **`packages/ui/src/components/ui/sidebar.tsx`** — `data-active:bg-background` pill
32
38
 
33
39
  ## Anti-pattern
34
40
 
35
- Legacy product sidebars with rainbow section text and bespoke selection chrome — **do not reproduce** on Exxat DS.
41
+ Legacy Exxat Prism sidebar: color-coded **text** per module block, pink sidebar wash, bespoke selection chrome — **do not reproduce** when building on Exxat DS.
@@ -1,6 +1,8 @@
1
1
  ---
2
- description: TablePropertiesDrawer must receive currentView and onViewChange when used with ListPageTemplate view tabs
3
- alwaysApply: true
2
+ description: TablePropertiesDrawer must receive currentView and onViewChange when used with ListPageTemplate view tabs. Auto-attaches when editing apps/web React files; ask explicitly when wiring view-type-aware drawers.
3
+ globs: apps/web/{components,packages/ui}/**/*.{tsx,ts}
4
+ alwaysApply: false
5
+ appliesTo: [react]
4
6
  ---
5
7
 
6
8
  # Exxat DS — Table properties + active view
@@ -28,7 +30,7 @@ When **`ListPageTemplate`** drives **`tab.viewType`** and the page renders **`Ta
28
30
 
29
31
  3. Thread **`view`** and **`onViewChange`** through: **client → table component → drawer toolbar → `TablePropertiesDrawer`**.
30
32
 
31
- **Reference implementations:** `components/placements-table.tsx` (`PlacementsTable`), `components/team-client.tsx` + `team-table.tsx`, `components/compliance-client.tsx` + `compliance-table.tsx`.
33
+ **Reference implementations:** `components/library-hub-client.tsx` + `library-table.tsx` (canonical seven-view hub), `components/columns-showcase.tsx` (`LibraryTable` + custom `columnDefs`), `components/tokens-themes-client.tsx` (`FULL_HUB_SUPPORTED_VIEWS` + `tokens-hub-auxiliary-views.tsx`). **Add view allowlist:** **`.cursor/rules/exxat-hub-supported-views.mdc`**.
32
34
 
33
35
  ## Deep-linking into a specific panel
34
36
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS — table row identity preview uses HoverCard + DS tokens, not bespoke Popover cards
3
3
  alwaysApply: false
4
+ appliesTo: [react]
4
5
  ---
5
6
 
6
7
  # Exxat DS — table row preview (hover / click)
@@ -1,6 +1,8 @@
1
1
  ---
2
- description: Exxat DS — Tabs and view toolbars must not stretch full width; use ListPageTemplate for hub views
3
- alwaysApply: true
2
+ description: Exxat DS — Tabs and view toolbars must not stretch full width; use ListPageTemplate for hub views. Auto-attaches when editing React surfaces with tabs or view toolbars.
3
+ globs: apps/web/{components,app}/**/*.{tsx,ts}
4
+ alwaysApply: false
5
+ appliesTo: [react]
4
6
  ---
5
7
 
6
8
  # Exxat DS — tabs chrome (no full-width stretch)
@@ -27,5 +29,5 @@ alwaysApply: true
27
29
 
28
30
  ## See also
29
31
 
30
- - **`docs/exxat-ds/handbook/HANDBOOK.md`** — header never carries view tabs
31
- - **`docs/exxat-ds/patterns/data-views-pattern.md`** — `ListPageTemplate` view toolbar
32
+ - **`apps/web/docs/blueprints/page-header.md`** — header never carries view tabs
33
+ - **`apps/web/docs/data-views-pattern.md`** — `ListPageTemplate` view toolbar
@@ -1,3 +1,9 @@
1
+ ---
2
+ description: Token discipline — no hex literals, prefer Exxat L0 tokens (--exxat-color-*, --exxat-radius-*, --exxat-spacing-*), no deprecated tokens. ESLint enforces via @exxatdesignux/eslint-plugin.
3
+ alwaysApply: true
4
+ appliesTo: [universal]
5
+ ---
6
+
1
7
  # Exxat DS — token discipline
2
8
 
3
9
  **Authoritative reference:** [`apps/web/docs/token-taxonomy.md`](mdc:apps/web/docs/token-taxonomy.md).
@@ -1,25 +1,73 @@
1
1
  ---
2
- description: Exxat DS — output a design brief before writing files for any new surface; question bank by surface type
2
+ description: Exxat DS — STOP before code on any surface design (new, rebuild, redesign, replace); output a design brief and WAIT for user go-ahead
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — UX discovery protocol
7
8
 
8
- On any task that creates a **new route, page, template, wizard, or
9
- significant component**, the assistant MUST output a **design brief in chat**
10
- BEFORE writing files. Brief format is defined in
11
- `.cursor/skills/exxat-senior-ux/SKILL.md` §3.
9
+ ## STOP read before you write any file
10
+
11
+ If the user's prompt asks you to **design, create, build, rebuild, redesign,
12
+ replace, redo, refresh, modernize, re-imagine, or "make a new version of"**
13
+ any **page, route, screen, hub, detail view, wizard, settings section,
14
+ dashboard, dialog, sheet, drawer, panel, layout, or significant component**:
15
+
16
+ 1. **Do NOT write code, do NOT edit files, do NOT call edit tools yet.**
17
+ 2. **Output the design brief** (template below) in chat.
18
+ 3. **Wait for the user to reply** with `yes` / `proceed` / `ship it` / edits.
19
+ 4. **Only then** move to implementation.
20
+
21
+ If your next tool call would be `write_file`, `str_replace`, `create_file`,
22
+ or any code-mutating action **and** you have not posted a brief and received
23
+ go-ahead, you are violating this rule. **Stop and post the brief.**
24
+
25
+ ## When this gate fires (and when it doesn't)
26
+
27
+ This gate fires on **any task that decides what a surface should look like
28
+ or how it works** — whether the surface exists today or not. Treat
29
+ "replace what we have" and "create from scratch" identically — both need a
30
+ brief, because both make a design decision.
31
+
32
+ **Fires (brief required):**
33
+
34
+ - "Create a new student detail page."
35
+ - "Rebuild the dashboard."
36
+ - "Redesign the settings screen instead of what we have."
37
+ - "Make a new version of the placements table."
38
+ - "Replace the current onboarding flow."
39
+ - "Build a wizard for adding a site."
40
+ - "Design a sheet for inviting collaborators."
41
+ - User attaches a screenshot / mockup / Figma link and asks to "build this".
42
+
43
+ **Does NOT fire (brief not required, edit freely):**
44
+
45
+ - Single-class restyle of an existing surface that already follows DS rules.
46
+ - Copy / label edits.
47
+ - Bug fixes (a11y violation, broken state, wrong data).
48
+ - Dependency bumps, ESLint passes, type fixes, test-only changes.
49
+ - Adding a new column / filter to an *existing* `HubTable` that doesn't
50
+ change the page's IA.
51
+
52
+ When in doubt, ask: **"Am I deciding what this surface should be?"** Yes →
53
+ brief. No → edit.
12
54
 
13
55
  ## MUST
14
56
 
15
- 1. **No code without a brief.** New surfaces require the brief. Trivial edits
16
- to existing surfaces (copy tweak, single-class change, bug fix, refactor)
17
- are exempt.
57
+ 0. **Output the brief, then WAIT.** The brief is a checkpoint, not a
58
+ preamble. Do not bundle the brief and the first file edit in the same
59
+ turn. After posting the brief, end your turn with an explicit
60
+ "Ready to build — confirm or edit." prompt. Resume only on the user's
61
+ next message.
62
+ 1. **No code without a confirmed brief.** "Confirmed" means the user wrote
63
+ `yes`, `proceed`, `ship it`, `LGTM`, `build it`, accepted edits, or asked
64
+ a follow-up that implies acceptance. Silence is not consent.
18
65
  2. **Cite a reference.** Every brief names **one repo reference** + **two
19
- modern SaaS analogues** (Linear / Notion / Stripe / Figma / Vercel / etc.)
20
- that solve the same **job-to-be-done**. Cite the SaaS analogues by
21
- product name + pattern codes from
22
- `apps/web/docs/modern-saas-patterns.md` (e.g. `Linear issue detail (M1, M4, M7)`).
66
+ modern SaaS analogues** (Linear / Notion / Stripe / Figma / Vercel /
67
+ Linear / Airtable / Coda / Height / etc.) that solve the same
68
+ **job-to-be-done**. Cite the SaaS analogues by product name + pattern
69
+ codes from `apps/web/docs/modern-saas-patterns.md` (e.g.
70
+ `Linear issue detail (M1, M4, M7)`).
23
71
  3. **Name principles + breaks.** Brief lists the principles applied
24
72
  (`exxat-ux-principles.mdc`) and any deviations with one-sentence reasons.
25
73
  **Never-break** principles (P1–P8) cannot be deviated from.
@@ -30,6 +78,11 @@ BEFORE writing files. Brief format is defined in
30
78
 
31
79
  ## MUST NOT
32
80
 
81
+ - **Skip the brief because the prompt sounds like a refactor.** "Rebuild",
82
+ "redesign", "replace", "instead of what we have", and "from scratch" are
83
+ design decisions, not refactors. Brief required.
84
+ - **Post a brief and then write 8 files in the same turn.** That's not a
85
+ brief — that's a press release. End the turn after the brief.
33
86
  - Generate files before the brief.
34
87
  - Ask more than **3** questions in one batch.
35
88
  - Ask questions whose answer is already in the prompt, the file tree, or
@@ -113,6 +166,32 @@ Open questions: <max 2; ideally 0>
113
166
  > User: "make a settings page". *Agent writes generic form.* Should have
114
167
  > asked: scope (personal/workspace), search needed, apply-on-change vs Save.
115
168
 
169
+ ## Closing artifact: the design → engineering handoff
170
+
171
+ When the build is complete (files written, surface working in dev), produce
172
+ **one filled-in handoff document** before declaring the task done.
173
+
174
+ **Template** lives at:
175
+
176
+ - Workspace: `apps/web/docs/templates/handoff.md` (or workspace root if not yet copied — copy from `packages/ui/consumer-extras/templates/handoff.md`)
177
+ - Consumer apps (after `exxat-ui sync-extras`): `docs/exxat-ds/templates/handoff.md`
178
+
179
+ **Fill it in** with the actual primitives, tokens, icons, and shortcuts the
180
+ build used. Save the filled copy at:
181
+
182
+ - `apps/web/docs/handoff/<surface-slug>.md` (workspace)
183
+ - `docs/exxat-ds/handoff/<surface-slug>.md` (consumer)
184
+
185
+ Attach the filled handoff to the PR description (or paste inline). The
186
+ engineer reads it once, runs `exxat-ui audit <generated-file>` to verify
187
+ the floor, and is done.
188
+
189
+ **MUST sections:** 1 (job-to-be-done), 3 (pattern + IA), 5 (DS components
190
+ used), 6 (tokens), 8 (a11y checklist — every box ticked), 11 (keyboard map),
191
+ 12 (any deviations from P9–P20).
192
+
193
+ If the handoff is incomplete or hand-wavy, the design task is not finished.
194
+
116
195
  ## See also
117
196
 
118
197
  - `.cursor/skills/exxat-senior-ux/SKILL.md` — the persona + full protocol
@@ -120,3 +199,4 @@ Open questions: <max 2; ideally 0>
120
199
  - `apps/web/docs/jobs/` — canonical references per job type
121
200
  - `apps/web/docs/modern-saas-patterns.md` — pattern codes (M1–M12)
122
201
  - `.cursor/rules/exxat-no-image-pixel-copy.mdc` — IA from screenshots only
202
+ - **Closing artifact:** `packages/ui/consumer-extras/templates/handoff.md`
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  description: Exxat DS UX principles — what to follow, when to break, why
3
3
  alwaysApply: true
4
+ appliesTo: [universal]
4
5
  ---
5
6
 
6
7
  # Exxat DS — UX principles (and when to break them)
@@ -23,7 +23,7 @@ description: >
23
23
  - **Single source of truth:** `apps/web/AGENTS.md` for full prose explanations; this skill is the actionable summary
24
24
  - **Companion skills (narrow topics):** `exxat-fontawesome-icons`, `exxat-mono-ids`, `exxat-primary-nav-secondary-panel`, `exxat-centralized-list-dataset`, `exxat-list-page-view-shells`, `exxat-dedicated-search-surfaces`, `exxat-accessibility`, `exxat-board-cards`, `exxat-collaboration-access` — live under `.cursor/skills/`; vetted copies ship with **`@exxatdesignux/ui`** in `consumer-extras/cursor-skills/` after **`pnpm --filter @exxatdesignux/ui vendor:consumer-extras`**.
25
25
  - **Library folder-scoped header (rule + doc):** **`.cursor/rules/exxat-library-hub-header.mdc`** and **`docs/library-hub-header-pattern.md`** — pair with **`exxat-primary-nav-secondary-panel`** when URL **`scope=folder`** drives the hub title.
26
- - **Consumer repos (npm install of `@exxatdesignux/ui`):** After a version bump, read **`node_modules/@exxatdesignux/ui/CHANGELOG.md`**, run **`npx --package=@exxatdesignux/ui@latest exxat-ui sync-extras`** so **`docs/exxat-ds/consumer-upgrade-checklist.md`** and Cursor skills match the tarball, and diff the host app against **`node_modules/@exxatdesignux/ui/template/`** for anything new to port (routes, re-exports, AGENTS). Use **`exxat-ui changelog`**, **`exxat-ui update`**, and **`exxat-ui doctor`** for CLI guidance.
26
+ - **Consumer repos (npm install of `@exxatdesignux/ui`):** After a version bump, read **`node_modules/@exxatdesignux/ui/CHANGELOG.md`**, run **`npx --package=@exxatdesignux/ui@latest exxat-ui sync-extras`** so **`docs/exxat-ds/consumer-upgrade-checklist.md`** and Cursor skills match the tarball, and diff the host app against **`node_modules/@exxatdesignux/ui/template-vite/`** for anything new to port (routes, re-exports, AGENTS). Use **`exxat-ui changelog`**, **`exxat-ui update`**, and **`exxat-ui doctor`** for CLI guidance.
27
27
 
28
28
  ---
29
29
 
@@ -12,9 +12,11 @@ Use when adding or reviewing **`KeyMetrics`**, **`lib/mock/*-kpi.ts`** helpers,
12
12
 
13
13
  1. **Delta honest?** `trend` follows the sign of the change vs the comparison period.
14
14
  2. **Polarity correct?** If “more” is bad → **`trendPolarity: "lower_is_better"`**. If no value judgment → **`"informational"`** (muted tints).
15
- 3. **Copy contextual?** Label + value + delta tell users *what* moved, not only *how much*.
16
- 4. **Screen readers** Chip keeps icon + visible delta; `aria-label` reflects favorable / unfavorable wording automatically when polarity is set.
17
- 5. **Chart cards** When using **`ChartCard`** `miniMetrics`, pass **`trendPolarity`** the same way as on **`MetricItem`**.
15
+ 3. **Delta is a count, not prose.** **`delta`** is `"+5"`, `"-3"`, `"+12%"`. Captions like `"left + right"`, `"vs last week"`, `"scheduled for removal"` go in **`description`** (renders **below** the value, muted).
16
+ 4. **No empty `—` chip.** If there’s no direction *and* no count, leave **`delta: ""`** + **`trend: "neutral"`** **`KeyMetrics`** hides the chip. Don’t hand-roll a placeholder.
17
+ 5. **Copy contextual?** Label + value + (delta when present) + description tell users *what* moved, not only *how much*.
18
+ 6. **Screen readers** — Chip keeps icon + visible delta; `aria-label` reflects favorable / unfavorable wording automatically when polarity is set.
19
+ 7. **Chart cards** — When using **`ChartCard`** `miniMetrics`, pass **`trendPolarity`** the same way as on **`MetricItem`**.
18
20
 
19
21
  ## Quick examples
20
22