@exxatdesignux/ui 0.2.19 → 0.4.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 (716) hide show
  1. package/CHANGELOG.md +662 -7
  2. package/bin/sync-extras.mjs +116 -29
  3. package/consumer-extras/README.md +42 -7
  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 +43 -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-library-hub-header.mdc +28 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  23. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  24. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  25. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  26. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  27. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  28. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  29. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -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 +3 -3
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +5 -16
  36. package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
  37. package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
  38. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +19 -34
  39. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  40. package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
  41. package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
  42. package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
  43. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +10 -12
  44. package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
  45. package/consumer-extras/handbook/HANDBOOK.md +187 -0
  46. package/consumer-extras/handbook/glossary.md +58 -0
  47. package/consumer-extras/handbook/reference-implementations.md +153 -0
  48. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  49. package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
  50. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  51. package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
  52. package/consumer-extras/patterns/data-views-pattern.md +31 -66
  53. package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
  54. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
  55. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  56. package/dist/components/data-table/filter-date-calendar.js +280 -0
  57. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  58. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  59. package/dist/components/data-table/filter-text-value-input.js +561 -0
  60. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  61. package/dist/components/data-table/index.d.ts +45 -0
  62. package/dist/components/data-table/index.js +3085 -0
  63. package/dist/components/data-table/index.js.map +1 -0
  64. package/dist/components/data-table/pagination.d.ts +28 -0
  65. package/dist/components/data-table/pagination.js +3264 -0
  66. package/dist/components/data-table/pagination.js.map +1 -0
  67. package/dist/components/data-table/types.d.ts +84 -0
  68. package/dist/components/data-table/types.js +3 -0
  69. package/dist/components/data-table/types.js.map +1 -0
  70. package/dist/components/data-table/use-table-state.d.ts +116 -0
  71. package/dist/components/data-table/use-table-state.js +670 -0
  72. package/dist/components/data-table/use-table-state.js.map +1 -0
  73. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  74. package/dist/components/data-views/board-card-primitives.js +84 -0
  75. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  76. package/dist/components/data-views/data-row-list.d.ts +33 -0
  77. package/dist/components/data-views/data-row-list.js +106 -0
  78. package/dist/components/data-views/data-row-list.js.map +1 -0
  79. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  80. package/dist/components/data-views/finder-panel-view.js +388 -0
  81. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  82. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  83. package/dist/components/data-views/folder-grid-view.js +58 -0
  84. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  85. package/dist/components/data-views/hub-table.d.ts +173 -0
  86. package/dist/components/data-views/hub-table.js +5783 -0
  87. package/dist/components/data-views/hub-table.js.map +1 -0
  88. package/dist/components/data-views/index.d.ts +27 -0
  89. package/dist/components/data-views/index.js +6797 -0
  90. package/dist/components/data-views/index.js.map +1 -0
  91. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  92. package/dist/components/data-views/list-page-board-card.js +264 -0
  93. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  94. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  95. package/dist/components/data-views/list-page-board-template.js +137 -0
  96. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  97. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  98. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  99. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  100. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  101. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  102. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  103. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  104. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  105. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  106. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  107. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  108. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  109. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  110. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  111. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  112. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  113. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  114. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  115. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  116. package/dist/components/data-views/os-folder-glyph.js +104 -0
  117. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  118. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  119. package/dist/components/data-views/outline-tree-menu.js +131 -0
  120. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  121. package/dist/components/table-properties/column-row.d.ts +22 -0
  122. package/dist/components/table-properties/column-row.js +153 -0
  123. package/dist/components/table-properties/column-row.js.map +1 -0
  124. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  125. package/dist/components/table-properties/draggable-list.js +53 -0
  126. package/dist/components/table-properties/draggable-list.js.map +1 -0
  127. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  128. package/dist/components/table-properties/drawer-button.js +2748 -0
  129. package/dist/components/table-properties/drawer-button.js.map +1 -0
  130. package/dist/components/table-properties/drawer.d.ts +100 -0
  131. package/dist/components/table-properties/drawer.js +2595 -0
  132. package/dist/components/table-properties/drawer.js.map +1 -0
  133. package/dist/components/table-properties/filter-card.d.ts +24 -0
  134. package/dist/components/table-properties/filter-card.js +854 -0
  135. package/dist/components/table-properties/filter-card.js.map +1 -0
  136. package/dist/components/table-properties/index.d.ts +14 -0
  137. package/dist/components/table-properties/index.js +2768 -0
  138. package/dist/components/table-properties/index.js.map +1 -0
  139. package/dist/components/table-properties/sort-card.d.ts +20 -0
  140. package/dist/components/table-properties/sort-card.js +102 -0
  141. package/dist/components/table-properties/sort-card.js.map +1 -0
  142. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  143. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  144. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  145. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  146. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  147. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  148. package/dist/components/templates/index.d.ts +9 -0
  149. package/dist/components/templates/index.js +2720 -0
  150. package/dist/components/templates/index.js.map +1 -0
  151. package/dist/components/templates/list-page.d.ts +83 -0
  152. package/dist/components/templates/list-page.js +2433 -0
  153. package/dist/components/templates/list-page.js.map +1 -0
  154. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  155. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  156. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  157. package/dist/components/ui/accordion.d.ts +10 -0
  158. package/dist/components/ui/accordion.js +74 -0
  159. package/dist/components/ui/accordion.js.map +1 -0
  160. package/dist/components/ui/alert-dialog.d.ts +37 -0
  161. package/dist/components/ui/alert-dialog.js +201 -0
  162. package/dist/components/ui/alert-dialog.js.map +1 -0
  163. package/dist/components/ui/avatar.d.ts +84 -0
  164. package/dist/components/ui/avatar.js +328 -0
  165. package/dist/components/ui/avatar.js.map +1 -0
  166. package/dist/components/ui/badge.d.ts +13 -0
  167. package/dist/components/ui/badge.js +49 -0
  168. package/dist/components/ui/badge.js.map +1 -0
  169. package/dist/components/ui/banner.d.ts +62 -0
  170. package/dist/components/ui/banner.js +364 -0
  171. package/dist/components/ui/banner.js.map +1 -0
  172. package/dist/components/ui/breadcrumb.d.ts +14 -0
  173. package/dist/components/ui/breadcrumb.js +114 -0
  174. package/dist/components/ui/breadcrumb.js.map +1 -0
  175. package/dist/components/ui/button.d.ts +16 -0
  176. package/dist/components/ui/button.js +59 -0
  177. package/dist/components/ui/button.js.map +1 -0
  178. package/dist/components/ui/calendar.d.ts +13 -0
  179. package/dist/components/ui/calendar.js +238 -0
  180. package/dist/components/ui/calendar.js.map +1 -0
  181. package/dist/components/ui/card.d.ts +14 -0
  182. package/dist/components/ui/card.js +102 -0
  183. package/dist/components/ui/card.js.map +1 -0
  184. package/dist/components/ui/chart.d.ts +58 -0
  185. package/dist/components/ui/chart.js +292 -0
  186. package/dist/components/ui/chart.js.map +1 -0
  187. package/dist/components/ui/checkbox.d.ts +23 -0
  188. package/dist/components/ui/checkbox.js +155 -0
  189. package/dist/components/ui/checkbox.js.map +1 -0
  190. package/dist/components/ui/coach-mark.d.ts +27 -0
  191. package/dist/components/ui/coach-mark.js +306 -0
  192. package/dist/components/ui/coach-mark.js.map +1 -0
  193. package/dist/components/ui/collapsible.d.ts +8 -0
  194. package/dist/components/ui/collapsible.js +35 -0
  195. package/dist/components/ui/collapsible.js.map +1 -0
  196. package/dist/components/ui/command.d.ts +36 -0
  197. package/dist/components/ui/command.js +274 -0
  198. package/dist/components/ui/command.js.map +1 -0
  199. package/dist/components/ui/context-menu.d.ts +32 -0
  200. package/dist/components/ui/context-menu.js +245 -0
  201. package/dist/components/ui/context-menu.js.map +1 -0
  202. package/dist/components/ui/date-picker-field.d.ts +38 -0
  203. package/dist/components/ui/date-picker-field.js +550 -0
  204. package/dist/components/ui/date-picker-field.js.map +1 -0
  205. package/dist/components/ui/dialog.d.ts +22 -0
  206. package/dist/components/ui/dialog.js +200 -0
  207. package/dist/components/ui/dialog.js.map +1 -0
  208. package/dist/components/ui/dot-pattern.d.ts +21 -0
  209. package/dist/components/ui/dot-pattern.js +139 -0
  210. package/dist/components/ui/dot-pattern.js.map +1 -0
  211. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  212. package/dist/components/ui/drag-handle-grip.js +15 -0
  213. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  214. package/dist/components/ui/drawer.d.ts +16 -0
  215. package/dist/components/ui/drawer.js +125 -0
  216. package/dist/components/ui/drawer.js.map +1 -0
  217. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  218. package/dist/components/ui/dropdown-menu.js +353 -0
  219. package/dist/components/ui/dropdown-menu.js.map +1 -0
  220. package/dist/components/ui/export-drawer.d.ts +11 -0
  221. package/dist/components/ui/export-drawer.js +1658 -0
  222. package/dist/components/ui/export-drawer.js.map +1 -0
  223. package/dist/components/ui/field.d.ts +30 -0
  224. package/dist/components/ui/field.js +249 -0
  225. package/dist/components/ui/field.js.map +1 -0
  226. package/dist/components/ui/form.d.ts +28 -0
  227. package/dist/components/ui/form.js +110 -0
  228. package/dist/components/ui/form.js.map +1 -0
  229. package/dist/components/ui/hover-card.d.ts +9 -0
  230. package/dist/components/ui/hover-card.js +43 -0
  231. package/dist/components/ui/hover-card.js.map +1 -0
  232. package/dist/components/ui/input-group.d.ts +20 -0
  233. package/dist/components/ui/input-group.js +219 -0
  234. package/dist/components/ui/input-group.js.map +1 -0
  235. package/dist/components/ui/input-mask.d.ts +39 -0
  236. package/dist/components/ui/input-mask.js +118 -0
  237. package/dist/components/ui/input-mask.js.map +1 -0
  238. package/dist/components/ui/input.d.ts +5 -0
  239. package/dist/components/ui/input.js +30 -0
  240. package/dist/components/ui/input.js.map +1 -0
  241. package/dist/components/ui/kbd.d.ts +20 -0
  242. package/dist/components/ui/kbd.js +45 -0
  243. package/dist/components/ui/kbd.js.map +1 -0
  244. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  245. package/dist/components/ui/key-metrics-context.js +26 -0
  246. package/dist/components/ui/key-metrics-context.js.map +1 -0
  247. package/dist/components/ui/key-metrics.d.ts +131 -0
  248. package/dist/components/ui/key-metrics.js +1015 -0
  249. package/dist/components/ui/key-metrics.js.map +1 -0
  250. package/dist/components/ui/label.d.ts +6 -0
  251. package/dist/components/ui/label.js +28 -0
  252. package/dist/components/ui/label.js.map +1 -0
  253. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  254. package/dist/components/ui/list-page-view-frame.js +24 -0
  255. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  256. package/dist/components/ui/page-header.d.ts +51 -0
  257. package/dist/components/ui/page-header.js +372 -0
  258. package/dist/components/ui/page-header.js.map +1 -0
  259. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  260. package/dist/components/ui/payment-card-fields.js +80 -0
  261. package/dist/components/ui/payment-card-fields.js.map +1 -0
  262. package/dist/components/ui/popover.d.ts +10 -0
  263. package/dist/components/ui/popover.js +47 -0
  264. package/dist/components/ui/popover.js.map +1 -0
  265. package/dist/components/ui/radio-group.d.ts +29 -0
  266. package/dist/components/ui/radio-group.js +190 -0
  267. package/dist/components/ui/radio-group.js.map +1 -0
  268. package/dist/components/ui/resizable.d.ts +16 -0
  269. package/dist/components/ui/resizable.js +51 -0
  270. package/dist/components/ui/resizable.js.map +1 -0
  271. package/dist/components/ui/scroll-area.d.ts +8 -0
  272. package/dist/components/ui/scroll-area.js +66 -0
  273. package/dist/components/ui/scroll-area.js.map +1 -0
  274. package/dist/components/ui/select.d.ts +18 -0
  275. package/dist/components/ui/select.js +186 -0
  276. package/dist/components/ui/select.js.map +1 -0
  277. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  278. package/dist/components/ui/selection-tile-grid.js +347 -0
  279. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  280. package/dist/components/ui/separator.d.ts +7 -0
  281. package/dist/components/ui/separator.js +33 -0
  282. package/dist/components/ui/separator.js.map +1 -0
  283. package/dist/components/ui/sheet.d.ts +18 -0
  284. package/dist/components/ui/sheet.js +181 -0
  285. package/dist/components/ui/sheet.js.map +1 -0
  286. package/dist/components/ui/sidebar.d.ts +94 -0
  287. package/dist/components/ui/sidebar.js +805 -0
  288. package/dist/components/ui/sidebar.js.map +1 -0
  289. package/dist/components/ui/skeleton.d.ts +5 -0
  290. package/dist/components/ui/skeleton.js +22 -0
  291. package/dist/components/ui/skeleton.js.map +1 -0
  292. package/dist/components/ui/slider.d.ts +7 -0
  293. package/dist/components/ui/slider.js +66 -0
  294. package/dist/components/ui/slider.js.map +1 -0
  295. package/dist/components/ui/sonner.d.ts +6 -0
  296. package/dist/components/ui/sonner.js +38 -0
  297. package/dist/components/ui/sonner.js.map +1 -0
  298. package/dist/components/ui/status-badge.d.ts +38 -0
  299. package/dist/components/ui/status-badge.js +77 -0
  300. package/dist/components/ui/status-badge.js.map +1 -0
  301. package/dist/components/ui/table.d.ts +13 -0
  302. package/dist/components/ui/table.js +115 -0
  303. package/dist/components/ui/table.js.map +1 -0
  304. package/dist/components/ui/tabs.d.ts +15 -0
  305. package/dist/components/ui/tabs.js +93 -0
  306. package/dist/components/ui/tabs.js.map +1 -0
  307. package/dist/components/ui/textarea.d.ts +6 -0
  308. package/dist/components/ui/textarea.js +25 -0
  309. package/dist/components/ui/textarea.js.map +1 -0
  310. package/dist/components/ui/tip.d.ts +12 -0
  311. package/dist/components/ui/tip.js +61 -0
  312. package/dist/components/ui/tip.js.map +1 -0
  313. package/dist/components/ui/toggle-group.d.ts +14 -0
  314. package/dist/components/ui/toggle-group.js +104 -0
  315. package/dist/components/ui/toggle-group.js.map +1 -0
  316. package/dist/components/ui/toggle-switch.d.ts +10 -0
  317. package/dist/components/ui/toggle-switch.js +33 -0
  318. package/dist/components/ui/toggle-switch.js.map +1 -0
  319. package/dist/components/ui/toggle.d.ts +13 -0
  320. package/dist/components/ui/toggle.js +51 -0
  321. package/dist/components/ui/toggle.js.map +1 -0
  322. package/dist/components/ui/tooltip.d.ts +10 -0
  323. package/dist/components/ui/tooltip.js +68 -0
  324. package/dist/components/ui/tooltip.js.map +1 -0
  325. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  326. package/dist/components/ui/view-segmented-control.js +167 -0
  327. package/dist/components/ui/view-segmented-control.js.map +1 -0
  328. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  329. package/dist/hooks/use-app-theme.d.ts +24 -0
  330. package/dist/hooks/use-app-theme.js +286 -0
  331. package/dist/hooks/use-app-theme.js.map +1 -0
  332. package/dist/hooks/use-coach-mark.d.ts +86 -0
  333. package/dist/hooks/use-coach-mark.js +218 -0
  334. package/dist/hooks/use-coach-mark.js.map +1 -0
  335. package/dist/hooks/use-mobile.d.ts +3 -0
  336. package/dist/hooks/use-mobile.js +29 -0
  337. package/dist/hooks/use-mobile.js.map +1 -0
  338. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  339. package/dist/hooks/use-mod-key-label.js +25 -0
  340. package/dist/hooks/use-mod-key-label.js.map +1 -0
  341. package/dist/index.d.ts +120 -0
  342. package/dist/index.js +13421 -0
  343. package/dist/index.js.map +1 -0
  344. package/dist/lib/compose-refs.d.ts +6 -0
  345. package/dist/lib/compose-refs.js +17 -0
  346. package/dist/lib/compose-refs.js.map +1 -0
  347. package/dist/lib/conditional-rule-match.d.ts +30 -0
  348. package/dist/lib/conditional-rule-match.js +66 -0
  349. package/dist/lib/conditional-rule-match.js.map +1 -0
  350. package/dist/lib/data-list-display-options.d.ts +26 -0
  351. package/dist/lib/data-list-display-options.js +14 -0
  352. package/dist/lib/data-list-display-options.js.map +1 -0
  353. package/dist/lib/data-list-view-registry.d.ts +2 -0
  354. package/dist/lib/data-list-view-registry.js +102 -0
  355. package/dist/lib/data-list-view-registry.js.map +1 -0
  356. package/dist/lib/data-list-view-surface.d.ts +2 -0
  357. package/dist/lib/data-list-view-surface.js +80 -0
  358. package/dist/lib/data-list-view-surface.js.map +1 -0
  359. package/dist/lib/data-list-view.d.ts +21 -0
  360. package/dist/lib/data-list-view.js +25 -0
  361. package/dist/lib/data-list-view.js.map +1 -0
  362. package/dist/lib/date-filter.d.ts +22 -0
  363. package/dist/lib/date-filter.js +61 -0
  364. package/dist/lib/date-filter.js.map +1 -0
  365. package/dist/lib/dev-log.d.ts +8 -0
  366. package/dist/lib/dev-log.js +10 -0
  367. package/dist/lib/dev-log.js.map +1 -0
  368. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  369. package/dist/lib/dropdown-menu-surface.js +6 -0
  370. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  371. package/dist/lib/editable-target.d.ts +12 -0
  372. package/dist/lib/editable-target.js +12 -0
  373. package/dist/lib/editable-target.js.map +1 -0
  374. package/dist/lib/list-page-table-properties.d.ts +35 -0
  375. package/dist/lib/list-page-table-properties.js +81 -0
  376. package/dist/lib/list-page-table-properties.js.map +1 -0
  377. package/dist/lib/raf-throttle.d.ts +23 -0
  378. package/dist/lib/raf-throttle.js +27 -0
  379. package/dist/lib/raf-throttle.js.map +1 -0
  380. package/dist/lib/row-height.d.ts +16 -0
  381. package/dist/lib/row-height.js +10 -0
  382. package/dist/lib/row-height.js.map +1 -0
  383. package/dist/lib/table-properties-types.d.ts +83 -0
  384. package/dist/lib/table-properties-types.js +19 -0
  385. package/dist/lib/table-properties-types.js.map +1 -0
  386. package/dist/lib/utils.d.ts +5 -0
  387. package/dist/lib/utils.js +11 -0
  388. package/dist/lib/utils.js.map +1 -0
  389. package/package.json +83 -19
  390. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  391. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  392. package/src/components/data-table/index.tsx +1678 -0
  393. package/src/components/data-table/pagination.tsx +259 -0
  394. package/src/components/data-table/types.ts +96 -0
  395. package/src/components/data-table/use-table-state.ts +767 -0
  396. package/src/components/data-views/board-card-primitives.tsx +93 -0
  397. package/src/components/data-views/data-row-list.tsx +183 -0
  398. package/src/components/data-views/finder-panel-view.tsx +405 -0
  399. package/src/components/data-views/folder-grid-view.tsx +86 -0
  400. package/src/components/data-views/hub-table.tsx +606 -0
  401. package/src/components/data-views/index.ts +28 -0
  402. package/src/components/data-views/list-page-board-card.tsx +192 -0
  403. package/src/components/data-views/list-page-board-template.tsx +122 -0
  404. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  405. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  406. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  407. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  408. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  409. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  410. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  411. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  412. package/src/components/table-properties/column-row.tsx +90 -0
  413. package/src/components/table-properties/draggable-list.ts +54 -0
  414. package/src/components/table-properties/drawer-button.tsx +300 -0
  415. package/src/components/table-properties/drawer.tsx +1148 -0
  416. package/src/components/table-properties/filter-card.tsx +251 -0
  417. package/src/components/table-properties/index.ts +36 -0
  418. package/src/components/table-properties/sort-card.tsx +63 -0
  419. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  420. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  421. package/src/components/templates/index.ts +33 -0
  422. package/src/components/templates/list-page.tsx +602 -0
  423. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  424. package/src/components/ui/accordion.tsx +92 -0
  425. package/src/components/ui/alert-dialog.tsx +221 -0
  426. package/src/components/ui/avatar.tsx +13 -2
  427. package/src/components/ui/banner.tsx +2 -2
  428. package/src/components/ui/button.tsx +4 -4
  429. package/src/components/ui/calendar.tsx +1 -1
  430. package/src/components/ui/coach-mark.tsx +1 -1
  431. package/src/components/ui/context-menu.tsx +291 -0
  432. package/src/components/ui/date-picker-field.tsx +2 -2
  433. package/src/components/ui/dot-pattern.tsx +183 -0
  434. package/src/components/ui/export-drawer.tsx +375 -0
  435. package/src/components/ui/hover-card.tsx +66 -0
  436. package/src/components/ui/key-metrics-context.tsx +78 -0
  437. package/src/components/ui/key-metrics.tsx +1133 -0
  438. package/src/components/ui/list-page-view-frame.tsx +64 -0
  439. package/src/components/ui/page-header.tsx +244 -0
  440. package/src/components/ui/payment-card-fields.tsx +2 -2
  441. package/src/components/ui/resizable.tsx +68 -0
  442. package/src/components/ui/scroll-area.tsx +72 -0
  443. package/src/components/ui/selection-tile-grid.tsx +9 -2
  444. package/src/components/ui/sidebar.tsx +84 -12
  445. package/src/components/ui/slider.tsx +83 -0
  446. package/src/globals.css +2201 -7
  447. package/src/globals.d.ts +20 -0
  448. package/src/index.ts +68 -1
  449. package/src/lib/conditional-rule-match.ts +119 -0
  450. package/src/lib/data-list-display-options.ts +35 -0
  451. package/src/lib/data-list-view-registry.ts +104 -0
  452. package/src/lib/data-list-view-surface.ts +83 -0
  453. package/src/lib/data-list-view.ts +47 -0
  454. package/src/lib/dev-log.ts +10 -0
  455. package/src/lib/editable-target.ts +20 -0
  456. package/src/lib/list-page-table-properties.ts +48 -0
  457. package/src/lib/raf-throttle.ts +45 -0
  458. package/src/lib/row-height.ts +19 -0
  459. package/src/lib/table-properties-types.ts +98 -0
  460. package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
  461. package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
  462. package/template/.cursor/rules/exxat-command-menu.mdc +2 -2
  463. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +7 -7
  464. package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
  465. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  466. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +7 -7
  467. package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
  468. package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
  469. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  470. package/template/AGENTS.md +135 -103
  471. package/template/app/(app)/columns/page.tsx +11 -0
  472. package/template/app/(app)/dashboard/loading.tsx +15 -3
  473. package/template/app/(app)/dashboard/page.tsx +14 -2
  474. package/template/app/(app)/layout.tsx +17 -4
  475. package/template/app/(app)/library/all/page.tsx +11 -0
  476. package/template/app/(app)/library/find/page.tsx +12 -0
  477. package/template/app/(app)/{question-bank → library}/layout.tsx +17 -17
  478. package/template/app/(app)/library/list/page.tsx +12 -0
  479. package/template/app/(app)/library/new/page.tsx +45 -0
  480. package/template/app/(app)/library/page.tsx +11 -0
  481. package/template/app/(app)/loading.tsx +18 -1
  482. package/template/app/(app)/settings/page.tsx +5 -4
  483. package/template/app/(app)/tokens-themes/page.tsx +11 -0
  484. package/template/app/globals.css +14 -16
  485. package/template/components/ask-leo-composer.tsx +2 -2
  486. package/template/components/ask-leo-sidebar.tsx +5 -1
  487. package/template/components/brand-color-picker.tsx +2 -2
  488. package/template/components/charts-overview.tsx +1 -1
  489. package/template/components/columns-client.tsx +158 -0
  490. package/template/components/columns-showcase.tsx +541 -0
  491. package/template/components/dashboard-report-charts.tsx +1 -1
  492. package/template/components/dashboard-tabs.tsx +1 -1
  493. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  494. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  495. package/template/components/data-table/index.tsx +1 -1634
  496. package/template/components/data-table/pagination.tsx +1 -255
  497. package/template/components/data-table/types.ts +1 -94
  498. package/template/components/data-table/use-table-state.test.ts +420 -0
  499. package/template/components/data-table/use-table-state.ts +1 -758
  500. package/template/components/data-views/board-card-primitives.tsx +1 -93
  501. package/template/components/data-views/data-row-list.tsx +1 -183
  502. package/template/components/data-views/finder-panel-view.tsx +1 -405
  503. package/template/components/data-views/folder-grid-view.tsx +1 -86
  504. package/template/components/data-views/hub-table.tsx +1 -0
  505. package/template/components/data-views/index.ts +77 -38
  506. package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
  507. package/template/components/data-views/list-page-board-card.tsx +1 -192
  508. package/template/components/data-views/list-page-board-template.tsx +1 -122
  509. package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
  510. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  511. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
  512. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  513. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  514. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  515. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  516. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  517. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  518. package/template/components/data-views/table-cells.tsx +673 -0
  519. package/template/components/export-drawer.test.tsx +71 -0
  520. package/template/components/export-drawer.tsx +1 -375
  521. package/template/components/exxat-product-logo.tsx +5 -5
  522. package/template/components/folder-details-shell.tsx +11 -11
  523. package/template/components/hub-tree-panel-view.tsx +26 -26
  524. package/template/components/invite-collaborators-drawer.tsx +3 -3
  525. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  526. package/template/components/key-metrics.tsx +1 -1063
  527. package/template/components/leo-insight-indicator.tsx +2 -2
  528. package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
  529. package/template/components/{question-bank-client.tsx → library-client.tsx} +83 -83
  530. package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
  531. package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
  532. package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +44 -44
  533. package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +16 -16
  534. package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
  535. package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
  536. package/template/components/library-panel-activator.tsx +8 -0
  537. package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +63 -63
  538. package/template/components/library-table.tsx +839 -0
  539. package/template/components/list-hub-status-badge.tsx +2 -2
  540. package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +489 -441
  541. package/template/components/onboarding/index.ts +9 -0
  542. package/template/components/onboarding/onboarding-01.tsx +1 -1
  543. package/template/components/onboarding/onboarding-02.tsx +1 -1
  544. package/template/components/onboarding/onboarding-03.tsx +1 -1
  545. package/template/components/onboarding/onboarding-04.tsx +1 -1
  546. package/template/components/page-header.tsx +8 -226
  547. package/template/components/product-switcher.tsx +3 -4
  548. package/template/components/product-wordmark.tsx +2 -1
  549. package/template/components/settings-appearance-card.tsx +3 -4
  550. package/template/components/settings-client.tsx +15 -59
  551. package/template/components/settings-form-row.tsx +4 -9
  552. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  553. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +114 -73
  554. package/template/components/sidebar/index.ts +16 -0
  555. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  556. package/template/components/sidebar/secondary-panel.tsx +316 -0
  557. package/template/components/sidebar/sidebar-auto-collapse.tsx +27 -0
  558. package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +2 -1
  559. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  560. package/template/components/site-header.tsx +1 -1
  561. package/template/components/table-properties/column-row.tsx +1 -90
  562. package/template/components/table-properties/draggable-list.ts +1 -49
  563. package/template/components/table-properties/drawer-button.tsx +1 -262
  564. package/template/components/table-properties/drawer.tsx +1 -1166
  565. package/template/components/table-properties/filter-card.tsx +1 -251
  566. package/template/components/table-properties/sort-card.tsx +1 -59
  567. package/template/components/table-properties/types.ts +28 -71
  568. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  569. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  570. package/template/components/templates/discovery-hub-template.tsx +1 -1
  571. package/template/components/templates/list-page.tsx +1 -608
  572. package/template/components/templates/nested-secondary-panel-shell.tsx +1 -63
  573. package/template/components/templates/new-focus-template.tsx +659 -0
  574. package/template/components/templates/secondary-panel-hub-template.tsx +2 -2
  575. package/template/components/tokens-secondary-nav.tsx +192 -0
  576. package/template/components/tokens-themes-client.tsx +476 -0
  577. package/template/components/tokens-themes-section.tsx +386 -0
  578. package/template/components/ui/accordion.tsx +1 -0
  579. package/template/components/ui/alert-dialog.tsx +1 -0
  580. package/template/components/ui/context-menu.tsx +1 -0
  581. package/template/components/ui/dot-pattern.tsx +1 -183
  582. package/template/components/ui/hover-card.tsx +1 -0
  583. package/template/components/ui/resizable.tsx +1 -68
  584. package/template/components/ui/scroll-area.tsx +1 -0
  585. package/template/components/ui/slider.tsx +1 -0
  586. package/template/docs/HANDBOOK.md +187 -0
  587. package/template/docs/blueprints/README.md +86 -0
  588. package/template/docs/blueprints/_template.md +91 -0
  589. package/template/docs/blueprints/board-card.md +123 -0
  590. package/template/docs/blueprints/data-table.md +139 -0
  591. package/template/docs/blueprints/key-metrics.md +128 -0
  592. package/template/docs/blueprints/list-page-template.md +123 -0
  593. package/template/docs/blueprints/page-header.md +130 -0
  594. package/template/docs/collaboration-access-pattern.md +7 -7
  595. package/template/docs/command-menu-pattern.md +1 -1
  596. package/template/docs/component-selection-guide.md +224 -0
  597. package/template/docs/components-audit-2026-05.md +158 -0
  598. package/template/docs/data-views-pattern.md +31 -66
  599. package/template/docs/drawer-vs-dialog-pattern.md +1 -3
  600. package/template/docs/glossary.md +58 -0
  601. package/template/docs/kpi-flat-band-pattern.md +3 -3
  602. package/template/docs/kpi-trend-pattern.md +18 -3
  603. package/template/docs/large-dataset-strategy.md +155 -0
  604. package/template/docs/library-hub-header-pattern.md +25 -0
  605. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  606. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  607. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  608. package/template/docs/migrations/README.md +100 -0
  609. package/template/docs/migrations/_template.md +64 -0
  610. package/template/docs/reference-implementations.md +151 -0
  611. package/template/docs/shell-surface-elevation-pattern.md +3 -5
  612. package/template/docs/token-taxonomy.md +416 -0
  613. package/template/docs/voice-and-tone.md +262 -0
  614. package/template/eslint.config.mjs +27 -0
  615. package/template/hooks/use-secondary-panel-hub-nav.ts +11 -11
  616. package/template/lib/ask-leo-route-context.ts +6 -18
  617. package/template/lib/coach-mark-registry.ts +0 -16
  618. package/template/lib/command-menu-config.ts +5 -13
  619. package/template/lib/command-menu-search-data.ts +8 -23
  620. package/template/lib/conditional-rule-match.ts +6 -97
  621. package/template/lib/data-list-display-options.ts +1 -49
  622. package/template/lib/data-list-view-registry.ts +1 -104
  623. package/template/lib/data-list-view-surface.ts +1 -83
  624. package/template/lib/data-list-view.ts +1 -47
  625. package/template/lib/data-view-dashboard-storage.ts +35 -38
  626. package/template/lib/dev-log.ts +1 -8
  627. package/template/lib/editable-target.ts +1 -10
  628. package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
  629. package/template/lib/library-dedicated-search.ts +19 -0
  630. package/template/lib/library-hub-search.ts +90 -0
  631. package/template/lib/library-nav.ts +477 -0
  632. package/template/lib/library-recent-searches.ts +22 -0
  633. package/template/lib/{question-bank-supported-views.ts → library-supported-views.ts} +2 -3
  634. package/template/lib/list-page-table-properties.ts +1 -48
  635. package/template/lib/list-status-badges.ts +16 -11
  636. package/template/lib/mock/dashboard.ts +1 -1
  637. package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
  638. package/template/lib/mock/library-header-collaborators.ts +54 -0
  639. package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
  640. package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
  641. package/template/lib/mock/library.ts +249 -0
  642. package/template/lib/mock/navigation.tsx +32 -35
  643. package/template/lib/raf-throttle.ts +1 -45
  644. package/template/lib/row-height.ts +4 -10
  645. package/template/lib/sidebar-state-cookie.ts +11 -2
  646. package/template/lib/table-state-lifecycle.ts +3 -3
  647. package/template/next.config.mjs +7 -4
  648. package/template/package.json +1 -0
  649. package/template/tests/setup.ts +25 -0
  650. package/consumer-extras/AGENTS.md +0 -76
  651. package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
  652. package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
  653. package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
  654. package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
  655. package/src/components/ui/button-group.tsx +0 -81
  656. package/src/theme.css +0 -16
  657. package/src/tokens/README.md +0 -15
  658. package/src/tokens/base.css +0 -337
  659. package/src/tokens/high-contrast.css +0 -1195
  660. package/src/tokens/layers.css +0 -224
  661. package/src/tokens/tailwind-bridge.css +0 -118
  662. package/src/tokens/themes.css +0 -201
  663. package/template/app/(app)/data-list/layout.tsx +0 -43
  664. package/template/app/(app)/data-list/page.tsx +0 -10
  665. package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
  666. package/template/app/(app)/examples/page.tsx +0 -43
  667. package/template/app/(app)/question-bank/find/page.tsx +0 -13
  668. package/template/app/(app)/question-bank/library/page.tsx +0 -12
  669. package/template/app/(app)/question-bank/list/page.tsx +0 -13
  670. package/template/app/(app)/question-bank/new/page.tsx +0 -50
  671. package/template/app/(app)/question-bank/page.tsx +0 -12
  672. package/template/components/app-route-loading.tsx +0 -14
  673. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  674. package/template/components/dashboard-onboarding.tsx +0 -21
  675. package/template/components/data-views/list-page-calendar-view.tsx +0 -593
  676. package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
  677. package/template/components/examples/focused-workflow-showcase.tsx +0 -183
  678. package/template/components/list-hub-board-view.tsx +0 -68
  679. package/template/components/list-hub-client.tsx +0 -186
  680. package/template/components/list-hub-list-view.tsx +0 -36
  681. package/template/components/list-hub-panel-activator.tsx +0 -8
  682. package/template/components/list-hub-secondary-nav.tsx +0 -121
  683. package/template/components/list-hub-table.tsx +0 -336
  684. package/template/components/question-bank-folder-columns-panel.tsx +0 -104
  685. package/template/components/question-bank-list-view.tsx +0 -53
  686. package/template/components/question-bank-panel-activator.tsx +0 -8
  687. package/template/components/question-bank-table.tsx +0 -729
  688. package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
  689. package/template/components/secondary-panel.tsx +0 -220
  690. package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
  691. package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
  692. package/template/components/secondary-panels/registry.tsx +0 -15
  693. package/template/components/section-cards.tsx +0 -106
  694. package/template/components/sidebar-auto-collapse.tsx +0 -23
  695. package/template/components/templates/focused-workflow-layouts.tsx +0 -448
  696. package/template/components/templates/focused-workflow-page-template.tsx +0 -69
  697. package/template/components/templates/page-loading-shell.tsx +0 -262
  698. package/template/components/ui/button-group.tsx +0 -1
  699. package/template/docs/consumer-app-pattern.md +0 -39
  700. package/template/docs/focused-workflow-page-pattern.md +0 -84
  701. package/template/docs/question-bank-hub-header-pattern.md +0 -25
  702. package/template/lib/list-hub-nav.ts +0 -121
  703. package/template/lib/mock/list-hub-directory.ts +0 -27
  704. package/template/lib/mock/list-hub-kpi.ts +0 -27
  705. package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
  706. package/template/lib/mock/question-bank.ts +0 -249
  707. package/template/lib/page-loading-variant.ts +0 -40
  708. package/template/lib/question-bank-dedicated-search.ts +0 -19
  709. package/template/lib/question-bank-hub-search.ts +0 -90
  710. package/template/lib/question-bank-nav.ts +0 -477
  711. package/template/lib/question-bank-recent-searches.ts +0 -22
  712. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  713. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  714. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  715. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  716. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
