@exxatdesignux/ui 0.2.18 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (618) hide show
  1. package/CHANGELOG.md +69 -1
  2. package/bin/sync-extras.mjs +116 -29
  3. package/consumer-extras/README.md +43 -4
  4. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
  5. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
  6. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
  7. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
  8. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
  9. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
  10. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
  11. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
  12. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
  13. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
  14. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
  15. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
  16. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
  17. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
  18. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
  19. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
  20. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
  21. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  23. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  24. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  25. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  26. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  27. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  28. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
  29. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
  30. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
  31. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
  32. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
  33. package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
  34. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +1 -1
  36. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +9 -9
  37. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  38. package/consumer-extras/handbook/HANDBOOK.md +185 -0
  39. package/consumer-extras/handbook/glossary.md +57 -0
  40. package/consumer-extras/handbook/reference-implementations.md +126 -0
  41. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  42. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  43. package/consumer-extras/patterns/data-views-pattern.md +14 -14
  44. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  45. package/dist/components/data-table/filter-date-calendar.js +280 -0
  46. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  47. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  48. package/dist/components/data-table/filter-text-value-input.js +561 -0
  49. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  50. package/dist/components/data-table/index.d.ts +45 -0
  51. package/dist/components/data-table/index.js +3085 -0
  52. package/dist/components/data-table/index.js.map +1 -0
  53. package/dist/components/data-table/pagination.d.ts +28 -0
  54. package/dist/components/data-table/pagination.js +3264 -0
  55. package/dist/components/data-table/pagination.js.map +1 -0
  56. package/dist/components/data-table/types.d.ts +84 -0
  57. package/dist/components/data-table/types.js +3 -0
  58. package/dist/components/data-table/types.js.map +1 -0
  59. package/dist/components/data-table/use-table-state.d.ts +116 -0
  60. package/dist/components/data-table/use-table-state.js +670 -0
  61. package/dist/components/data-table/use-table-state.js.map +1 -0
  62. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  63. package/dist/components/data-views/board-card-primitives.js +84 -0
  64. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  65. package/dist/components/data-views/data-row-list.d.ts +33 -0
  66. package/dist/components/data-views/data-row-list.js +106 -0
  67. package/dist/components/data-views/data-row-list.js.map +1 -0
  68. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  69. package/dist/components/data-views/finder-panel-view.js +388 -0
  70. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  71. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  72. package/dist/components/data-views/folder-grid-view.js +58 -0
  73. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  74. package/dist/components/data-views/hub-table.d.ts +167 -0
  75. package/dist/components/data-views/hub-table.js +5561 -0
  76. package/dist/components/data-views/hub-table.js.map +1 -0
  77. package/dist/components/data-views/index.d.ts +27 -0
  78. package/dist/components/data-views/index.js +6575 -0
  79. package/dist/components/data-views/index.js.map +1 -0
  80. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  81. package/dist/components/data-views/list-page-board-card.js +264 -0
  82. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  83. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  84. package/dist/components/data-views/list-page-board-template.js +137 -0
  85. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  86. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  87. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  88. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  89. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  90. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  91. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  92. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  93. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  94. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  95. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  96. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  97. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  98. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  99. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  100. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  101. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  102. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  103. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  104. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  105. package/dist/components/data-views/os-folder-glyph.js +104 -0
  106. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  107. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  108. package/dist/components/data-views/outline-tree-menu.js +131 -0
  109. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  110. package/dist/components/table-properties/column-row.d.ts +22 -0
  111. package/dist/components/table-properties/column-row.js +153 -0
  112. package/dist/components/table-properties/column-row.js.map +1 -0
  113. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  114. package/dist/components/table-properties/draggable-list.js +53 -0
  115. package/dist/components/table-properties/draggable-list.js.map +1 -0
  116. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  117. package/dist/components/table-properties/drawer-button.js +2748 -0
  118. package/dist/components/table-properties/drawer-button.js.map +1 -0
  119. package/dist/components/table-properties/drawer.d.ts +100 -0
  120. package/dist/components/table-properties/drawer.js +2595 -0
  121. package/dist/components/table-properties/drawer.js.map +1 -0
  122. package/dist/components/table-properties/filter-card.d.ts +24 -0
  123. package/dist/components/table-properties/filter-card.js +854 -0
  124. package/dist/components/table-properties/filter-card.js.map +1 -0
  125. package/dist/components/table-properties/index.d.ts +14 -0
  126. package/dist/components/table-properties/index.js +2768 -0
  127. package/dist/components/table-properties/index.js.map +1 -0
  128. package/dist/components/table-properties/sort-card.d.ts +20 -0
  129. package/dist/components/table-properties/sort-card.js +102 -0
  130. package/dist/components/table-properties/sort-card.js.map +1 -0
  131. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  132. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  133. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  134. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  135. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  136. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  137. package/dist/components/templates/index.d.ts +9 -0
  138. package/dist/components/templates/index.js +2720 -0
  139. package/dist/components/templates/index.js.map +1 -0
  140. package/dist/components/templates/list-page.d.ts +83 -0
  141. package/dist/components/templates/list-page.js +2433 -0
  142. package/dist/components/templates/list-page.js.map +1 -0
  143. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  144. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  145. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  146. package/dist/components/ui/accordion.d.ts +10 -0
  147. package/dist/components/ui/accordion.js +74 -0
  148. package/dist/components/ui/accordion.js.map +1 -0
  149. package/dist/components/ui/alert-dialog.d.ts +37 -0
  150. package/dist/components/ui/alert-dialog.js +201 -0
  151. package/dist/components/ui/alert-dialog.js.map +1 -0
  152. package/dist/components/ui/avatar.d.ts +84 -0
  153. package/dist/components/ui/avatar.js +328 -0
  154. package/dist/components/ui/avatar.js.map +1 -0
  155. package/dist/components/ui/badge.d.ts +13 -0
  156. package/dist/components/ui/badge.js +49 -0
  157. package/dist/components/ui/badge.js.map +1 -0
  158. package/dist/components/ui/banner.d.ts +62 -0
  159. package/dist/components/ui/banner.js +364 -0
  160. package/dist/components/ui/banner.js.map +1 -0
  161. package/dist/components/ui/breadcrumb.d.ts +14 -0
  162. package/dist/components/ui/breadcrumb.js +114 -0
  163. package/dist/components/ui/breadcrumb.js.map +1 -0
  164. package/dist/components/ui/button.d.ts +16 -0
  165. package/dist/components/ui/button.js +59 -0
  166. package/dist/components/ui/button.js.map +1 -0
  167. package/dist/components/ui/calendar.d.ts +13 -0
  168. package/dist/components/ui/calendar.js +238 -0
  169. package/dist/components/ui/calendar.js.map +1 -0
  170. package/dist/components/ui/card.d.ts +14 -0
  171. package/dist/components/ui/card.js +102 -0
  172. package/dist/components/ui/card.js.map +1 -0
  173. package/dist/components/ui/chart.d.ts +58 -0
  174. package/dist/components/ui/chart.js +292 -0
  175. package/dist/components/ui/chart.js.map +1 -0
  176. package/dist/components/ui/checkbox.d.ts +23 -0
  177. package/dist/components/ui/checkbox.js +155 -0
  178. package/dist/components/ui/checkbox.js.map +1 -0
  179. package/dist/components/ui/coach-mark.d.ts +27 -0
  180. package/dist/components/ui/coach-mark.js +306 -0
  181. package/dist/components/ui/coach-mark.js.map +1 -0
  182. package/dist/components/ui/collapsible.d.ts +8 -0
  183. package/dist/components/ui/collapsible.js +35 -0
  184. package/dist/components/ui/collapsible.js.map +1 -0
  185. package/dist/components/ui/command.d.ts +36 -0
  186. package/dist/components/ui/command.js +274 -0
  187. package/dist/components/ui/command.js.map +1 -0
  188. package/dist/components/ui/context-menu.d.ts +32 -0
  189. package/dist/components/ui/context-menu.js +245 -0
  190. package/dist/components/ui/context-menu.js.map +1 -0
  191. package/dist/components/ui/date-picker-field.d.ts +38 -0
  192. package/dist/components/ui/date-picker-field.js +550 -0
  193. package/dist/components/ui/date-picker-field.js.map +1 -0
  194. package/dist/components/ui/dialog.d.ts +22 -0
  195. package/dist/components/ui/dialog.js +200 -0
  196. package/dist/components/ui/dialog.js.map +1 -0
  197. package/dist/components/ui/dot-pattern.d.ts +21 -0
  198. package/dist/components/ui/dot-pattern.js +139 -0
  199. package/dist/components/ui/dot-pattern.js.map +1 -0
  200. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  201. package/dist/components/ui/drag-handle-grip.js +15 -0
  202. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  203. package/dist/components/ui/drawer.d.ts +16 -0
  204. package/dist/components/ui/drawer.js +125 -0
  205. package/dist/components/ui/drawer.js.map +1 -0
  206. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  207. package/dist/components/ui/dropdown-menu.js +353 -0
  208. package/dist/components/ui/dropdown-menu.js.map +1 -0
  209. package/dist/components/ui/export-drawer.d.ts +11 -0
  210. package/dist/components/ui/export-drawer.js +1658 -0
  211. package/dist/components/ui/export-drawer.js.map +1 -0
  212. package/dist/components/ui/field.d.ts +30 -0
  213. package/dist/components/ui/field.js +249 -0
  214. package/dist/components/ui/field.js.map +1 -0
  215. package/dist/components/ui/form.d.ts +28 -0
  216. package/dist/components/ui/form.js +110 -0
  217. package/dist/components/ui/form.js.map +1 -0
  218. package/dist/components/ui/hover-card.d.ts +9 -0
  219. package/dist/components/ui/hover-card.js +43 -0
  220. package/dist/components/ui/hover-card.js.map +1 -0
  221. package/dist/components/ui/input-group.d.ts +20 -0
  222. package/dist/components/ui/input-group.js +219 -0
  223. package/dist/components/ui/input-group.js.map +1 -0
  224. package/dist/components/ui/input-mask.d.ts +39 -0
  225. package/dist/components/ui/input-mask.js +118 -0
  226. package/dist/components/ui/input-mask.js.map +1 -0
  227. package/dist/components/ui/input.d.ts +5 -0
  228. package/dist/components/ui/input.js +30 -0
  229. package/dist/components/ui/input.js.map +1 -0
  230. package/dist/components/ui/kbd.d.ts +20 -0
  231. package/dist/components/ui/kbd.js +45 -0
  232. package/dist/components/ui/kbd.js.map +1 -0
  233. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  234. package/dist/components/ui/key-metrics-context.js +26 -0
  235. package/dist/components/ui/key-metrics-context.js.map +1 -0
  236. package/dist/components/ui/key-metrics.d.ts +131 -0
  237. package/dist/components/ui/key-metrics.js +1015 -0
  238. package/dist/components/ui/key-metrics.js.map +1 -0
  239. package/dist/components/ui/label.d.ts +6 -0
  240. package/dist/components/ui/label.js +28 -0
  241. package/dist/components/ui/label.js.map +1 -0
  242. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  243. package/dist/components/ui/list-page-view-frame.js +24 -0
  244. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  245. package/dist/components/ui/page-header.d.ts +51 -0
  246. package/dist/components/ui/page-header.js +372 -0
  247. package/dist/components/ui/page-header.js.map +1 -0
  248. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  249. package/dist/components/ui/payment-card-fields.js +80 -0
  250. package/dist/components/ui/payment-card-fields.js.map +1 -0
  251. package/dist/components/ui/popover.d.ts +10 -0
  252. package/dist/components/ui/popover.js +47 -0
  253. package/dist/components/ui/popover.js.map +1 -0
  254. package/dist/components/ui/radio-group.d.ts +29 -0
  255. package/dist/components/ui/radio-group.js +190 -0
  256. package/dist/components/ui/radio-group.js.map +1 -0
  257. package/dist/components/ui/resizable.d.ts +16 -0
  258. package/dist/components/ui/resizable.js +51 -0
  259. package/dist/components/ui/resizable.js.map +1 -0
  260. package/dist/components/ui/scroll-area.d.ts +8 -0
  261. package/dist/components/ui/scroll-area.js +66 -0
  262. package/dist/components/ui/scroll-area.js.map +1 -0
  263. package/dist/components/ui/select.d.ts +18 -0
  264. package/dist/components/ui/select.js +186 -0
  265. package/dist/components/ui/select.js.map +1 -0
  266. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  267. package/dist/components/ui/selection-tile-grid.js +347 -0
  268. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  269. package/dist/components/ui/separator.d.ts +7 -0
  270. package/dist/components/ui/separator.js +33 -0
  271. package/dist/components/ui/separator.js.map +1 -0
  272. package/dist/components/ui/sheet.d.ts +18 -0
  273. package/dist/components/ui/sheet.js +181 -0
  274. package/dist/components/ui/sheet.js.map +1 -0
  275. package/dist/components/ui/sidebar.d.ts +94 -0
  276. package/dist/components/ui/sidebar.js +805 -0
  277. package/dist/components/ui/sidebar.js.map +1 -0
  278. package/dist/components/ui/skeleton.d.ts +5 -0
  279. package/dist/components/ui/skeleton.js +22 -0
  280. package/dist/components/ui/skeleton.js.map +1 -0
  281. package/dist/components/ui/slider.d.ts +7 -0
  282. package/dist/components/ui/slider.js +66 -0
  283. package/dist/components/ui/slider.js.map +1 -0
  284. package/dist/components/ui/sonner.d.ts +6 -0
  285. package/dist/components/ui/sonner.js +38 -0
  286. package/dist/components/ui/sonner.js.map +1 -0
  287. package/dist/components/ui/status-badge.d.ts +38 -0
  288. package/dist/components/ui/status-badge.js +77 -0
  289. package/dist/components/ui/status-badge.js.map +1 -0
  290. package/dist/components/ui/table.d.ts +13 -0
  291. package/dist/components/ui/table.js +115 -0
  292. package/dist/components/ui/table.js.map +1 -0
  293. package/dist/components/ui/tabs.d.ts +15 -0
  294. package/dist/components/ui/tabs.js +93 -0
  295. package/dist/components/ui/tabs.js.map +1 -0
  296. package/dist/components/ui/textarea.d.ts +6 -0
  297. package/dist/components/ui/textarea.js +25 -0
  298. package/dist/components/ui/textarea.js.map +1 -0
  299. package/dist/components/ui/tip.d.ts +12 -0
  300. package/dist/components/ui/tip.js +61 -0
  301. package/dist/components/ui/tip.js.map +1 -0
  302. package/dist/components/ui/toggle-group.d.ts +14 -0
  303. package/dist/components/ui/toggle-group.js +104 -0
  304. package/dist/components/ui/toggle-group.js.map +1 -0
  305. package/dist/components/ui/toggle-switch.d.ts +10 -0
  306. package/dist/components/ui/toggle-switch.js +33 -0
  307. package/dist/components/ui/toggle-switch.js.map +1 -0
  308. package/dist/components/ui/toggle.d.ts +13 -0
  309. package/dist/components/ui/toggle.js +51 -0
  310. package/dist/components/ui/toggle.js.map +1 -0
  311. package/dist/components/ui/tooltip.d.ts +10 -0
  312. package/dist/components/ui/tooltip.js +68 -0
  313. package/dist/components/ui/tooltip.js.map +1 -0
  314. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  315. package/dist/components/ui/view-segmented-control.js +167 -0
  316. package/dist/components/ui/view-segmented-control.js.map +1 -0
  317. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  318. package/dist/hooks/use-app-theme.d.ts +24 -0
  319. package/dist/hooks/use-app-theme.js +286 -0
  320. package/dist/hooks/use-app-theme.js.map +1 -0
  321. package/dist/hooks/use-coach-mark.d.ts +86 -0
  322. package/dist/hooks/use-coach-mark.js +218 -0
  323. package/dist/hooks/use-coach-mark.js.map +1 -0
  324. package/dist/hooks/use-mobile.d.ts +3 -0
  325. package/dist/hooks/use-mobile.js +29 -0
  326. package/dist/hooks/use-mobile.js.map +1 -0
  327. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  328. package/dist/hooks/use-mod-key-label.js +25 -0
  329. package/dist/hooks/use-mod-key-label.js.map +1 -0
  330. package/dist/index.d.ts +120 -0
  331. package/dist/index.js +13324 -0
  332. package/dist/index.js.map +1 -0
  333. package/dist/lib/compose-refs.d.ts +6 -0
  334. package/dist/lib/compose-refs.js +17 -0
  335. package/dist/lib/compose-refs.js.map +1 -0
  336. package/dist/lib/conditional-rule-match.d.ts +30 -0
  337. package/dist/lib/conditional-rule-match.js +66 -0
  338. package/dist/lib/conditional-rule-match.js.map +1 -0
  339. package/dist/lib/data-list-display-options.d.ts +26 -0
  340. package/dist/lib/data-list-display-options.js +14 -0
  341. package/dist/lib/data-list-display-options.js.map +1 -0
  342. package/dist/lib/data-list-view-registry.d.ts +2 -0
  343. package/dist/lib/data-list-view-registry.js +102 -0
  344. package/dist/lib/data-list-view-registry.js.map +1 -0
  345. package/dist/lib/data-list-view-surface.d.ts +2 -0
  346. package/dist/lib/data-list-view-surface.js +80 -0
  347. package/dist/lib/data-list-view-surface.js.map +1 -0
  348. package/dist/lib/data-list-view.d.ts +21 -0
  349. package/dist/lib/data-list-view.js +25 -0
  350. package/dist/lib/data-list-view.js.map +1 -0
  351. package/dist/lib/date-filter.d.ts +22 -0
  352. package/dist/lib/date-filter.js +61 -0
  353. package/dist/lib/date-filter.js.map +1 -0
  354. package/dist/lib/dev-log.d.ts +8 -0
  355. package/dist/lib/dev-log.js +10 -0
  356. package/dist/lib/dev-log.js.map +1 -0
  357. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  358. package/dist/lib/dropdown-menu-surface.js +6 -0
  359. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  360. package/dist/lib/editable-target.d.ts +12 -0
  361. package/dist/lib/editable-target.js +12 -0
  362. package/dist/lib/editable-target.js.map +1 -0
  363. package/dist/lib/list-page-table-properties.d.ts +35 -0
  364. package/dist/lib/list-page-table-properties.js +81 -0
  365. package/dist/lib/list-page-table-properties.js.map +1 -0
  366. package/dist/lib/raf-throttle.d.ts +23 -0
  367. package/dist/lib/raf-throttle.js +27 -0
  368. package/dist/lib/raf-throttle.js.map +1 -0
  369. package/dist/lib/row-height.d.ts +16 -0
  370. package/dist/lib/row-height.js +10 -0
  371. package/dist/lib/row-height.js.map +1 -0
  372. package/dist/lib/table-properties-types.d.ts +83 -0
  373. package/dist/lib/table-properties-types.js +19 -0
  374. package/dist/lib/table-properties-types.js.map +1 -0
  375. package/dist/lib/utils.d.ts +5 -0
  376. package/dist/lib/utils.js +11 -0
  377. package/dist/lib/utils.js.map +1 -0
  378. package/package.json +83 -18
  379. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  380. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  381. package/src/components/data-table/index.tsx +1678 -0
  382. package/src/components/data-table/pagination.tsx +255 -0
  383. package/src/components/data-table/types.ts +96 -0
  384. package/src/components/data-table/use-table-state.ts +767 -0
  385. package/src/components/data-views/board-card-primitives.tsx +93 -0
  386. package/src/components/data-views/data-row-list.tsx +183 -0
  387. package/src/components/data-views/finder-panel-view.tsx +405 -0
  388. package/src/components/data-views/folder-grid-view.tsx +86 -0
  389. package/src/components/data-views/hub-table.tsx +498 -0
  390. package/src/components/data-views/index.ts +28 -0
  391. package/src/components/data-views/list-page-board-card.tsx +192 -0
  392. package/src/components/data-views/list-page-board-template.tsx +122 -0
  393. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  394. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  395. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  396. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  397. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  398. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  399. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  400. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  401. package/src/components/table-properties/column-row.tsx +90 -0
  402. package/src/components/table-properties/draggable-list.ts +54 -0
  403. package/src/components/table-properties/drawer-button.tsx +300 -0
  404. package/src/components/table-properties/drawer.tsx +1148 -0
  405. package/src/components/table-properties/filter-card.tsx +251 -0
  406. package/src/components/table-properties/index.ts +36 -0
  407. package/src/components/table-properties/sort-card.tsx +63 -0
  408. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  409. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  410. package/src/components/templates/index.ts +33 -0
  411. package/src/components/templates/list-page.tsx +602 -0
  412. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  413. package/src/components/ui/accordion.tsx +92 -0
  414. package/src/components/ui/alert-dialog.tsx +221 -0
  415. package/src/components/ui/avatar.tsx +13 -2
  416. package/src/components/ui/banner.tsx +2 -2
  417. package/src/components/ui/calendar.tsx +1 -1
  418. package/src/components/ui/coach-mark.tsx +1 -1
  419. package/src/components/ui/context-menu.tsx +291 -0
  420. package/src/components/ui/date-picker-field.tsx +2 -2
  421. package/src/components/ui/dot-pattern.tsx +183 -0
  422. package/src/components/ui/export-drawer.tsx +375 -0
  423. package/src/components/ui/hover-card.tsx +66 -0
  424. package/src/components/ui/key-metrics-context.tsx +78 -0
  425. package/src/components/ui/key-metrics.tsx +1133 -0
  426. package/src/components/ui/list-page-view-frame.tsx +64 -0
  427. package/src/components/ui/page-header.tsx +244 -0
  428. package/src/components/ui/payment-card-fields.tsx +2 -2
  429. package/src/components/ui/resizable.tsx +68 -0
  430. package/src/components/ui/scroll-area.tsx +72 -0
  431. package/src/components/ui/selection-tile-grid.tsx +9 -2
  432. package/src/components/ui/sidebar.tsx +84 -12
  433. package/src/components/ui/slider.tsx +83 -0
  434. package/src/globals.css +494 -151
  435. package/src/globals.d.ts +20 -0
  436. package/src/index.ts +68 -1
  437. package/src/lib/conditional-rule-match.ts +119 -0
  438. package/src/lib/data-list-display-options.ts +35 -0
  439. package/src/lib/data-list-view-registry.ts +104 -0
  440. package/src/lib/data-list-view-surface.ts +83 -0
  441. package/src/lib/data-list-view.ts +47 -0
  442. package/src/lib/dev-log.ts +10 -0
  443. package/src/lib/editable-target.ts +20 -0
  444. package/src/lib/list-page-table-properties.ts +48 -0
  445. package/src/lib/raf-throttle.ts +45 -0
  446. package/src/lib/row-height.ts +19 -0
  447. package/src/lib/table-properties-types.ts +98 -0
  448. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  449. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
  450. package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
  451. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  452. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
  453. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  454. package/template/AGENTS.md +84 -20
  455. package/template/app/(app)/examples/page.tsx +0 -1
  456. package/template/app/(app)/layout.tsx +17 -4
  457. package/template/app/(app)/question-bank/layout.tsx +1 -1
  458. package/template/app/(app)/question-bank/new/page.tsx +11 -24
  459. package/template/app/globals.css +13 -1972
  460. package/template/components/ask-leo-sidebar.tsx +5 -1
  461. package/template/components/brand-color-picker.tsx +2 -2
  462. package/template/components/charts-overview.tsx +1 -1
  463. package/template/components/compliance-table.tsx +240 -384
  464. package/template/components/dashboard-report-charts.tsx +1 -1
  465. package/template/components/dashboard-tabs.tsx +1 -1
  466. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  467. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  468. package/template/components/data-table/index.tsx +1 -1634
  469. package/template/components/data-table/pagination.tsx +1 -255
  470. package/template/components/data-table/types.ts +1 -94
  471. package/template/components/data-table/use-table-state.test.ts +420 -0
  472. package/template/components/data-table/use-table-state.ts +1 -758
  473. package/template/components/data-view-dashboard-charts-compliance.tsx +2 -2
  474. package/template/components/data-view-dashboard-charts-team.tsx +2 -2
  475. package/template/components/data-view-dashboard-charts.tsx +2 -2
  476. package/template/components/data-views/board-card-primitives.tsx +1 -93
  477. package/template/components/data-views/data-row-list.tsx +1 -183
  478. package/template/components/data-views/finder-panel-view.tsx +1 -405
  479. package/template/components/data-views/folder-grid-view.tsx +1 -86
  480. package/template/components/data-views/hub-table.tsx +1 -0
  481. package/template/components/data-views/index.ts +42 -1
  482. package/template/components/data-views/list-page-board-card.tsx +1 -192
  483. package/template/components/data-views/list-page-board-template.tsx +1 -122
  484. package/template/components/data-views/list-page-connected-view-body.tsx +1 -0
  485. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  486. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -60
  487. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  488. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  489. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  490. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  491. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  492. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  493. package/template/components/export-drawer.test.tsx +71 -0
  494. package/template/components/export-drawer.tsx +1 -375
  495. package/template/components/exxat-product-logo.tsx +5 -5
  496. package/template/components/hub-tree-panel-view.tsx +2 -2
  497. package/template/components/invite-collaborators-drawer.tsx +3 -3
  498. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  499. package/template/components/key-metrics.tsx +1 -1063
  500. package/template/components/leo-insight-indicator.tsx +2 -2
  501. package/template/components/new-placement-back-btn.tsx +1 -1
  502. package/template/components/new-placement-form.tsx +63 -189
  503. package/template/components/new-question-composer.tsx +432 -402
  504. package/template/components/onboarding/index.ts +9 -0
  505. package/template/components/onboarding/onboarding-01.tsx +1 -1
  506. package/template/components/onboarding/onboarding-02.tsx +1 -1
  507. package/template/components/onboarding/onboarding-03.tsx +1 -1
  508. package/template/components/onboarding/onboarding-04.tsx +1 -1
  509. package/template/components/page-header.tsx +8 -226
  510. package/template/components/placement-board-card.tsx +71 -83
  511. package/template/components/placements-board-view.tsx +3 -10
  512. package/template/components/placements-client.tsx +10 -42
  513. package/template/components/placements-list-view.tsx +22 -69
  514. package/template/components/placements-table-columns.tsx +8 -438
  515. package/template/components/placements-table.tsx +588 -1296
  516. package/template/components/product-switcher.tsx +1 -1
  517. package/template/components/product-wordmark.tsx +2 -1
  518. package/template/components/question-bank-client.tsx +4 -1
  519. package/template/components/question-bank-hub-client.tsx +1 -1
  520. package/template/components/question-bank-new-folder-sheet.tsx +2 -2
  521. package/template/components/question-bank-secondary-nav.tsx +3 -3
  522. package/template/components/question-bank-table.tsx +294 -526
  523. package/template/components/rotations-empty-state.tsx +1 -1
  524. package/template/components/rotations-panel-activator.tsx +1 -1
  525. package/template/components/settings-appearance-card.tsx +1 -1
  526. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  527. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +4 -4
  528. package/template/components/sidebar/index.ts +16 -0
  529. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  530. package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +6 -3
  531. package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
  532. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  533. package/template/components/site-header.tsx +1 -1
  534. package/template/components/{sites-all-client.tsx → sites-client.tsx} +1 -1
  535. package/template/components/sites-table.tsx +124 -257
  536. package/template/components/table-properties/column-row.tsx +1 -90
  537. package/template/components/table-properties/draggable-list.ts +1 -49
  538. package/template/components/table-properties/drawer-button.tsx +1 -249
  539. package/template/components/table-properties/drawer.tsx +1 -1105
  540. package/template/components/table-properties/filter-card.tsx +1 -251
  541. package/template/components/table-properties/sort-card.tsx +1 -59
  542. package/template/components/table-properties/types.ts +28 -71
  543. package/template/components/team-table.tsx +242 -382
  544. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  545. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  546. package/template/components/templates/list-page.tsx +1 -584
  547. package/template/components/templates/nested-secondary-panel-shell.tsx +1 -62
  548. package/template/components/templates/new-focus-template.tsx +659 -0
  549. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  550. package/template/components/ui/accordion.tsx +1 -0
  551. package/template/components/ui/alert-dialog.tsx +1 -0
  552. package/template/components/ui/context-menu.tsx +1 -0
  553. package/template/components/ui/dot-pattern.tsx +1 -183
  554. package/template/components/ui/hover-card.tsx +1 -0
  555. package/template/components/ui/resizable.tsx +1 -68
  556. package/template/components/ui/scroll-area.tsx +1 -0
  557. package/template/components/ui/slider.tsx +1 -0
  558. package/template/docs/blueprints/README.md +86 -0
  559. package/template/docs/blueprints/_template.md +91 -0
  560. package/template/docs/blueprints/board-card.md +123 -0
  561. package/template/docs/blueprints/data-table.md +139 -0
  562. package/template/docs/blueprints/key-metrics.md +128 -0
  563. package/template/docs/blueprints/list-page-template.md +123 -0
  564. package/template/docs/blueprints/page-header.md +130 -0
  565. package/template/docs/command-menu-pattern.md +1 -1
  566. package/template/docs/component-selection-guide.md +224 -0
  567. package/template/docs/components-audit-2026-05.md +158 -0
  568. package/template/docs/data-views-pattern.md +14 -14
  569. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  570. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  571. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  572. package/template/docs/migrations/README.md +100 -0
  573. package/template/docs/migrations/_template.md +64 -0
  574. package/template/docs/token-taxonomy.md +416 -0
  575. package/template/eslint.config.mjs +27 -0
  576. package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
  577. package/template/lib/command-menu-config.ts +0 -1
  578. package/template/lib/compliance-supported-views.ts +10 -0
  579. package/template/lib/conditional-rule-match.ts +6 -97
  580. package/template/lib/data-list-display-options.ts +1 -35
  581. package/template/lib/data-list-view-registry.ts +1 -0
  582. package/template/lib/data-list-view-surface.ts +1 -69
  583. package/template/lib/data-list-view.ts +1 -38
  584. package/template/lib/dev-log.ts +1 -8
  585. package/template/lib/editable-target.ts +1 -10
  586. package/template/lib/hub-connected-view-renderers.ts +58 -0
  587. package/template/lib/list-hub-supported-views.ts +10 -0
  588. package/template/lib/list-page-table-properties.ts +1 -52
  589. package/template/lib/mock/navigation.tsx +0 -8
  590. package/template/lib/mock/placements.ts +0 -7
  591. package/template/lib/placement-board-card-layout.ts +41 -41
  592. package/template/lib/placements-supported-views.ts +12 -0
  593. package/template/lib/question-bank-supported-views.ts +12 -0
  594. package/template/lib/raf-throttle.ts +1 -45
  595. package/template/lib/row-height.ts +4 -10
  596. package/template/lib/sidebar-state-cookie.ts +11 -2
  597. package/template/lib/sites-supported-views.ts +10 -0
  598. package/template/lib/team-supported-views.ts +10 -0
  599. package/template/package.json +1 -0
  600. package/template/tests/setup.ts +25 -0
  601. package/src/theme.css +0 -1132
  602. package/template/app/(app)/data-list/[id]/page.tsx +0 -44
  603. package/template/app/(app)/data-list/new/page.tsx +0 -34
  604. package/template/app/(app)/data-list/page.tsx +0 -10
  605. package/template/components/compliance-list-view.tsx +0 -54
  606. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  607. package/template/components/dashboard-onboarding.tsx +0 -21
  608. package/template/components/question-bank-list-view.tsx +0 -53
  609. package/template/components/section-cards.tsx +0 -106
  610. package/template/components/sites-list-view.tsx +0 -42
  611. package/template/components/team-list-view.tsx +0 -59
  612. package/template/lib/placement-lifecycle.ts +0 -5
  613. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  614. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  615. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  616. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  617. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
  618. /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
