@exxatdesignux/ui 0.2.19 → 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 (688) hide show
  1. package/CHANGELOG.md +60 -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 +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 +4 -15
  36. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +13 -28
  37. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  38. package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +2 -4
  39. package/consumer-extras/handbook/HANDBOOK.md +185 -0
  40. package/consumer-extras/handbook/glossary.md +57 -0
  41. package/consumer-extras/handbook/reference-implementations.md +126 -0
  42. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  43. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  44. package/consumer-extras/patterns/consumer-upgrade-checklist.md +0 -20
  45. package/consumer-extras/patterns/data-views-pattern.md +17 -54
  46. package/consumer-extras/patterns/shell-surface-elevation-pattern.md +3 -5
  47. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  48. package/dist/components/data-table/filter-date-calendar.js +280 -0
  49. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  50. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  51. package/dist/components/data-table/filter-text-value-input.js +561 -0
  52. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  53. package/dist/components/data-table/index.d.ts +45 -0
  54. package/dist/components/data-table/index.js +3085 -0
  55. package/dist/components/data-table/index.js.map +1 -0
  56. package/dist/components/data-table/pagination.d.ts +28 -0
  57. package/dist/components/data-table/pagination.js +3264 -0
  58. package/dist/components/data-table/pagination.js.map +1 -0
  59. package/dist/components/data-table/types.d.ts +84 -0
  60. package/dist/components/data-table/types.js +3 -0
  61. package/dist/components/data-table/types.js.map +1 -0
  62. package/dist/components/data-table/use-table-state.d.ts +116 -0
  63. package/dist/components/data-table/use-table-state.js +670 -0
  64. package/dist/components/data-table/use-table-state.js.map +1 -0
  65. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  66. package/dist/components/data-views/board-card-primitives.js +84 -0
  67. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  68. package/dist/components/data-views/data-row-list.d.ts +33 -0
  69. package/dist/components/data-views/data-row-list.js +106 -0
  70. package/dist/components/data-views/data-row-list.js.map +1 -0
  71. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  72. package/dist/components/data-views/finder-panel-view.js +388 -0
  73. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  74. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  75. package/dist/components/data-views/folder-grid-view.js +58 -0
  76. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  77. package/dist/components/data-views/hub-table.d.ts +167 -0
  78. package/dist/components/data-views/hub-table.js +5561 -0
  79. package/dist/components/data-views/hub-table.js.map +1 -0
  80. package/dist/components/data-views/index.d.ts +27 -0
  81. package/dist/components/data-views/index.js +6575 -0
  82. package/dist/components/data-views/index.js.map +1 -0
  83. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  84. package/dist/components/data-views/list-page-board-card.js +264 -0
  85. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  86. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  87. package/dist/components/data-views/list-page-board-template.js +137 -0
  88. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  89. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  90. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  91. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  92. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  93. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  94. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  95. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  96. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  97. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  98. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  99. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  100. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  101. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  102. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  103. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  104. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  105. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  106. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  107. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  108. package/dist/components/data-views/os-folder-glyph.js +104 -0
  109. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  110. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  111. package/dist/components/data-views/outline-tree-menu.js +131 -0
  112. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  113. package/dist/components/table-properties/column-row.d.ts +22 -0
  114. package/dist/components/table-properties/column-row.js +153 -0
  115. package/dist/components/table-properties/column-row.js.map +1 -0
  116. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  117. package/dist/components/table-properties/draggable-list.js +53 -0
  118. package/dist/components/table-properties/draggable-list.js.map +1 -0
  119. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  120. package/dist/components/table-properties/drawer-button.js +2748 -0
  121. package/dist/components/table-properties/drawer-button.js.map +1 -0
  122. package/dist/components/table-properties/drawer.d.ts +100 -0
  123. package/dist/components/table-properties/drawer.js +2595 -0
  124. package/dist/components/table-properties/drawer.js.map +1 -0
  125. package/dist/components/table-properties/filter-card.d.ts +24 -0
  126. package/dist/components/table-properties/filter-card.js +854 -0
  127. package/dist/components/table-properties/filter-card.js.map +1 -0
  128. package/dist/components/table-properties/index.d.ts +14 -0
  129. package/dist/components/table-properties/index.js +2768 -0
  130. package/dist/components/table-properties/index.js.map +1 -0
  131. package/dist/components/table-properties/sort-card.d.ts +20 -0
  132. package/dist/components/table-properties/sort-card.js +102 -0
  133. package/dist/components/table-properties/sort-card.js.map +1 -0
  134. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  135. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  136. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  137. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  138. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  139. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  140. package/dist/components/templates/index.d.ts +9 -0
  141. package/dist/components/templates/index.js +2720 -0
  142. package/dist/components/templates/index.js.map +1 -0
  143. package/dist/components/templates/list-page.d.ts +83 -0
  144. package/dist/components/templates/list-page.js +2433 -0
  145. package/dist/components/templates/list-page.js.map +1 -0
  146. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  147. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  148. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  149. package/dist/components/ui/accordion.d.ts +10 -0
  150. package/dist/components/ui/accordion.js +74 -0
  151. package/dist/components/ui/accordion.js.map +1 -0
  152. package/dist/components/ui/alert-dialog.d.ts +37 -0
  153. package/dist/components/ui/alert-dialog.js +201 -0
  154. package/dist/components/ui/alert-dialog.js.map +1 -0
  155. package/dist/components/ui/avatar.d.ts +84 -0
  156. package/dist/components/ui/avatar.js +328 -0
  157. package/dist/components/ui/avatar.js.map +1 -0
  158. package/dist/components/ui/badge.d.ts +13 -0
  159. package/dist/components/ui/badge.js +49 -0
  160. package/dist/components/ui/badge.js.map +1 -0
  161. package/dist/components/ui/banner.d.ts +62 -0
  162. package/dist/components/ui/banner.js +364 -0
  163. package/dist/components/ui/banner.js.map +1 -0
  164. package/dist/components/ui/breadcrumb.d.ts +14 -0
  165. package/dist/components/ui/breadcrumb.js +114 -0
  166. package/dist/components/ui/breadcrumb.js.map +1 -0
  167. package/dist/components/ui/button.d.ts +16 -0
  168. package/dist/components/ui/button.js +59 -0
  169. package/dist/components/ui/button.js.map +1 -0
  170. package/dist/components/ui/calendar.d.ts +13 -0
  171. package/dist/components/ui/calendar.js +238 -0
  172. package/dist/components/ui/calendar.js.map +1 -0
  173. package/dist/components/ui/card.d.ts +14 -0
  174. package/dist/components/ui/card.js +102 -0
  175. package/dist/components/ui/card.js.map +1 -0
  176. package/dist/components/ui/chart.d.ts +58 -0
  177. package/dist/components/ui/chart.js +292 -0
  178. package/dist/components/ui/chart.js.map +1 -0
  179. package/dist/components/ui/checkbox.d.ts +23 -0
  180. package/dist/components/ui/checkbox.js +155 -0
  181. package/dist/components/ui/checkbox.js.map +1 -0
  182. package/dist/components/ui/coach-mark.d.ts +27 -0
  183. package/dist/components/ui/coach-mark.js +306 -0
  184. package/dist/components/ui/coach-mark.js.map +1 -0
  185. package/dist/components/ui/collapsible.d.ts +8 -0
  186. package/dist/components/ui/collapsible.js +35 -0
  187. package/dist/components/ui/collapsible.js.map +1 -0
  188. package/dist/components/ui/command.d.ts +36 -0
  189. package/dist/components/ui/command.js +274 -0
  190. package/dist/components/ui/command.js.map +1 -0
  191. package/dist/components/ui/context-menu.d.ts +32 -0
  192. package/dist/components/ui/context-menu.js +245 -0
  193. package/dist/components/ui/context-menu.js.map +1 -0
  194. package/dist/components/ui/date-picker-field.d.ts +38 -0
  195. package/dist/components/ui/date-picker-field.js +550 -0
  196. package/dist/components/ui/date-picker-field.js.map +1 -0
  197. package/dist/components/ui/dialog.d.ts +22 -0
  198. package/dist/components/ui/dialog.js +200 -0
  199. package/dist/components/ui/dialog.js.map +1 -0
  200. package/dist/components/ui/dot-pattern.d.ts +21 -0
  201. package/dist/components/ui/dot-pattern.js +139 -0
  202. package/dist/components/ui/dot-pattern.js.map +1 -0
  203. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  204. package/dist/components/ui/drag-handle-grip.js +15 -0
  205. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  206. package/dist/components/ui/drawer.d.ts +16 -0
  207. package/dist/components/ui/drawer.js +125 -0
  208. package/dist/components/ui/drawer.js.map +1 -0
  209. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  210. package/dist/components/ui/dropdown-menu.js +353 -0
  211. package/dist/components/ui/dropdown-menu.js.map +1 -0
  212. package/dist/components/ui/export-drawer.d.ts +11 -0
  213. package/dist/components/ui/export-drawer.js +1658 -0
  214. package/dist/components/ui/export-drawer.js.map +1 -0
  215. package/dist/components/ui/field.d.ts +30 -0
  216. package/dist/components/ui/field.js +249 -0
  217. package/dist/components/ui/field.js.map +1 -0
  218. package/dist/components/ui/form.d.ts +28 -0
  219. package/dist/components/ui/form.js +110 -0
  220. package/dist/components/ui/form.js.map +1 -0
  221. package/dist/components/ui/hover-card.d.ts +9 -0
  222. package/dist/components/ui/hover-card.js +43 -0
  223. package/dist/components/ui/hover-card.js.map +1 -0
  224. package/dist/components/ui/input-group.d.ts +20 -0
  225. package/dist/components/ui/input-group.js +219 -0
  226. package/dist/components/ui/input-group.js.map +1 -0
  227. package/dist/components/ui/input-mask.d.ts +39 -0
  228. package/dist/components/ui/input-mask.js +118 -0
  229. package/dist/components/ui/input-mask.js.map +1 -0
  230. package/dist/components/ui/input.d.ts +5 -0
  231. package/dist/components/ui/input.js +30 -0
  232. package/dist/components/ui/input.js.map +1 -0
  233. package/dist/components/ui/kbd.d.ts +20 -0
  234. package/dist/components/ui/kbd.js +45 -0
  235. package/dist/components/ui/kbd.js.map +1 -0
  236. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  237. package/dist/components/ui/key-metrics-context.js +26 -0
  238. package/dist/components/ui/key-metrics-context.js.map +1 -0
  239. package/dist/components/ui/key-metrics.d.ts +131 -0
  240. package/dist/components/ui/key-metrics.js +1015 -0
  241. package/dist/components/ui/key-metrics.js.map +1 -0
  242. package/dist/components/ui/label.d.ts +6 -0
  243. package/dist/components/ui/label.js +28 -0
  244. package/dist/components/ui/label.js.map +1 -0
  245. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  246. package/dist/components/ui/list-page-view-frame.js +24 -0
  247. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  248. package/dist/components/ui/page-header.d.ts +51 -0
  249. package/dist/components/ui/page-header.js +372 -0
  250. package/dist/components/ui/page-header.js.map +1 -0
  251. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  252. package/dist/components/ui/payment-card-fields.js +80 -0
  253. package/dist/components/ui/payment-card-fields.js.map +1 -0
  254. package/dist/components/ui/popover.d.ts +10 -0
  255. package/dist/components/ui/popover.js +47 -0
  256. package/dist/components/ui/popover.js.map +1 -0
  257. package/dist/components/ui/radio-group.d.ts +29 -0
  258. package/dist/components/ui/radio-group.js +190 -0
  259. package/dist/components/ui/radio-group.js.map +1 -0
  260. package/dist/components/ui/resizable.d.ts +16 -0
  261. package/dist/components/ui/resizable.js +51 -0
  262. package/dist/components/ui/resizable.js.map +1 -0
  263. package/dist/components/ui/scroll-area.d.ts +8 -0
  264. package/dist/components/ui/scroll-area.js +66 -0
  265. package/dist/components/ui/scroll-area.js.map +1 -0
  266. package/dist/components/ui/select.d.ts +18 -0
  267. package/dist/components/ui/select.js +186 -0
  268. package/dist/components/ui/select.js.map +1 -0
  269. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  270. package/dist/components/ui/selection-tile-grid.js +347 -0
  271. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  272. package/dist/components/ui/separator.d.ts +7 -0
  273. package/dist/components/ui/separator.js +33 -0
  274. package/dist/components/ui/separator.js.map +1 -0
  275. package/dist/components/ui/sheet.d.ts +18 -0
  276. package/dist/components/ui/sheet.js +181 -0
  277. package/dist/components/ui/sheet.js.map +1 -0
  278. package/dist/components/ui/sidebar.d.ts +94 -0
  279. package/dist/components/ui/sidebar.js +805 -0
  280. package/dist/components/ui/sidebar.js.map +1 -0
  281. package/dist/components/ui/skeleton.d.ts +5 -0
  282. package/dist/components/ui/skeleton.js +22 -0
  283. package/dist/components/ui/skeleton.js.map +1 -0
  284. package/dist/components/ui/slider.d.ts +7 -0
  285. package/dist/components/ui/slider.js +66 -0
  286. package/dist/components/ui/slider.js.map +1 -0
  287. package/dist/components/ui/sonner.d.ts +6 -0
  288. package/dist/components/ui/sonner.js +38 -0
  289. package/dist/components/ui/sonner.js.map +1 -0
  290. package/dist/components/ui/status-badge.d.ts +38 -0
  291. package/dist/components/ui/status-badge.js +77 -0
  292. package/dist/components/ui/status-badge.js.map +1 -0
  293. package/dist/components/ui/table.d.ts +13 -0
  294. package/dist/components/ui/table.js +115 -0
  295. package/dist/components/ui/table.js.map +1 -0
  296. package/dist/components/ui/tabs.d.ts +15 -0
  297. package/dist/components/ui/tabs.js +93 -0
  298. package/dist/components/ui/tabs.js.map +1 -0
  299. package/dist/components/ui/textarea.d.ts +6 -0
  300. package/dist/components/ui/textarea.js +25 -0
  301. package/dist/components/ui/textarea.js.map +1 -0
  302. package/dist/components/ui/tip.d.ts +12 -0
  303. package/dist/components/ui/tip.js +61 -0
  304. package/dist/components/ui/tip.js.map +1 -0
  305. package/dist/components/ui/toggle-group.d.ts +14 -0
  306. package/dist/components/ui/toggle-group.js +104 -0
  307. package/dist/components/ui/toggle-group.js.map +1 -0
  308. package/dist/components/ui/toggle-switch.d.ts +10 -0
  309. package/dist/components/ui/toggle-switch.js +33 -0
  310. package/dist/components/ui/toggle-switch.js.map +1 -0
  311. package/dist/components/ui/toggle.d.ts +13 -0
  312. package/dist/components/ui/toggle.js +51 -0
  313. package/dist/components/ui/toggle.js.map +1 -0
  314. package/dist/components/ui/tooltip.d.ts +10 -0
  315. package/dist/components/ui/tooltip.js +68 -0
  316. package/dist/components/ui/tooltip.js.map +1 -0
  317. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  318. package/dist/components/ui/view-segmented-control.js +167 -0
  319. package/dist/components/ui/view-segmented-control.js.map +1 -0
  320. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  321. package/dist/hooks/use-app-theme.d.ts +24 -0
  322. package/dist/hooks/use-app-theme.js +286 -0
  323. package/dist/hooks/use-app-theme.js.map +1 -0
  324. package/dist/hooks/use-coach-mark.d.ts +86 -0
  325. package/dist/hooks/use-coach-mark.js +218 -0
  326. package/dist/hooks/use-coach-mark.js.map +1 -0
  327. package/dist/hooks/use-mobile.d.ts +3 -0
  328. package/dist/hooks/use-mobile.js +29 -0
  329. package/dist/hooks/use-mobile.js.map +1 -0
  330. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  331. package/dist/hooks/use-mod-key-label.js +25 -0
  332. package/dist/hooks/use-mod-key-label.js.map +1 -0
  333. package/dist/index.d.ts +120 -0
  334. package/dist/index.js +13324 -0
  335. package/dist/index.js.map +1 -0
  336. package/dist/lib/compose-refs.d.ts +6 -0
  337. package/dist/lib/compose-refs.js +17 -0
  338. package/dist/lib/compose-refs.js.map +1 -0
  339. package/dist/lib/conditional-rule-match.d.ts +30 -0
  340. package/dist/lib/conditional-rule-match.js +66 -0
  341. package/dist/lib/conditional-rule-match.js.map +1 -0
  342. package/dist/lib/data-list-display-options.d.ts +26 -0
  343. package/dist/lib/data-list-display-options.js +14 -0
  344. package/dist/lib/data-list-display-options.js.map +1 -0
  345. package/dist/lib/data-list-view-registry.d.ts +2 -0
  346. package/dist/lib/data-list-view-registry.js +102 -0
  347. package/dist/lib/data-list-view-registry.js.map +1 -0
  348. package/dist/lib/data-list-view-surface.d.ts +2 -0
  349. package/dist/lib/data-list-view-surface.js +80 -0
  350. package/dist/lib/data-list-view-surface.js.map +1 -0
  351. package/dist/lib/data-list-view.d.ts +21 -0
  352. package/dist/lib/data-list-view.js +25 -0
  353. package/dist/lib/data-list-view.js.map +1 -0
  354. package/dist/lib/date-filter.d.ts +22 -0
  355. package/dist/lib/date-filter.js +61 -0
  356. package/dist/lib/date-filter.js.map +1 -0
  357. package/dist/lib/dev-log.d.ts +8 -0
  358. package/dist/lib/dev-log.js +10 -0
  359. package/dist/lib/dev-log.js.map +1 -0
  360. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  361. package/dist/lib/dropdown-menu-surface.js +6 -0
  362. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  363. package/dist/lib/editable-target.d.ts +12 -0
  364. package/dist/lib/editable-target.js +12 -0
  365. package/dist/lib/editable-target.js.map +1 -0
  366. package/dist/lib/list-page-table-properties.d.ts +35 -0
  367. package/dist/lib/list-page-table-properties.js +81 -0
  368. package/dist/lib/list-page-table-properties.js.map +1 -0
  369. package/dist/lib/raf-throttle.d.ts +23 -0
  370. package/dist/lib/raf-throttle.js +27 -0
  371. package/dist/lib/raf-throttle.js.map +1 -0
  372. package/dist/lib/row-height.d.ts +16 -0
  373. package/dist/lib/row-height.js +10 -0
  374. package/dist/lib/row-height.js.map +1 -0
  375. package/dist/lib/table-properties-types.d.ts +83 -0
  376. package/dist/lib/table-properties-types.js +19 -0
  377. package/dist/lib/table-properties-types.js.map +1 -0
  378. package/dist/lib/utils.d.ts +5 -0
  379. package/dist/lib/utils.js +11 -0
  380. package/dist/lib/utils.js.map +1 -0
  381. package/package.json +83 -19
  382. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  383. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  384. package/src/components/data-table/index.tsx +1678 -0
  385. package/src/components/data-table/pagination.tsx +255 -0
  386. package/src/components/data-table/types.ts +96 -0
  387. package/src/components/data-table/use-table-state.ts +767 -0
  388. package/src/components/data-views/board-card-primitives.tsx +93 -0
  389. package/src/components/data-views/data-row-list.tsx +183 -0
  390. package/src/components/data-views/finder-panel-view.tsx +405 -0
  391. package/src/components/data-views/folder-grid-view.tsx +86 -0
  392. package/src/components/data-views/hub-table.tsx +498 -0
  393. package/src/components/data-views/index.ts +28 -0
  394. package/src/components/data-views/list-page-board-card.tsx +192 -0
  395. package/src/components/data-views/list-page-board-template.tsx +122 -0
  396. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  397. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  398. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  399. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  400. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  401. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  402. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  403. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  404. package/src/components/table-properties/column-row.tsx +90 -0
  405. package/src/components/table-properties/draggable-list.ts +54 -0
  406. package/src/components/table-properties/drawer-button.tsx +300 -0
  407. package/src/components/table-properties/drawer.tsx +1148 -0
  408. package/src/components/table-properties/filter-card.tsx +251 -0
  409. package/src/components/table-properties/index.ts +36 -0
  410. package/src/components/table-properties/sort-card.tsx +63 -0
  411. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  412. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  413. package/src/components/templates/index.ts +33 -0
  414. package/src/components/templates/list-page.tsx +602 -0
  415. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  416. package/src/components/ui/accordion.tsx +92 -0
  417. package/src/components/ui/alert-dialog.tsx +221 -0
  418. package/src/components/ui/avatar.tsx +13 -2
  419. package/src/components/ui/banner.tsx +2 -2
  420. package/src/components/ui/button.tsx +4 -4
  421. package/src/components/ui/calendar.tsx +1 -1
  422. package/src/components/ui/coach-mark.tsx +1 -1
  423. package/src/components/ui/context-menu.tsx +291 -0
  424. package/src/components/ui/date-picker-field.tsx +2 -2
  425. package/src/components/ui/dot-pattern.tsx +183 -0
  426. package/src/components/ui/export-drawer.tsx +375 -0
  427. package/src/components/ui/hover-card.tsx +66 -0
  428. package/src/components/ui/key-metrics-context.tsx +78 -0
  429. package/src/components/ui/key-metrics.tsx +1133 -0
  430. package/src/components/ui/list-page-view-frame.tsx +64 -0
  431. package/src/components/ui/page-header.tsx +244 -0
  432. package/src/components/ui/payment-card-fields.tsx +2 -2
  433. package/src/components/ui/resizable.tsx +68 -0
  434. package/src/components/ui/scroll-area.tsx +72 -0
  435. package/src/components/ui/selection-tile-grid.tsx +9 -2
  436. package/src/components/ui/sidebar.tsx +84 -12
  437. package/src/components/ui/slider.tsx +83 -0
  438. package/src/globals.css +2201 -7
  439. package/src/globals.d.ts +20 -0
  440. package/src/index.ts +68 -1
  441. package/src/lib/conditional-rule-match.ts +119 -0
  442. package/src/lib/data-list-display-options.ts +35 -0
  443. package/src/lib/data-list-view-registry.ts +104 -0
  444. package/src/lib/data-list-view-surface.ts +83 -0
  445. package/src/lib/data-list-view.ts +47 -0
  446. package/src/lib/dev-log.ts +10 -0
  447. package/src/lib/editable-target.ts +20 -0
  448. package/src/lib/list-page-table-properties.ts +48 -0
  449. package/src/lib/raf-throttle.ts +45 -0
  450. package/src/lib/row-height.ts +19 -0
  451. package/src/lib/table-properties-types.ts +98 -0
  452. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  453. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
  454. package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
  455. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  456. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
  457. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  458. package/template/AGENTS.md +104 -78
  459. package/template/app/(app)/dashboard/loading.tsx +15 -3
  460. package/template/app/(app)/dashboard/page.tsx +14 -2
  461. package/template/app/(app)/examples/page.tsx +0 -2
  462. package/template/app/(app)/layout.tsx +17 -4
  463. package/template/app/(app)/loading.tsx +18 -1
  464. package/template/app/(app)/question-bank/find/page.tsx +1 -2
  465. package/template/app/(app)/question-bank/layout.tsx +1 -1
  466. package/template/app/(app)/question-bank/library/page.tsx +1 -2
  467. package/template/app/(app)/question-bank/list/page.tsx +1 -2
  468. package/template/app/(app)/question-bank/new/page.tsx +15 -20
  469. package/template/app/(app)/question-bank/page.tsx +1 -2
  470. package/template/app/(app)/settings/page.tsx +5 -4
  471. package/template/app/globals.css +14 -16
  472. package/template/components/ask-leo-sidebar.tsx +5 -1
  473. package/template/components/brand-color-picker.tsx +2 -2
  474. package/template/components/charts-overview.tsx +1 -1
  475. package/template/components/compliance-board-view.tsx +142 -0
  476. package/template/components/compliance-client.tsx +92 -0
  477. package/template/components/compliance-page-header.tsx +89 -0
  478. package/template/components/compliance-table.tsx +468 -0
  479. package/template/components/dashboard-report-charts.tsx +1 -1
  480. package/template/components/dashboard-tabs.tsx +1 -1
  481. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  482. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  483. package/template/components/data-table/index.tsx +1 -1634
  484. package/template/components/data-table/pagination.tsx +1 -255
  485. package/template/components/data-table/types.ts +1 -94
  486. package/template/components/data-table/use-table-state.test.ts +420 -0
  487. package/template/components/data-table/use-table-state.ts +1 -758
  488. package/template/components/data-view-dashboard-charts-compliance.tsx +963 -0
  489. package/template/components/data-view-dashboard-charts-team.tsx +971 -0
  490. package/template/components/data-view-dashboard-charts.tsx +1503 -0
  491. package/template/components/data-views/board-card-primitives.tsx +1 -93
  492. package/template/components/data-views/data-row-list.tsx +1 -183
  493. package/template/components/data-views/finder-panel-view.tsx +1 -405
  494. package/template/components/data-views/folder-grid-view.tsx +1 -86
  495. package/template/components/data-views/hub-table.tsx +1 -0
  496. package/template/components/data-views/index.ts +50 -37
  497. package/template/components/data-views/list-page-board-card.tsx +1 -192
  498. package/template/components/data-views/list-page-board-template.tsx +1 -122
  499. package/template/components/data-views/list-page-connected-view-body.tsx +1 -66
  500. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  501. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -68
  502. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  503. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  504. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  505. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  506. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  507. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  508. package/template/components/export-drawer.test.tsx +71 -0
  509. package/template/components/export-drawer.tsx +1 -375
  510. package/template/components/exxat-product-logo.tsx +5 -5
  511. package/template/components/hub-tree-panel-view.tsx +2 -2
  512. package/template/components/invite-collaborators-drawer.tsx +3 -3
  513. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  514. package/template/components/key-metrics.tsx +1 -1063
  515. package/template/components/leo-insight-indicator.tsx +2 -2
  516. package/template/components/new-placement-back-btn.tsx +28 -0
  517. package/template/components/new-placement-form.tsx +942 -0
  518. package/template/components/new-question-composer.tsx +456 -408
  519. package/template/components/onboarding/index.ts +9 -0
  520. package/template/components/onboarding/onboarding-01.tsx +1 -1
  521. package/template/components/onboarding/onboarding-02.tsx +1 -1
  522. package/template/components/onboarding/onboarding-03.tsx +1 -1
  523. package/template/components/onboarding/onboarding-04.tsx +1 -1
  524. package/template/components/page-header.tsx +8 -226
  525. package/template/components/placement-board-card.tsx +250 -0
  526. package/template/components/placement-detail.tsx +438 -0
  527. package/template/components/placements-board-view.tsx +397 -0
  528. package/template/components/placements-client.tsx +220 -0
  529. package/template/components/placements-list-view.tsx +124 -0
  530. package/template/components/placements-page-header.tsx +166 -0
  531. package/template/components/placements-table-cells.test.tsx +22 -0
  532. package/template/components/placements-table-cells.tsx +173 -0
  533. package/template/components/placements-table-columns.tsx +210 -0
  534. package/template/components/placements-table.tsx +934 -0
  535. package/template/components/product-switcher.tsx +3 -4
  536. package/template/components/product-wordmark.tsx +2 -1
  537. package/template/components/question-bank-client.tsx +5 -5
  538. package/template/components/question-bank-hub-client.tsx +1 -1
  539. package/template/components/question-bank-new-folder-sheet.tsx +2 -2
  540. package/template/components/question-bank-secondary-nav.tsx +3 -3
  541. package/template/components/question-bank-table.tsx +541 -431
  542. package/template/components/rotations-empty-state.tsx +50 -0
  543. package/template/components/rotations-panel-activator.tsx +8 -0
  544. package/template/components/settings-appearance-card.tsx +3 -4
  545. package/template/components/settings-client.tsx +15 -59
  546. package/template/components/settings-form-row.tsx +4 -9
  547. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  548. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +59 -74
  549. package/template/components/sidebar/index.ts +16 -0
  550. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  551. package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +50 -7
  552. package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
  553. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  554. package/template/components/site-header.tsx +1 -1
  555. package/template/components/sites-board-view.tsx +67 -0
  556. package/template/components/sites-client.tsx +154 -0
  557. package/template/components/sites-table.tsx +249 -0
  558. package/template/components/table-properties/column-row.tsx +1 -90
  559. package/template/components/table-properties/draggable-list.ts +1 -49
  560. package/template/components/table-properties/drawer-button.tsx +1 -262
  561. package/template/components/table-properties/drawer.tsx +1 -1166
  562. package/template/components/table-properties/filter-card.tsx +1 -251
  563. package/template/components/table-properties/sort-card.tsx +1 -59
  564. package/template/components/table-properties/types.ts +28 -71
  565. package/template/components/team-board-view.tsx +122 -0
  566. package/template/components/team-client.tsx +100 -0
  567. package/template/components/team-page-header.tsx +92 -0
  568. package/template/components/team-table.tsx +553 -0
  569. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  570. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  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 +1 -1
  575. package/template/components/ui/accordion.tsx +1 -0
  576. package/template/components/ui/alert-dialog.tsx +1 -0
  577. package/template/components/ui/context-menu.tsx +1 -0
  578. package/template/components/ui/dot-pattern.tsx +1 -183
  579. package/template/components/ui/hover-card.tsx +1 -0
  580. package/template/components/ui/resizable.tsx +1 -68
  581. package/template/components/ui/scroll-area.tsx +1 -0
  582. package/template/components/ui/slider.tsx +1 -0
  583. package/template/docs/blueprints/README.md +86 -0
  584. package/template/docs/blueprints/_template.md +91 -0
  585. package/template/docs/blueprints/board-card.md +123 -0
  586. package/template/docs/blueprints/data-table.md +139 -0
  587. package/template/docs/blueprints/key-metrics.md +128 -0
  588. package/template/docs/blueprints/list-page-template.md +123 -0
  589. package/template/docs/blueprints/page-header.md +130 -0
  590. package/template/docs/command-menu-pattern.md +1 -1
  591. package/template/docs/component-selection-guide.md +224 -0
  592. package/template/docs/components-audit-2026-05.md +158 -0
  593. package/template/docs/data-views-pattern.md +17 -54
  594. package/template/docs/drawer-vs-dialog-pattern.md +1 -3
  595. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  596. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  597. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  598. package/template/docs/migrations/README.md +100 -0
  599. package/template/docs/migrations/_template.md +64 -0
  600. package/template/docs/shell-surface-elevation-pattern.md +3 -5
  601. package/template/docs/token-taxonomy.md +416 -0
  602. package/template/eslint.config.mjs +27 -0
  603. package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
  604. package/template/lib/command-menu-config.ts +0 -1
  605. package/template/lib/command-menu-search-data.ts +27 -11
  606. package/template/lib/compliance-supported-views.ts +10 -0
  607. package/template/lib/conditional-rule-match.ts +6 -97
  608. package/template/lib/data-list-display-options.ts +1 -49
  609. package/template/lib/data-list-view-registry.ts +1 -104
  610. package/template/lib/data-list-view-surface.ts +1 -83
  611. package/template/lib/data-list-view.ts +1 -47
  612. package/template/lib/data-view-dashboard-placements-layout.ts +215 -0
  613. package/template/lib/data-view-dashboard-storage.ts +35 -38
  614. package/template/lib/dev-log.ts +1 -8
  615. package/template/lib/editable-target.ts +1 -10
  616. package/template/lib/list-page-table-properties.ts +1 -48
  617. package/template/lib/list-status-badges.ts +97 -4
  618. package/template/lib/mock/compliance-kpi.ts +61 -0
  619. package/template/lib/mock/compliance.ts +146 -0
  620. package/template/lib/mock/navigation.tsx +0 -9
  621. package/template/lib/mock/placements-kpi.ts +134 -0
  622. package/template/lib/mock/placements.ts +176 -0
  623. package/template/lib/mock/sites-directory.ts +16 -0
  624. package/template/lib/mock/sites-kpi.ts +25 -0
  625. package/template/lib/mock/team-kpi.ts +60 -0
  626. package/template/lib/mock/team.ts +118 -0
  627. package/template/lib/placement-board-card-layout.ts +79 -0
  628. package/template/lib/placements-supported-views.ts +12 -0
  629. package/template/lib/question-bank-supported-views.ts +0 -1
  630. package/template/lib/raf-throttle.ts +1 -45
  631. package/template/lib/row-height.ts +4 -10
  632. package/template/lib/sidebar-state-cookie.ts +11 -2
  633. package/template/lib/sites-supported-views.ts +10 -0
  634. package/template/lib/table-state-lifecycle.ts +2 -2
  635. package/template/lib/team-supported-views.ts +10 -0
  636. package/template/package.json +1 -0
  637. package/template/tests/setup.ts +25 -0
  638. package/consumer-extras/AGENTS.md +0 -76
  639. package/consumer-extras/cursor-skills/exxat-consumer-app/SKILL.md +0 -37
  640. package/consumer-extras/cursor-skills/exxat-focused-workflow-page/SKILL.md +0 -57
  641. package/consumer-extras/patterns/consumer-app-pattern.md +0 -39
  642. package/consumer-extras/patterns/focused-workflow-page-pattern.md +0 -84
  643. package/src/components/ui/button-group.tsx +0 -81
  644. package/src/theme.css +0 -16
  645. package/src/tokens/README.md +0 -15
  646. package/src/tokens/base.css +0 -337
  647. package/src/tokens/high-contrast.css +0 -1195
  648. package/src/tokens/layers.css +0 -224
  649. package/src/tokens/tailwind-bridge.css +0 -118
  650. package/src/tokens/themes.css +0 -201
  651. package/template/app/(app)/data-list/layout.tsx +0 -43
  652. package/template/app/(app)/data-list/page.tsx +0 -10
  653. package/template/app/(app)/examples/focused-workflow/page.tsx +0 -5
  654. package/template/components/app-route-loading.tsx +0 -14
  655. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  656. package/template/components/dashboard-onboarding.tsx +0 -21
  657. package/template/components/data-views/list-page-calendar-view.tsx +0 -593
  658. package/template/components/data-views/list-page-folder-columns-panel.tsx +0 -345
  659. package/template/components/examples/focused-workflow-showcase.tsx +0 -183
  660. package/template/components/list-hub-board-view.tsx +0 -68
  661. package/template/components/list-hub-client.tsx +0 -186
  662. package/template/components/list-hub-list-view.tsx +0 -36
  663. package/template/components/list-hub-panel-activator.tsx +0 -8
  664. package/template/components/list-hub-secondary-nav.tsx +0 -121
  665. package/template/components/list-hub-table.tsx +0 -336
  666. package/template/components/question-bank-folder-columns-panel.tsx +0 -104
  667. package/template/components/question-bank-list-view.tsx +0 -53
  668. package/template/components/secondary-panel/nav-link-rows.tsx +0 -83
  669. package/template/components/secondary-panels/list-hub-panel.tsx +0 -39
  670. package/template/components/secondary-panels/question-bank-panel.tsx +0 -39
  671. package/template/components/secondary-panels/registry.tsx +0 -15
  672. package/template/components/section-cards.tsx +0 -106
  673. package/template/components/templates/focused-workflow-layouts.tsx +0 -448
  674. package/template/components/templates/focused-workflow-page-template.tsx +0 -69
  675. package/template/components/templates/page-loading-shell.tsx +0 -262
  676. package/template/components/ui/button-group.tsx +0 -1
  677. package/template/docs/consumer-app-pattern.md +0 -39
  678. package/template/docs/focused-workflow-page-pattern.md +0 -84
  679. package/template/lib/list-hub-nav.ts +0 -121
  680. package/template/lib/mock/list-hub-directory.ts +0 -27
  681. package/template/lib/mock/list-hub-kpi.ts +0 -27
  682. package/template/lib/page-loading-variant.ts +0 -40
  683. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  684. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  685. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  686. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  687. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
  688. /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