@@ -0,0 +1,153 @@
1
+ # Exxat DS — Reference implementations
2
+
3
+ > When a rule says "see Placements" or "see Team", **this is the index**. Open the file. Copy. Don't reinvent.
4
+
5
+ Reference pages are the **canonical working implementations** of a pattern. They're the source of truth that rules + blueprints summarize. If a rule conflicts with a reference page, the bug is in the rule — open a PR.
6
+
7
+ ---
8
+
9
+ ## How to use this page
10
+
11
+ 1. Find the row that matches the pattern you're building.
12
+ 2. Open the **Reference page** column — that file is the template.
13
+ 3. Read the linked **Blueprint** for the framework-agnostic spec.
14
+ 4. Read the linked **Rule** for the binding MUST / MUST NOT.
15
+ 5. Read the linked **Pattern** for the long-form "why".
16
+
17
+ If you find yourself diverging from the reference page, ask **why** before shipping.
18
+
19
+ ---
20
+
21
+ ## Primary hubs
22
+
23
+ | Pattern | Reference page | Blueprint | Rule(s) | Pattern doc |
24
+ |---|---|---|---|---|
25
+ | Full hub: table + board + dashboard + list + paginated + conditional rules + dashboard customize | `apps/web/components/placements-table.tsx` + `placements-client.tsx` | [`list-page-template`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/list-page-template.md), [`data-table`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/data-table.md), [`board-card`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/board-card.md), [`key-metrics`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/key-metrics.md) | [`exxat-data-tables`](../../../.cursor/rules/exxat-data-tables.mdc), [`exxat-list-page-connected-views`](../../../.cursor/rules/exxat-list-page-connected-views.mdc), [`exxat-centralized-list-dataset`](../../../.cursor/rules/exxat-centralized-list-dataset.mdc) | [`data-views-pattern`](../data-views-pattern.md) |
26
+ | Hub with dashboard customize (canvas layout edit) | `apps/web/components/team-table.tsx` + `team-client.tsx` | [`list-page-template`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/list-page-template.md), [`key-metrics`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/key-metrics.md) | [`exxat-list-page-connected-views`](../../../.cursor/rules/exxat-list-page-connected-views.mdc) | [`data-views-pattern`](../data-views-pattern.md) |
27
+ | Hub with finder / split-panel view | `apps/web/components/sites-table.tsx` + `sites-client.tsx` | [`list-page-template`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/list-page-template.md) | [`exxat-list-page-view-shells`](../../../.cursor/rules/exxat-list-page-view-shells.mdc) | [`data-views-pattern`](../data-views-pattern.md) |
28
+ | Hub with secondary panel scope (folder rail) | `apps/web/components/library-table.tsx` + `library-client.tsx` | [`list-page-template`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/list-page-template.md) | [`exxat-primary-nav-secondary-panel`](../../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc), [`exxat-library-hub-header`](../../../.cursor/rules/exxat-library-hub-header.mdc) | [`library-hub-header-pattern`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/library-hub-header-pattern.md) |
29
+ | Hub with secondary panel scope (token categories) — **smallest** secondary-panel reference | `apps/web/components/tokens-themes-client.tsx` + `tokens-secondary-nav.tsx` | [`list-page-template`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/list-page-template.md) | [`exxat-primary-nav-secondary-panel`](../../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc) | [`shell-surface-elevation-pattern`](../shell-surface-elevation-pattern.md) |
30
+ | Single-view showcase hub (table only) — **18 SaaS cell patterns**, each rendered by an **importable named cell** from `@/components/data-views` (see "Cell primitives" table below). Categories: select, primary identity + ID + favorite, avatar + name + email, avatar group +N, type pill, difficulty signal, status chip, inline toggle, tag list, rating stars, progress bar, currency, numeric, attachment count, external link, relative time, absolute date, row actions overflow. | `apps/web/components/columns-showcase.tsx` + `columns-client.tsx` | [`list-page-template`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/list-page-template.md), [`data-table`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/data-table.md) | [`exxat-data-tables`](../../../.cursor/rules/exxat-data-tables.mdc) | — |
31
+
32
+ > **First-time hub builder:** start with `sites-table.tsx` (smallest complete hub) or `columns-showcase.tsx` (single-view, easiest).
33
+
34
+ ---
35
+
36
+ ## Cell primitives (importable)
37
+
38
+ Every cell renderer below is exported from `@/components/data-views` (re-exported from `apps/web/components/data-views/table-cells.tsx`). The live catalog page is `/columns`. **Do not re-implement these inside a `ColumnDef['cell']`** — import the name.
39
+
40
+ | Cell | Renders | Import |
41
+ |------|---------|--------|
42
+ | `ProgressCell` | Track + filled bar with auto-tone in thirds; `value`, `max`, `tone`, `label` | `@/components/data-views` |
43
+ | `CurrencyCell` | Right-aligned `tabular-nums`; `value`, `currency` (USD), `locale`, `maximumFractionDigits` | same |
44
+ | `NumericCell` | Right-aligned plain count; `value`, `fractionDigits` | same |
45
+ | `RatingCell` | N of `max` FA stars + value; color + glyph paired (WCAG 1.4.1) | same |
46
+ | `SignalBarsCell` | Wi-Fi-style ordinal bars; `level`, `max`, `tone`, `label` (required) | same |
47
+ | `BooleanToggleCell` | Inline `ToggleSwitch` with `checked` + `onChange(next)`; stops row click propagation | same |
48
+ | `AttachmentCountCell` | Paperclip + count chip; muted dash on `0` | same |
49
+ | `ExternalLinkCell` | Truncated host + new-tab icon; `url`, `label?`; `Tip` shows full URL | same |
50
+ | `RelativeTimeCell` | "3 hours ago" with `Tip(absolute)`; `iso`, `now?` (deterministic snapshots) | same |
51
+ | `PeopleAvatarRailCell` | Face rail with `+N` overflow; `people: PersonStub[]`, **non-overlapping** | same |
52
+ | `PillCell` | Outlined badge + leading FA icon; `label`, `icon?` | same |
53
+ | `TagListCell` | Soft badges with `+N` overflow; `tags`, `visibleMax?`, `formatLabel?` | same |
54
+ | `RowActionsCell<TRow>` | `⋯` overflow dropdown; `row`, `actions: RowActionDef<TRow>[]` (label, icon, onSelect, variant, shortcut, disabled) | same |
55
+ | `EMPTY_DASH` | Aria-hidden `—` placeholder for null/undefined cells | same |
56
+
57
+ **Anti-references** (do NOT copy):
58
+ - ❌ Inlining `Intl.NumberFormat`, `[1,2,3,4,5].map(s => …)` star loops, raw `<a target="_blank">`, `new URL(…).hostname`, or `Intl.RelativeTimeFormat` inside a `cell:`. Import the named cell.
59
+ - ❌ Re-implementing `RowActionsCell` per hub with a custom `DropdownMenu`. The generic `RowActionsCell<TRow>` covers `Open / Edit / Duplicate / Archive`-style menus.
60
+
61
+ ---
62
+
63
+ ## Hub chrome
64
+
65
+ | Pattern | Reference page | Blueprint | Rule(s) |
66
+ |---|---|---|---|
67
+ | Page header — primary hub | `apps/web/components/placements-page-header.tsx` | [`page-header`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/page-header.md) | [`exxat-collaboration-access`](../../../.cursor/rules/exxat-collaboration-access.mdc), [`exxat-mono-ids`](../../../.cursor/rules/exxat-mono-ids.mdc) |
68
+ | Page header — collaboration variant (face rail + invite) | `apps/web/components/library-page-header.tsx` | [`page-header`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/page-header.md) | [`exxat-collaboration-access`](../../../.cursor/rules/exxat-collaboration-access.mdc) |
69
+ | Page header — entity / record (no view tabs) | `apps/web/components/page-header.tsx` (variants) | [`page-header`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/page-header.md) | — |
70
+ | KPI flat band on a hub | `apps/web/components/placements-client.tsx` | [`key-metrics`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/key-metrics.md) | [`exxat-kpi-flat-band`](../../../.cursor/rules/exxat-kpi-flat-band.mdc), [`exxat-kpi-max-four`](../../../.cursor/rules/exxat-kpi-max-four.mdc), [`exxat-kpi-trends`](../../../.cursor/rules/exxat-kpi-trends.mdc) |
71
+ | Properties drawer wiring | `apps/web/components/placements-table.tsx` | — | [`exxat-table-properties-drawer`](../../../.cursor/rules/exxat-table-properties-drawer.mdc) |
72
+ | Export drawer + ⋯ menu | `apps/web/components/placements-page-header.tsx` + `export-drawer.tsx` | — | [`exxat-drawer-vs-dialog`](../../../.cursor/rules/exxat-drawer-vs-dialog.mdc) |
73
+
74
+ ---
75
+
76
+ ## Board, list, dashboard views
77
+
78
+ | Pattern | Reference page | Blueprint | Rule(s) |
79
+ |---|---|---|---|
80
+ | Board card (kanban) | `apps/web/components/placements-board-view.tsx`, `team-table.tsx` (`renderListRow`) | [`board-card`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/board-card.md) | [`exxat-board-cards`](../../../.cursor/rules/exxat-board-cards.mdc), [`exxat-card-vs-list-rows`](../../../.cursor/rules/exxat-card-vs-list-rows.mdc) |
81
+ | List row (single-column) | `apps/web/components/team-table.tsx` `renderListRow` | [`board-card`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/board-card.md) (row layout) | [`exxat-card-vs-list-rows`](../../../.cursor/rules/exxat-card-vs-list-rows.mdc) |
82
+ | Dashboard view with charts + KPI band | `apps/web/components/placements-dashboard-charts-section.tsx` | [`key-metrics`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/key-metrics.md) | [`exxat-dashboard-view-charts`](../../../.cursor/rules/exxat-dashboard-view-charts.mdc) |
83
+ | Folder / finder split view | `apps/web/components/data-views/finder-panel-view.tsx` (used in `sites-table.tsx`) | — | [`exxat-list-page-view-shells`](../../../.cursor/rules/exxat-list-page-view-shells.mdc) |
84
+
85
+ ---
86
+
87
+ ## Search
88
+
89
+ | Pattern | Reference page | Rule(s) | Pattern doc |
90
+ |---|---|---|---|
91
+ | Global command palette (⌘K) | `apps/web/components/command-menu.tsx` + `lib/command-menu-config.ts` | [`exxat-command-menu`](../../../.cursor/rules/exxat-command-menu.mdc) | [`command-menu-pattern`](../command-menu-pattern.md) |
92
+ | Dedicated search (landing + results) | `apps/web/components/dedicated-search-*.tsx` | [`exxat-dedicated-search-surfaces`](../../../.cursor/rules/exxat-dedicated-search-surfaces.mdc) | — |
93
+ | In-table search (toolbar) | wired by `HubTable` automatically | [`exxat-data-tables`](../../../.cursor/rules/exxat-data-tables.mdc) | [`data-views-pattern`](../data-views-pattern.md) |
94
+
95
+ ---
96
+
97
+ ## Collaboration
98
+
99
+ | Pattern | Reference page | Rule(s) | Pattern doc |
100
+ |---|---|---|---|
101
+ | Face rail + invite drawer | `apps/web/components/collaboration-access-flow.tsx`, `invite-collaborators-drawer.tsx` | [`exxat-collaboration-access`](../../../.cursor/rules/exxat-collaboration-access.mdc) | [`collaboration-access-pattern`](../collaboration-access-pattern.md) |
102
+
103
+ ---
104
+
105
+ ## Overlays and confirmations
106
+
107
+ | Pattern | Reference page | Rule(s) | Pattern doc |
108
+ |---|---|---|---|
109
+ | Side drawer (long auxiliary flow) | `apps/web/components/export-drawer.tsx`, `invite-collaborators-drawer.tsx`, `apps/web/components/table-properties/drawer.tsx` | [`exxat-drawer-vs-dialog`](../../../.cursor/rules/exxat-drawer-vs-dialog.mdc), [`exxat-page-vs-drawer`](../../../.cursor/rules/exxat-page-vs-drawer.mdc) | [`drawer-vs-dialog-pattern`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/drawer-vs-dialog-pattern.md) |
110
+ | Dialog (blocking short confirm / destructive) | `apps/web/components/ui/alert-dialog.tsx` consumers (search `<AlertDialog`) | [`exxat-drawer-vs-dialog`](../../../.cursor/rules/exxat-drawer-vs-dialog.mdc) | [`drawer-vs-dialog-pattern`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/drawer-vs-dialog-pattern.md) |
111
+ | Coach mark / onboarding | `apps/web/lib/coach-mark-registry.ts` consumers (Placements dashboard customize) | — | — |
112
+
113
+ ---
114
+
115
+ ## Settings, tokens, themes
116
+
117
+ | Pattern | Reference page | Rule(s) |
118
+ |---|---|---|
119
+ | Settings page (preferences + sections) | `apps/web/app/(app)/settings/page.tsx` | — |
120
+ | Tokens & themes hub (secondary panel + categories + visualizers) | `apps/web/components/tokens-themes-client.tsx`, `tokens-themes-section.tsx`, `tokens-secondary-nav.tsx` | [`exxat-token-discipline`](../../../.cursor/rules/exxat-token-discipline.mdc), [`exxat-primary-nav-secondary-panel`](../../../.cursor/rules/exxat-primary-nav-secondary-panel.mdc) |
121
+
122
+ ---
123
+
124
+ ## Anti-references (what NOT to copy)
125
+
126
+ These exist but are **not** canonical. They predate a rule, are scoped to a one-off, or use a legacy primitive. **Don't copy from them.**
127
+
128
+ | Anti-reference | Why not | What to use instead |
129
+ |---|---|---|
130
+ | Raw `<DataTable>` mounted directly in `ListPageTemplate.renderContent` (historical) | Loses filter chips + Properties drawer; users lose discoverability | `HubTable` (see Sites / Placements / Tokens / Columns refs) |
131
+ | Custom search input above a `DataTable` | `HubTable`'s toolbar already does this; duplicating leads to drift | Configure `ColumnDef.filter` + use `HubTable` |
132
+ | `toast()` / Sonner / snackbar | Forbidden — see [`exxat-no-toast.mdc`](../../../.cursor/rules/exxat-no-toast.mdc) | `LocalBanner` / `SystemBanner` or inline status |
133
+ | Negative-margin overlapping avatars | Forbidden — see [`exxat-person-identity-display.mdc`](../../../.cursor/rules/exxat-person-identity-display.mdc) | `AvatarGroup` (gapped by default) |
134
+
135
+ ---
136
+
137
+ ## Adding a new reference page
138
+
139
+ If you build a pattern that **other hubs will copy**, list it here. A reference page is canonical when:
140
+
141
+ 1. It satisfies the matching blueprint or rule end-to-end.
142
+ 2. It passes the §13 PR-review checklist in [`AGENTS.md`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/AGENTS.md).
143
+ 3. The file has a top-level doc comment that names what it's the reference for (e.g. *"Sites hub — thin wrapper around `<HubTable>`. Owns only the column defs, renderers for non-table views, and the mock-data wiring."*).
144
+ 4. The matching rule's "Reference implementations" list points back to it.
145
+
146
+ ---
147
+
148
+ ## See also
149
+
150
+ - [`HANDBOOK.md`](./HANDBOOK.md) — start-here doc map
151
+ - [`blueprints/README.md`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/blueprints/README.md) — what a blueprint is
152
+ - [`component-selection-guide.md`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/docs/component-selection-guide.md) — decision tree across blueprints
153
+ - [`apps/web/AGENTS.md` §13](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/AGENTS.md) — full PR-review checklist
@@ -0,0 +1,262 @@
1
+ # Exxat DS — Voice and tone
2
+
3
+ > The single biggest driver of "this feels like one product" — or "this feels random" — is **copy**. Empty states, errors, buttons, banners, validation, labels. This doc is the binding reference for all of it.
4
+ >
5
+ > **Audience:** designers writing copy, engineers shipping strings, AI agents drafting UI text. Reviewed in PR alongside `.cursor/rules/exxat-accessibility.mdc`.
6
+
7
+ ---
8
+
9
+ ## 1. Voice (the constant)
10
+
11
+ Exxat copy is **clear, direct, and respectful**. We talk to grown professionals (faculty, admins) and to students. We never:
12
+
13
+ - talk down (no "Oops!" / "Whoops" / "Uh-oh"),
14
+ - over-celebrate ("Awesome!" / "Great job!" / 🎉),
15
+ - guilt-trip ("You haven't… yet" / "Don't forget!"),
16
+ - hide the cause behind metaphor ("Something went wrong" with no detail),
17
+ - shout (sentence case everywhere; ALL CAPS only for system status acronyms).
18
+
19
+ We **always**:
20
+
21
+ - name the **thing**: the entity (placement, site, student), the action (Save, Invite, Export), the outcome (saved, sent, downloaded),
22
+ - say what **changed** or what **the user can do next**,
23
+ - use **present tense** (`Saving` / `Saved` / `Try again`), not past-aspirational (`We've saved your changes!`),
24
+ - use **active voice** (`Exxat couldn't save the placement.` not `The placement could not be saved.`).
25
+
26
+ ---
27
+
28
+ ## 2. Tone (the variable)
29
+
30
+ Tone shifts by surface. Same voice, different temperature.
31
+
32
+ | Surface | Tone | Example |
33
+ |---|---|---|
34
+ | Primary action label | Imperative, 1–3 words | "Save", "Invite people", "Export" |
35
+ | Empty state (filtered) | Helpful, names the filter | "No placements match the current filters. Clear them to see all 247." |
36
+ | Empty state (no data ever) | Welcoming, names the next step | "No placements yet. Add your first one to get started." |
37
+ | Inline validation | Neutral, says the rule | "Use the format MM/DD/YYYY." |
38
+ | Banner (informational) | Calm, explains why | "Read-only — this term has ended." |
39
+ | Banner (warning) | Direct, says the consequence | "Saving will overwrite 3 students' assignments." |
40
+ | Banner (error) | Honest, names the failure + next step | "Exxat couldn't reach the placement service. Try again, or check your network." |
41
+ | Dialog (destructive confirm) | Specific, names the object | "Delete placement P-2026-014? This cannot be undone." |
42
+ | Microcopy (helper, hints) | Brief, format-only | "Out of 4.0", "MM/DD/YYYY" |
43
+
44
+ ---
45
+
46
+ ## 3. Buttons
47
+
48
+ | Pattern | Use | Example |
49
+ |---|---|---|
50
+ | **Sentence case** | Always | `Save`, `Invite people`, `Export selection` |
51
+ | **Title case** | Never | ~~`Save Changes`~~ → `Save changes` |
52
+ | **Verb-first imperative** | Primary actions | `Save`, `Send invite`, `Create placement`, `Download CSV` |
53
+ | **No "Please"** | The button is the request | ~~`Please save`~~ → `Save` |
54
+ | **Don't repeat the field name** | Inline context is enough | ~~`Save changes to placement`~~ → `Save` |
55
+ | **"Cancel" not "Discard"** | Cancel returns to a safe state; Discard is only for destructive draft loss | dialog primary = `Save changes`; cancel = `Cancel` |
56
+ | **Loading verb** | When in-flight, swap to `…` form, preserve width | `Save` → `Saving…` |
57
+ | **Disabled tooltip** | Always say why | "Add at least one collaborator first." |
58
+
59
+ ### Don't
60
+
61
+ | ❌ Don't | ✅ Do |
62
+ |---|---|
63
+ | `Click here` | `Open placement` |
64
+ | `OK` | `Save`, `Got it`, `Continue` (the actual outcome) |
65
+ | `Submit` | `Send invite`, `Save changes`, `Create placement` |
66
+ | `Yes` / `No` in destructive dialogs | `Delete placement`, `Cancel` |
67
+ | `Loading…` for >2 s with no detail | `Loading placements…` (name the thing) |
68
+
69
+ ---
70
+
71
+ ## 4. Empty states
72
+
73
+ There are **three** kinds. The copy is different for each.
74
+
75
+ ### 4a. Filter-empty ("zero matches")
76
+
77
+ The dataset has rows; the active filters hide all of them. Tell the user the filters are responsible and offer to clear them.
78
+
79
+ ```
80
+ No placements match the current filters.
81
+ [Clear filters]
82
+ ```
83
+
84
+ Rules:
85
+
86
+ - Name the entity ("placements", not "items").
87
+ - Mention "the current filters" — not just "no results".
88
+ - Surface a **Clear filters** action if the toolbar has any filters applied.
89
+ - If the search box is the only filter, the message becomes `No placements match "<query>".` (quote the query exactly).
90
+
91
+ ### 4b. True-empty ("no data ever")
92
+
93
+ The dataset is empty for this user / scope. Tell them what to do next.
94
+
95
+ ```
96
+ No placements yet.
97
+ Add your first one to start tracking student rotations.
98
+ [New placement]
99
+ ```
100
+
101
+ Rules:
102
+
103
+ - One-line headline + one-line context.
104
+ - The CTA is the same imperative used elsewhere in the app — don't invent "Start now" for an empty state.
105
+ - If creation requires a precursor ("Add at least one site first"), say so and link to the precursor.
106
+
107
+ ### 4c. Permission-empty ("not allowed to see")
108
+
109
+ The user can't see anything because of access. Don't show counts; don't suggest creating.
110
+
111
+ ```
112
+ You don't have access to this hub.
113
+ Ask a coordinator to invite you with Viewer or higher access.
114
+ ```
115
+
116
+ Rules:
117
+
118
+ - Name the access level required.
119
+ - Don't show row counts the user can't see.
120
+ - Don't expose the existence of restricted records by mentioning "0 of N hidden".
121
+
122
+ ---
123
+
124
+ ## 5. Errors
125
+
126
+ Errors must answer three questions: **What happened? Why? What can the user do?**
127
+
128
+ | Element | Required? | Example |
129
+ |---|---|---|
130
+ | Subject | required | `Exxat couldn't save the placement.` |
131
+ | Cause | when knowable | `The site was deleted while you were editing.` |
132
+ | Next step | required | `Choose another site or refresh.` |
133
+
134
+ ### Don't
135
+
136
+ - `Something went wrong.` — every word is empty. Replace with the subject + cause.
137
+ - `Error 500: Internal Server Error.` — leak the trace ID to logs, not the user. User-facing: "Exxat had a problem. Try again in a moment."
138
+ - Toasts for errors. Use `SystemBanner` (route-level) or inline `FormMessage` (field-level). See [`exxat-no-toast.mdc`](../../../.cursor/rules/exxat-no-toast.mdc).
139
+
140
+ ### Field-level (`FormMessage`)
141
+
142
+ Match the rule, not the field name. Keep under 60 chars.
143
+
144
+ | Rule | Message |
145
+ |---|---|
146
+ | Required | `This is required.` |
147
+ | Format (date) | `Use MM/DD/YYYY.` |
148
+ | Format (phone) | `Use +1 (555) 555-0100.` |
149
+ | Range (number) | `Enter a number between 0 and 4.0.` |
150
+ | Unique | `That ID is already in use.` |
151
+ | Server | `Exxat couldn't save this field. Try again.` |
152
+
153
+ ---
154
+
155
+ ## 6. Banners
156
+
157
+ We use **persistent banners** (not toasts) for all product feedback. See [`exxat-no-toast.mdc`](../../../.cursor/rules/exxat-no-toast.mdc) and `LocalBanner` / `SystemBanner` in `packages/ui`.
158
+
159
+ | Variant | Use | Lead with |
160
+ |---|---|---|
161
+ | `info` | Read-only / scope notice / "you're viewing X" | The fact: "Read-only — this term has ended." |
162
+ | `success` | Confirmed state change (long-lived; toasts forbidden) | The outcome: "Invite sent to 3 collaborators." |
163
+ | `warning` | Action will cause consequence | The consequence: "Saving will overwrite 3 students' assignments." |
164
+ | `error` | Recoverable failure | The subject + next step: "Exxat couldn't reach the placement service. Try again." |
165
+ | `destructive` | Pending destructive change | The object + reversibility: "This term will be archived in 7 days. Restore now to keep it." |
166
+
167
+ Rules:
168
+
169
+ - One banner per region. If two compete, the higher-severity wins.
170
+ - Pair a banner with an **action** when there's something the user can do (`[Restore]`, `[Try again]`, `[Open log]`).
171
+ - No exclamation marks. The variant color carries the tone.
172
+
173
+ ---
174
+
175
+ ## 7. Status badges
176
+
177
+ Status labels live in [`lib/list-status-badges.ts`](https://github.com/ExxatDesign/Exxat-DS-Workspace/blob/main/apps/web/lib/list-status-badges.ts) and are shared across every surface (table, board card, list row). Don't fork labels per page.
178
+
179
+ | Type | Conventions | Example |
180
+ |---|---|---|
181
+ | Lifecycle | Title case, single word where possible | `Active`, `Draft`, `Archived`, `Pending` |
182
+ | Outcome | Past-tense verb when an action completed | `Approved`, `Rejected`, `Sent`, `Skipped` |
183
+ | Risk | Plain language, no jargon | `On track`, `At risk`, `Blocked` |
184
+ | Mandatory pairing | Color **AND** icon (WCAG 1.4.1 — never color alone) | green check, amber triangle, red circle-x |
185
+
186
+ Never: `OK`, `N/A`, `?` as a status label. Show the actual lifecycle state or `Unknown` with a tooltip describing how to resolve it.
187
+
188
+ ---
189
+
190
+ ## 8. KPI copy (the highest-stakes copy in the product)
191
+
192
+ KPIs read top-down: **label → value → trend chip → description**. The reader is scanning, not reading. Each line earns its place.
193
+
194
+ | Field | Rule | Example |
195
+ |---|---|---|
196
+ | `label` | Sentence case noun phrase. ≤ 24 chars. No "Total" prefix (the value is total by default). | `Active placements`, `New invites`, `Compliance issues` |
197
+ | `value` | The number. Use `tabular-nums`. Round to a sensible precision. Suffix unit (`%`, `hrs`) without space when natural. | `247`, `12 %`, `38 hrs` |
198
+ | `delta` | The **count** of change. Empty (`""` or `0`) hides the chip entirely. Never prose. | `+12`, `-3`, `+8 %` |
199
+ | `description` | The caption beneath the value row. Prose explaining what the number is or how it splits. Never the delta. | `vs last week`, `across 4 sites`, `left + right` |
200
+
201
+ See [`exxat-kpi-trends.mdc`](../../../.cursor/rules/exxat-kpi-trends.mdc) for the trend-polarity rules (when up means bad, set `trendPolarity: "lower_is_better"`).
202
+
203
+ ### Don't
204
+
205
+ - `Total: 247` — drop "Total".
206
+ - `247 placements` in `value` — put `247` in `value`, `placements` is in `label`.
207
+ - `+5 (up 12 % from last week)` in `delta` — `delta = "+5"`, `description = "vs last week"`.
208
+
209
+ ---
210
+
211
+ ## 9. Form labels and helper text
212
+
213
+ | Element | Rule | Example |
214
+ |---|---|---|
215
+ | Label | Sentence case, no colon, no "*" — pair `*` decoration with `aria-required` only. | `Date of birth` |
216
+ | Required marker | Visible `*` (`aria-hidden`), programmatic `aria-required="true"`. | `Date of birth *` |
217
+ | Helper text | Persistent, format-first. Use `FormDescription`. Never placeholder-only. | `MM/DD/YYYY` |
218
+ | Placeholder | May mirror the format. Never the sole carrier. | `MM/DD/YYYY` |
219
+ | Inline error | Replaces helper while active. Match the rule, not the field name. | `Use MM/DD/YYYY.` |
220
+ | Unit in label vs description | Units go in description when context-dependent (`Out of 4.0` under "GPA"), in label when fixed (`Hours per week`). | — |
221
+
222
+ See [`exxat-accessibility.mdc`](../../../.cursor/rules/exxat-accessibility.mdc) §"Form fields — format hints MUST be persistent".
223
+
224
+ ---
225
+
226
+ ## 10. Dates, times, numbers
227
+
228
+ | Type | Format | Example |
229
+ |---|---|---|
230
+ | Date (UI) | Locale-aware, defaults to `MM/DD/YYYY` for en-US | `12/14/2025` |
231
+ | Date range | Same format, en-dash with hair-thin spaces (or hyphen-minus in mono) | `12/14/2025 – 12/20/2025` |
232
+ | Time | 12-hour with am/pm in lowercase | `2:30 pm` |
233
+ | Relative time | Use sparingly; pair with absolute on hover/tooltip | `Updated 3 hours ago` (tip: `12/15/2025, 11:14 am`) |
234
+ | Numbers | `tabular-nums`. Use thousands separator (`12,547`) for ≥ 4 digits | `12,547` |
235
+ | Currency | Symbol-first, no space (`$1,200.00`) | `$1,200.00` |
236
+ | Percent | No space (`12 %` is wrong, use `12%`) | `12%` |
237
+ | Duration | Short form (`38 hrs`, `2 wks`) | `38 hrs` |
238
+
239
+ ---
240
+
241
+ ## 11. Reviewer checklist (paste into PRs that touch copy)
242
+
243
+ - [ ] Sentence case (not title case) everywhere.
244
+ - [ ] No `Click here`, `Submit`, `OK`, `Loading…` without a noun.
245
+ - [ ] No toasts; banners or inline status instead.
246
+ - [ ] Empty state names the entity and surfaces a next action or "Clear filters".
247
+ - [ ] Errors answer: what / why / what now.
248
+ - [ ] Status labels come from `lib/list-status-badges.ts`, not new strings.
249
+ - [ ] KPI `delta` is a count; KPI `description` is prose. Polarity matches the metric.
250
+ - [ ] Form helper text is `FormDescription`, not placeholder-only.
251
+ - [ ] No exclamation marks outside `success` banners (and even those rarely).
252
+ - [ ] No emoji unless explicitly approved for that surface.
253
+
254
+ ---
255
+
256
+ ## See also
257
+
258
+ - [`HANDBOOK.md`](./HANDBOOK.md) — where this fits in the docs map
259
+ - [`glossary.md`](./glossary.md) — vocabulary
260
+ - [`.cursor/rules/exxat-no-toast.mdc`](../../../.cursor/rules/exxat-no-toast.mdc) — why banners, not toasts
261
+ - [`.cursor/rules/exxat-kpi-trends.mdc`](../../../.cursor/rules/exxat-kpi-trends.mdc) — KPI delta vs description
262
+ - [`.cursor/rules/exxat-accessibility.mdc`](../../../.cursor/rules/exxat-accessibility.mdc) — format-hint persistence rule
@@ -1,8 +1,8 @@
1
1
  # Collaboration & access pattern
2
2
 
3
- Shared UI for **who can access a hub** (face stack in the header) and **inviting people** (floating sheet). **Reference:** Question bank — `QuestionBankPageHeader`, `QuestionBankClient`, `InviteCollaboratorsDrawer`.
3
+ Shared UI for **who can access a hub** (face stack in the header) and **inviting people** (floating sheet). **Reference:** Library — `LibraryPageHeader`, `LibraryClient`, `InviteCollaboratorsDrawer`.
4
4
 
5
- **Folder-scoped question bank:** When the library URL selects a folder (`?scope=folder&folderId=`), the same header **⋯ More** menu also exposes **Customize folder** (name / color / icon) via **`QuestionBankNewFolderSheet`** mounted on **`QuestionBankClient`** so it works on every view tab. See **`docs/question-bank-hub-header-pattern.md`** and **`.cursor/rules/exxat-question-bank-hub-header.mdc`**.
5
+ **Folder-scoped library:** When the library URL selects a folder (`?scope=folder&folderId=`), the same header **⋯ More** menu also exposes **Customize folder** (name / color / icon) via **`LibraryNewFolderSheet`** mounted on **`LibraryClient`** so it works on every view tab. See **`docs/library-hub-header-pattern.md`** and **`.cursor/rules/exxat-library-hub-header.mdc`**.
6
6
 
7
7
  ## When to use
8
8
 
@@ -33,11 +33,11 @@ Shared UI for **who can access a hub** (face stack in the header) and **inviting
33
33
 
34
34
  ```tsx
35
35
  <CollaborationAccessFlow
36
- initialCollaborators={QUESTION_BANK_HEADER_COLLABORATORS}
36
+ initialCollaborators={LIBRARY_HEADER_COLLABORATORS}
37
37
  resourceLabel={hubHeader.title}
38
38
  >
39
39
  {({ collaborators, openInvite }) => (
40
- <QuestionBankPageHeader
40
+ <LibraryPageHeader
41
41
  variant="collaboration"
42
42
  title={hubHeader.title}
43
43
  questionCount={count}
@@ -100,9 +100,9 @@ Row order:
100
100
  | Hub flow | `components/collaboration-access-flow.tsx` |
101
101
  | Collaborator type | `components/page-header.tsx` (`PageHeaderCollaborator`) |
102
102
  | Invite sheet | `components/invite-collaborators-drawer.tsx` |
103
- | Entity header | `components/question-bank-page-header.tsx` |
104
- | Hub wiring | `components/question-bank-client.tsx` |
105
- | Demo roster | `lib/mock/question-bank-header-collaborators.ts` |
103
+ | Entity header | `components/library-page-header.tsx` |
104
+ | Hub wiring | `components/library-client.tsx` |
105
+ | Demo roster | `lib/mock/library-header-collaborators.ts` |
106
106
 
107
107
  ## Checklist (new hub)
108
108
 
@@ -42,4 +42,4 @@ The command menu is the app’s **global search and AI entry**—one place to ju
42
42
 
43
43
  ---
44
44
 
45
- Keep this document aligned with **`exxat-ds/AGENTS.md` §7.1** when behavior or copy changes.
45
+ Keep this document aligned with **`apps/web/AGENTS.md` §7.1** when behavior or copy changes.
@@ -25,26 +25,6 @@ The npm package includes a full Next.js reference under:
25
25
 
26
26
  Use it when you need to know **what files exist**, **how shims re-export** `@exxatdesignux/ui`, or **what AGENTS / layout** patterns look like for the current release. Porting is manual: diff template vs your repo and apply intentional changes (imports, new components, CSS entrypoints).
27
27
 
28
- ### List-page view registry (required for data hubs)
29
-
30
- After upgrading, confirm each hub table uses **`ListPageConnectedViewBody`** (not long **`if (view === …)`** chains) and that these stay aligned:
31
-
32
- | File | Purpose |
33
- |------|---------|
34
- | `lib/data-list-view-registry.ts` | Render kinds + hub KPI strip rules |
35
- | `lib/<hub>-supported-views.ts` | What the hub can add/switch to |
36
- | `components/templates/list-page.tsx` | `supportedViewTypes` on Add view + shortcuts |
37
- | `components/data-views/list-page-connected-view-body.tsx` | View router |
38
- | `lib/hub-connected-view-renderers.ts` | **`defineHubViewRenderers(supported, { … })`** — dev warnings when a supported view has no body |
39
- | `components/data-views/list-page-folder-columns-panel.tsx` | Generic Miller columns for **panel** view (hub wrapper for QB colors/actions) |
40
-
41
- Pass the **same** `supportedViewTypes` array to **`ListPageTemplate`** and **`TablePropertiesDrawerButton`**. Wrap hub renderers with **`defineHubViewRenderers`**. Import **question-bank-only** tree/folder nav from hub files, not the generic **`data-views`** barrel. See **`docs/exxat-ds/data-views-pattern.md`** § “View registry and connected bodies” and **`consumer-app-pattern.md`** for the full consumer-app checklist.
42
-
43
- ### Shell + sidebar (after DS token changes)
44
-
45
- - [ ] Dark mode **secondary panel** uses **`--secondary-panel-bg`** from DS globals (sidebar-accent mix) — spot-check Question bank **Library** rail.
46
- - [ ] Collapsed **product switcher** — **`SidebarMenuButton` `tooltip=`** + **`DropdownMenuTrigger`** only (no outer **`Tooltip`** wrapping the trigger).
47
-
48
28
  ## 4. Dependency and Node
49
29
 
50
30
  - Keep **`@exxatdesignux/ui`** on the same semver your team tested; prefer explicit **`^x.y.z`** or pinned **`x.y.z`**.