@@ -0,0 +1,224 @@
1
+ # Exxat DS — Component Selection Guide
2
+
3
+ **Audience:** humans + AI agents. **Companion to:** [`token-taxonomy.md`](./token-taxonomy.md), [`blueprints/`](./blueprints/).
4
+
5
+ When you're about to build a UI, **start here**. Follow the decision tree
6
+ to find the right composition before you write any markup. The rule is
7
+ always: **compose existing components first**; only create a new shared
8
+ primitive after asking the user
9
+ ([`exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc)).
10
+
11
+ ---
12
+
13
+ ## 0. Quick chart
14
+
15
+ ```
16
+ ┌─────────────────────────────────────┐
17
+ │ What is the surface? │
18
+ └──┬──────────────────────────────────┘
19
+
20
+ ┌───────────┴────────────────────────────┐
21
+ │ │
22
+ PRIMARY HUB OVERLAY / SECONDARY
23
+ (route w/ many records, (on top of a hub,
24
+ filters, properties) modal task, side panel)
25
+ │ │
26
+ │ ▼
27
+ │ See § 3
28
+
29
+ See § 1
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 1. Building a primary hub (route with records)
35
+
36
+ ```
37
+ Q: Is the data > ~10 comparable records?
38
+ ─────────────────────────────────────────
39
+ │ yes ──────────────────────────────► DataTable inside ListPageTemplate (§1.1)
40
+ │ no ──┬─ all rows shown at once?
41
+ │ │ yes ── simple `<dl>` / card list (no Properties / Filters needed)
42
+ │ │ no ── still use DataTable — future growth is expected
43
+ └─────►
44
+ ```
45
+
46
+ ### 1.1 DataTable hub (canonical)
47
+
48
+ | Need | Use |
49
+ |---|---|
50
+ | Browsable grid | **`DataTable`** + **`useTableState`** ([blueprint](./blueprints/data-table.md)) |
51
+ | View tabs (table/list/board/dashboard) | **`ListPageTemplate`** + connected views ([`exxat-list-page-connected-views.mdc`](../../.cursor/rules/exxat-list-page-connected-views.mdc)) |
52
+ | Column/density/properties | **`TablePropertiesDrawer`** (pass `currentView` + `onViewChange`) |
53
+ | Filters | Shared `FilterFieldDef` chips |
54
+ | Find-in-list | Toolbar search (`⌘K`) |
55
+ | Metrics strip | **`KeyMetrics`** `variant="flat"` ([`kpi-flat-band-pattern.md`](./kpi-flat-band-pattern.md)) — **max 4 tiles** ([`exxat-kpi-max-four.mdc`](../../.cursor/rules/exxat-kpi-max-four.mdc)) |
56
+ | Export | Filled primary CTA + `⋯` → `ExportDrawer` |
57
+ | Kanban view body | **`ListPageBoardCard`** + `ListPageBoardTemplate` ([`exxat-board-cards.mdc`](../../.cursor/rules/exxat-board-cards.mdc)) |
58
+ | Folder / panel view body | **`FolderGridView`** / **`FinderPanelView`** wrapped in **`ListPageViewFrame`** ([`exxat-list-page-view-shells.mdc`](../../.cursor/rules/exxat-list-page-view-shells.mdc)) |
59
+ | Dashboard view body | **`KeyMetrics variant="card"`** + chart sections from `data-view-dashboard-charts*.tsx` |
60
+ | Nested scope nav (All / Mine / tree) | **`secondaryPanel`** + `PANELS` + `useAutoPanel` ([`exxat-primary-nav-secondary-panel.mdc`](../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc)) |
61
+ | Shared hub w/ invite | **`PageHeader` `variant="collaboration"`** + `InviteCollaboratorsDrawer` |
62
+ | Dedicated search (empty `?q=` vs results) | **`DedicatedSearchLandingTemplate`** + **`DedicatedSearchResultsHeaderChrome`** |
63
+
64
+ **Reference:** `PlacementsClient` (Placements) is the most complete example.
65
+
66
+ ### 1.2 Visual-browse hub (kanban / gallery)
67
+
68
+ If the product wants a **kanban-first** experience and the table is the
69
+ fallback rather than primary:
70
+
71
+ ```
72
+ ListPageTemplate
73
+ ├── PageHeader
74
+ ├── KeyMetrics (optional, ≤4)
75
+ └── viewType="board" → ListPageBoardTemplate + ListPageBoardCard
76
+ ```
77
+
78
+ Even here, **back the board with `useTableState`** so switching to the table
79
+ tab is consistent. Don't fork the data.
80
+
81
+ ---
82
+
83
+ ## 2. Naming a card / row / list
84
+
85
+ | Pattern | What to reach for |
86
+ |---|---|
87
+ | Dense comparable rows | `DataTable` row (don't card-wall it — see [`card-vs-rows-pattern.md`](./card-vs-rows-pattern.md)) |
88
+ | Kanban column card | `ListPageBoardCard` + `BoardCardTwoLineBlock` + `BoardCardIconRow` |
89
+ | OS-folder grid | `FolderGridView` in `ListPageViewFrame` |
90
+ | Finder split (list + preview) | `FinderPanelView` |
91
+ | Sidebar nav row | `SidebarMenuButton` (do not roll your own) |
92
+ | KPI tile | `KeyMetrics` `MetricItem` — never a custom `Card` w/ number |
93
+ | Coach mark tile | `CoachMark` step — never an ad-hoc onboarding popover |
94
+
95
+ ---
96
+
97
+ ## 3. Same-route overlay vs new route
98
+
99
+ Always ask: **does the user need the hub visible behind them?**
100
+
101
+ ```
102
+ ┌────────────────────────────┐
103
+ │ Does the user need the hub │
104
+ │ visible behind them? │
105
+ └─────────────┬──────────────┘
106
+
107
+ ┌───── YES ─────┴───── NO ─────┐
108
+ ▼ ▼
109
+ Same route New route
110
+ (overlay) (own URL)
111
+ │ │
112
+ ┌─────┴──────┐ │
113
+ │ Is the task│ │
114
+ │ short + │ │
115
+ │ blocking? │ │
116
+ └─────┬──────┘ │
117
+ │ │
118
+ ┌─ YES ┴ NO ──┐ │
119
+ ▼ ▼ ▼
120
+ Dialog Drawer / Sheet Page route
121
+ (AlertDialog, (TablePropertiesDrawer, (full create/edit
122
+ delete confirm) ExportDrawer, wizard, deep detail)
123
+ InviteCollaboratorsDrawer)
124
+ ```
125
+
126
+ See [`drawer-vs-dialog-pattern.md`](./drawer-vs-dialog-pattern.md) and
127
+ [`exxat-page-vs-drawer.mdc`](../../.cursor/rules/exxat-page-vs-drawer.mdc).
128
+
129
+ ---
130
+
131
+ ## 4. Search / Find / Command
132
+
133
+ | Need | Use | Shortcut |
134
+ |---|---|---|
135
+ | Find inside a table | `DataTableToolbar` search | `⌘K` / `Ctrl K` (no Alt) |
136
+ | Find inside a hub (across tabs/views) | Same `⌘K` while focus is on the hub | `⌘K` |
137
+ | Global navigation + AI starter | `CommandMenu` ([`command-menu-pattern.md`](./command-menu-pattern.md)) | `⌘K` while no input has focus |
138
+ | Long AI / chat | `AskLeoSidebar` | `⌘⌥K` |
139
+ | Dedicated search page (results view) | `DedicatedSearchLandingTemplate` + `DedicatedSearchResultsHeaderChrome` | — |
140
+
141
+ ---
142
+
143
+ ## 5. Feedback / messaging
144
+
145
+ | Need | Use |
146
+ |---|---|
147
+ | Persistent banner ("system maintenance") | `SystemBanner` |
148
+ | Per-page contextual info | `LocalBanner` |
149
+ | Per-control success/error | Inline text next to the field |
150
+ | Confirm a destructive action | `AlertDialog` |
151
+ | **Never** | `toast()` / Sonner / snackbars ([`exxat-no-toast.mdc`](../../.cursor/rules/exxat-no-toast.mdc)) |
152
+
153
+ ---
154
+
155
+ ## 6. Icons
156
+
157
+ | Use case | Pattern |
158
+ |---|---|
159
+ | Icon next to a label | FA glyph + `aria-hidden` (Case A) |
160
+ | Icon standing alone (meaning-bearing) | `<span role="img" aria-label="…" tabIndex={0}>` + `Tooltip` (Case B) |
161
+ | Icon-only button / link | `<button aria-label="…">` wrapped in `Tooltip` (Case C) |
162
+ | Product mark | `ExxatProductLogo` |
163
+ | School / org mark | `logoDevUrl()` |
164
+
165
+ Source: `apps/web/AGENTS.md` §8.6.
166
+
167
+ ---
168
+
169
+ ## 7. KPIs / metrics
170
+
171
+ | Need | Use |
172
+ |---|---|
173
+ | Hub metric strip on top of `ListPageTemplate` | `KeyMetrics variant="flat"` |
174
+ | Dashboard view tab key-metrics card | `KeyMetrics variant="card"` (1–4 tiles) |
175
+ | Chart + mini-metric next to it | `ChartCard` + chart's own KPI helpers |
176
+ | Trend arrow on a metric | Set `MetricItem.trend` to match delta sign; set `trendPolarity` when "up" is bad |
177
+
178
+ Cap visible KPIs at **4** ([`exxat-kpi-max-four.mdc`](../../.cursor/rules/exxat-kpi-max-four.mdc)).
179
+
180
+ ---
181
+
182
+ ## 8. Identifiers and typography
183
+
184
+ | Carries | Use |
185
+ |---|---|
186
+ | System ID (`questionId`, record key) | `font-mono tabular-nums` ([`exxat-mono-ids.mdc`](../../.cursor/rules/exxat-mono-ids.mdc)) |
187
+ | Page title | `<h1>` with `font-heading` (Ivy Presto) inside `PageHeader` |
188
+ | Body | Default Inter, ≥ 11px (`text-xs` minimum) |
189
+ | Status label | `ListHubStatusBadge` from `lib/list-status-badges.ts` — never raw text |
190
+ | Currency / counts | `tabular-nums` (no `font-mono`) |
191
+
192
+ ---
193
+
194
+ ## 9. When NOTHING here fits
195
+
196
+ You are now in the territory covered by
197
+ [`exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc):
198
+
199
+ 1. Re-scan `apps/web/components/`, `packages/ui/src/components/`, and `apps/web/components/data-views/`.
200
+ 2. Check `AGENTS.md` §9 architecture table.
201
+ 3. If still no fit, **ask the user** with a short option list:
202
+ - extend an existing primitive (preferred),
203
+ - add a new component under `components/data-views/` or `components/templates/`,
204
+ - or open a packaged shared primitive in `packages/ui`.
205
+
206
+ ---
207
+
208
+ ## 10. Cheat sheet — one-line rules
209
+
210
+ - **Data list, > 10 rows** → `DataTable` + `ListPageTemplate`.
211
+ - **Visual browse / kanban** → `ListPageBoardCard`.
212
+ - **Folder / panel / OS-folder view** → `data-views/` primitive in `ListPageViewFrame`.
213
+ - **Quick auxiliary task with hub behind** → drawer.
214
+ - **Blocking short confirm** → dialog.
215
+ - **Primary / long / own-URL flow** → new route.
216
+ - **Global ⌘K** → `CommandMenu` (search + quick AI).
217
+ - **Long AI** → Ask Leo (`⌘⌥K`).
218
+ - **Feedback** → banner / inline / dialog — **never** toast.
219
+ - **Icon-only button** → `aria-label` + `Tooltip` (Case C).
220
+ - **System ID** → `font-mono tabular-nums`.
221
+ - **KPI strip** → ≤ 4 tiles, `variant="flat"` on hubs.
222
+ - **Hex color in code** → no. Use a token.
223
+
224
+ See also: [`AGENTS.md` §13 checklist](../AGENTS.md) — run it before shipping a hub.
@@ -0,0 +1,158 @@
1
+ # `apps/web/components/` audit — 2026-05
2
+
3
+ **Author:** Exxat DS hardening sweep · **Scope:** observation only — no code moved.
4
+
5
+ This audit was triggered by formalizing the design system (token taxonomy +
6
+ blueprints + selection guide + ESLint guardrails) so that any future
7
+ component refactor has a clear target structure. **No file is moved or
8
+ deleted by this audit itself.** Treat each finding as a follow-up PR
9
+ candidate; bundle them as you like.
10
+
11
+ ## 1. Sizes & shape
12
+
13
+ | Bucket | Count | Notes |
14
+ |---|---|---|
15
+ | Top-level `components/*.tsx` | **99** | Mix of hub clients, hub tables, hub views, page headers, dashboard charts, sidebar bits, leaf primitives |
16
+ | `components/data-table/` | 5 | Correct — base table stack |
17
+ | `components/data-views/` | 14 | Correct — generic view primitives + board card |
18
+ | `components/onboarding/` | 5 (4 demos + index) | Demo variants of `GettingStarted` |
19
+ | `components/table-properties/` | (drawer + parts) | Correct |
20
+ | `components/templates/` | 7 | Correct — page-level templates |
21
+ | `components/ui/` | 40+ | Reserved for shadcn primitives bridged from `packages/ui` |
22
+
23
+ ## 2. Findings
24
+
25
+ ### 2.1 Dead components (zero importers found)
26
+
27
+ > **Resolved 2026-05-19.** A re-verification scan confirmed that
28
+ > `form-layout-01.tsx` and `section-cards.tsx` are **not present** in either
29
+ > `apps/web/components/` or `packages/ui/template/components/` — the audit's
30
+ > initial finding was based on a stale snapshot. No action needed.
31
+
32
+ ### 2.2 Onboarding components split between two locations
33
+
34
+ > **Resolved 2026-05-19.** Option A landed:
35
+ > - `getting-started.tsx` moved into `components/onboarding/getting-started.tsx`
36
+ > (both `apps/web/` and `packages/ui/template/`).
37
+ > - Deprecated shims `dashboard-onboarding.tsx` and
38
+ > `dashboard-onboarding-gallery.tsx` deleted in both locations
39
+ > (no consumers outside themselves).
40
+ > - `components/onboarding/index.ts` now re-exports `GettingStarted`,
41
+ > `GettingStartedProgressCard`, `GettingStartedVariantView`,
42
+ > `renderGettingStartedVariant`, `GETTING_STARTED_STORAGE_KEY`, and
43
+ > the `Onboarding01`–`Onboarding04` variant cards.
44
+ > - Dashboard consumers (`dashboard-tabs.tsx`, `dashboard-report-charts.tsx`)
45
+ > import via `@/components/onboarding/getting-started`; intra-folder
46
+ > variants use the relative `./getting-started` path.
47
+
48
+ ### 2.3 Sidebar shell — high top-level density
49
+
50
+ > **Resolved 2026-05-19.** All 11 sidebar files relocated into
51
+ > `components/sidebar/` (both `apps/web/` and `packages/ui/template/`):
52
+ >
53
+ > ```
54
+ > components/sidebar/
55
+ > ├── index.ts ← barrel re-export
56
+ > ├── app-sidebar.tsx
57
+ > ├── app-sidebar-dynamic.tsx
58
+ > ├── sidebar-shell.tsx
59
+ > ├── sidebar-auto-collapse.tsx
60
+ > ├── sidebar-auto-open.tsx
61
+ > ├── nav-main.tsx
62
+ > ├── nav-secondary.tsx
63
+ > ├── nav-documents.tsx
64
+ > ├── nav-user.tsx
65
+ > ├── secondary-nav.tsx
66
+ > └── secondary-panel.tsx
67
+ > ```
68
+ >
69
+ > **External consumers** now import via the barrel:
70
+ > `import { AppSidebar, SidebarShell, useSecondaryPanel } from "@/components/sidebar"`.
71
+ > Per-file paths still resolve (escape hatch), e.g.
72
+ > `@/components/sidebar/secondary-panel`.
73
+ >
74
+ > **Intra-folder** imports use relative paths (`./nav-user`, `./secondary-panel`)
75
+ > so internal restructure does not ripple out.
76
+ >
77
+ > Dead-import audit at completion: zero references to `@/components/<sidebar-file>"`
78
+ > remain outside the new folder.
79
+ >
80
+ > `nav-main`, `nav-secondary`, `nav-documents`, `sidebar-auto-open` are
81
+ > currently zero-import (only mentioned in docs/skills). They were moved for
82
+ > directory consistency; pruning truly dead files is a separate concern.
83
+
84
+ ### 2.4 Dedicated-search files — naming consistent
85
+
86
+ `dedicated-search-recents.tsx`, `dedicated-search-url-composer.tsx`,
87
+ `components/templates/dedicated-search-{landing,results}-template.tsx` —
88
+ generic family already lives across `templates/` + top-level. **No action.**
89
+
90
+ ### 2.5 Entity-bound views — correctly at top level
91
+
92
+ `*-list-view.tsx`, `*-board-view.tsx`, `*-page-header.tsx`, `*-client.tsx`,
93
+ `*-table.tsx`, `*-dashboard-charts*.tsx`, `*-os-folder-view.tsx`,
94
+ `*-panel-activator.tsx` — these are entity-specific compositions that
95
+ **must** stay co-located with the hub they serve. **No action.**
96
+
97
+ ### 2.6 Possibly generic — re-evaluate during reuse work
98
+
99
+ - `tinted-icon-disc.tsx` — used in KPI/empty states. If the API has stabilized,
100
+ consider moving to `components/data-views/` or `packages/ui/src/components/ui/`.
101
+ - `task-list-panel.tsx`, `task-priority-badge.tsx` — generic-sounding but
102
+ bound to a Task entity. Confirm scope before any move.
103
+ - `tree-panel-view.tsx`-style: `hub-tree-panel-view.tsx`,
104
+ `folder-details-shell.tsx` — already generic-sounding. If imported by
105
+ ≥ 2 hubs, move under `data-views/`.
106
+
107
+ A quick rule of thumb:
108
+
109
+ > If a component is imported by **only one** hub, it stays at the top level
110
+ > next to that hub.
111
+ > If it is (or could be) imported by **≥ 2** hubs, promote it into
112
+ > `components/data-views/` (record-bearing) or `components/templates/`
113
+ > (page chrome).
114
+
115
+ ### 2.7 `packages/ui/template/` parity
116
+
117
+ Most top-level files are mirrored under `packages/ui/template/components/`
118
+ (starter scaffold for `create-exxat-app`). When a file moves in
119
+ `apps/web/components/`, `pnpm --filter @exxatdesignux/ui sync-template`
120
+ will also move it under `template/`. **Always run `sync-template` after any
121
+ refactor under §2.3 / §2.6** so the published starter stays buildable.
122
+
123
+ ## 3. Non-findings — what's already healthy
124
+
125
+ - **`components/ui/`** is reserved for shadcn-aligned primitives; no
126
+ duplicates appear at the top level (e.g. no rogue `button.tsx` next to the
127
+ one in `ui/`).
128
+ - **`components/data-views/`** is the right home for generic record-bearing
129
+ surfaces (`FolderGridView`, `FinderPanelView`, `ListPageBoardCard`).
130
+ Entity-specific board cards (`placement-board-card.tsx`) correctly stay
131
+ at top level.
132
+ - **`components/templates/`** is the right home for page-level wrappers
133
+ (`ListPageTemplate`, `DedicatedSearch*Template`,
134
+ `SecondaryPanelHubTemplate`, `DiscoveryHubTemplate`). No drift.
135
+ - **No `components/lightning/`** folder anywhere — `exxat-no-slds-leakage`
136
+ rule already passes.
137
+ - **No second toast surface** — only `components/ui/sonner.tsx` exists, and
138
+ it's gated by `exxat-no-toast` + the new `exxat-ds/no-sonner-toast` lint.
139
+
140
+ ## 4. Suggested follow-up PRs
141
+
142
+ | # | Title | Scope | Risk |
143
+ |---|---|---|---|
144
+ | 1 | Remove dead `form-layout-01.tsx` + `section-cards.tsx` from `apps/web/` and `packages/ui/template/` | Trivial | Low |
145
+ | 2 | Consolidate `getting-started.tsx` + `dashboard-onboarding*.tsx` under `components/onboarding/` | Small | Low (import rename) |
146
+ | 3 | ~~Move sidebar files into `components/sidebar/`~~ — **done 2026-05-19** (§2.3) | Medium | — |
147
+ | 4 | Promote `tinted-icon-disc.tsx`, `hub-tree-panel-view.tsx`, `folder-details-shell.tsx` to `data-views/` if used by ≥ 2 hubs | Small per file | Low |
148
+ | 5 | Run `sync-template` after each of 1–4 to keep `packages/ui/template/` aligned | Single command | Low |
149
+
150
+ None of these is urgent. They become valuable when the top-level file count
151
+ exceeds ~110 or when a new hub joins the codebase.
152
+
153
+ ## 5. References
154
+
155
+ - [`apps/web/AGENTS.md`](../AGENTS.md) §9 — architecture pointers
156
+ - [`apps/web/docs/component-selection-guide.md`](./component-selection-guide.md)
157
+ - [`.cursor/rules/exxat-reuse-before-custom.mdc`](../../.cursor/rules/exxat-reuse-before-custom.mdc) — ask before adding new primitives
158
+ - [`.cursor/rules/exxat-list-page-view-shells.mdc`](../../.cursor/rules/exxat-list-page-view-shells.mdc) — when to extract to `data-views/`
@@ -10,17 +10,17 @@ This document describes how list pages combine **views**, **toolbar** behavior,
10
10
 
11
11
  | Need | Reuse | Where Placements uses it |
12
12
  | --- | --- | --- |
13
- | **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/data-list-client.tsx` + `components/templates/list-page.tsx` |
14
- | **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/data-list-table.tsx` |
15
- | **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `data-list-table.tsx` |
16
- | **Board / list** | `PlacementsBoardView`, `PlacementsListView` + same `useTableState` | `DataListTable` |
13
+ | **View tabs** (table / list / board, lifecycle filters) | `ListPageTemplate` (`ViewTab`, `renderContent`, optional metrics + export) | `components/placements-client.tsx` + `components/templates/list-page.tsx` |
14
+ | **Table shell** (search, filter bar, sort, grouping, columns, pagination) | `DataTable`, `DataTableToolbar`, `useTableState` | `components/data-table/`, `components/placements-table.tsx` |
15
+ | **Properties drawer** (display, columns, filters, sort, view type tiles) | `TablePropertiesDrawer` from `@/components/table-properties` | `DrawerToolbar` / list–board shells in `placements-table.tsx` |
16
+ | **Board / list** | `PlacementsBoardView`, `PlacementListRowContent` (wrapped by `HubTable.renderListRow` → `DataRowList`) + same `useTableState` | `PlacementsTable` |
17
17
  | **Page header** (primary CTA + More ⋯ + export) | `PlacementsPageHeader` or `TeamPageHeader` | `components/placements-page-header.tsx`, `components/team-page-header.tsx` |
18
- | **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `DataListClient`) | `components/team-client.tsx`, `lib/mock/team-kpi.ts` |
18
+ | **Team page (primary template)** | `TeamClient` = `ListPageTemplate` + `KeyMetrics` + `TeamPageHeader` + `TeamTable` (same composition as `PlacementsClient`) | `components/team-client.tsx`, `lib/mock/team-kpi.ts` |
19
19
  | **Team roster** | `TeamTable` — `DataTable` + `useTableState` + `TablePropertiesDrawer`; list/board/dashboard read **`tableState.rows`** | `components/team-table.tsx` |
20
20
  | **Dashboard view (list tab)** | **`KeyMetrics`** (`variant="flat"` or `"card"`) — same KPI system as the template metrics strip; **do not** add ad-hoc `Card` grids for entity summaries | `TeamTable` dashboard branch, `lib/mock/team-kpi.ts` |
21
21
  | **List hub metrics strip** | **`KeyMetrics variant="flat"`** — transparent cells, OKLCH brand glow only, border hairlines (**no** grey panel) | **`docs/kpi-flat-band-pattern.md`**, Placements / Team / Question bank clients |
22
22
  | **Secondary panel chrome** | **`--secondary-panel-bg`** on **`NestedSecondaryPanelShell`** (lighter than sidebar, follows active product) | **`docs/shell-surface-elevation-pattern.md`**, Question bank |
23
- | **Export** | `ExportDrawer` | `ListPageTemplate` export props; `DataListClient` |
23
+ | **Export** | `ExportDrawer` | `ListPageTemplate` export props; `PlacementsClient` |
24
24
  | **View body layout** (gutter + centered max-width for folder / icon / panel-style content) | **`ListPageViewFrame`** (`components/data-views/list-page-view-frame.tsx`, re-exported from `components/data-views`) | **`FolderGridView`** (uses the frame); **`QuestionBankOsFolderView`** — see **`AGENTS.md` §4.5** |
25
25
 
26
26
  **Rules:** (1) Import and compose these components; pass **props** and **column defs** for your entity. (2) If something is missing, **extend the shared component** under `components/` (e.g. a new optional slot on `DataTableToolbar`) rather than copying markup into a single page. (3) Card-only or lightweight pages may use a smaller **Properties** sheet only when there is **no** table—otherwise use `TablePropertiesDrawer` with `DataTable` (see Team).
@@ -29,7 +29,7 @@ This document describes how list pages combine **views**, **toolbar** behavior,
29
29
 
30
30
  If the page uses a **`DataTable`** (or equivalent data grid) as the main surface, it **must** sit under **`ListPageTemplate`** so users get the **views toolbar** (tabs, add view, per-tab settings). The default `ViewTab` entries should include at least one tab whose `viewType` is **`table`** when the primary experience is tabular data. **Do not** render a `DataTable` alone under only `PageHeader` + body.
31
31
 
32
- - **Reference:** `DataListClient` (Placements) and `TeamClient` (Team).
32
+ - **Reference:** `PlacementsClient` (Placements) and `TeamClient` (Team).
33
33
  - **Rationale:** Consistent navigation, saved views, per-tab view type (table / list / board), and export at the template level.
34
34
 
35
35
  ## View layout frame (centered, reusable)
@@ -41,7 +41,7 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
41
41
  ## Architecture
42
42
 
43
43
  - **Page shell** — `ListPageTemplate` owns the views toolbar (tabs), optional metrics, and export drawer. Content for the active tab is rendered via `renderContent`.
44
- - **Per–lifecycle (or category) data** — `DataListTable` swaps **columns** and **row sets** based on `lifecycleTabId` (e.g. All / Upcoming / Ongoing / Completed). Each lifecycle tab gets its **own** `DataListTable` instance (`key={tab.filterId}`) so `useTableState` resets correctly when columns change.
44
+ - **Per–lifecycle (or category) data** — `PlacementsTable` swaps **columns** and **row sets** based on `lifecycleTabId` (e.g. All / Upcoming / Ongoing / Completed). Each lifecycle tab gets its **own** `PlacementsTable` instance (`key={tab.filterId}`) so `useTableState` resets correctly when columns change.
45
45
  - **Shared table state** — `useTableState` holds sort, search, filters, grouping, column order/visibility/pins/widths, row height, gridlines, and pagination flags. **Table**, **list**, **board**, and **dashboard** all read the same state so switching view type keeps behavior aligned.
46
46
 
47
47
  ## Mock data and connected views
@@ -59,10 +59,10 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
59
59
 
60
60
  | Concern | Table | List | Board | Dashboard (view tab) |
61
61
  | --- | --- | --- | --- | --- |
62
- | Primary surface | `DataTable` | `PlacementsListView` / entity list | `PlacementsBoardView` / entity board | **`KeyMetrics`** (+ optional charts via shared dashboard components) |
62
+ | Primary surface | `DataTable` | `DataRowList` + entity row body (e.g. `PlacementListRowContent`) wired via `HubTable.renderListRow` | `PlacementsBoardView` / entity board | **`KeyMetrics`** (+ optional charts via shared dashboard components) |
63
63
  | Data source | `useTableState` | **`tableState.rows`** | **`tableState.rows`** | **`tableState.rows`** via KPI helpers |
64
64
  | Column headers / labels | `showColumnLabels` | Same source columns, list layout | Phase columns + optional board column menu | N/A (metrics from same columns/filters) |
65
- | Row click / navigation | From `DataListTable` | From list shell | Card `onOpen` | N/A |
65
+ | Row click / navigation | From `PlacementsTable` | From list shell | Card `onOpen` | N/A |
66
66
  | Pagination | Optional `PaginationBar` + `CountSyncer` | Same pattern | N/A (board uses phase columns) | N/A |
67
67
 
68
68
  ## Toolbar and properties
@@ -99,10 +99,10 @@ Non-table view branches (e.g. **folder** icon grid, **panel** finder, OS-style f
99
99
 
100
100
  ## Persistence
101
101
 
102
- - **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `DataListClient` with `useLayoutEffect`, saved debounced on change. `ListPageTemplate` runs in **controlled** mode when `tabs` / `onTabsChange` / `activeTabId` / `onActiveTabChange` are passed.
103
- - **Per–lifecycle tab** (key `exxat-ds:data-list:lifecycle:v1:<filterId>`): sort, search, filters, group by, column order/hidden/widths/pins/wrap, column menu search map, row height, gridlines, filter bar visibility, search popover, conditional rules, pagination toggle and page/size. Hydrated in `DataListTable` with `useLayoutEffect`; saved debounced when those fields change.
102
+ - **Page-level** (`lib/data-list-persistence.ts`, key `exxat-ds:data-list:page:v1`): `displayOptions`, `showMetrics`, `tabs`, `activeTabId`. Loaded in `PlacementsClient` with `useLayoutEffect`, saved debounced on change. `ListPageTemplate` runs in **controlled** mode when `tabs` / `onTabsChange` / `activeTabId` / `onActiveTabChange` are passed.
103
+ - **Per–lifecycle tab** (key `exxat-ds:data-list:lifecycle:v1:<filterId>`): sort, search, filters, group by, column order/hidden/widths/pins/wrap, column menu search map, row height, gridlines, filter bar visibility, search popover, conditional rules, pagination toggle and page/size. Hydrated in `PlacementsTable` with `useLayoutEffect`; saved debounced when those fields change.
104
104
 
105
- To add a new page: copy the `DataListClient` pattern (controlled `ListPageTemplate` + storage key namespace) or call `schedulePageSave` / `scheduleLifecycleSave` with your own keys.
105
+ To add a new page: copy the `PlacementsClient` pattern (controlled `ListPageTemplate` + storage key namespace) or call `schedulePageSave` / `scheduleLifecycleSave` with your own keys.
106
106
 
107
107
  ## Rules of thumb
108
108
 
@@ -158,7 +158,7 @@ Canonical rules: **`AGENTS.md` §6.4**, root **`.cursor/rules/exxat-page-vs-draw
158
158
 
159
159
  When a route is a **primary** destination in nav (main hub for an entity) **and** the dataset is **large** or **highly interactive**:
160
160
 
161
- - Use the **primary page template**: `ListPageTemplate` (tabs, metrics strip, export drawer at template level) + data client pattern as in **`DataListClient`** / **`DataListTable`** — not a minimal `PageHeader`-only layout.
161
+ - Use the **primary page template**: `ListPageTemplate` (tabs, metrics strip, export drawer at template level) + data client pattern as in **`PlacementsClient`** / **`PlacementsTable`** — not a minimal `PageHeader`-only layout.
162
162
  - Smaller satellite pages may use **`PageHeader` + section content**; once the dataset grows past the dense-list threshold, add the toolbar rules above and consider promoting to the full template if the page becomes a main hub.
163
163
 
164
164
  ---
@@ -0,0 +1,95 @@
1
+ # Migration 0001 — `brand-deep` alias stabilization
2
+
3
+ > **Released in:** v0.2.18 · **Removed in:** — (no removal — alias is now official) · **Owner:** Exxat DS core
4
+ > **Type:** stabilization (clarifies an existing naming convention)
5
+
6
+ ## Why
7
+
8
+ `bg-brand-deep` / `text-brand-deep` Tailwind utilities are used throughout
9
+ `CoachMark` and several skill docs, but the **only** declared primitive is
10
+ `--brand-color-deep`. The bridge `--color-brand-deep: var(--brand-color-deep)`
11
+ in `theme.css @theme inline` made the utilities work — but contributors kept
12
+ asking "is `--brand-deep` a real token or a typo of `--brand-color-deep`?".
13
+
14
+ This migration **does not rename anything**. It documents the alias as
15
+ **official** and codifies the rule for similar future cases:
16
+
17
+ > A Tailwind utility may use a **short, semantic alias** at the L2 bridge,
18
+ > distinct from the L1 primitive name, **only when the alias prevents an
19
+ > awkward utility class** (e.g. `bg-brand-color-deep` is unwieldy; `bg-brand-deep`
20
+ > reads naturally). The alias MUST be listed in `docs/token-taxonomy.md` and
21
+ > in the generated `hooks-index.json`.
22
+
23
+ Without this migration entry, future contributors might "fix" `bg-brand-deep`
24
+ by renaming it to `bg-brand-color-deep`, breaking every coach mark.
25
+
26
+ ## Affected surface
27
+
28
+ | Surface | Was | Becomes |
29
+ |---|---|---|
30
+ | Tailwind utility | `bg-brand-deep`, `text-brand-deep` | **unchanged** (stabilized) |
31
+ | CSS custom prop (L2 bridge) | `--color-brand-deep` | **unchanged** (stabilized as alias) |
32
+ | CSS custom prop (L1 primitive) | `--brand-color-deep` | **unchanged** (canonical name) |
33
+ | Doc | _undocumented alias_ | Documented in `docs/token-taxonomy.md` §2.2 |
34
+
35
+ ## Before
36
+
37
+ ```css
38
+ /* packages/ui/src/theme.css */
39
+ @theme inline {
40
+ --color-brand-deep: var(--brand-color-deep); /* alias — was undocumented */
41
+ }
42
+
43
+ :root {
44
+ --brand-color-deep: oklch(0.28 0.085 286.1); /* L1 primitive */
45
+ }
46
+ ```
47
+
48
+ ```tsx
49
+ // packages/ui/src/components/ui/coach-mark.tsx — already correct
50
+ <div className="bg-brand-deep text-white">…</div>
51
+ ```
52
+
53
+ The risk was that someone would "tidy up" `--color-brand-deep` to
54
+ `--color-brand-color-deep`, breaking `bg-brand-deep`.
55
+
56
+ ## After
57
+
58
+ Same code; same tokens; **plus** an authoritative entry in
59
+ [`docs/token-taxonomy.md`](../token-taxonomy.md) §2.2 listing every L1 → L2
60
+ short-alias pair, and a regenerated [`packages/ui/tokens/hooks-index.json`](../../../packages/ui/tokens/hooks-index.json)
61
+ that exposes `--brand-color-deep` with `tailwindUtilities:
62
+ ["bg-brand-deep", "text-brand-deep", …]` so tooling can discover the link.
63
+
64
+ ## Migration recipe
65
+
66
+ ### Automatic
67
+
68
+ None needed — this migration changes documentation only.
69
+
70
+ ### Manual
71
+
72
+ For **future** short-alias additions, follow this pattern:
73
+
74
+ 1. Declare the L1 primitive: `--brand-<name>: oklch(...)` in `:root` and any
75
+ theme overrides in `.dark` / `.theme-prism` / etc.
76
+ 2. Declare the L2 alias in `@theme inline`: `--color-<short>: var(--brand-<name>)`.
77
+ 3. Add a row to `docs/token-taxonomy.md` §2.2 listing the alias.
78
+ 4. Run `pnpm --filter @exxatdesignux/ui tokens:index` and commit.
79
+ 5. Use the alias **only** for the case where the long name is awkward; do
80
+ **not** create aliases for ergonomics alone.
81
+
82
+ ## Verification
83
+
84
+ - [x] `pnpm --filter @exxatdesignux/ui tokens:index` runs and emits the alias
85
+ under `tailwindUtilities` for `--brand-color-deep`.
86
+ - [x] `docs/token-taxonomy.md` §2.2 lists `--brand-color-deep` and its alias.
87
+ - [x] `coach-mark.tsx` continues to render the deep-brand background.
88
+
89
+ ## References
90
+
91
+ - `packages/ui/src/theme.css` — lines declaring `--brand-color-deep` and the alias
92
+ - `packages/ui/src/components/ui/coach-mark.tsx`
93
+ - `apps/web/docs/token-taxonomy.md` §2.2 (Brand)
94
+ - `apps/web/docs/blueprints/page-header.md` (uses `--brand-color-*` family)
95
+ - `.cursor/rules/exxat-token-discipline.mdc` (codifies the alias rule)