@@ -0,0 +1,50 @@
1
+ "use client"
2
+
3
+ /**
4
+ * Rotations hub — main canvas when no rotation detail is selected.
5
+ * Pairs with SecondaryPanel (nested sidebar); CTA reopens the panel if closed.
6
+ */
7
+
8
+ import { Button } from "@/components/ui/button"
9
+ import { useSecondaryPanel } from "@/components/sidebar"
10
+
11
+ export function RotationsEmptyState() {
12
+ const { openPanel } = useSecondaryPanel()
13
+
14
+ return (
15
+ <section
16
+ aria-labelledby="rotations-empty-title"
17
+ className="flex flex-1 flex-col items-center justify-center rounded-xl border border-dashed border-border/80 bg-muted/25 px-6 py-12 text-center min-h-[min(420px,calc(100svh-var(--header-height)-6rem))]"
18
+ >
19
+ <div className="mb-6 w-full max-w-[min(100%,280px)] shrink-0">
20
+ {/* Static SVG hero, above the fold — next/image can't optimize SVGs
21
+ without `dangerouslyAllowSVG`, and lazy-loading is wrong here. */}
22
+ {/* eslint-disable-next-line @next/next/no-img-element -- SVG; next/image can't optimize without dangerouslyAllowSVG */}
23
+ <img
24
+ src="/Illustration/Rotation.svg"
25
+ alt=""
26
+ width={622}
27
+ height={559}
28
+ decoding="async"
29
+ className="h-auto w-full select-none"
30
+ />
31
+ </div>
32
+ <h2
33
+ id="rotations-empty-title"
34
+ className="font-heading text-xl font-semibold tracking-tight text-foreground sm:text-2xl"
35
+ >
36
+ Select a rotation
37
+ </h2>
38
+ <p className="mt-2 max-w-md text-sm leading-relaxed text-muted-foreground">
39
+ Use the rotations panel next to the sidebar to browse cycles, open a rotation for
40
+ details, or review schedules and assigned students.
41
+ </p>
42
+ <div className="mt-8 flex flex-wrap items-center justify-center gap-3">
43
+ <Button type="button" size="lg" onClick={() => openPanel("rotations")}>
44
+ <i className="fa-light fa-sidebar text-[15px]" aria-hidden="true" />
45
+ Open rotations panel
46
+ </Button>
47
+ </div>
48
+ </section>
49
+ )
50
+ }
@@ -0,0 +1,8 @@
1
+ "use client"
2
+
3
+ import { useAutoPanel } from "@/components/sidebar"
4
+
5
+ export function RotationsPanelActivator() {
6
+ useAutoPanel("rotations")
7
+ return null
8
+ }
@@ -518,7 +518,7 @@ export function SettingsAppearanceCard() {
518
518
  )
