@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,156 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * dev-guard — catches the #1 cause of memory exhaustion before a second
4
+ * dev server boots and lifts total system RSS unnecessarily.
5
+ *
6
+ * Detects Vite parents under the same `pnpm dev` lineage. A single Vite
7
+ * dev server stabilizes at ~250–500 MB; stacking two doubles total RSS,
8
+ * confuses HMR (two ports, two websockets), and creates "which one am I
9
+ * actually viewing?" mistakes when designers compare branches.
10
+ *
11
+ * (History: until PR-6 (May 2026) this guard also detected `next-server`
12
+ * parents because `apps/web` ran on Next + Turbopack. After Next was
13
+ * removed, the Next branch became dead code — this version is Vite-only.)
14
+ *
15
+ * Run as `predev` hook (or any time you want to verify environment health):
16
+ * "predev": "exxat-ui dev-guard"
17
+ *
18
+ * Behavior:
19
+ * - Lists every running `vite` parent.
20
+ * - Exits 0 silently if zero or one is found (the one is *us* — fine).
21
+ * - Prints a guided warning if 2+ are found, names the cwd of each,
22
+ * and asks the user whether to abort or continue.
23
+ * - In CI (`CI=true`) or with `--quiet`, exits 0 without prompting.
24
+ *
25
+ * Tested against macOS / Linux. Windows users: PowerShell `Get-Process` would
26
+ * need a separate branch; not implemented yet because the team is mac/linux.
27
+ */
28
+
29
+ import { execFileSync } from "node:child_process"
30
+ import { createInterface } from "node:readline/promises"
31
+
32
+ const QUIET = process.argv.includes("--quiet") || process.env.CI === "true"
33
+
34
+ /** @typedef {{ pid: number, cwd: string, rss: number }} ViteProc */
35
+
36
+ /** @returns {ViteProc[]} */
37
+ function listDevServers() {
38
+ let out = ""
39
+ try {
40
+ out = execFileSync(
41
+ "ps",
42
+ ["-axo", "pid=,rss=,command="],
43
+ { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] },
44
+ )
45
+ } catch {
46
+ // ps unavailable (very unusual). Fail open — better to let dev start.
47
+ return []
48
+ }
49
+
50
+ const matches = []
51
+ for (const line of out.split("\n")) {
52
+ const m = line.match(/^\s*(\d+)\s+(\d+)\s+(.+)$/)
53
+ if (!m) continue
54
+ const [, pid, rss, command] = m
55
+
56
+ // Vite — bin/vite.js or `node ... vite ...` parents. Skip vitest, esbuild
57
+ // children, vite preview workers. We require the literal `vite` token
58
+ // either at end of path (.../bin/vite[.js]) or as a subcommand argv.
59
+ const isViteDev =
60
+ /(\/vite(\.js|\.mjs)?|[\s/]vite\s)\b/.test(command) &&
61
+ !/\bvitest\b/.test(command) &&
62
+ !/\bvite\s+preview\b/.test(command) &&
63
+ !/\besbuild\b/.test(command)
64
+
65
+ if (!isViteDev) continue
66
+ matches.push({
67
+ pid: Number(pid),
68
+ cwd: cwdOfPid(Number(pid)) ?? "(cwd unknown)",
69
+ rss: Number(rss), // KB
70
+ })
71
+ }
72
+ return matches
73
+ }
74
+
75
+ /** Best-effort cwd lookup. macOS has lsof; Linux has /proc/<pid>/cwd. */
76
+ function cwdOfPid(pid) {
77
+ try {
78
+ if (process.platform === "darwin") {
79
+ const out = execFileSync("lsof", ["-p", String(pid), "-d", "cwd", "-Fn"], {
80
+ encoding: "utf8",
81
+ stdio: ["ignore", "pipe", "ignore"],
82
+ })
83
+ const line = out.split("\n").find(l => l.startsWith("n"))
84
+ return line ? line.slice(1) : null
85
+ }
86
+ if (process.platform === "linux") {
87
+ const out = execFileSync("readlink", ["-f", `/proc/${pid}/cwd`], {
88
+ encoding: "utf8",
89
+ stdio: ["ignore", "pipe", "ignore"],
90
+ })
91
+ return out.trim() || null
92
+ }
93
+ } catch {
94
+ return null
95
+ }
96
+ return null
97
+ }
98
+
99
+ function fmtMB(kb) {
100
+ return (kb / 1024).toFixed(0) + " MB"
101
+ }
102
+
103
+ async function main() {
104
+ const servers = listDevServers()
105
+ if (servers.length <= 1) {
106
+ if (!QUIET) {
107
+ console.log(
108
+ servers.length === 0
109
+ ? "[dev-guard] No other dev server running. Safe to start."
110
+ : `[dev-guard] One vite already running (pid ${servers[0].pid}, ${fmtMB(servers[0].rss)}). Reusing it.`,
111
+ )
112
+ }
113
+ process.exit(0)
114
+ }
115
+
116
+ // Two or more — this is the bad path.
117
+ console.error("")
118
+ console.error("⚠ dev-guard: multiple Vite dev-server processes detected.")
119
+ console.error("")
120
+ console.error("Two parallel Vite dev servers stabilize at ~500–800 MB combined")
121
+ console.error("and confuse HMR (two ports, two websockets, components from two")
122
+ console.error("workspace roots). Stop the one you're not actively touching.")
123
+ console.error("")
124
+ for (const s of servers) {
125
+ console.error(
126
+ ` pid ${String(s.pid).padEnd(6)} ${fmtMB(s.rss).padEnd(8)} ${s.cwd}`,
127
+ )
128
+ }
129
+ console.error("")
130
+ console.error("Recommended: stop the one you're not actively touching.")
131
+ console.error(" • macOS / Linux: kill <pid>")
132
+ console.error(" • pm2 daemon: pm2 stop exxat-ds (or pm2 delete exxat-ds)")
133
+ console.error("")
134
+
135
+ if (QUIET) {
136
+ // CI / quiet mode — don't block, just warn.
137
+ process.exit(0)
138
+ }
139
+
140
+ const rl = createInterface({ input: process.stdin, output: process.stdout })
141
+ const ans = (await rl.question("Continue starting another dev server anyway? [y/N] ")).trim().toLowerCase()
142
+ rl.close()
143
+
144
+ if (ans === "y" || ans === "yes") {
145
+ console.error("[dev-guard] Continuing.")
146
+ process.exit(0)
147
+ }
148
+ console.error("[dev-guard] Aborted. Stop the other server, then re-run dev.")
149
+ process.exit(1)
150
+ }
151
+
152
+ main().catch(err => {
153
+ // Never let a guard bug block dev. Log and pass through.
154
+ console.error("[dev-guard] internal error, allowing dev to start:", err?.message ?? err)
155
+ process.exit(0)
156
+ })
@@ -0,0 +1,23 @@
1
+ # Exxat DS — templates
2
+
3
+ Markdown templates the agent fills in (or copies into a PR / docs folder) at
4
+ specific points of a design task.
5
+
6
+ | File | When the agent emits it |
7
+ |------|------------------------|
8
+ | `handoff.md` | After every design task that creates or rebuilds a surface, before the engineer wires real data. Source of truth for the design → engineering handoff. |
9
+
10
+ These ship via `@exxatdesignux/ui` and are written into the consumer repo at:
11
+
12
+ ```
13
+ docs/exxat-ds/templates/<file>
14
+ ```
15
+
16
+ …by `exxat-ui sync-extras`.
17
+
18
+ The agent locates the template via the `exxat-ux-discovery-protocol` rule
19
+ (see `.cursor/rules/exxat-ux-discovery-protocol.mdc`) and fills it in as
20
+ the closing artifact of a build.
21
+
22
+ Engineers do not edit these templates by hand. They open the filled-in copy
23
+ attached to a PR / saved at `docs/exxat-ds/handoff/<surface-slug>.md`.
@@ -0,0 +1,190 @@
1
+ # Design → Engineering Handoff
2
+
3
+ This template is the **single artifact** the agent produces at the end of any
4
+ design task that creates or rebuilds a surface (page, hub, detail view,
5
+ wizard, drawer, sheet). It is the contract between the designer who shaped
6
+ the work in the brief and the engineer who ships it.
7
+
8
+ The agent fills this in as part of the `exxat-ux-discovery-protocol` flow.
9
+ The engineer reads it once, runs `exxat-ui audit <file>` against the
10
+ generated files, and is done.
11
+
12
+ ---
13
+
14
+ ## 1. Job-to-be-done
15
+
16
+ > Single sentence. The decision or action this surface enables for the user.
17
+ > Copy from the design brief — do not invent.
18
+
19
+ (example) *Coordinator identifies and acts on at-risk students before placement.*
20
+
21
+ ## 2. Audience & frequency
22
+
23
+ > Persona (admin / coordinator / faculty / student / preceptor) + how often
24
+ > they hit this surface (daily / weekly / occasional).
25
+
26
+ (example) *Program coordinator, daily, keyboard-first.*
27
+
28
+ ## 3. Pattern + IA
29
+
30
+ > The DS pattern this surface uses + the information architecture shape.
31
+ > Should match the brief.
32
+
33
+ - **Surface kind**: route | sheet | dialog | inline (one of the four)
34
+ - **Layout**: page-header + ?? (single column / split / data-table grid / …)
35
+ - **Navigation**: breadcrumb? back affordance? anchor sub-nav?
36
+ - **Header tier**: identity, status, KPI, ⋯ overflow, primary CTA
37
+
38
+ ## 4. Reference implementations
39
+
40
+ > One **repo** reference + two **modern SaaS** analogues (cite by product
41
+ > name + Mx codes from `docs/exxat-ds/modern-saas-patterns.md`).
42
+
43
+ - **Repo**: `apps/web/components/<file>.tsx`
44
+ - **Modern**: `<Product 1>` (Mx, Mx); `<Product 2>` (Mx, Mx)
45
+
46
+ ## 5. Components used (DS inventory)
47
+
48
+ > Every DS primitive consumed. The agent fills this in by inspecting its
49
+ > own diff. No new bespoke widgets unless approved in the brief.
50
+
51
+ | Primitive | From | Why |
52
+ |-----------|------|-----|
53
+ | `PageHeader` | `@exxatdesignux/ui/page-header` | Identity + actions row |
54
+ | `HubTable` | `@/components/data-views` | Rows + filters + properties |
55
+ | … | … | … |
56
+
57
+ ## 6. Tokens consumed
58
+
59
+ > Every CSS custom property the agent referenced. No hex literals — see
60
+ > `exxat-token-discipline`.
61
+
62
+ - Colors: `--exxat-color-bg-app`, `--exxat-color-text-primary`, …
63
+ - Spacing: `--exxat-spacing-*`
64
+ - Radii: `--exxat-radius-*`
65
+ - Shadow / elevation: `--exxat-shadow-*`
66
+
67
+ ## 7. Icons used
68
+
69
+ > Font Awesome Pro classes. Add to the subset audit (`fa:subset-audit`)
70
+ > if any are new to the kit.
71
+
72
+ - `fa-light fa-graduation-cap` — student identity
73
+ - `fa-light fa-shield-check` — compliance status
74
+ - …
75
+
76
+ ## 8. Accessibility floor
77
+
78
+ > Filled by the agent automatically (the universal a11y rule is on). Engineer
79
+ > verifies by running axe / Deque on the deployed surface.
80
+
81
+ - [x] One H1 per page; record name in `PageHeader.title` only
82
+ - [x] Single primary CTA; everything else is outline / ghost / link
83
+ - [x] `Tablist` semantics correct (no buttons inside `role=tablist`)
84
+ - [x] All interactive targets ≥ 24 × 24 CSS px
85
+ - [x] Contrast ≥ 4.5 : 1 for text, ≥ 3 : 1 for UI / focus
86
+ - [x] Every icon has either `aria-hidden` (decorative) or `aria-label` + tooltip (informational)
87
+ - [x] Format hints rendered as `FormDescription`, not placeholder
88
+ - [x] Every primary action has an `Enter` shortcut + visible Kbd hint
89
+ - [x] Every cancel action accepts `Esc`
90
+
91
+ ## 9. Data shape
92
+
93
+ > What rows / records / fields this surface reads from. Engineer wires the
94
+ > real API; the agent uses `lib/mock/<entity>.ts` for the demo dataset.
95
+
96
+ - **Mock**: `apps/web/lib/mock/<entity>.ts`
97
+ - **API contract** (when known): `<endpoint>` returns `<RowShape>`
98
+ - **State container**: `useTableState({ data, columns })`
99
+
100
+ ## 10. Empty / loading / error
101
+
102
+ > Every list, detail, and action ships all three states. Filled in by the
103
+ > agent; engineer verifies the copy.
104
+
105
+ - **Loading**: skeleton (`<HubTableSkeleton />` or matched shape)
106
+ - **Empty**: copy + primary CTA to start the flow
107
+ - **Error**: copy + retry affordance + Ask Leo entry point
108
+
109
+ ## 11. Keyboard map
110
+
111
+ > Every shortcut bound on this surface. The agent must declare these so the
112
+ > engineer can write a Playwright test against them.
113
+
114
+ | Action | Shortcut |
115
+ |--------|----------|
116
+ | Open Add view | `1..9` |
117
+ | Submit primary form | `Enter` |
118
+ | Cancel | `Esc` |
119
+ | Search | `⌘K` / `Ctrl+K` |
120
+ | Ask Leo | `⌘⌥K` / `Ctrl+Alt+K` |
121
+ | New record | `⌘⌥N` |
122
+
123
+ ## 12. Deviations from principles
124
+
125
+ > Any P9–P20 principle the design intentionally breaks, and the one-sentence
126
+ > reason. P1–P8 cannot be deviated from. If this section has rows, the
127
+ > engineer must include them in the PR description.
128
+
129
+ | Principle | Reason |
130
+ |-----------|--------|
131
+ | P14 (density) | Mixed audience — added density toggle, default cozy |
132
+
133
+ ## 13. Out of scope
134
+
135
+ > What this surface deliberately does **not** do. Helps the engineer decide
136
+ > what tickets *not* to file.
137
+
138
+ (example)
139
+ - Inline editing of student name (v2)
140
+ - Bulk message (lives on the list hub, not on the detail)
141
+
142
+ ## 14. Open questions
143
+
144
+ > Things the brief could not answer. Engineer pings the designer or product.
145
+
146
+ - (example) Should the compliance badge link out to the source document or open in a side panel?
147
+
148
+ ## 15. Designer-stack → engineering-stack port (delete if same stack)
149
+
150
+ > **Skip this section** if your designer prototype and your production app
151
+ > are on the same framework (both Vite, both Next.js).
152
+ >
153
+ > **Fill this in** if the designer prototyped on the **Vite scaffold**
154
+ > (`create-exxat-app`, the lightweight default) but the production app
155
+ > still runs on **Next.js**. The agent or engineer maps each Vite-specific
156
+ > import to its Next equivalent before merging the work into prod.
157
+
158
+ | Vite scaffold (designer) | Next.js prod (engineer) | Notes |
159
+ |---|---|---|
160
+ | `import { Link } from "@/lib/next-compat"` → `<Link to="…">` | `import Link from "next/link"` → `<Link href="…">` | Drop the shim re-export; rename `to` → `href` |
161
+ | `import { useNavigate } from "react-router-dom"` | `import { useRouter } from "next/navigation"` + `router.push(...)` | One-line swap |
162
+ | `import { useLocation } from "react-router-dom"` → `useLocation().pathname` | `import { usePathname } from "next/navigation"` | Direct equivalent |
163
+ | `import { useSearchParams } from "react-router-dom"` returns `[params, setParams]` | `import { useSearchParams } from "next/navigation"` returns `ReadonlyURLSearchParams` | Drop the destructure, accept readonly shape |
164
+ | `import { Navigate } from "react-router-dom"` (JSX redirect) | `import { redirect } from "next/navigation"` (function call) | Move from JSX to component body |
165
+ | `React.lazy(() => import(...))` + `<Suspense>` | `dynamic(() => import(...), { loading, ssr: false })` | Functionally equivalent — pick whichever the surrounding file already uses |
166
+ | `vite.config.ts` aliases | `next.config.mjs` `experimental.turbopack.resolveAlias` or `tsconfig.json` `paths` | Rare — most aliases live in `tsconfig.json` already |
167
+ | `index.html` `<meta>` tags + `<title>` | `app/layout.tsx` `metadata` export | Move static meta into the route's `metadata`; dynamic meta moves into `generateMetadata` |
168
+ | `document.cookie` reads in client components | `cookies()` from `next/headers` (server) | Most cases are client-only; only swap if the value must be SSR-rendered |
169
+ | `@fontsource-variable/inter` import in `main.tsx` | `Inter()` from `next/font/google` in `app/layout.tsx` | Both produce zero-CLS variable fonts; Next has the edge on hashed asset names |
170
+
171
+ The agent runs this map as a codemod — see
172
+ `packages/ui/template-vite/scripts/port-next-imports.mjs` (template-vite
173
+ internal use) for the inverse direction (Next → Vite, used during PR-2).
174
+ Engineers porting **Vite → Next** can copy that script and reverse the
175
+ regexes; the patterns are symmetric.
176
+
177
+ ---
178
+
179
+ ## How the engineer uses this file
180
+
181
+ 1. Read sections 1–3 to understand intent.
182
+ 2. Skim sections 4–7 to confirm the agent reused DS primitives + tokens (no surprises).
183
+ 3. Run `npx --package=@exxatdesignux/ui exxat-ui audit <generated-file>.tsx` to validate the floor automatically.
184
+ 4. Wire real data per section 9.
185
+ 5. Verify section 10 states render with real API data (not just mocks).
186
+ 6. Add section 11 shortcuts to the route's e2e test.
187
+ 7. Surface section 12 deviations + section 14 open questions in the PR description.
188
+
189
+ If any section is missing or hand-wavy, the handoff is incomplete. Push it
190
+ back to the designer / agent before merging.
@@ -10,7 +10,7 @@ declare function useAppTheme(): {
10
10
  brand: Brand;
11
11
  setBrand: (b: Brand) => void;
12
12
  /** The user's preference: "system" | "normal" | "high" | "windows" */
13
- contrastPref: "system" | "normal" | "high" | "windows";
13
+ contrastPref: "normal" | "high" | "system" | "windows";
14
14
  /** The resolved contrast mode actually applied to the DOM. */
15
15
  contrast: ContrastMode;
16
16
  /** Set the contrast preference. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exxatdesignux/ui",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "description": "Exxat shared design system (components, hooks, tokens). Monorepo setup: clone repo then pnpm bootstrap at workspace root — see github.com/ExxatDesign/Exxat-DS-Workspace README.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Exxat Design",
@@ -97,7 +97,7 @@
97
97
  "dist",
98
98
  "src",
99
99
  "bin",
100
- "template",
100
+ "template-vite",
101
101
  "consumer-extras",
102
102
  "tokens"
103
103
  ],