519
519
 
520
520
  return (
521
- <>
521
+ <section id="appearance" className="scroll-mt-20">
522
522
  <header className="mb-8 space-y-1">
523
523
  <h2 className="text-lg font-semibold text-foreground">Appearance &amp; display</h2>
524
524
  <p className="text-sm text-muted-foreground">Saved in this browser.</p>
@@ -529,7 +529,6 @@ export function SettingsAppearanceCard() {
529
529
  ) : (
530
530
  <FieldGroup className="gap-8">
531
531
  <SettingsFormRow
532
- layout="stacked"
533
532
  label="Products"
534
533
  description="Recolour the brand mark + wordmark for each product. Switch the active product from the sidebar."
535
534
  >
@@ -623,7 +622,7 @@ export function SettingsAppearanceCard() {
623
622
  side="top"
624
623
  >
625
624
  <span
626
- className="inline-flex shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-foreground"
625
+ className="inline-flex shrink-0 items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium uppercase tracking-wide text-foreground"
627
626
  aria-label="Active product"
628
627
  >
629
628
  <i
@@ -863,6 +862,6 @@ export function SettingsAppearanceCard() {
863
862
  </DialogFooter>
864
863
  </DialogContent>
865
864
  </Dialog>
866
- </>
865
+ </section>
867
866
  )
868
867
  }
@@ -39,19 +39,6 @@ import { SettingsAppearanceCard } from "@/components/settings-appearance-card"
39
39
  import { SettingsFormRow } from "@/components/settings-form-row"
40
40
  import { FieldGroup } from "@/components/ui/field"
41
41
  import { FilterTextValueInput } from "@/components/data-table/filter-text-value-input"
42
- import {
43
- FocusedWorkflowSidebarSections,
44
- type FocusedWorkflowSidebarSection,
45
- } from "@/components/templates/focused-workflow-layouts"
46
- import { PageHeader } from "@/components/page-header"
47
-
48
- const SETTINGS_SECTIONS: readonly FocusedWorkflowSidebarSection[] = [
49
- { id: "account", label: "Account" },
50
- { id: "appearance", label: "Appearance" },
51
- { id: "input-formats", label: "Input formats" },
52
- { id: "banner", label: "System banner" },
53
- { id: "tours", label: "Guided tours" },
54
- ]
55
42
 
56
43
  const SYSTEM_BANNER_VARIANTS: SystemBannerVariant[] = [
57
44
  "info",
@@ -376,32 +363,8 @@ function buildFlowStatuses() {
376
363
  }))
377
364
  }
378
365
 
379
- function sectionIdFromHash(hash: string): string {
380
- const id = hash.startsWith("#") ? hash.slice(1) : hash
381
- if (id && SETTINGS_SECTIONS.some(s => s.id === id)) return id
382
- return SETTINGS_SECTIONS[0]!.id
383
- }
384
-
385
366
  export function SettingsClient() {
386
367
  const router = useRouter()
387
- const [activeSection, setActiveSection] = React.useState(() =>
388
- typeof window !== "undefined" ? sectionIdFromHash(window.location.hash) : SETTINGS_SECTIONS[0]!.id,
389
- )
390
-
391
- React.useEffect(() => {
392
- const syncFromHash = () => {
393
- const id = sectionIdFromHash(window.location.hash)
394
- setActiveSection(id)
395
- if (window.location.hash) {
396
- requestAnimationFrame(() => {
397
- document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" })
398
- })
399
- }
400
- }
401
- syncFromHash()
402
- window.addEventListener("hashchange", syncFromHash)
403
- return () => window.removeEventListener("hashchange", syncFromHash)
404
- }, [])
405
368
 
406
369
  const [demoPhone, setDemoPhone] = React.useState("")
407
370
  const [demoZip, setDemoZip] = React.useState("")
@@ -440,27 +403,20 @@ export function SettingsClient() {
440
403
  }
441
404
 
442
405
  return (
443
- <FocusedWorkflowSidebarSections
444
- sections={SETTINGS_SECTIONS}
445
- activeSectionId={activeSection}
446
- onSectionSelect={id => {
447
- setActiveSection(id)
448
- const nextHash = `#${id}`
449
- if (window.location.hash !== nextHash) {
450
- window.history.replaceState(null, "", `${window.location.pathname}${window.location.search}${nextHash}`)
451
- }
452
- document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" })
453
- }}
454
- navLabel="Settings sections"
455
- header={
456
- <PageHeader
457
- title="Settings"
458
- subtitle="Preferences and tools for this workspace. Display options apply on this device and are stored in your browser."
459
- className="px-0 pt-0 pb-0 lg:px-0"
460
- />
461
- }
462
- >
463
- <div className="flex flex-col gap-20">
406
+ <div className="flex w-full min-w-0 flex-col">
407
+ <div>
408
+ <h1
409
+ className="text-2xl font-semibold tracking-tight leading-tight text-foreground"
410
+ style={{ fontFamily: "var(--font-heading)" }}
411
+ >
412
+ Settings
413
+ </h1>
414
+ <p className="mt-1 text-sm leading-relaxed text-muted-foreground">
415
+ Preferences and tools for this workspace. Display options apply on this device and are stored in your browser.
416
+ </p>
417
+ </div>
418
+
419
+ <div className="mt-10 flex flex-col gap-20">
464
420
  <section id="account" className="scroll-mt-20">
465
421
  <header className="mb-6 space-y-1">
466
422
  <h2 className="text-lg font-semibold text-foreground">Account</h2>
@@ -578,6 +534,6 @@ export function SettingsClient() {
578
534
  </div>
579
535
  </section>
580
536
  </div>
581
- </FocusedWorkflowSidebarSections>
537
+ </div>
582
538
  )
583
539
  }
@@ -5,7 +5,7 @@ import { Label } from "@/components/ui/label"
5
5
  import { cn } from "@/lib/utils"
6
6
 
7
7
  /**
8
- * Settings row inline (label left, control right on lg+) or stacked (label above).
8
+ * Two-column settings row: label + helper on the left, controls on the right.
9
9
  */
10
10
  export function SettingsFormRow({
11
11
  label,
@@ -13,27 +13,22 @@ export function SettingsFormRow({
13
13
  htmlFor,
14
14
  children,
15
15
  className,
16
- layout = "inline",
17
16
  }: {
18
17
  label: string
19
18
  description?: string
20
19
  htmlFor?: string
21
20
  children: React.ReactNode
22
21
  className?: string
23
- /** `stacked` — label block above full-width controls (wide panels, product lists). */
24
- layout?: "inline" | "stacked"
25
22
  }) {
26
23
  return (
27
24
  <div
28
25
  className={cn(
29
- "grid grid-cols-1 gap-3 sm:gap-4 border-b border-border/70 pb-8 last:border-0 last:pb-0",
30
- layout === "inline" &&
31
- "lg:grid-cols-[minmax(0,220px)_minmax(0,1fr)] lg:gap-10 lg:items-start",
32
- layout === "stacked" && "gap-4",
26
+ "grid grid-cols-1 gap-3 sm:gap-4 lg:grid-cols-[minmax(0,220px)_minmax(0,1fr)] lg:gap-10 lg:items-start",
27
+ "border-b border-border/70 pb-8 last:border-0 last:pb-0",
33
28
  className,
34
29
  )}
35
30
  >
36
- <div className="space-y-1 text-start lg:pt-1">
31
+ <div className="space-y-1 lg:pt-1 text-start">
37
32
  <Label htmlFor={htmlFor} className="text-sm font-medium text-foreground">
38
33
  {label}
39
34
  </Label>
@@ -7,7 +7,7 @@
7
7
  * Radix ID mismatch is suppressed at the CollapsibleContent level instead.
8
8
  */
9
9
  import type { ComponentProps } from "react"
10
- import { AppSidebar } from "@/components/app-sidebar"
10
+ import { AppSidebar } from "./app-sidebar"
11
11
  import type { Sidebar } from "@/components/ui/sidebar"
12
12
 
13
13
  export function AppSidebarDynamic(props: ComponentProps<typeof Sidebar>) {
@@ -67,8 +67,8 @@ import { useModKeyLabel } from "@/hooks/use-mod-key-label"
67
67
  import { useLocationHash } from "@/hooks/use-location-hash"
68
68
  import { useSidebarReflowZoom } from "@/hooks/use-sidebar-reflow-zoom"
69
69
  import { useProduct, type Product } from "@/contexts/product-context"
70
- import { NavUser } from "@/components/nav-user"
71
- import { useSecondaryPanel } from "@/components/secondary-panel"
70
+ import { NavUser } from "./nav-user"
71
+ import { useSecondaryPanel } from "./secondary-panel"
72
72
  import { ExxatProductLogo, ExxatProductMark } from "@/components/exxat-product-logo"
73
73
  import { motionHeaderEnter } from "@/lib/motion-ui"
74
74
  import { customProductBrandConfig, productBrandLabel } from "@/lib/product-brand"
@@ -105,22 +105,11 @@ function normalizedLocationHash(locationHash: string): string {
105
105
  return locationHash.startsWith("#") ? locationHash.slice(1) : locationHash
106
106
  }
107
107
 
108
- /**
109
- * Paths where a sibling sidebar row uses `#fragment` on the same pathname
110
- * (e.g. Settings vs Tokens & themes). The plain-path row must not stay active
111
- * when the hash belongs to that sibling.
112
- */
113
- const NAV_EXCLUSIVE_HASH_BY_PATH: Readonly<Record<string, readonly string[]>> = {
114
- "/settings": ["appearance"],
115
- "/help": ["more"],
116
- }
117
-
118
108
  /**
119
109
  * Whether `pathname` (+ optional `location.hash`) matches a sidebar `href`.
120
110
  * When several links share the same path (e.g. `/settings`), disambiguate with `#fragment`
121
111
  * in each `href` — those rows use the `frag !== null` branch below.
122
- * For `href` without `#…`, an in-page hash (e.g. QB view tabs) does not clear the match,
123
- * except when the hash is reserved for a hash-sibling row on that path.
112
+ * For `href` without `#…`, an in-page hash (e.g. QB view tabs) does not clear the match.
124
113
  */
125
114
  function isNavActive(pathname: string, url: string, locationHash = ""): boolean {
126
115
  const pathOnly = navUrlPath(url)
@@ -142,13 +131,7 @@ function isNavActive(pathname: string, url: string, locationHash = ""): boolean
142
131
 
143
132
  if (pathOnly === "/") return pathname === "/" && h === ""
144
133
  /** Exact path match — ignore `location.hash` when the nav `href` has no `#…` fragment (QB view tabs use hash). */
145
- if (pathname === pathOnly) {
146
- if (h !== "") {
147
- const exclusive = NAV_EXCLUSIVE_HASH_BY_PATH[pathOnly]
148
- if (exclusive?.includes(h)) return false
149
- }
150
- return true
151
- }
134
+ if (pathname === pathOnly) return true
152
135
  // Design system library — active on hub and detail routes.
153
136
  if (pathOnly === "/library") {
154
137
  return pathname.startsWith("/library/")
@@ -440,7 +423,7 @@ function CollapsibleNavItem({ item, pathname }: { item: NavLinkItem; pathname: s
440
423
  </span>
441
424
  <span>{item.title}</span>
442
425
  <i
443
- className="fa-light fa-chevron-right ml-auto text-xs text-current transition-transform duration-200 ease-out group-data-[state=open]/collapsible:rotate-90 motion-reduce:transition-none"
426
+ className="fa-light fa-chevron-right ms-auto text-xs text-current transition-transform duration-200 ease-out group-data-[state=open]/collapsible:rotate-90 motion-reduce:transition-none"
444
427
  aria-hidden="true"
445
428
  />
446
429
  </SidebarMenuButton>
@@ -844,58 +827,60 @@ function ProductLogoButton() {
844
827
 
845
828
  return (
846
829
  <DropdownMenu>
847
- <DropdownMenuTrigger asChild>
848
- <SidebarMenuButton
849
- size="lg"
850
- tooltip={iconRail ? current.label : undefined}
851
- className={cn(
852
- "py-2 text-sidebar-foreground data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
853
- expandedOrMobile &&
854
- "h-auto min-h-12 !overflow-visible items-center [&>span:last-child]:!overflow-visible [&>span:last-child]:!whitespace-normal [&>span:last-child]:text-clip",
855
- "group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:justify-center",
856
- iconRail &&
857
- "group-data-[collapsible=icon]:!size-9 group-data-[collapsible=icon]:!min-h-9 group-data-[collapsible=icon]:!max-h-9 group-data-[collapsible=icon]:!p-0 group-data-[collapsible=icon]:overflow-visible",
858
- )}
859
- aria-label={`Current product: ${current.label}. Switch product`}
860
- suppressHydrationWarning
861
- >
862
- {iconRail ? (
863
- // Match the school selector footprint in the icon rail (32px frame,
864
- // 28px mark same visual weight as the avatar with inset padding).
865
- <span className="flex size-8 shrink-0 items-center justify-center">
866
- <ExxatProductMark product={current.id} className="size-7" />
867
- </span>
868
- ) : (
869
- <span className="flex min-h-0 min-w-0 flex-1 items-stretch gap-2">
870
- <span
871
- className="flex min-h-0 min-w-0 flex-1 items-center justify-start overflow-visible"
872
- aria-hidden="true"
873
- >
874
- <ExxatProductLogo
875
- product={current.id}
876
- variant="mutedSuffix"
877
- className="w-auto max-w-[min(100%,280px)] object-left object-contain"
878
- />
879
- </span>
880
- <span
881
- className="flex w-6 shrink-0 items-center justify-center self-stretch text-muted-foreground"
882
- aria-hidden="true"
883
- >
884
- <i
885
- className="fa-light fa-chevron-down block text-xs leading-none"
886
- aria-hidden="true"
887
- />
888
- </span>
889
- </span>
890
- )}
891
- </SidebarMenuButton>
892
- </DropdownMenuTrigger>
830
+ <Tooltip>
831
+ <TooltipTrigger asChild>
832
+ <DropdownMenuTrigger asChild>
833
+ <SidebarMenuButton
834
+ size="lg"
835
+ className={cn(
836
+ "py-2 text-sidebar-foreground data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
837
+ expandedOrMobile &&
838
+ "h-auto min-h-12 !overflow-visible items-center [&>span:last-child]:!overflow-visible [&>span:last-child]:!whitespace-normal [&>span:last-child]:text-clip",
839
+ "group-data-[collapsible=icon]:items-center group-data-[collapsible=icon]:justify-center",
840
+ iconRail &&
841
+ "group-data-[collapsible=icon]:!size-9 group-data-[collapsible=icon]:!min-h-9 group-data-[collapsible=icon]:!max-h-9 group-data-[collapsible=icon]:!p-0 group-data-[collapsible=icon]:overflow-visible",
842
+ )}
843
+ aria-label={`Current product: ${current.label}. Switch product`}
844
+ suppressHydrationWarning
845
+ >
846
+ {iconRail ? (
847
+ // Match the school selector footprint in the icon rail (32px frame,
848
+ // 28px mark same visual weight as the avatar with inset padding).
849
+ <span className="flex size-8 shrink-0 items-center justify-center">
850
+ <ExxatProductMark product={current.id} className="size-7" />
851
+ </span>
852
+ ) : (
853
+ <span className="flex min-h-0 min-w-0 flex-1 items-stretch gap-2">
854
+ <span
855
+ className="flex min-h-0 min-w-0 flex-1 items-center justify-start overflow-visible"
856
+ aria-hidden="true"
857
+ >
858
+ <ExxatProductLogo
859
+ product={current.id}
860
+ variant="mutedSuffix"
861
+ className="w-auto max-w-[min(100%,280px)] object-left object-contain"
862
+ />
863
+ </span>
864
+ <span
865
+ className="flex w-6 shrink-0 items-center justify-center self-stretch text-muted-foreground"
866
+ aria-hidden="true"
867
+ >
868
+ <i
869
+ className="fa-light fa-chevron-down block text-xs leading-none"
870
+ aria-hidden="true"
871
+ />
872
+ </span>
873
+ </span>
874
+ )}
875
+ </SidebarMenuButton>
876
+ </DropdownMenuTrigger>
877
+ </TooltipTrigger>
878
+ <TooltipContent side="right" align="center" hidden={state !== "collapsed" || isMobile}>
879
+ {current.label}
880
+ </TooltipContent>
881
+ </Tooltip>
893
882
 
894
- <DropdownMenuContent
895
- align="start"
896
- side={iconRail ? "right" : "bottom"}
897
- sideOffset={iconRail ? 8 : 4}
898
- >
883
+ <DropdownMenuContent align="start" side="right" sideOffset={8}>
899
884
  <DropdownMenuLabel className="text-xs text-muted-foreground">
900
885
  Switch product
901
886
  </DropdownMenuLabel>
@@ -913,7 +898,7 @@ function ProductLogoButton() {
913
898
  className="w-auto shrink-0 max-w-[min(100%,260px)]"
914
899
  />
915
900
  {p.id === product && (
916
- <i className="fa-solid fa-check ml-auto text-brand text-xs" aria-hidden="true" />
901
+ <i className="fa-solid fa-check ms-auto text-brand text-xs" aria-hidden="true" />
917
902
  )}
918
903
  </DropdownMenuItem>
919
904
  ))}
@@ -0,0 +1,16 @@
1
+ // Barrel re-export for the sidebar shell.
2
+ // Consumers SHOULD import via `@/components/sidebar`; per-file paths still
3
+ // work as escape hatch (e.g. `@/components/sidebar/secondary-panel`).
4
+ //
5
+ // See apps/web/docs/components-audit-2026-05.md §2.3.
6
+ export * from "./app-sidebar"
7
+ export * from "./app-sidebar-dynamic"
8
+ export * from "./sidebar-shell"
9
+ export * from "./sidebar-auto-collapse"
10
+ export * from "./sidebar-auto-open"
11
+ export * from "./nav-main"
12
+ export * from "./nav-secondary"
13
+ export * from "./nav-documents"
14
+ export * from "./nav-user"
15
+ export * from "./secondary-nav"
16
+ export * from "./secondary-panel"
@@ -293,7 +293,7 @@ export function SecondaryNavPanel({
293
293
  title={section.action.label}
294
294
  onClick={section.action.onClick}
295
295
  className={cn(
296
- "inline-flex size-6 items-center justify-center rounded-md -mr-1",
296
+ "inline-flex size-6 items-center justify-center rounded-md -me-1",
297
297
  "text-muted-foreground hover:text-interactive-hover-foreground hover:bg-interactive-hover-strong",
298
298
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
299
299
  )}
@@ -318,7 +318,7 @@ export function SecondaryNavPanel({
318
318
  placeholder={section.searchPlaceholder ?? "Search"}
319
319
  aria-label={`Search ${section.label}`}
320
320
  className={cn(
321
- "w-full h-7 pl-7 pr-2 rounded-md text-xs bg-background border border-border",
321
+ "w-full h-7 ps-7 pe-2 rounded-md text-xs bg-background border border-border",
322
322
  "placeholder:text-muted-foreground/70",
323
323
  "focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent"
324
324
  )}
@@ -4,14 +4,16 @@
4
4
  * SecondaryPanel — nested rail between the primary icon sidebar and content.
5
5
  * Full width shows hub scope nav; **compact** matches the primary sidebar icon rail (`w-12`).
6
6
  *
7
- * Chrome uses {@link NestedSecondaryPanelShell}. Panel bodies live in
8
- * `components/secondary-panels/` + {@link SECONDARY_PANELS}; hub nav stays domain-specific.
7
+ * Chrome uses {@link NestedSecondaryPanelShell}. Question bank body stays in
8
+ * `question-bank-secondary-nav.tsx` (domain-specific), not duplicated here.
9
9
  */
10
10
 
11
11
  import * as React from "react"
12
12
  import { useSidebar } from "@/components/ui/sidebar"
13
+ import { Tip } from "@/components/ui/tip"
14
+ import { Button } from "@/components/ui/button"
15
+ import { QuestionBankSecondaryNav } from "@/components/question-bank-secondary-nav"
13
16
  import { NestedSecondaryPanelShell } from "@/components/templates/nested-secondary-panel-shell"
14
- import { SECONDARY_PANELS } from "@/components/secondary-panels/registry"
15
17
  import { useSidebarReflowZoom } from "@/hooks/use-sidebar-reflow-zoom"
16
18
  import type { QuestionBankItem } from "@/lib/mock/question-bank"
17
19
  import type { QuestionBankFolder } from "@/lib/mock/question-bank-folders"
@@ -109,7 +111,10 @@ export function SecondaryPanelProvider({ children }: { children: React.ReactNode
109
111
  // zoom this stays the legacy behavior (full-width on open).
110
112
  setSecondaryPanelCompact(reflowZoom)
111
113
  setActivePanel(id)
112
- setOpen(false) // collapse main sidebar to icon rail
114
+ // `persist: false` collapsing the rail to make room for the secondary
115
+ // panel is an incidental layout side-effect; the user's saved
116
+ // expanded/collapsed preference (cookie) must not be overwritten by it.
117
+ setOpen(false, { persist: false }) // collapse main sidebar to icon rail
113
118
  },
114
119
  [setOpen, reflowZoom],
115
120
  )
@@ -120,9 +125,9 @@ export function SecondaryPanelProvider({ children }: { children: React.ReactNode
120
125
  const mainSidebar = opts?.mainSidebar ?? "leave"
121
126
  if (mainSidebar === "leave") return
122
127
  if (mainSidebar === "collapse") {
123
- setOpen(false)
128
+ setOpen(false, { persist: false })
124
129
  } else {
125
- setOpen(true) // expand main sidebar back
130
+ setOpen(true, { persist: false }) // expand main sidebar back
126
131
  }
127
132
  }, [setOpen])
128
133
 
@@ -164,9 +169,47 @@ export function SecondaryPanelProvider({ children }: { children: React.ReactNode
164
169
  // SecondaryPanel — the actual rendered panel
165
170
  // ─────────────────────────────────────────────────────────────────────────────
166
171
 
172
+ function QuestionBankPanel() {
173
+ const { collapseActiveSecondaryPanel, secondaryPanelCompact } = useSecondaryPanel()
174
+
175
+ if (secondaryPanelCompact) {
176
+ return <QuestionBankSecondaryNav />
177
+ }
178
+
179
+ return (
180
+ <>
181
+ <div className="flex items-center justify-between gap-2 px-4 pt-4 pb-2">
182
+ <h2
183
+ className="text-xl font-semibold leading-tight text-sidebar-foreground"
184
+ style={{ fontFamily: "var(--font-heading)" }}
185
+ >
186
+ Library
187
+ </h2>
188
+ <Tip label="Collapse to icons" side="bottom">
189
+ <Button
190
+ type="button"
191
+ size="icon"
192
+ variant="ghost"
193
+ onClick={() => collapseActiveSecondaryPanel()}
194
+ aria-label="Collapse to icons"
195
+ >
196
+ <i className="fa-light fa-angles-left" aria-hidden="true" />
197
+ </Button>
198
+ </Tip>
199
+ </div>
200
+ <QuestionBankSecondaryNav />
201
+ </>
202
+ )
203
+ }
204
+
205
+ /** Register panel components by id when a route opts into `secondaryPanel` in nav. */
206
+ const PANELS: Record<string, React.FC> = {
207
+ "question-bank": QuestionBankPanel,
208
+ }
209
+
167
210
  export function SecondaryPanel() {
168
211
  const { activePanel, secondaryPanelCompact } = useSecondaryPanel()
169
- const PanelContent = activePanel ? SECONDARY_PANELS[activePanel] : null
212
+ const PanelContent = activePanel ? PANELS[activePanel] : null
170
213
 
171
214
  return (
172
215
  <NestedSecondaryPanelShell open={Boolean(activePanel)} compact={secondaryPanelCompact}>
@@ -7,6 +7,10 @@ import { useSidebar } from "@/components/ui/sidebar"
7
7
  * Collapses the sidebar on mount. Restores previous state on unmount.
8
8
  * Used on the new-placement page so the sidebar collapses when entering
9
9
  * and reverts to whatever it was when leaving.
10
+ *
11
+ * Both transitions pass `{ persist: false }` so the visual collapse never
12
+ * overwrites the user's saved sidebar preference (the `sidebar_state_v2`
13
+ * cookie). Only an explicit toggle (⌘B / sidebar button) persists.
10
14
  */
11
15
  export function SidebarAutoCollapse() {
12
16
  const { open, setOpen } = useSidebar()
@@ -14,8 +18,8 @@ export function SidebarAutoCollapse() {
14
18
 
15
19
  useEffect(() => {
16
20
  prevOpen.current = open
17
- setOpen(false)
18
- return () => { setOpen(prevOpen.current) }
21
+ setOpen(false, { persist: false })
22
+ return () => { setOpen(prevOpen.current, { persist: false }) }
19
23
  // eslint-disable-next-line react-hooks/exhaustive-deps
20
24
  }, [])
21
25
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * SidebarShell — SidebarProvider with layout-aware widths.
5
- * Desktop expanded/collapsed is persisted in the `sidebar_state` cookie by `@exxatdesignux/ui`
5
+ * Desktop expanded/collapsed is persisted in the `sidebar_state_v2` cookie by `@exxatdesignux/ui`
6
6
  * `SidebarProvider` (read on mount + write on toggle). `(app)/layout` passes
7
7
  * `defaultOpen` from the same cookie on the server so SSR matches the first client paint.
8
8
  */
@@ -107,7 +107,7 @@ export function SiteHeader({
107
107
  />
108
108
  )}
109
109
 
110
- <div className="ml-auto shrink-0">
110
+ <div className="ms-auto shrink-0">
111
111
  <AskLeoToggle />
112
112
  </div>
113
113
  </div>