@exxatdesignux/ui 0.2.18 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (618) hide show
  1. package/CHANGELOG.md +69 -1
  2. package/bin/sync-extras.mjs +116 -29
  3. package/consumer-extras/README.md +43 -4
  4. package/consumer-extras/cursor-rules/exxat-accessibility.mdc +39 -0
  5. package/consumer-extras/cursor-rules/exxat-board-cards.mdc +26 -0
  6. package/consumer-extras/cursor-rules/exxat-breadcrumbs-no-back.mdc +21 -0
  7. package/consumer-extras/cursor-rules/exxat-card-vs-list-rows.mdc +21 -0
  8. package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +44 -0
  9. package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +32 -0
  10. package/consumer-extras/cursor-rules/exxat-command-menu.mdc +22 -0
  11. package/consumer-extras/cursor-rules/exxat-dashboard-view-charts.mdc +53 -0
  12. package/consumer-extras/cursor-rules/exxat-data-tables.mdc +41 -0
  13. package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +25 -0
  14. package/consumer-extras/cursor-rules/exxat-drawer-vs-dialog.mdc +22 -0
  15. package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +56 -0
  16. package/consumer-extras/cursor-rules/exxat-fontawesome-icons.mdc +31 -0
  17. package/consumer-extras/cursor-rules/exxat-kbd-shortcuts.mdc +100 -0
  18. package/consumer-extras/cursor-rules/exxat-kpi-flat-band.mdc +28 -0
  19. package/consumer-extras/cursor-rules/exxat-kpi-max-four.mdc +21 -0
  20. package/consumer-extras/cursor-rules/exxat-kpi-trends.mdc +31 -0
  21. package/consumer-extras/cursor-rules/exxat-list-page-connected-views.mdc +24 -0
  22. package/consumer-extras/cursor-rules/exxat-list-page-view-shells.mdc +31 -0
  23. package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +30 -0
  24. package/consumer-extras/cursor-rules/exxat-no-slds-leakage.mdc +78 -0
  25. package/consumer-extras/cursor-rules/exxat-no-toast.mdc +25 -0
  26. package/consumer-extras/cursor-rules/exxat-page-vs-drawer.mdc +23 -0
  27. package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +47 -0
  28. package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +52 -0
  29. package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +28 -0
  30. package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +34 -0
  31. package/consumer-extras/cursor-rules/exxat-table-properties-drawer.mdc +77 -0
  32. package/consumer-extras/cursor-rules/exxat-token-discipline.mdc +103 -0
  33. package/consumer-extras/cursor-skills/exxat-accessibility/SKILL.md +1 -1
  34. package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
  35. package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +1 -1
  36. package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +9 -9
  37. package/consumer-extras/cursor-skills/exxat-ds-skill/references/data-table-pattern.md +1 -1
  38. package/consumer-extras/handbook/HANDBOOK.md +185 -0
  39. package/consumer-extras/handbook/glossary.md +57 -0
  40. package/consumer-extras/handbook/reference-implementations.md +126 -0
  41. package/consumer-extras/handbook/voice-and-tone.md +262 -0
  42. package/consumer-extras/patterns/command-menu-pattern.md +1 -1
  43. package/consumer-extras/patterns/data-views-pattern.md +14 -14
  44. package/dist/components/data-table/filter-date-calendar.d.ts +10 -0
  45. package/dist/components/data-table/filter-date-calendar.js +280 -0
  46. package/dist/components/data-table/filter-date-calendar.js.map +1 -0
  47. package/dist/components/data-table/filter-text-value-input.d.ts +15 -0
  48. package/dist/components/data-table/filter-text-value-input.js +561 -0
  49. package/dist/components/data-table/filter-text-value-input.js.map +1 -0
  50. package/dist/components/data-table/index.d.ts +45 -0
  51. package/dist/components/data-table/index.js +3085 -0
  52. package/dist/components/data-table/index.js.map +1 -0
  53. package/dist/components/data-table/pagination.d.ts +28 -0
  54. package/dist/components/data-table/pagination.js +3264 -0
  55. package/dist/components/data-table/pagination.js.map +1 -0
  56. package/dist/components/data-table/types.d.ts +84 -0
  57. package/dist/components/data-table/types.js +3 -0
  58. package/dist/components/data-table/types.js.map +1 -0
  59. package/dist/components/data-table/use-table-state.d.ts +116 -0
  60. package/dist/components/data-table/use-table-state.js +670 -0
  61. package/dist/components/data-table/use-table-state.js.map +1 -0
  62. package/dist/components/data-views/board-card-primitives.d.ts +22 -0
  63. package/dist/components/data-views/board-card-primitives.js +84 -0
  64. package/dist/components/data-views/board-card-primitives.js.map +1 -0
  65. package/dist/components/data-views/data-row-list.d.ts +33 -0
  66. package/dist/components/data-views/data-row-list.js +106 -0
  67. package/dist/components/data-views/data-row-list.js.map +1 -0
  68. package/dist/components/data-views/finder-panel-view.d.ts +54 -0
  69. package/dist/components/data-views/finder-panel-view.js +388 -0
  70. package/dist/components/data-views/finder-panel-view.js.map +1 -0
  71. package/dist/components/data-views/folder-grid-view.d.ts +22 -0
  72. package/dist/components/data-views/folder-grid-view.js +58 -0
  73. package/dist/components/data-views/folder-grid-view.js.map +1 -0
  74. package/dist/components/data-views/hub-table.d.ts +167 -0
  75. package/dist/components/data-views/hub-table.js +5561 -0
  76. package/dist/components/data-views/hub-table.js.map +1 -0
  77. package/dist/components/data-views/index.d.ts +27 -0
  78. package/dist/components/data-views/index.js +6575 -0
  79. package/dist/components/data-views/index.js.map +1 -0
  80. package/dist/components/data-views/list-page-board-card.d.ts +72 -0
  81. package/dist/components/data-views/list-page-board-card.js +264 -0
  82. package/dist/components/data-views/list-page-board-card.js.map +1 -0
  83. package/dist/components/data-views/list-page-board-template.d.ts +24 -0
  84. package/dist/components/data-views/list-page-board-template.js +137 -0
  85. package/dist/components/data-views/list-page-board-template.js.map +1 -0
  86. package/dist/components/data-views/list-page-connected-view-body.d.ts +19 -0
  87. package/dist/components/data-views/list-page-connected-view-body.js +116 -0
  88. package/dist/components/data-views/list-page-connected-view-body.js.map +1 -0
  89. package/dist/components/data-views/list-page-split-details-placeholder.d.ts +14 -0
  90. package/dist/components/data-views/list-page-split-details-placeholder.js +38 -0
  91. package/dist/components/data-views/list-page-split-details-placeholder.js.map +1 -0
  92. package/dist/components/data-views/list-page-split-hub-chrome.d.ts +17 -0
  93. package/dist/components/data-views/list-page-split-hub-chrome.js +54 -0
  94. package/dist/components/data-views/list-page-split-hub-chrome.js.map +1 -0
  95. package/dist/components/data-views/list-page-split-hub-tokens.d.ts +12 -0
  96. package/dist/components/data-views/list-page-split-hub-tokens.js +8 -0
  97. package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -0
  98. package/dist/components/data-views/list-page-tree-column-header.d.ts +15 -0
  99. package/dist/components/data-views/list-page-tree-column-header.js +22 -0
  100. package/dist/components/data-views/list-page-tree-column-header.js.map +1 -0
  101. package/dist/components/data-views/list-page-tree-panel-shell.d.ts +25 -0
  102. package/dist/components/data-views/list-page-tree-panel-shell.js +146 -0
  103. package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -0
  104. package/dist/components/data-views/os-folder-glyph.d.ts +35 -0
  105. package/dist/components/data-views/os-folder-glyph.js +104 -0
  106. package/dist/components/data-views/os-folder-glyph.js.map +1 -0
  107. package/dist/components/data-views/outline-tree-menu.d.ts +36 -0
  108. package/dist/components/data-views/outline-tree-menu.js +131 -0
  109. package/dist/components/data-views/outline-tree-menu.js.map +1 -0
  110. package/dist/components/table-properties/column-row.d.ts +22 -0
  111. package/dist/components/table-properties/column-row.js +153 -0
  112. package/dist/components/table-properties/column-row.js.map +1 -0
  113. package/dist/components/table-properties/draggable-list.d.ts +24 -0
  114. package/dist/components/table-properties/draggable-list.js +53 -0
  115. package/dist/components/table-properties/draggable-list.js.map +1 -0
  116. package/dist/components/table-properties/drawer-button.d.ts +110 -0
  117. package/dist/components/table-properties/drawer-button.js +2748 -0
  118. package/dist/components/table-properties/drawer-button.js.map +1 -0
  119. package/dist/components/table-properties/drawer.d.ts +100 -0
  120. package/dist/components/table-properties/drawer.js +2595 -0
  121. package/dist/components/table-properties/drawer.js.map +1 -0
  122. package/dist/components/table-properties/filter-card.d.ts +24 -0
  123. package/dist/components/table-properties/filter-card.js +854 -0
  124. package/dist/components/table-properties/filter-card.js.map +1 -0
  125. package/dist/components/table-properties/index.d.ts +14 -0
  126. package/dist/components/table-properties/index.js +2768 -0
  127. package/dist/components/table-properties/index.js.map +1 -0
  128. package/dist/components/table-properties/sort-card.d.ts +20 -0
  129. package/dist/components/table-properties/sort-card.js +102 -0
  130. package/dist/components/table-properties/sort-card.js.map +1 -0
  131. package/dist/components/templates/dedicated-search-landing-template.d.ts +21 -0
  132. package/dist/components/templates/dedicated-search-landing-template.js +254 -0
  133. package/dist/components/templates/dedicated-search-landing-template.js.map +1 -0
  134. package/dist/components/templates/dedicated-search-results-template.d.ts +15 -0
  135. package/dist/components/templates/dedicated-search-results-template.js +16 -0
  136. package/dist/components/templates/dedicated-search-results-template.js.map +1 -0
  137. package/dist/components/templates/index.d.ts +9 -0
  138. package/dist/components/templates/index.js +2720 -0
  139. package/dist/components/templates/index.js.map +1 -0
  140. package/dist/components/templates/list-page.d.ts +83 -0
  141. package/dist/components/templates/list-page.js +2433 -0
  142. package/dist/components/templates/list-page.js.map +1 -0
  143. package/dist/components/templates/nested-secondary-panel-shell.d.ts +20 -0
  144. package/dist/components/templates/nested-secondary-panel-shell.js +54 -0
  145. package/dist/components/templates/nested-secondary-panel-shell.js.map +1 -0
  146. package/dist/components/ui/accordion.d.ts +10 -0
  147. package/dist/components/ui/accordion.js +74 -0
  148. package/dist/components/ui/accordion.js.map +1 -0
  149. package/dist/components/ui/alert-dialog.d.ts +37 -0
  150. package/dist/components/ui/alert-dialog.js +201 -0
  151. package/dist/components/ui/alert-dialog.js.map +1 -0
  152. package/dist/components/ui/avatar.d.ts +84 -0
  153. package/dist/components/ui/avatar.js +328 -0
  154. package/dist/components/ui/avatar.js.map +1 -0
  155. package/dist/components/ui/badge.d.ts +13 -0
  156. package/dist/components/ui/badge.js +49 -0
  157. package/dist/components/ui/badge.js.map +1 -0
  158. package/dist/components/ui/banner.d.ts +62 -0
  159. package/dist/components/ui/banner.js +364 -0
  160. package/dist/components/ui/banner.js.map +1 -0
  161. package/dist/components/ui/breadcrumb.d.ts +14 -0
  162. package/dist/components/ui/breadcrumb.js +114 -0
  163. package/dist/components/ui/breadcrumb.js.map +1 -0
  164. package/dist/components/ui/button.d.ts +16 -0
  165. package/dist/components/ui/button.js +59 -0
  166. package/dist/components/ui/button.js.map +1 -0
  167. package/dist/components/ui/calendar.d.ts +13 -0
  168. package/dist/components/ui/calendar.js +238 -0
  169. package/dist/components/ui/calendar.js.map +1 -0
  170. package/dist/components/ui/card.d.ts +14 -0
  171. package/dist/components/ui/card.js +102 -0
  172. package/dist/components/ui/card.js.map +1 -0
  173. package/dist/components/ui/chart.d.ts +58 -0
  174. package/dist/components/ui/chart.js +292 -0
  175. package/dist/components/ui/chart.js.map +1 -0
  176. package/dist/components/ui/checkbox.d.ts +23 -0
  177. package/dist/components/ui/checkbox.js +155 -0
  178. package/dist/components/ui/checkbox.js.map +1 -0
  179. package/dist/components/ui/coach-mark.d.ts +27 -0
  180. package/dist/components/ui/coach-mark.js +306 -0
  181. package/dist/components/ui/coach-mark.js.map +1 -0
  182. package/dist/components/ui/collapsible.d.ts +8 -0
  183. package/dist/components/ui/collapsible.js +35 -0
  184. package/dist/components/ui/collapsible.js.map +1 -0
  185. package/dist/components/ui/command.d.ts +36 -0
  186. package/dist/components/ui/command.js +274 -0
  187. package/dist/components/ui/command.js.map +1 -0
  188. package/dist/components/ui/context-menu.d.ts +32 -0
  189. package/dist/components/ui/context-menu.js +245 -0
  190. package/dist/components/ui/context-menu.js.map +1 -0
  191. package/dist/components/ui/date-picker-field.d.ts +38 -0
  192. package/dist/components/ui/date-picker-field.js +550 -0
  193. package/dist/components/ui/date-picker-field.js.map +1 -0
  194. package/dist/components/ui/dialog.d.ts +22 -0
  195. package/dist/components/ui/dialog.js +200 -0
  196. package/dist/components/ui/dialog.js.map +1 -0
  197. package/dist/components/ui/dot-pattern.d.ts +21 -0
  198. package/dist/components/ui/dot-pattern.js +139 -0
  199. package/dist/components/ui/dot-pattern.js.map +1 -0
  200. package/dist/components/ui/drag-handle-grip.d.ts +10 -0
  201. package/dist/components/ui/drag-handle-grip.js +15 -0
  202. package/dist/components/ui/drag-handle-grip.js.map +1 -0
  203. package/dist/components/ui/drawer.d.ts +16 -0
  204. package/dist/components/ui/drawer.js +125 -0
  205. package/dist/components/ui/drawer.js.map +1 -0
  206. package/dist/components/ui/dropdown-menu.d.ts +45 -0
  207. package/dist/components/ui/dropdown-menu.js +353 -0
  208. package/dist/components/ui/dropdown-menu.js.map +1 -0
  209. package/dist/components/ui/export-drawer.d.ts +11 -0
  210. package/dist/components/ui/export-drawer.js +1658 -0
  211. package/dist/components/ui/export-drawer.js.map +1 -0
  212. package/dist/components/ui/field.d.ts +30 -0
  213. package/dist/components/ui/field.js +249 -0
  214. package/dist/components/ui/field.js.map +1 -0
  215. package/dist/components/ui/form.d.ts +28 -0
  216. package/dist/components/ui/form.js +110 -0
  217. package/dist/components/ui/form.js.map +1 -0
  218. package/dist/components/ui/hover-card.d.ts +9 -0
  219. package/dist/components/ui/hover-card.js +43 -0
  220. package/dist/components/ui/hover-card.js.map +1 -0
  221. package/dist/components/ui/input-group.d.ts +20 -0
  222. package/dist/components/ui/input-group.js +219 -0
  223. package/dist/components/ui/input-group.js.map +1 -0
  224. package/dist/components/ui/input-mask.d.ts +39 -0
  225. package/dist/components/ui/input-mask.js +118 -0
  226. package/dist/components/ui/input-mask.js.map +1 -0
  227. package/dist/components/ui/input.d.ts +5 -0
  228. package/dist/components/ui/input.js +30 -0
  229. package/dist/components/ui/input.js.map +1 -0
  230. package/dist/components/ui/kbd.d.ts +20 -0
  231. package/dist/components/ui/kbd.js +45 -0
  232. package/dist/components/ui/kbd.js.map +1 -0
  233. package/dist/components/ui/key-metrics-context.d.ts +19 -0
  234. package/dist/components/ui/key-metrics-context.js +26 -0
  235. package/dist/components/ui/key-metrics-context.js.map +1 -0
  236. package/dist/components/ui/key-metrics.d.ts +131 -0
  237. package/dist/components/ui/key-metrics.js +1015 -0
  238. package/dist/components/ui/key-metrics.js.map +1 -0
  239. package/dist/components/ui/label.d.ts +6 -0
  240. package/dist/components/ui/label.js +28 -0
  241. package/dist/components/ui/label.js.map +1 -0
  242. package/dist/components/ui/list-page-view-frame.d.ts +22 -0
  243. package/dist/components/ui/list-page-view-frame.js +24 -0
  244. package/dist/components/ui/list-page-view-frame.js.map +1 -0
  245. package/dist/components/ui/page-header.d.ts +51 -0
  246. package/dist/components/ui/page-header.js +372 -0
  247. package/dist/components/ui/page-header.js.map +1 -0
  248. package/dist/components/ui/payment-card-fields.d.ts +10 -0
  249. package/dist/components/ui/payment-card-fields.js +80 -0
  250. package/dist/components/ui/payment-card-fields.js.map +1 -0
  251. package/dist/components/ui/popover.d.ts +10 -0
  252. package/dist/components/ui/popover.js +47 -0
  253. package/dist/components/ui/popover.js.map +1 -0
  254. package/dist/components/ui/radio-group.d.ts +29 -0
  255. package/dist/components/ui/radio-group.js +190 -0
  256. package/dist/components/ui/radio-group.js.map +1 -0
  257. package/dist/components/ui/resizable.d.ts +16 -0
  258. package/dist/components/ui/resizable.js +51 -0
  259. package/dist/components/ui/resizable.js.map +1 -0
  260. package/dist/components/ui/scroll-area.d.ts +8 -0
  261. package/dist/components/ui/scroll-area.js +66 -0
  262. package/dist/components/ui/scroll-area.js.map +1 -0
  263. package/dist/components/ui/select.d.ts +18 -0
  264. package/dist/components/ui/select.js +186 -0
  265. package/dist/components/ui/select.js.map +1 -0
  266. package/dist/components/ui/selection-tile-grid.d.ts +52 -0
  267. package/dist/components/ui/selection-tile-grid.js +347 -0
  268. package/dist/components/ui/selection-tile-grid.js.map +1 -0
  269. package/dist/components/ui/separator.d.ts +7 -0
  270. package/dist/components/ui/separator.js +33 -0
  271. package/dist/components/ui/separator.js.map +1 -0
  272. package/dist/components/ui/sheet.d.ts +18 -0
  273. package/dist/components/ui/sheet.js +181 -0
  274. package/dist/components/ui/sheet.js.map +1 -0
  275. package/dist/components/ui/sidebar.d.ts +94 -0
  276. package/dist/components/ui/sidebar.js +805 -0
  277. package/dist/components/ui/sidebar.js.map +1 -0
  278. package/dist/components/ui/skeleton.d.ts +5 -0
  279. package/dist/components/ui/skeleton.js +22 -0
  280. package/dist/components/ui/skeleton.js.map +1 -0
  281. package/dist/components/ui/slider.d.ts +7 -0
  282. package/dist/components/ui/slider.js +66 -0
  283. package/dist/components/ui/slider.js.map +1 -0
  284. package/dist/components/ui/sonner.d.ts +6 -0
  285. package/dist/components/ui/sonner.js +38 -0
  286. package/dist/components/ui/sonner.js.map +1 -0
  287. package/dist/components/ui/status-badge.d.ts +38 -0
  288. package/dist/components/ui/status-badge.js +77 -0
  289. package/dist/components/ui/status-badge.js.map +1 -0
  290. package/dist/components/ui/table.d.ts +13 -0
  291. package/dist/components/ui/table.js +115 -0
  292. package/dist/components/ui/table.js.map +1 -0
  293. package/dist/components/ui/tabs.d.ts +15 -0
  294. package/dist/components/ui/tabs.js +93 -0
  295. package/dist/components/ui/tabs.js.map +1 -0
  296. package/dist/components/ui/textarea.d.ts +6 -0
  297. package/dist/components/ui/textarea.js +25 -0
  298. package/dist/components/ui/textarea.js.map +1 -0
  299. package/dist/components/ui/tip.d.ts +12 -0
  300. package/dist/components/ui/tip.js +61 -0
  301. package/dist/components/ui/tip.js.map +1 -0
  302. package/dist/components/ui/toggle-group.d.ts +14 -0
  303. package/dist/components/ui/toggle-group.js +104 -0
  304. package/dist/components/ui/toggle-group.js.map +1 -0
  305. package/dist/components/ui/toggle-switch.d.ts +10 -0
  306. package/dist/components/ui/toggle-switch.js +33 -0
  307. package/dist/components/ui/toggle-switch.js.map +1 -0
  308. package/dist/components/ui/toggle.d.ts +13 -0
  309. package/dist/components/ui/toggle.js +51 -0
  310. package/dist/components/ui/toggle.js.map +1 -0
  311. package/dist/components/ui/tooltip.d.ts +10 -0
  312. package/dist/components/ui/tooltip.js +68 -0
  313. package/dist/components/ui/tooltip.js.map +1 -0
  314. package/dist/components/ui/view-segmented-control.d.ts +31 -0
  315. package/dist/components/ui/view-segmented-control.js +167 -0
  316. package/dist/components/ui/view-segmented-control.js.map +1 -0
  317. package/dist/data-list-view-registry-CyBoBML4.d.ts +73 -0
  318. package/dist/hooks/use-app-theme.d.ts +24 -0
  319. package/dist/hooks/use-app-theme.js +286 -0
  320. package/dist/hooks/use-app-theme.js.map +1 -0
  321. package/dist/hooks/use-coach-mark.d.ts +86 -0
  322. package/dist/hooks/use-coach-mark.js +218 -0
  323. package/dist/hooks/use-coach-mark.js.map +1 -0
  324. package/dist/hooks/use-mobile.d.ts +3 -0
  325. package/dist/hooks/use-mobile.js +29 -0
  326. package/dist/hooks/use-mobile.js.map +1 -0
  327. package/dist/hooks/use-mod-key-label.d.ts +6 -0
  328. package/dist/hooks/use-mod-key-label.js +25 -0
  329. package/dist/hooks/use-mod-key-label.js.map +1 -0
  330. package/dist/index.d.ts +120 -0
  331. package/dist/index.js +13324 -0
  332. package/dist/index.js.map +1 -0
  333. package/dist/lib/compose-refs.d.ts +6 -0
  334. package/dist/lib/compose-refs.js +17 -0
  335. package/dist/lib/compose-refs.js.map +1 -0
  336. package/dist/lib/conditional-rule-match.d.ts +30 -0
  337. package/dist/lib/conditional-rule-match.js +66 -0
  338. package/dist/lib/conditional-rule-match.js.map +1 -0
  339. package/dist/lib/data-list-display-options.d.ts +26 -0
  340. package/dist/lib/data-list-display-options.js +14 -0
  341. package/dist/lib/data-list-display-options.js.map +1 -0
  342. package/dist/lib/data-list-view-registry.d.ts +2 -0
  343. package/dist/lib/data-list-view-registry.js +102 -0
  344. package/dist/lib/data-list-view-registry.js.map +1 -0
  345. package/dist/lib/data-list-view-surface.d.ts +2 -0
  346. package/dist/lib/data-list-view-surface.js +80 -0
  347. package/dist/lib/data-list-view-surface.js.map +1 -0
  348. package/dist/lib/data-list-view.d.ts +21 -0
  349. package/dist/lib/data-list-view.js +25 -0
  350. package/dist/lib/data-list-view.js.map +1 -0
  351. package/dist/lib/date-filter.d.ts +22 -0
  352. package/dist/lib/date-filter.js +61 -0
  353. package/dist/lib/date-filter.js.map +1 -0
  354. package/dist/lib/dev-log.d.ts +8 -0
  355. package/dist/lib/dev-log.js +10 -0
  356. package/dist/lib/dev-log.js.map +1 -0
  357. package/dist/lib/dropdown-menu-surface.d.ts +14 -0
  358. package/dist/lib/dropdown-menu-surface.js +6 -0
  359. package/dist/lib/dropdown-menu-surface.js.map +1 -0
  360. package/dist/lib/editable-target.d.ts +12 -0
  361. package/dist/lib/editable-target.js +12 -0
  362. package/dist/lib/editable-target.js.map +1 -0
  363. package/dist/lib/list-page-table-properties.d.ts +35 -0
  364. package/dist/lib/list-page-table-properties.js +81 -0
  365. package/dist/lib/list-page-table-properties.js.map +1 -0
  366. package/dist/lib/raf-throttle.d.ts +23 -0
  367. package/dist/lib/raf-throttle.js +27 -0
  368. package/dist/lib/raf-throttle.js.map +1 -0
  369. package/dist/lib/row-height.d.ts +16 -0
  370. package/dist/lib/row-height.js +10 -0
  371. package/dist/lib/row-height.js.map +1 -0
  372. package/dist/lib/table-properties-types.d.ts +83 -0
  373. package/dist/lib/table-properties-types.js +19 -0
  374. package/dist/lib/table-properties-types.js.map +1 -0
  375. package/dist/lib/utils.d.ts +5 -0
  376. package/dist/lib/utils.js +11 -0
  377. package/dist/lib/utils.js.map +1 -0
  378. package/package.json +83 -18
  379. package/src/components/data-table/filter-date-calendar.tsx +38 -0
  380. package/src/components/data-table/filter-text-value-input.tsx +77 -0
  381. package/src/components/data-table/index.tsx +1678 -0
  382. package/src/components/data-table/pagination.tsx +255 -0
  383. package/src/components/data-table/types.ts +96 -0
  384. package/src/components/data-table/use-table-state.ts +767 -0
  385. package/src/components/data-views/board-card-primitives.tsx +93 -0
  386. package/src/components/data-views/data-row-list.tsx +183 -0
  387. package/src/components/data-views/finder-panel-view.tsx +405 -0
  388. package/src/components/data-views/folder-grid-view.tsx +86 -0
  389. package/src/components/data-views/hub-table.tsx +498 -0
  390. package/src/components/data-views/index.ts +28 -0
  391. package/src/components/data-views/list-page-board-card.tsx +192 -0
  392. package/src/components/data-views/list-page-board-template.tsx +122 -0
  393. package/src/components/data-views/list-page-connected-view-body.tsx +66 -0
  394. package/src/components/data-views/list-page-split-details-placeholder.tsx +39 -0
  395. package/src/components/data-views/list-page-split-hub-chrome.tsx +60 -0
  396. package/src/components/data-views/list-page-split-hub-tokens.ts +16 -0
  397. package/src/components/data-views/list-page-tree-column-header.tsx +31 -0
  398. package/src/components/data-views/list-page-tree-panel-shell.tsx +91 -0
  399. package/src/components/data-views/os-folder-glyph.tsx +141 -0
  400. package/src/components/data-views/outline-tree-menu.tsx +157 -0
  401. package/src/components/table-properties/column-row.tsx +90 -0
  402. package/src/components/table-properties/draggable-list.ts +54 -0
  403. package/src/components/table-properties/drawer-button.tsx +300 -0
  404. package/src/components/table-properties/drawer.tsx +1148 -0
  405. package/src/components/table-properties/filter-card.tsx +251 -0
  406. package/src/components/table-properties/index.ts +36 -0
  407. package/src/components/table-properties/sort-card.tsx +63 -0
  408. package/src/components/templates/dedicated-search-landing-template.tsx +124 -0
  409. package/src/components/templates/dedicated-search-results-template.tsx +19 -0
  410. package/src/components/templates/index.ts +33 -0
  411. package/src/components/templates/list-page.tsx +602 -0
  412. package/src/components/templates/nested-secondary-panel-shell.tsx +70 -0
  413. package/src/components/ui/accordion.tsx +92 -0
  414. package/src/components/ui/alert-dialog.tsx +221 -0
  415. package/src/components/ui/avatar.tsx +13 -2
  416. package/src/components/ui/banner.tsx +2 -2
  417. package/src/components/ui/calendar.tsx +1 -1
  418. package/src/components/ui/coach-mark.tsx +1 -1
  419. package/src/components/ui/context-menu.tsx +291 -0
  420. package/src/components/ui/date-picker-field.tsx +2 -2
  421. package/src/components/ui/dot-pattern.tsx +183 -0
  422. package/src/components/ui/export-drawer.tsx +375 -0
  423. package/src/components/ui/hover-card.tsx +66 -0
  424. package/src/components/ui/key-metrics-context.tsx +78 -0
  425. package/src/components/ui/key-metrics.tsx +1133 -0
  426. package/src/components/ui/list-page-view-frame.tsx +64 -0
  427. package/src/components/ui/page-header.tsx +244 -0
  428. package/src/components/ui/payment-card-fields.tsx +2 -2
  429. package/src/components/ui/resizable.tsx +68 -0
  430. package/src/components/ui/scroll-area.tsx +72 -0
  431. package/src/components/ui/selection-tile-grid.tsx +9 -2
  432. package/src/components/ui/sidebar.tsx +84 -12
  433. package/src/components/ui/slider.tsx +83 -0
  434. package/src/globals.css +494 -151
  435. package/src/globals.d.ts +20 -0
  436. package/src/index.ts +68 -1
  437. package/src/lib/conditional-rule-match.ts +119 -0
  438. package/src/lib/data-list-display-options.ts +35 -0
  439. package/src/lib/data-list-view-registry.ts +104 -0
  440. package/src/lib/data-list-view-surface.ts +83 -0
  441. package/src/lib/data-list-view.ts +47 -0
  442. package/src/lib/dev-log.ts +10 -0
  443. package/src/lib/editable-target.ts +20 -0
  444. package/src/lib/list-page-table-properties.ts +48 -0
  445. package/src/lib/raf-throttle.ts +45 -0
  446. package/src/lib/row-height.ts +19 -0
  447. package/src/lib/table-properties-types.ts +98 -0
  448. package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
  449. package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +3 -3
  450. package/template/.cursor/rules/exxat-data-tables.mdc +1 -1
  451. package/template/.cursor/rules/exxat-ds-agents.mdc +2 -2
  452. package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +2 -2
  453. package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
  454. package/template/AGENTS.md +84 -20
  455. package/template/app/(app)/examples/page.tsx +0 -1
  456. package/template/app/(app)/layout.tsx +17 -4
  457. package/template/app/(app)/question-bank/layout.tsx +1 -1
  458. package/template/app/(app)/question-bank/new/page.tsx +11 -24
  459. package/template/app/globals.css +13 -1972
  460. package/template/components/ask-leo-sidebar.tsx +5 -1
  461. package/template/components/brand-color-picker.tsx +2 -2
  462. package/template/components/charts-overview.tsx +1 -1
  463. package/template/components/compliance-table.tsx +240 -384
  464. package/template/components/dashboard-report-charts.tsx +1 -1
  465. package/template/components/dashboard-tabs.tsx +1 -1
  466. package/template/components/data-table/filter-date-calendar.tsx +1 -38
  467. package/template/components/data-table/filter-text-value-input.tsx +1 -77
  468. package/template/components/data-table/index.tsx +1 -1634
  469. package/template/components/data-table/pagination.tsx +1 -255
  470. package/template/components/data-table/types.ts +1 -94
  471. package/template/components/data-table/use-table-state.test.ts +420 -0
  472. package/template/components/data-table/use-table-state.ts +1 -758
  473. package/template/components/data-view-dashboard-charts-compliance.tsx +2 -2
  474. package/template/components/data-view-dashboard-charts-team.tsx +2 -2
  475. package/template/components/data-view-dashboard-charts.tsx +2 -2
  476. package/template/components/data-views/board-card-primitives.tsx +1 -93
  477. package/template/components/data-views/data-row-list.tsx +1 -183
  478. package/template/components/data-views/finder-panel-view.tsx +1 -405
  479. package/template/components/data-views/folder-grid-view.tsx +1 -86
  480. package/template/components/data-views/hub-table.tsx +1 -0
  481. package/template/components/data-views/index.ts +42 -1
  482. package/template/components/data-views/list-page-board-card.tsx +1 -192
  483. package/template/components/data-views/list-page-board-template.tsx +1 -122
  484. package/template/components/data-views/list-page-connected-view-body.tsx +1 -0
  485. package/template/components/data-views/list-page-split-details-placeholder.tsx +1 -39
  486. package/template/components/data-views/list-page-split-hub-chrome.tsx +1 -60
  487. package/template/components/data-views/list-page-split-hub-tokens.ts +1 -16
  488. package/template/components/data-views/list-page-tree-column-header.tsx +1 -31
  489. package/template/components/data-views/list-page-tree-panel-shell.tsx +1 -91
  490. package/template/components/data-views/list-page-view-frame.tsx +5 -53
  491. package/template/components/data-views/os-folder-glyph.tsx +1 -129
  492. package/template/components/data-views/outline-tree-menu.tsx +1 -157
  493. package/template/components/export-drawer.test.tsx +71 -0
  494. package/template/components/export-drawer.tsx +1 -375
  495. package/template/components/exxat-product-logo.tsx +5 -5
  496. package/template/components/hub-tree-panel-view.tsx +2 -2
  497. package/template/components/invite-collaborators-drawer.tsx +3 -3
  498. package/template/components/key-metrics-ask-leo-bridge.tsx +40 -0
  499. package/template/components/key-metrics.tsx +1 -1063
  500. package/template/components/leo-insight-indicator.tsx +2 -2
  501. package/template/components/new-placement-back-btn.tsx +1 -1
  502. package/template/components/new-placement-form.tsx +63 -189
  503. package/template/components/new-question-composer.tsx +432 -402
  504. package/template/components/onboarding/index.ts +9 -0
  505. package/template/components/onboarding/onboarding-01.tsx +1 -1
  506. package/template/components/onboarding/onboarding-02.tsx +1 -1
  507. package/template/components/onboarding/onboarding-03.tsx +1 -1
  508. package/template/components/onboarding/onboarding-04.tsx +1 -1
  509. package/template/components/page-header.tsx +8 -226
  510. package/template/components/placement-board-card.tsx +71 -83
  511. package/template/components/placements-board-view.tsx +3 -10
  512. package/template/components/placements-client.tsx +10 -42
  513. package/template/components/placements-list-view.tsx +22 -69
  514. package/template/components/placements-table-columns.tsx +8 -438
  515. package/template/components/placements-table.tsx +588 -1296
  516. package/template/components/product-switcher.tsx +1 -1
  517. package/template/components/product-wordmark.tsx +2 -1
  518. package/template/components/question-bank-client.tsx +4 -1
  519. package/template/components/question-bank-hub-client.tsx +1 -1
  520. package/template/components/question-bank-new-folder-sheet.tsx +2 -2
  521. package/template/components/question-bank-secondary-nav.tsx +3 -3
  522. package/template/components/question-bank-table.tsx +294 -526
  523. package/template/components/rotations-empty-state.tsx +1 -1
  524. package/template/components/rotations-panel-activator.tsx +1 -1
  525. package/template/components/settings-appearance-card.tsx +1 -1
  526. package/template/components/{app-sidebar-dynamic.tsx → sidebar/app-sidebar-dynamic.tsx} +1 -1
  527. package/template/components/{app-sidebar.tsx → sidebar/app-sidebar.tsx} +4 -4
  528. package/template/components/sidebar/index.ts +16 -0
  529. package/template/components/{secondary-nav.tsx → sidebar/secondary-nav.tsx} +2 -2
  530. package/template/components/{secondary-panel.tsx → sidebar/secondary-panel.tsx} +6 -3
  531. package/template/components/{sidebar-auto-collapse.tsx → sidebar/sidebar-auto-collapse.tsx} +6 -2
  532. package/template/components/{sidebar-shell.tsx → sidebar/sidebar-shell.tsx} +1 -1
  533. package/template/components/site-header.tsx +1 -1
  534. package/template/components/{sites-all-client.tsx → sites-client.tsx} +1 -1
  535. package/template/components/sites-table.tsx +124 -257
  536. package/template/components/table-properties/column-row.tsx +1 -90
  537. package/template/components/table-properties/draggable-list.ts +1 -49
  538. package/template/components/table-properties/drawer-button.tsx +1 -249
  539. package/template/components/table-properties/drawer.tsx +1 -1105
  540. package/template/components/table-properties/filter-card.tsx +1 -251
  541. package/template/components/table-properties/sort-card.tsx +1 -59
  542. package/template/components/table-properties/types.ts +28 -71
  543. package/template/components/team-table.tsx +242 -382
  544. package/template/components/templates/dedicated-search-landing-template.tsx +1 -124
  545. package/template/components/templates/dedicated-search-results-template.tsx +1 -19
  546. package/template/components/templates/list-page.tsx +1 -584
  547. package/template/components/templates/nested-secondary-panel-shell.tsx +1 -62
  548. package/template/components/templates/new-focus-template.tsx +659 -0
  549. package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
  550. package/template/components/ui/accordion.tsx +1 -0
  551. package/template/components/ui/alert-dialog.tsx +1 -0
  552. package/template/components/ui/context-menu.tsx +1 -0
  553. package/template/components/ui/dot-pattern.tsx +1 -183
  554. package/template/components/ui/hover-card.tsx +1 -0
  555. package/template/components/ui/resizable.tsx +1 -68
  556. package/template/components/ui/scroll-area.tsx +1 -0
  557. package/template/components/ui/slider.tsx +1 -0
  558. package/template/docs/blueprints/README.md +86 -0
  559. package/template/docs/blueprints/_template.md +91 -0
  560. package/template/docs/blueprints/board-card.md +123 -0
  561. package/template/docs/blueprints/data-table.md +139 -0
  562. package/template/docs/blueprints/key-metrics.md +128 -0
  563. package/template/docs/blueprints/list-page-template.md +123 -0
  564. package/template/docs/blueprints/page-header.md +130 -0
  565. package/template/docs/command-menu-pattern.md +1 -1
  566. package/template/docs/component-selection-guide.md +224 -0
  567. package/template/docs/components-audit-2026-05.md +158 -0
  568. package/template/docs/data-views-pattern.md +14 -14
  569. package/template/docs/migrations/0001-brand-deep-alias-stabilization.md +95 -0
  570. package/template/docs/migrations/0002-exxat-token-namespace.md +154 -0
  571. package/template/docs/migrations/0003-globals-css-canonical.md +110 -0
  572. package/template/docs/migrations/README.md +100 -0
  573. package/template/docs/migrations/_template.md +64 -0
  574. package/template/docs/token-taxonomy.md +416 -0
  575. package/template/eslint.config.mjs +27 -0
  576. package/template/hooks/use-secondary-panel-hub-nav.ts +1 -1
  577. package/template/lib/command-menu-config.ts +0 -1
  578. package/template/lib/compliance-supported-views.ts +10 -0
  579. package/template/lib/conditional-rule-match.ts +6 -97
  580. package/template/lib/data-list-display-options.ts +1 -35
  581. package/template/lib/data-list-view-registry.ts +1 -0
  582. package/template/lib/data-list-view-surface.ts +1 -69
  583. package/template/lib/data-list-view.ts +1 -38
  584. package/template/lib/dev-log.ts +1 -8
  585. package/template/lib/editable-target.ts +1 -10
  586. package/template/lib/hub-connected-view-renderers.ts +58 -0
  587. package/template/lib/list-hub-supported-views.ts +10 -0
  588. package/template/lib/list-page-table-properties.ts +1 -52
  589. package/template/lib/mock/navigation.tsx +0 -8
  590. package/template/lib/mock/placements.ts +0 -7
  591. package/template/lib/placement-board-card-layout.ts +41 -41
  592. package/template/lib/placements-supported-views.ts +12 -0
  593. package/template/lib/question-bank-supported-views.ts +12 -0
  594. package/template/lib/raf-throttle.ts +1 -45
  595. package/template/lib/row-height.ts +4 -10
  596. package/template/lib/sidebar-state-cookie.ts +11 -2
  597. package/template/lib/sites-supported-views.ts +10 -0
  598. package/template/lib/team-supported-views.ts +10 -0
  599. package/template/package.json +1 -0
  600. package/template/tests/setup.ts +25 -0
  601. package/src/theme.css +0 -1132
  602. package/template/app/(app)/data-list/[id]/page.tsx +0 -44
  603. package/template/app/(app)/data-list/new/page.tsx +0 -34
  604. package/template/app/(app)/data-list/page.tsx +0 -10
  605. package/template/components/compliance-list-view.tsx +0 -54
  606. package/template/components/dashboard-onboarding-gallery.tsx +0 -13
  607. package/template/components/dashboard-onboarding.tsx +0 -21
  608. package/template/components/question-bank-list-view.tsx +0 -53
  609. package/template/components/section-cards.tsx +0 -106
  610. package/template/components/sites-list-view.tsx +0 -42
  611. package/template/components/team-list-view.tsx +0 -59
  612. package/template/lib/placement-lifecycle.ts +0 -5
  613. /package/template/components/{getting-started.tsx → onboarding/getting-started.tsx} +0 -0
  614. /package/template/components/{nav-documents.tsx → sidebar/nav-documents.tsx} +0 -0
  615. /package/template/components/{nav-main.tsx → sidebar/nav-main.tsx} +0 -0
  616. /package/template/components/{nav-secondary.tsx → sidebar/nav-secondary.tsx} +0 -0
  617. /package/template/components/{nav-user.tsx → sidebar/nav-user.tsx} +0 -0
  618. /package/template/components/{sidebar-auto-open.tsx → sidebar/sidebar-auto-open.tsx} +0 -0
package/src/globals.css CHANGED
@@ -10,7 +10,9 @@
10
10
 
11
11
  @import "tailwindcss";
12
12
  @import "tw-animate-css";
13
- /* Inter is loaded via next/font/google in layout.tsx — no @import needed here */
13
+ /* Inter is loaded via next/font/google in the consuming app's layout — no @import needed here. */
14
+ /* `@source` is declared by the consuming app's globals.css so the path resolves relative to its location
15
+ (workspace clone vs. npm install). See apps/web/app/globals.css. */
14
16
 
15
17
  /* RTL layout direction support */
16
18
  @custom-variant dark (&:is(.dark *));
@@ -119,14 +121,51 @@
119
121
  --radius-xl: 16px;
120
122
  --radius-2xl: 20px;
121
123
  --radius-3xl: 24px;
124
+
125
+ /* ============================================================
126
+ Exxat L0 — Tailwind utility bridges (additive)
127
+ ------------------------------------------------------------
128
+ Short utility forms backed by --exxat-* canonical primitives.
129
+ They coexist with the shadcn-named bridges above. Prefer
130
+ these for new code; see apps/web/docs/token-taxonomy.md.
131
+ ============================================================ */
132
+ --color-surface-1: var(--exxat-color-surface-1);
133
+ --color-surface-2: var(--exxat-color-surface-2);
134
+ --color-surface-3: var(--exxat-color-surface-3);
135
+ --color-surface-muted: var(--exxat-color-surface-muted);
136
+ --color-surface-accent: var(--exxat-color-surface-accent);
137
+ --color-surface-sidebar: var(--exxat-color-surface-sidebar);
138
+ --color-ink-1: var(--exxat-color-ink-1);
139
+ --color-ink-2: var(--exxat-color-ink-2);
140
+ --color-ink-on-brand: var(--exxat-color-ink-on-brand);
141
+ --color-brand-1: var(--exxat-color-brand-1);
142
+ --color-brand-2: var(--exxat-color-brand-2);
143
+ --color-brand-3: var(--exxat-color-brand-3);
144
+ --color-brand-tint-1: var(--exxat-color-brand-tint-1);
145
+ --color-brand-tint-2: var(--exxat-color-brand-tint-2);
146
+ --color-brand-tint-3: var(--exxat-color-brand-tint-3);
147
+ --color-border-1: var(--exxat-color-border-1);
148
+ --color-focus-ring: var(--exxat-color-focus-ring);
149
+
150
+ /* Exxat L0 radius scale → rounded-1 … rounded-6 */
151
+ --radius-1: var(--exxat-radius-1);
152
+ --radius-2: var(--exxat-radius-2);
153
+ --radius-3: var(--exxat-radius-3);
154
+ --radius-4: var(--exxat-radius-4);
155
+ --radius-5: var(--exxat-radius-5);
156
+ --radius-6: var(--exxat-radius-6);
122
157
  }
123
158
 
124
159
  /* --------------------------------------------------------------------------
125
- Text size (Settings → Appearance) — see apps/web app copy for rationale.
160
+ Text size (Settings → Appearance)
161
+ Pattern: root `font-size` steps like iOS Larger Text / Android font scale /
162
+ browser zoom-at-root so rem-based components track together. We keep steps
163
+ modest; `compact` redefines `--text-xs` so minimum UI copy stays 11px (Exxat
164
+ accessibility rule) when the root is slightly below 16px.
126
165
  -------------------------------------------------------------------------- */
127
166
  html[data-text-size="compact"] {
128
167
  font-size: 94%;
129
- --text-xs: 0.7333rem;
168
+ --text-xs: 0.7333rem; /* ~11px when 1rem ≈ 15px */
130
169
  }
131
170
  html[data-text-size="large"] {
132
171
  font-size: 112.5%;
@@ -145,6 +184,14 @@ html[data-text-size="large"] {
145
184
  via a scoped class, not globally on :root. */
146
185
  /* Minimum readable UI copy: 11px (`text-xs` / --text-xs). Do not use smaller arbitrary sizes. */
147
186
 
187
+ /* ── Layout ─────────────────────────────────────────────────── */
188
+ /* SiteHeader / breadcrumb height. Mirrored on the SidebarProvider for
189
+ descendants; declared here too so JS that reads from documentElement
190
+ (e.g. DataTable sticky-head offset) can resolve it. Plain px so
191
+ `parseFloat` can read it as a number. Keep in sync with `headerHeight`
192
+ in components/sidebar-shell.tsx (currently `calc(var(--spacing) * 12)` = 48px). */
193
+ --header-height: 48px;
194
+
148
195
  /* ── Typography ─────────────────────────────────────────────── */
149
196
  /* Ivy Presto loaded via Adobe Fonts Kit wuk5wqn (use.typekit.net) */
150
197
  --font-heading: "ivypresto-text";
@@ -228,8 +275,8 @@ html[data-text-size="large"] {
228
275
  --control-border: var(--border-control-3); /* default form-field border */
229
276
 
230
277
  /* ── Input ───────────────────────────────────────────────────── */
231
- /* 3:1 on white WCAG 1.4.11 compliant for interactive element borders */
232
- --input: oklch(0.6694 0.0063 264.52);
278
+ /* Raised contrast target for control outlines (>= 3.1:1 on white). */
279
+ --input: oklch(0.62 0.01 264.52);
233
280
  --input-background: oklch(0.97 0.002 270);
234
281
 
235
282
  /* ── Focus ring ──────────────────────────────────────────────── */
@@ -267,7 +314,7 @@ html[data-text-size="large"] {
267
314
  --sidebar-ring: oklch(0.25 0 0);
268
315
  /* Nav section titles — ≥4.5:1 vs --sidebar (not vs page white) */
269
316
  --sidebar-section-label-foreground: color-mix(in oklch, var(--sidebar-foreground) 58%, var(--sidebar));
270
- /* Nested secondary rail — elevation 1: brand wash, lighter than `--brand-tint` / sidebar. */
317
+ /* Nested secondary rail — elevation 1: brand wash, lighter than `--sidebar` / `--brand-tint`. */
271
318
  --secondary-panel-bg: color-mix(in oklch, var(--background) 40%, var(--brand-tint-light) 60%);
272
319
 
273
320
  /* Browser UI (meta theme-color) — aligned with --brand-tint */
@@ -333,7 +380,7 @@ html[data-text-size="large"] {
333
380
  --insight-severity-info-bg: color-mix(in oklch, var(--chart-1) 14%, transparent);
334
381
  --insight-severity-info-fg: color-mix(in oklch, var(--chart-1) 75%, var(--foreground));
335
382
 
336
- /* ── Tinted icon discs — soft wash (≈14% tint); contrast from fg tokens */
383
+ /* ── Tinted icon discs — soft wash (≈14% tint like legacy inline styles); contrast from --chip-* / brand-dark on fg */
337
384
  --icon-disc-chart-2-bg: color-mix(in oklch, var(--chart-2) 14%, transparent);
338
385
  --icon-disc-chart-2-fg: var(--chip-2);
339
386
  --icon-disc-chart-4-bg: color-mix(in oklch, var(--chart-4) 14%, transparent);
@@ -350,6 +397,113 @@ html[data-text-size="large"] {
350
397
  --conditional-rule-red: color-mix(in oklch, var(--destructive) 22%, transparent);
351
398
  --conditional-rule-purple: color-mix(in oklch, var(--brand-color) 22%, transparent);
352
399
  --conditional-rule-orange: color-mix(in oklch, var(--chart-5) 25%, transparent);
400
+
401
+ /* ============================================================
402
+ Exxat L0 — canonical namespace (additive aliases)
403
+ ------------------------------------------------------------
404
+ SLDS-style flat namespace. These are the official names the
405
+ DS scales on — components SHOULD migrate to these over time.
406
+ Existing shadcn-style names above are L1 aliases that resolve
407
+ to the same values. The L0 names use var(...) so they inherit
408
+ every theme override (.dark / .theme-one / .theme-prism /
409
+ [data-contrast="high"]) automatically — no per-theme block
410
+ needed.
411
+ Reference: apps/web/docs/token-taxonomy.md (§ L0 Exxat).
412
+ ============================================================ */
413
+
414
+ /* ── Surfaces (canvas → muted → input) ──────────────────────── */
415
+ --exxat-color-surface-1: var(--background);
416
+ --exxat-color-surface-2: var(--card);
417
+ --exxat-color-surface-3: var(--popover);
418
+ --exxat-color-surface-muted: var(--muted);
419
+ --exxat-color-surface-accent: var(--accent);
420
+ --exxat-color-surface-secondary: var(--secondary);
421
+ --exxat-color-surface-sidebar: var(--sidebar);
422
+ --exxat-color-surface-input: var(--input-background);
423
+
424
+ /* ── Ink (foreground / on-surface text) ─────────────────────── */
425
+ --exxat-color-ink-1: var(--foreground);
426
+ --exxat-color-ink-2: var(--muted-foreground);
427
+ --exxat-color-ink-on-surface-2: var(--card-foreground);
428
+ --exxat-color-ink-on-surface-3: var(--popover-foreground);
429
+ --exxat-color-ink-on-brand: var(--brand-foreground);
430
+ --exxat-color-ink-on-primary: var(--primary-foreground);
431
+ --exxat-color-ink-on-secondary: var(--secondary-foreground);
432
+ --exxat-color-ink-on-accent: var(--accent-foreground);
433
+ --exxat-color-ink-on-destructive: var(--destructive-foreground);
434
+
435
+ /* ── Brand (interactive accent + scale) ─────────────────────── */
436
+ --exxat-color-brand-1: var(--brand-color);
437
+ --exxat-color-brand-2: var(--brand-color-dark);
438
+ --exxat-color-brand-3: var(--brand-color-light);
439
+ --exxat-color-brand-deep: var(--brand-color-deep);
440
+ --exxat-color-brand-tint-1: var(--brand-tint);
441
+ --exxat-color-brand-tint-2: var(--brand-tint-subtle);
442
+ --exxat-color-brand-tint-3: var(--brand-tint-light);
443
+
444
+ /* ── Wordmark ink (Exxat product logo SVG + HTML prefix) ─────
445
+ Brand-frozen slate/cool-grey pair used by the "Exxat" SVG
446
+ letters and the HTML wordmark prefix. Held outside the
447
+ `--foreground` family because the wordmark stays at brand
448
+ ink even when the rest of the surface inverts. Replaces
449
+ the bare `#273441` / `#A8B2BA` literals in
450
+ `apps/web/components/exxat-product-logo.tsx` and
451
+ `product-wordmark.tsx`. */
452
+ --exxat-color-wordmark-ink-light: oklch(0.301 0.022 252); /* ≈ #273441 */
453
+ --exxat-color-wordmark-ink-dark: oklch(0.755 0.012 230); /* ≈ #A8B2BA */
454
+
455
+ /* ── Action surfaces ────────────────────────────────────────── */
456
+ --exxat-color-action-primary: var(--primary);
457
+ --exxat-color-action-secondary: var(--secondary);
458
+ --exxat-color-action-destructive: var(--destructive);
459
+
460
+ /* ── Borders (decorative + form-field ladder) ──────────────── */
461
+ --exxat-color-border-1: var(--border);
462
+ --exxat-color-border-control-subtle: var(--border-control);
463
+ --exxat-color-border-control-1: var(--border-control-3);
464
+ --exxat-color-border-control-2: var(--border-control-35);
465
+
466
+ /* ── Focus + overlay ────────────────────────────────────────── */
467
+ --exxat-color-focus-ring: var(--ring);
468
+ --exxat-color-overlay: var(--overlay);
469
+
470
+ /* ── Chart slots ────────────────────────────────────────────── */
471
+ --exxat-color-chart-1: var(--chart-1);
472
+ --exxat-color-chart-2: var(--chart-2);
473
+ --exxat-color-chart-3: var(--chart-3);
474
+ --exxat-color-chart-4: var(--chart-4);
475
+ --exxat-color-chart-5: var(--chart-5);
476
+
477
+ /* ── Chip / badge slots ─────────────────────────────────────── */
478
+ --exxat-color-chip-1: var(--chip-1);
479
+ --exxat-color-chip-2: var(--chip-2);
480
+ --exxat-color-chip-3: var(--chip-3);
481
+ --exxat-color-chip-4: var(--chip-4);
482
+ --exxat-color-chip-5: var(--chip-5);
483
+ --exxat-color-chip-destructive: var(--chip-destructive);
484
+
485
+ /* ── Radius scale ──────────────────────────────────────────── */
486
+ --exxat-radius-1: 4px;
487
+ --exxat-radius-2: 8px;
488
+ --exxat-radius-3: 12px;
489
+ --exxat-radius-4: 16px;
490
+ --exxat-radius-5: 20px;
491
+ --exxat-radius-6: 24px;
492
+
493
+ /* ── Spacing scale ─────────────────────────────────────────── */
494
+ --exxat-spacing-1: 0.25rem;
495
+ --exxat-spacing-2: 0.5rem;
496
+ --exxat-spacing-3: 0.75rem;
497
+ --exxat-spacing-4: 1rem;
498
+ --exxat-spacing-5: 1.25rem;
499
+ --exxat-spacing-6: 1.5rem;
500
+ --exxat-spacing-8: 2rem;
501
+ --exxat-spacing-12: 3rem;
502
+
503
+ /* ── Control height scale ──────────────────────────────────── */
504
+ --exxat-control-height-1: var(--control-height-sm);
505
+ --exxat-control-height-2: var(--control-height);
506
+ --exxat-control-height-3: var(--control-height-touch);
353
507
  }
354
508
 
355
509
  /* ==========================================================================
@@ -358,12 +512,43 @@ html[data-text-size="large"] {
358
512
  .dark {
359
513
  --sticky-edge-fade: oklch(0 0 0 / 0.32);
360
514
 
361
- /* Canvascharcoal grey (not near-black) */
362
- --background: oklch(0.20 0.008 270);
515
+ /* Brand-tint scale for dark mode same hue family as :root but at dark-mode
516
+ lightness so derived surfaces (`--secondary-panel-bg`, `--sidebar` fallback
517
+ via `var(--brand-tint)`, etc.) read as dark brand surfaces, not pale
518
+ pastel washes. Themed `.dark` variants (`.theme-one.dark`,
519
+ `.theme-prism.dark`, …) override these with their own hue.
520
+
521
+ Chroma note: at L≈0.27 the OKLCH hue-discrimination threshold is much
522
+ higher than at L≈0.97 (Helmholtz–Kohlrausch). The PRIMARY brand surface
523
+ (`--brand-tint`) needs ~3–4× the chroma of its light-mode counterpart so
524
+ different products read as visibly different in dark mode. The lighter /
525
+ subtler scale steps stay low-chroma — they're elevation hints, not the
526
+ brand carrier. */
527
+ --brand-tint: oklch(0.30 0.05 270);
528
+ --brand-tint-light: oklch(0.34 0.04 270);
529
+ --brand-tint-subtle: oklch(0.26 0.025 270);
530
+
531
+ /* Canvas — charcoal grey with a perceptible whisper of brand chroma (still
532
+ ≥ 12:1 against --foreground). Was 0.008 — below the OKLCH hue-perception
533
+ threshold at L 0.20, so the canvas read as dead-neutral grey. 0.014 ties
534
+ the canvas to the theme without compromising readability. */
535
+ --background: oklch(0.20 0.014 270);
363
536
  --foreground: oklch(0.985 0 0);
364
- --card: oklch(0.255 0.008 270);
537
+ /* Dark surface elevation ladder (see commentary at line ~605 for the full
538
+ stack across themed blocks):
539
+ --background L=0.20 canvas
540
+ --secondary-panel-bg L=0.22 nested chrome (between sidebar & canvas)
541
+ --card L=0.225 subtle inline elevation
542
+ --sidebar /input-bg L=0.245 outer chrome
543
+ --popover L=0.275 floating menus / dropdowns
544
+
545
+ Card stays at +0.025 above canvas so it reads as the same surface family.
546
+ Popover lifts further (+0.075) so it visibly floats above the canvas it
547
+ covers — a too-close popover blends into the page and a dropdown loses
548
+ its boundary. */
549
+ --card: oklch(0.225 0.008 270);
365
550
  --card-foreground: oklch(0.985 0 0);
366
- --popover: oklch(0.255 0.008 270);
551
+ --popover: oklch(0.275 0.012 270);
367
552
  --popover-foreground: oklch(0.985 0 0);
368
553
  --primary: oklch(0.985 0 0);
369
554
  --primary-foreground: oklch(0.3457 0.0052 286.13);
@@ -378,6 +563,7 @@ html[data-text-size="large"] {
378
563
 
379
564
  /* KeyMetrics flat band — no surface; bottom brand glow only (OKLCH). */
380
565
  --key-metrics-flat-cell-bg: transparent;
566
+ --key-metrics-flat-divider: color-mix(in oklch, var(--sidebar-border) 55%, transparent);
381
567
  --key-metrics-flat-band-radial: radial-gradient(
382
568
  ellipse 120% 68% at 50% 100%,
383
569
  color-mix(in oklch, var(--brand-color) 26%, transparent) 0%,
@@ -399,7 +585,7 @@ html[data-text-size="large"] {
399
585
  --control-border: var(--border-control-3);
400
586
 
401
587
  --input: oklch(0.72 0.012 270);
402
- --input-background: oklch(0.255 0 0);
588
+ --input-background: oklch(0.245 0 0);
403
589
 
404
590
  /* Focus ring — 3:1+ on dark bg */
405
591
  --ring: oklch(0.85 0 0);
@@ -429,18 +615,27 @@ html[data-text-size="large"] {
429
615
  --icon-disc-danger-bg: color-mix(in oklch, var(--destructive) 14%, transparent);
430
616
  --icon-disc-danger-fg: color-mix(in oklch, var(--foreground) 8%, var(--destructive));
431
617
 
432
- /* Sidebar */
433
- --sidebar: oklch(0.245 0.015 270);
618
+ /* Sidebar — same chroma-bump principle as `--brand-tint`: at L≈0.245 the
619
+ OKLCH hue-perception threshold is ~0.04, so 0.015 read as dead grey
620
+ regardless of brand. 0.04 reads as the brand without competing with the
621
+ content panel. `.theme-*.dark` blocks restate this scale at their hue. */
622
+ --sidebar: oklch(0.245 0.04 270);
434
623
  --sidebar-foreground: oklch(0.985 0 0);
435
624
  --sidebar-primary: oklch(0.488 0.243 264.376);
436
625
  --sidebar-primary-foreground: oklch(0.985 0 0);
437
- --sidebar-accent: oklch(0.30 0.012 270);
626
+ --sidebar-accent: oklch(0.30 0.035 270);
438
627
  --sidebar-accent-foreground: oklch(0.985 0 0);
439
- --sidebar-border: oklch(0.38 0.010 270);
628
+ --sidebar-border: oklch(0.38 0.025 270);
440
629
  --sidebar-ring: oklch(0.85 0 0);
441
630
  --sidebar-section-label-foreground: color-mix(in oklch, var(--sidebar-foreground) 48%, var(--sidebar));
442
- /* Nested secondary rail — elevation 1: brand stack, lifted toward `--card` / page. */
443
- --secondary-panel-bg: color-mix(in oklch, var(--card) 32%, var(--brand-tint) 68%);
631
+ /* Nested secondary rail — nested chrome wedged between the outer sidebar
632
+ (L=0.245) and the page canvas (L=0.20). Previously this resolved to
633
+ `var(--brand-tint)` at L=0.30, which made the panel *brighter* than the
634
+ sidebar — it popped out instead of nestling in. Now L=0.22 places it just
635
+ above canvas with a whisper of brand chroma; each themed dark block below
636
+ overrides with the brand hue so it still reads as Exxat One vs Prism vs
637
+ Assessment vs custom. */
638
+ --secondary-panel-bg: oklch(0.22 0.020 270);
444
639
  --theme-color-chrome: #2f2d36;
445
640
 
446
641
  /* Lifted scrim on dark — white-tinted veil, not heavy black */
@@ -486,12 +681,6 @@ html[data-text-size="large"] {
486
681
  --secondary: oklch(0.95 0.012 286.1);
487
682
  --accent: oklch(0.925 0.015 286.1);
488
683
  --muted: oklch(0.945 0.008 286.1);
489
- --key-metrics-flat-band-radial: radial-gradient(
490
- ellipse 120% 68% at 50% 100%,
491
- oklch(0.50 0.14 286.1 / 0.22) 0%,
492
- oklch(0.50 0.14 286.1 / 0.09) 42%,
493
- transparent 72%
494
- );
495
684
  }
496
685
 
497
686
  .theme-one.dark,
@@ -499,20 +688,32 @@ html[data-text-size="large"] {
499
688
  .theme-lavender.dark,
500
689
  .dark.theme-lavender {
501
690
  --ring: var(--brand-color);
502
- --background: oklch(0.20 0.008 286.1);
503
- --sidebar: oklch(0.245 0.015 286.1);
504
- --sidebar-accent: oklch(0.30 0.012 286.1);
505
- --sidebar-border: oklch(0.38 0.010 286.1);
691
+ --background: oklch(0.20 0.014 286.1);
692
+ --sidebar: oklch(0.245 0.04 286.1);
693
+ --sidebar-accent: oklch(0.30 0.035 286.1);
694
+ --sidebar-border: oklch(0.38 0.025 286.1);
506
695
  /* Restore dark surfaces (base .dark is overridden by :not(.dark) rules above when both classes apply) */
507
696
  --secondary: oklch(0.31 0.04 286.1);
508
697
  --muted: oklch(0.31 0.04 286.1);
509
698
  --accent: oklch(0.33 0.06 286.1);
510
- --key-metrics-flat-band-radial: radial-gradient(
511
- ellipse 120% 68% at 50% 100%,
512
- oklch(0.50 0.14 286.1 / 0.28) 0%,
513
- oklch(0.50 0.14 286.1 / 0.1) 42%,
514
- transparent 72%
515
- );
699
+ /* Surface elevation ladder — dark mode.
700
+ Card / input-background are *inline* elevations (same surface family as
701
+ canvas, small step). Popover is a *floating* surface — lifts further so a
702
+ dropdown over canvas reads as clearly above it instead of blending in.
703
+ Secondary panel is nested chrome — wedged between canvas (L=0.20) and
704
+ sidebar (L=0.245), so it nestles into the shell rather than popping out.
705
+ Brand chroma stays gentle on all three; the saturated brand expression
706
+ lives on --brand-tint / --sidebar. */
707
+ --secondary-panel-bg: oklch(0.22 0.025 286.1);
708
+ --card: oklch(0.225 0.017 286.1);
709
+ --popover: oklch(0.275 0.022 286.1);
710
+ --input-background: oklch(0.245 0.010 286.1);
711
+ /* Brand-tint scale — same hue (286.1 — Exxat One lavender), dark lightness.
712
+ PRIMARY (`--brand-tint`) carries enough chroma to read as visibly lavender
713
+ against the page canvas; LIGHT / SUBTLE steps are elevation aides only. */
714
+ --brand-tint: oklch(0.30 0.05 286.1);
715
+ --brand-tint-light: oklch(0.34 0.04 286.1);
716
+ --brand-tint-subtle: oklch(0.26 0.025 286.1);
516
717
  }
517
718
 
518
719
  /* ==========================================================================
@@ -541,12 +742,6 @@ html[data-text-size="large"] {
541
742
  --muted: oklch(0.945 0.008 343);
542
743
  --banner-prism-bg: oklch(0.97 0.02 343);
543
744
  --theme-color-chrome: #fff5f9;
544
- --key-metrics-flat-band-radial: radial-gradient(
545
- ellipse 120% 68% at 50% 100%,
546
- oklch(0.57 0.24 342 / 0.22) 0%,
547
- oklch(0.57 0.24 342 / 0.09) 42%,
548
- transparent 72%
549
- );
550
745
  }
551
746
 
552
747
  .theme-prism.dark,
@@ -554,20 +749,145 @@ html[data-text-size="large"] {
554
749
  .theme-rose.dark,
555
750
  .dark.theme-rose {
556
751
  --ring: var(--brand-color);
557
- --background: oklch(0.20 0.008 342);
558
- --sidebar: oklch(0.245 0.015 342);
559
- --sidebar-accent: oklch(0.30 0.012 342);
560
- --sidebar-border: oklch(0.38 0.010 342);
752
+ --background: oklch(0.20 0.014 342);
753
+ --sidebar: oklch(0.245 0.045 342);
754
+ --sidebar-accent: oklch(0.30 0.04 342);
755
+ --sidebar-border: oklch(0.38 0.028 342);
561
756
  --secondary: oklch(0.31 0.04 342);
562
757
  --muted: oklch(0.31 0.04 342);
563
758
  --accent: oklch(0.33 0.06 342);
564
759
  --theme-color-chrome: #2a2428;
565
- --key-metrics-flat-band-radial: radial-gradient(
566
- ellipse 120% 68% at 50% 100%,
567
- oklch(0.57 0.24 342 / 0.28) 0%,
568
- oklch(0.57 0.24 342 / 0.1) 42%,
569
- transparent 72%
570
- );
760
+ /* Surface elevation ladder — see commentary in .theme-one.dark. Chroma is a
761
+ touch higher than lavender at every step because rose reads slightly
762
+ dimmer at equal chroma at these lightnesses. */
763
+ --secondary-panel-bg: oklch(0.22 0.030 342);
764
+ --card: oklch(0.225 0.020 342);
765
+ --popover: oklch(0.275 0.026 342);
766
+ --input-background: oklch(0.245 0.011 342);
767
+ /* Brand-tint scale — same hue (342 — Prism rose), dark lightness. Rose can
768
+ carry slightly higher chroma without warming-shift on dark surfaces. */
769
+ --brand-tint: oklch(0.30 0.055 342);
770
+ --brand-tint-light: oklch(0.34 0.045 342);
771
+ --brand-tint-subtle: oklch(0.26 0.028 342);
772
+ }
773
+
774
+ /* ==========================================================================
775
+ Theme: Exxat Assessment · Green · hue 159.88
776
+ Usage: <html class="theme-assessment">
777
+ ========================================================================== */
778
+ .theme-assessment {
779
+ --brand-tint: oklch(0.965 0.018 159.88);
780
+ --brand-tint-light: oklch(0.992 0.008 159.88);
781
+ --brand-tint-subtle: oklch(0.93 0.028 159.88);
782
+ --brand-color: oklch(0.7 0.0913 159.88);
783
+ --brand-color-light: oklch(0.82 0.072 159.88);
784
+ --brand-color-dark: oklch(0.48 0.0913 159.88);
785
+ --brand-color-deep: oklch(0.34 0.075 159.88);
786
+ --ring: var(--brand-color-dark);
787
+ }
788
+
789
+ .theme-assessment:not(.dark) {
790
+ --sidebar: var(--brand-tint);
791
+ --sidebar-accent: oklch(0.945 0.026 159.88);
792
+ --sidebar-border: oklch(0.90 0.026 159.88);
793
+ --secondary: oklch(0.95 0.012 159.88);
794
+ --accent: oklch(0.925 0.016 159.88);
795
+ --muted: oklch(0.945 0.008 159.88);
796
+ --theme-color-chrome: #f1faf5;
797
+ }
798
+
799
+ .theme-assessment.dark,
800
+ .dark.theme-assessment {
801
+ --ring: var(--brand-color);
802
+ --background: oklch(0.20 0.014 159.88);
803
+ --sidebar: oklch(0.245 0.04 159.88);
804
+ --sidebar-accent: oklch(0.30 0.035 159.88);
805
+ --sidebar-border: oklch(0.38 0.025 159.88);
806
+ --secondary: oklch(0.31 0.04 159.88);
807
+ --muted: oklch(0.31 0.04 159.88);
808
+ --accent: oklch(0.33 0.06 159.88);
809
+ --theme-color-chrome: #242a27;
810
+ /* Surface elevation ladder — see commentary in .theme-one.dark. */
811
+ --secondary-panel-bg: oklch(0.22 0.025 159.88);
812
+ --card: oklch(0.225 0.017 159.88);
813
+ --popover: oklch(0.275 0.022 159.88);
814
+ --input-background: oklch(0.245 0.010 159.88);
815
+ /* Brand-tint scale — same hue (159.88 — Assessment teal-green), dark
816
+ lightness. Green at this lightness reads cleanly against the dark canvas. */
817
+ --brand-tint: oklch(0.30 0.05 159.88);
818
+ --brand-tint-light: oklch(0.34 0.04 159.88);
819
+ --brand-tint-subtle: oklch(0.26 0.025 159.88);
820
+ }
821
+
822
+ /* ==========================================================================
823
+ Theme: Custom product · user-selected hue
824
+ Usage: <html class="theme-custom" style="--custom-product-brand-color: …">
825
+ ========================================================================== */
826
+ /*
827
+ * Tint chroma is **derived from the source's chroma** so neighbouring hues
828
+ * (e.g. Blue h=252 vs Indigo h=280 vs Purple h=286) read as distinct pale
829
+ * tints instead of collapsing to the same near-white. The earlier formula
830
+ * pinned chroma to a fixed `0.018`, which is below the hue-discrimination
831
+ * threshold at L≈0.96 for closely-spaced hues — that's why Blue / Indigo /
832
+ * Purple looked identical in the sidebar.
833
+ *
834
+ * `max(<floor>, calc(c * <fraction>))` rules:
835
+ * - vibrant brand colours (c ≈ 0.10–0.23) get a meaningfully tinted
836
+ * sidebar / accent / muted scale → product chrome visibly changes per
837
+ * pick
838
+ * - low-chroma custom-hex picks (greys) fall back to the floor so they
839
+ * don't render as pure white
840
+ * - lightness + hue stay pinned to the original mock-up values, so the
841
+ * overall "very pale background" feel is unchanged
842
+ */
843
+ .theme-custom {
844
+ --brand-tint: oklch(from var(--custom-product-brand-color) 0.965 max(0.018, calc(c * 0.20)) h);
845
+ --brand-tint-light: oklch(from var(--custom-product-brand-color) 0.992 max(0.008, calc(c * 0.08)) h);
846
+ --brand-tint-subtle: oklch(from var(--custom-product-brand-color) 0.93 max(0.028, calc(c * 0.30)) h);
847
+ --brand-color: var(--custom-product-brand-color);
848
+ --brand-color-light: oklch(from var(--custom-product-brand-color) 0.82 c h);
849
+ --brand-color-dark: oklch(from var(--custom-product-brand-color) 0.48 c h);
850
+ --brand-color-deep: oklch(from var(--custom-product-brand-color) 0.34 c h);
851
+ --ring: var(--brand-color-dark);
852
+ }
853
+
854
+ .theme-custom:not(.dark) {
855
+ --sidebar: var(--brand-tint);
856
+ --sidebar-accent: oklch(from var(--custom-product-brand-color) 0.945 max(0.026, calc(c * 0.28)) h);
857
+ --sidebar-border: oklch(from var(--custom-product-brand-color) 0.90 max(0.026, calc(c * 0.28)) h);
858
+ --secondary: oklch(from var(--custom-product-brand-color) 0.95 max(0.012, calc(c * 0.14)) h);
859
+ --accent: oklch(from var(--custom-product-brand-color) 0.925 max(0.016, calc(c * 0.18)) h);
860
+ --muted: oklch(from var(--custom-product-brand-color) 0.945 max(0.008, calc(c * 0.10)) h);
861
+ --theme-color-chrome: color-mix(in oklch, var(--custom-product-brand-color) 10%, white);
862
+ }
863
+
864
+ .theme-custom.dark,
865
+ .dark.theme-custom {
866
+ --ring: var(--brand-color);
867
+ --background: oklch(from var(--custom-product-brand-color) 0.20 max(0.014, calc(c * 0.12)) h);
868
+ --sidebar: oklch(from var(--custom-product-brand-color) 0.245 max(0.035, calc(c * 0.28)) h);
869
+ --sidebar-accent: oklch(from var(--custom-product-brand-color) 0.30 max(0.030, calc(c * 0.24)) h);
870
+ --sidebar-border: oklch(from var(--custom-product-brand-color) 0.38 max(0.022, calc(c * 0.18)) h);
871
+ --secondary: oklch(from var(--custom-product-brand-color) 0.31 max(0.04, calc(c * 0.40)) h);
872
+ --muted: oklch(from var(--custom-product-brand-color) 0.31 max(0.04, calc(c * 0.40)) h);
873
+ --accent: oklch(from var(--custom-product-brand-color) 0.33 max(0.06, calc(c * 0.50)) h);
874
+ --theme-color-chrome: color-mix(in oklch, var(--custom-product-brand-color) 12%, black);
875
+ /* Surface elevation ladder — derived from the custom picked hue. See
876
+ commentary in .theme-one.dark for the full ladder. Chroma scales with
877
+ the source colour (~13% for inline cards / 16% for floating popovers /
878
+ 20% for secondary panel) with floors that keep near-grey picks from
879
+ collapsing back to neutral. */
880
+ --secondary-panel-bg: oklch(from var(--custom-product-brand-color) 0.22 max(0.020, calc(c * 0.20)) h);
881
+ --card: oklch(from var(--custom-product-brand-color) 0.225 max(0.015, calc(c * 0.13)) h);
882
+ --popover: oklch(from var(--custom-product-brand-color) 0.275 max(0.018, calc(c * 0.16)) h);
883
+ --input-background: oklch(from var(--custom-product-brand-color) 0.245 max(0.008, calc(c * 0.08)) h);
884
+ /* Brand-tint scale — derived from the picked hue, dark lightness. PRIMARY
885
+ carries chroma high enough for the secondary panel to read as the brand
886
+ hue; floor 0.04 prevents low-chroma picks (greys) from collapsing back to
887
+ a flat surface. */
888
+ --brand-tint: oklch(from var(--custom-product-brand-color) 0.30 max(0.04, calc(c * 0.30)) h);
889
+ --brand-tint-light: oklch(from var(--custom-product-brand-color) 0.34 max(0.03, calc(c * 0.24)) h);
890
+ --brand-tint-subtle: oklch(from var(--custom-product-brand-color) 0.26 max(0.022, calc(c * 0.20)) h);
571
891
  }
572
892
 
573
893
  /* ==========================================================================
@@ -595,13 +915,6 @@ html[data-text-size="large"] {
595
915
  /* ── Light High Contrast ─────────────────────────────────────────────────── */
596
916
  /* Fluent 2 / Microsoft 6-color strategy. */
597
917
  /* Highlight = saturated bright brand color (follows theme hue). */
598
- /* */
599
- /* Canvas = white */
600
- /* CanvasText = near-black */
601
- /* Highlight = saturated dark brand (selected / active / focus) */
602
- /* HighlightText= white */
603
- /* GrayText = mid-grey (disabled) */
604
- /* Error = dark red (destructive only) */
605
918
  html[data-contrast="high"]:not(.dark) {
606
919
  --hc-highlight: oklch(from var(--brand-color) 0.35 0.30 h);
607
920
  --hc-highlight-text: oklch(1 0 0);
@@ -612,33 +925,24 @@ html[data-contrast="high"]:not(.dark) {
612
925
  --card-foreground: oklch(0.14 0 0);
613
926
  --popover: oklch(1 0 0);
614
927
  --popover-foreground: oklch(0.14 0 0);
615
-
616
928
  --primary: oklch(0.14 0 0);
617
929
  --primary-foreground: oklch(1 0 0);
618
-
619
930
  --secondary: oklch(1 0 0);
620
931
  --secondary-foreground: oklch(0.14 0 0);
621
-
622
932
  --muted: oklch(0.94 0 0);
623
933
  --muted-foreground: oklch(0.14 0 0);
624
-
625
934
  --accent: var(--hc-highlight);
626
935
  --accent-foreground: var(--hc-highlight-text);
627
-
628
936
  --destructive: oklch(0.45 0.24 25);
629
937
  --destructive-foreground: oklch(1 0 0);
630
-
631
938
  --border: oklch(0.14 0 0);
632
939
  --border-control: oklch(0.14 0 0);
633
940
  --border-control-3: oklch(0.14 0 0);
634
941
  --border-control-35: oklch(0.14 0 0);
635
942
  --control-border: oklch(0.14 0 0);
636
-
637
943
  --input: oklch(0.14 0 0);
638
944
  --input-background: oklch(1 0 0);
639
-
640
945
  --ring: var(--hc-highlight);
641
-
642
946
  --sidebar: oklch(1 0 0);
643
947
  --sidebar-foreground: oklch(0.14 0 0);
644
948
  --sidebar-primary: oklch(0.14 0 0);
@@ -648,23 +952,17 @@ html[data-contrast="high"]:not(.dark) {
648
952
  --sidebar-border: oklch(0.14 0 0);
649
953
  --sidebar-ring: var(--hc-highlight);
650
954
  --sidebar-section-label-foreground: oklch(0.40 0 0);
651
-
652
- /* Charts — CanvasText (near-black) fill; differentiated by luminance */
653
955
  --chart-1: oklch(0.14 0 0);
654
956
  --chart-2: oklch(0.35 0 0);
655
957
  --chart-3: oklch(0.55 0 0);
656
958
  --chart-4: oklch(0.72 0 0);
657
959
  --chart-5: oklch(0.86 0 0);
658
-
659
- /* Chips — uniform foreground; differentiated by label text only */
660
960
  --chip-1: oklch(0.14 0 0);
661
961
  --chip-2: oklch(0.14 0 0);
662
962
  --chip-3: oklch(0.14 0 0);
663
963
  --chip-4: oklch(0.14 0 0);
664
964
  --chip-5: oklch(0.14 0 0);
665
965
  --chip-destructive: oklch(0.45 0.24 25);
666
-
667
- /* Hover — plain grey shift */
668
966
  --interactive-hover: oklch(0.88 0 0);
669
967
  --interactive-hover-foreground: oklch(0.14 0 0);
670
968
  --interactive-hover-subtle: oklch(0.92 0 0);
@@ -672,7 +970,6 @@ html[data-contrast="high"]:not(.dark) {
672
970
  --interactive-hover-medium: oklch(0.86 0 0);
673
971
  --interactive-hover-strong: oklch(0.82 0 0);
674
972
  --interactive-hover-row: oklch(0.88 0 0);
675
-
676
973
  --overlay: color-mix(in oklch, var(--foreground) 18%, transparent);
677
974
  --dt-row-bg: oklch(1 0 0);
678
975
  --dt-row-hover: oklch(0.92 0 0);
@@ -697,33 +994,24 @@ html[data-contrast="high"].dark {
697
994
  --card-foreground: oklch(0.96 0 0);
698
995
  --popover: oklch(0.20 0 0);
699
996
  --popover-foreground: oklch(0.96 0 0);
700
-
701
997
  --primary: oklch(0.96 0 0);
702
998
  --primary-foreground: oklch(0.10 0 0);
703
-
704
999
  --secondary: oklch(0.14 0 0);
705
1000
  --secondary-foreground: oklch(0.96 0 0);
706
-
707
1001
  --muted: oklch(0.22 0 0);
708
1002
  --muted-foreground: oklch(0.96 0 0);
709
-
710
1003
  --accent: var(--hc-highlight);
711
1004
  --accent-foreground: var(--hc-highlight-text);
712
-
713
1005
  --destructive: oklch(0.72 0.18 18);
714
1006
  --destructive-foreground: oklch(0.10 0 0);
715
-
716
1007
  --border: oklch(0.75 0 0);
717
1008
  --border-control: oklch(0.75 0 0);
718
1009
  --border-control-3: oklch(0.75 0 0);
719
1010
  --border-control-35: oklch(0.75 0 0);
720
1011
  --control-border: oklch(0.75 0 0);
721
-
722
1012
  --input: oklch(0.75 0 0);
723
1013
  --input-background: oklch(0.14 0 0);
724
-
725
1014
  --ring: var(--hc-highlight);
726
-
727
1015
  --sidebar: oklch(0.14 0 0);
728
1016
  --sidebar-foreground: oklch(0.96 0 0);
729
1017
  --sidebar-primary: oklch(0.96 0 0);
@@ -733,23 +1021,17 @@ html[data-contrast="high"].dark {
733
1021
  --sidebar-border: oklch(0.75 0 0);
734
1022
  --sidebar-ring: var(--hc-highlight);
735
1023
  --sidebar-section-label-foreground: oklch(0.65 0 0);
736
-
737
- /* Charts — CanvasText (white) fill; differentiated by luminance */
738
1024
  --chart-1: oklch(0.96 0 0);
739
1025
  --chart-2: oklch(0.75 0 0);
740
1026
  --chart-3: oklch(0.55 0 0);
741
1027
  --chart-4: oklch(0.38 0 0);
742
1028
  --chart-5: oklch(0.22 0 0);
743
-
744
- /* Chips — uniform foreground; differentiated by label text only */
745
1029
  --chip-1: oklch(0.96 0 0);
746
1030
  --chip-2: oklch(0.96 0 0);
747
1031
  --chip-3: oklch(0.96 0 0);
748
1032
  --chip-4: oklch(0.96 0 0);
749
1033
  --chip-5: oklch(0.96 0 0);
750
1034
  --chip-destructive: oklch(0.72 0.18 18);
751
-
752
- /* Hover — plain grey shift */
753
1035
  --interactive-hover: oklch(0.26 0 0);
754
1036
  --interactive-hover-foreground: oklch(0.96 0 0);
755
1037
  --interactive-hover-subtle: oklch(0.22 0 0);
@@ -757,7 +1039,6 @@ html[data-contrast="high"].dark {
757
1039
  --interactive-hover-medium: oklch(0.28 0 0);
758
1040
  --interactive-hover-strong: oklch(0.32 0 0);
759
1041
  --interactive-hover-row: oklch(0.26 0 0);
760
-
761
1042
  --overlay: color-mix(in oklch, var(--foreground) 22%, transparent);
762
1043
  --dt-row-bg: oklch(0.14 0 0);
763
1044
  --dt-row-hover: oklch(0.22 0 0);
@@ -769,13 +1050,7 @@ html[data-contrast="high"].dark {
769
1050
  --dt-new-row-border: oklch(0.96 0 0);
770
1051
  }
771
1052
 
772
-
773
- /* Override brand tokens in HC so text-brand / bg-brand become HC-safe.
774
- NOTE: --hc-highlight uses oklch(from var(--brand-color) ...) so we must
775
- NOT override --brand-color before that resolves. Instead, override
776
- brand-tint/wash tokens to neutral greys and leave --brand-color for
777
- the relative-color syntax to consume. Text using text-brand will get
778
- the saturated HC highlight, which is correct. */
1053
+ /* Neutralize brand tint washes in HC so bg-brand-tint doesn't compete */
779
1054
  html:is([data-contrast="high"], [data-contrast="windows"]):not(.dark) {
780
1055
  --brand-tint: oklch(0.94 0 0);
781
1056
  --brand-tint-light: oklch(0.97 0 0);
@@ -824,7 +1099,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
824
1099
  border: 2px solid var(--foreground) !important;
825
1100
  }
826
1101
 
827
- /* 1f. Badge / chip — border-based; fill only for destructive */
1102
+ /* 1f. Badge / chip — border-based; no decorative fills */
828
1103
  & [data-slot="badge"] {
829
1104
  border-width: 2px !important;
830
1105
  border-color: var(--foreground) !important;
@@ -833,15 +1108,26 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
833
1108
  box-shadow: none !important;
834
1109
  outline: none !important;
835
1110
  color: var(--foreground) !important;
836
- color: var(--foreground) !important;
837
1111
  }
838
1112
 
839
1113
  & [data-slot="badge"] * {
840
1114
  color: var(--foreground) !important;
841
1115
  }
842
1116
 
843
- /* Sidebar wrapper is positioning-only when it wraps Badge avoid double border */
844
- & [data-slot="sidebar-menu-badge"]:has([data-slot="badge"]) {
1117
+ /* Status chip same treatment as Badge (border-based, no decorative fill) */
1118
+ & [data-slot="status-badge"] {
1119
+ border-width: 2px !important;
1120
+ border-color: var(--foreground) !important;
1121
+ background-color: var(--background) !important;
1122
+ font-weight: 700 !important;
1123
+ box-shadow: none !important;
1124
+ outline: none !important;
1125
+ color: var(--foreground) !important;
1126
+ }
1127
+
1128
+ /* Sidebar wrapper is positioning-only when it wraps Badge/StatusBadge — avoid double border */
1129
+ & [data-slot="sidebar-menu-badge"]:has([data-slot="badge"]),
1130
+ & [data-slot="sidebar-menu-badge"]:has([data-slot="status-badge"]) {
845
1131
  border-width: 0 !important;
846
1132
  background-color: transparent !important;
847
1133
  box-shadow: none !important;
@@ -858,7 +1144,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
858
1144
  outline: none !important;
859
1145
  }
860
1146
 
861
- & [data-slot="sidebar-menu-badge"]:not(:has([data-slot="badge"])) {
1147
+ & [data-slot="sidebar-menu-badge"]:not(:has([data-slot="badge"])):not(:has([data-slot="status-badge"])) {
862
1148
  border-width: 2px !important;
863
1149
  border-color: currentColor !important;
864
1150
  background-color: var(--background) !important;
@@ -894,7 +1180,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
894
1180
  color: var(--foreground) !important;
895
1181
  }
896
1182
 
897
- /* List / menu rows — highlighted row uses Highlight brand color */
1183
+ /* List / menu rows — Highlight brand color for selection */
898
1184
  & [data-slot="dropdown-menu-item"][data-highlighted],
899
1185
  & [data-slot="dropdown-menu-checkbox-item"][data-highlighted],
900
1186
  & [data-slot="dropdown-menu-radio-item"][data-highlighted],
@@ -924,8 +1210,9 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
924
1210
 
925
1211
  & [data-slot="view-segmented-item"][aria-pressed="true"],
926
1212
  & [data-slot="view-segmented-item"][aria-checked="true"] {
927
- outline: 2px solid currentColor !important;
928
- outline-offset: -2px !important;
1213
+ background-color: var(--accent) !important;
1214
+ color: var(--accent-foreground) !important;
1215
+ outline: none !important;
929
1216
  }
930
1217
 
931
1218
  /* Floating surfaces — portal menus, popovers, sheets, dialogs */
@@ -963,7 +1250,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
963
1250
  color: var(--dt-row-selected-fg) !important;
964
1251
  }
965
1252
 
966
- /* Table selected rows — Highlight brand color (like MS Teams selection) */
1253
+ /* Table selected rows — Highlight brand color (like MS Teams selection) */
967
1254
  & tr[data-state="selected"] {
968
1255
  background-color: var(--dt-row-selected) !important;
969
1256
  color: var(--dt-row-selected-fg) !important;
@@ -971,22 +1258,23 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
971
1258
  & tr[data-state="selected"] *:not([data-slot="checkbox"] *):not([data-slot="badge"] *):not([data-slot="checkbox"]):not([data-slot="badge"]) {
972
1259
  color: var(--accent-foreground) !important;
973
1260
  }
974
- & tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"],
975
- & tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] {
1261
+ & tr[data-state="selected"] [data-slot="badge"] {
976
1262
  background-color: var(--accent-foreground) !important;
977
- border-color: var(--accent-foreground) !important;
978
1263
  color: var(--accent) !important;
1264
+ border-color: var(--accent-foreground) !important;
979
1265
  }
980
- & tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"] *,
981
- & tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] * {
1266
+ & tr[data-state="selected"] [data-slot="badge"] * {
982
1267
  color: var(--accent) !important;
983
1268
  }
984
- & tr[data-state="selected"] [data-slot="badge"] {
1269
+
1270
+ & tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"],
1271
+ & tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] {
985
1272
  background-color: var(--accent-foreground) !important;
986
- color: var(--accent) !important;
987
1273
  border-color: var(--accent-foreground) !important;
1274
+ color: var(--accent) !important;
988
1275
  }
989
- & tr[data-state="selected"] [data-slot="badge"] * {
1276
+ & tr[data-state="selected"] [data-slot="checkbox"][data-state="checked"] *,
1277
+ & tr[data-state="selected"] [data-slot="checkbox"][data-state="indeterminate"] * {
990
1278
  color: var(--accent) !important;
991
1279
  }
992
1280
  & tr[data-state="selected"] [data-slot="checkbox"]:not([data-state="checked"]):not([data-state="indeterminate"]) {
@@ -1009,7 +1297,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1009
1297
  /* Downstream: pair with a ⚠ icon in the component for non-colour signal */
1010
1298
  }
1011
1299
 
1012
- /* ── Pattern 3: Active nav / toggle items — Highlight brand fill ── */
1300
+ /* ── Pattern 3: Active nav — Highlight brand fill (like MS Teams) ── */
1013
1301
  & [data-slot="sidebar-menu-button"][data-active="true"] {
1014
1302
  background-color: var(--accent) !important;
1015
1303
  color: var(--accent-foreground) !important;
@@ -1080,23 +1368,21 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1080
1368
  background-color: var(--accent-foreground) !important;
1081
1369
  }
1082
1370
 
1083
- /* ── Pattern 3f: Select / dropdown item focus — accent is too subtle;
1084
- force visible inverted selection for keyboard focus (CSS :focus).
1085
- data-highlighted is already handled above; this catches native focus. ── */
1371
+ /* ── Pattern 3f: Select / dropdown item focus — Highlight brand fill ── */
1086
1372
  & [data-slot="select-item"]:focus,
1087
1373
  & [data-slot="dropdown-menu-item"]:focus,
1088
1374
  & [data-slot="dropdown-menu-checkbox-item"]:focus,
1089
1375
  & [data-slot="dropdown-menu-radio-item"]:focus,
1090
1376
  & [data-slot="dropdown-menu-sub-trigger"]:focus {
1091
- background-color: var(--foreground) !important;
1092
- color: var(--background) !important;
1377
+ background-color: var(--accent) !important;
1378
+ color: var(--accent-foreground) !important;
1093
1379
  }
1094
1380
  & [data-slot="select-item"]:focus *,
1095
1381
  & [data-slot="dropdown-menu-item"]:focus *,
1096
1382
  & [data-slot="dropdown-menu-checkbox-item"]:focus *,
1097
1383
  & [data-slot="dropdown-menu-radio-item"]:focus *,
1098
1384
  & [data-slot="dropdown-menu-sub-trigger"]:focus * {
1099
- color: var(--background) !important;
1385
+ color: var(--accent-foreground) !important;
1100
1386
  }
1101
1387
 
1102
1388
  /* ── Pattern 3g: Dropdown check / radio indicator — inherit from parent ── */
@@ -1140,7 +1426,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1140
1426
  color: var(--foreground) !important;
1141
1427
  }
1142
1428
 
1143
- /* ── Pattern 9: Avatars — border-defined, strip blend modes, force contrast ── */
1429
+ /* ── Pattern 9: Avatars — thicken ring, strip blend modes, force contrast ── */
1144
1430
  & [data-slot="avatar"] {
1145
1431
  border: 2px solid var(--foreground) !important;
1146
1432
  }
@@ -1186,12 +1472,6 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1186
1472
  }
1187
1473
 
1188
1474
  /* ── Pattern 13: Strip ALL hardcoded Tailwind palette colors ──────────── */
1189
- /* Banners, board columns, status pills, placement badges, etc. use */
1190
- /* hardcoded emerald/amber/blue/red/slate/yellow classes. In HC these */
1191
- /* MUST collapse to foreground text + border. Strip bg fills, force */
1192
- /* foreground text. (Microsoft HC: no semantic colors except error.) */
1193
-
1194
- /* Banner variants (info/warning/error/success) — border + text only */
1195
1475
  & [data-slot="banner"],
1196
1476
  & [data-slot="local-banner"] {
1197
1477
  background-color: var(--background) !important;
@@ -1204,14 +1484,12 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1204
1484
  color: var(--foreground) !important;
1205
1485
  }
1206
1486
 
1207
- /* Chart containers — add border between series, strip vivid fills */
1208
1487
  & .recharts-bar-rectangle,
1209
1488
  & .recharts-funnel-trapezoid {
1210
1489
  stroke: var(--background) !important;
1211
1490
  stroke-width: 2 !important;
1212
1491
  }
1213
1492
 
1214
- /* Progress bars — container gets border, indicator uses foreground */
1215
1493
  & [role="progressbar"] {
1216
1494
  border: 1px solid var(--foreground) !important;
1217
1495
  background-color: var(--background) !important;
@@ -1220,9 +1498,6 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1220
1498
  background-color: var(--foreground) !important;
1221
1499
  }
1222
1500
 
1223
- /* Generic: any element using Tailwind color utility that escapes tokens.
1224
- Force all text to foreground in the HC subtree except already-handled
1225
- inverted contexts (selected rows, highlighted items, buttons). */
1226
1501
  & [class*="text-emerald"],
1227
1502
  & [class*="text-amber"],
1228
1503
  & [class*="text-red-"],
@@ -1236,8 +1511,6 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1236
1511
  color: var(--foreground) !important;
1237
1512
  }
1238
1513
 
1239
- /* Brand-colored text/bg — map to HC highlight instead of foreground so
1240
- brand accent remains visually distinct (Ask Leo icon, product tints) */
1241
1514
  & [class*="text-brand"] {
1242
1515
  color: var(--accent) !important;
1243
1516
  }
@@ -1275,6 +1548,19 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1275
1548
  }
1276
1549
  }
1277
1550
 
1551
+ /* Coach mark HC override (top-level, outside nesting — bulletproof for portaled content) */
1552
+ html:is([data-contrast="high"], [data-contrast="windows"]) [data-slot="coach-mark"] {
1553
+ border: 2px solid var(--foreground) !important;
1554
+ background: var(--background) !important;
1555
+ background-color: var(--background) !important;
1556
+ color: var(--foreground) !important;
1557
+ background-image: none !important;
1558
+ opacity: 1 !important;
1559
+ }
1560
+ html:is([data-contrast="high"], [data-contrast="windows"]) [data-slot="coach-mark"] *:not(button):not(button *) {
1561
+ color: var(--foreground) !important;
1562
+ }
1563
+
1278
1564
  /* ── OS-level "Increase Contrast" — macOS / iOS / Android ───────────────── */
1279
1565
  @media (prefers-contrast: more) {
1280
1566
  :root:not([data-contrast="off"]):not([data-contrast="windows"]) {
@@ -1345,9 +1631,8 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1345
1631
  box-shadow: none !important;
1346
1632
  }
1347
1633
 
1348
- /* Positioning shell around <Badge/> or <StatusBadge/> — do not draw a second ring */
1349
- [data-slot="sidebar-menu-badge"]:has([data-slot="badge"]),
1350
- [data-slot="sidebar-menu-badge"]:has([data-slot="status-badge"]) {
1634
+ /* Positioning shell around <Badge/> — do not draw a second ring */
1635
+ [data-slot="sidebar-menu-badge"]:has([data-slot="badge"]) {
1351
1636
  border: none !important;
1352
1637
  background: transparent !important;
1353
1638
  outline: none !important;
@@ -1355,7 +1640,6 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1355
1640
  }
1356
1641
 
1357
1642
  [data-slot="badge"],
1358
- [data-slot="status-badge"],
1359
1643
  [data-slot="view-toolbar-count"] {
1360
1644
  border: 2px solid CanvasText !important;
1361
1645
  background-color: Canvas !important;
@@ -1365,7 +1649,6 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1365
1649
  }
1366
1650
 
1367
1651
  [data-slot="badge"] *,
1368
- [data-slot="status-badge"] *,
1369
1652
  [data-slot="view-toolbar-count"] * {
1370
1653
  color: CanvasText !important;
1371
1654
  }
@@ -1405,8 +1688,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1405
1688
  [data-slot="dropdown-menu-radio-item"][data-highlighted]:not([data-disabled]),
1406
1689
  [data-slot="dropdown-menu-sub-trigger"][data-highlighted]:not([data-disabled]),
1407
1690
  [data-slot="select-item"][data-highlighted]:not([data-disabled]),
1408
- /* cmdk sets data-selected="false" on every row — [data-selected] matches all; use ="true" only */
1409
- [data-slot="command-item"][data-selected="true"]:not([data-disabled]),
1691
+ [data-slot="command-item"][data-selected]:not([data-disabled]),
1410
1692
  [data-slot="command-item"][aria-selected="true"]:not([data-disabled]) {
1411
1693
  background-color: Highlight !important;
1412
1694
  color: HighlightText !important;
@@ -1417,7 +1699,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1417
1699
  [data-slot="dropdown-menu-radio-item"][data-highlighted] *,
1418
1700
  [data-slot="dropdown-menu-sub-trigger"][data-highlighted] *,
1419
1701
  [data-slot="select-item"][data-highlighted] *,
1420
- [data-slot="command-item"][data-selected="true"] *,
1702
+ [data-slot="command-item"][data-selected] *,
1421
1703
  [data-slot="command-item"][aria-selected="true"] * {
1422
1704
  color: HighlightText !important;
1423
1705
  }
@@ -1440,7 +1722,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1440
1722
  outline: none !important;
1441
1723
  }
1442
1724
 
1443
- /* Sidebar active item — Highlight brand fill (like MS Teams) */
1725
+ /* Sidebar active item — Highlight brand fill */
1444
1726
  [data-slot="sidebar-menu-button"][data-active="true"] {
1445
1727
  background-color: Highlight !important;
1446
1728
  color: HighlightText !important;
@@ -1516,17 +1798,20 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1516
1798
  background-color: HighlightText !important;
1517
1799
  color: Highlight !important;
1518
1800
  }
1801
+ /* Badge in forced-colors — opaque canvas bg */
1519
1802
  [data-slot="badge"] {
1520
1803
  background-color: Canvas !important;
1521
1804
  border-color: CanvasText !important;
1522
1805
  color: CanvasText !important;
1523
1806
  }
1524
1807
 
1808
+ /* Checked checkboxes — Highlight fill */
1525
1809
  [data-slot="checkbox"][data-state="checked"] *,
1526
1810
  [data-slot="checkbox"][data-state="indeterminate"] * {
1527
1811
  color: HighlightText !important;
1528
1812
  }
1529
1813
 
1814
+ /* Avatar in forced-colors */
1530
1815
  [data-slot="avatar"] {
1531
1816
  border: 2px solid CanvasText !important;
1532
1817
  }
@@ -1538,7 +1823,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1538
1823
  color: CanvasText !important;
1539
1824
  }
1540
1825
 
1541
- /* Checked checkboxes / radios — Highlight brand fill */
1826
+ /* Checked checkboxes / radios — Highlight fill */
1542
1827
  [data-slot="checkbox"][data-state="checked"],
1543
1828
  [data-slot="checkbox"][data-state="indeterminate"] {
1544
1829
  background-color: Highlight !important;
@@ -1549,9 +1834,6 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1549
1834
  background-color: Highlight !important;
1550
1835
  border-color: Highlight !important;
1551
1836
  }
1552
- [data-slot="radio-group-item"][data-state="checked"] [data-slot="radio-group-indicator"] span {
1553
- background-color: HighlightText !important;
1554
- }
1555
1837
 
1556
1838
  /* Switch ON — Highlight fill */
1557
1839
  [role="switch"][aria-checked="true"] {
@@ -1723,7 +2005,12 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1723
2005
  layout (spacing, heights, radii) is unaffected at any zoom level. */
1724
2006
  font-size: 0.875rem;
1725
2007
  line-height: 1.5;
1726
- /* Font smoothing: see apps/web/app/globals.css body block (macOS-only effect; Windows ClearType unchanged). */
2008
+ /* Font smoothing (Tailwind `antialiased` = -webkit-font-smoothing + -moz-osx):
2009
+ Industry practice per Josh Comeau’s CSS reset and 2024 cross-browser testing
2010
+ (e.g. David Bushell): the -webkit property affects macOS WebKit browsers only —
2011
+ it tones down browser-only subpixel AA (Mojave+ system UI already moved away).
2012
+ Windows/Linux/iOS/Android: no practical effect; OS font rasterizer (ClearType, etc.)
2013
+ owns rendering. Safe to apply on body for Mac parity without changing Windows output. */
1727
2014
  }
1728
2015
 
1729
2016
  html {
@@ -1762,11 +2049,14 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1762
2049
 
1763
2050
  /* ── Touch targets (WCAG 2.5.5) ─────────────────────────────── */
1764
2051
  /* Applied via utility: min-h-[var(--control-height-touch)] */
1765
- /* Global touch-target baseline for interactive elements on mobile */
1766
- @media (max-width: 767px) {
2052
+ /* Coarse pointer only: browser zoom (200–400%) shrinks the *layout* viewport
2053
+ in CSS px, so max-width: 767px becomes true on desktop — without pointer: coarse,
2054
+ 44px min-height hits every button and [role=checkbox], stretching 16px-wide
2055
+ checkboxes into tall pills and blowing up table/toolbar controls. Real phones
2056
+ and tablets report pointer: coarse. */
2057
+ @media (max-width: 767px) and (pointer: coarse) {
1767
2058
  button,
1768
2059
  [role="button"],
1769
- [role="checkbox"],
1770
2060
  [role="radio"],
1771
2061
  [role="switch"],
1772
2062
  [role="menuitem"],
@@ -1775,6 +2065,7 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1775
2065
  min-height: var(--control-height-touch, 44px);
1776
2066
  }
1777
2067
  }
2068
+ /* Checkboxes use compact box + pseudo-element hit slop (see ui/checkbox). */
1778
2069
 
1779
2070
  /* ── Heading hierarchy ───────────────────────────────────────── */
1780
2071
  /* Ivy Presto (font-heading) applied ONLY via explicit class/inline style
@@ -1861,6 +2152,58 @@ html:is([data-contrast="high"], [data-contrast="windows"]) {
1861
2152
  .banner-prism {
1862
2153
  background-color: var(--banner-prism-bg);
1863
2154
  }
2155
+
2156
+ /* Sidebar nav — little pop when an item becomes active. Key swap on the
2157
+ wrapper remounts the span, so the animation replays on selection. */
2158
+ @keyframes sidebar-icon-pop {
2159
+ 0% { opacity: 0.4; transform: scale(0.7) rotate(-6deg); }
2160
+ 60% { opacity: 1; transform: scale(1.15) rotate(2deg); }
2161
+ 100% { opacity: 1; transform: scale(1) rotate(0); }
2162
+ }
2163
+
2164
+ /* Radix Collapsible / Accordion — slide the children open/closed using the
2165
+ `--radix-collapsible-content-height` CSS var that Radix sets on the
2166
+ content element. Mirrors the shadcn accordion pattern (Tailwind v3
2167
+ "accordion-down" / "accordion-up"); we keep our own name so it can be
2168
+ reused by both Collapsible and Accordion primitives. */
2169
+ @keyframes collapsible-down {
2170
+ from { height: 0; }
2171
+ to { height: var(--radix-collapsible-content-height); }
2172
+ }
2173
+ @keyframes collapsible-up {
2174
+ from { height: var(--radix-collapsible-content-height); }
2175
+ to { height: 0; }
2176
+ }
2177
+
2178
+ /* Ask Leo suggestion chips — staggered fade-in + lift on first render. */
2179
+ @keyframes leo-chip-in {
2180
+ 0% { opacity: 0; transform: translateY(8px) scale(0.96); }
2181
+ 100% { opacity: 1; transform: translateY(0) scale(1); }
2182
+ }
2183
+
2184
+ /* Leo typing indicator — 3 dots bouncing opacity/scale, staggered via delay. */
2185
+ @keyframes leo-typing-dot {
2186
+ 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
2187
+ 40% { opacity: 1; transform: scale(1); }
2188
+ }
2189
+
2190
+ /* Whole-panel brand radial glow pulse — runs on the BG layer while Leo thinks. */
2191
+ @keyframes leo-panel-pulse {
2192
+ 0%, 100% { opacity: 0.5; transform: scale(1); }
2193
+ 50% { opacity: 0.75; transform: scale(1.01); }
2194
+ }
2195
+
2196
+ /* Chart “Leo insight” marker — soft breathing halo behind the chip. */
2197
+ @keyframes leo-chart-insight-halo {
2198
+ 0%, 100% { opacity: 0.45; transform: scale(1); }
2199
+ 50% { opacity: 0.72; transform: scale(1.12); }
2200
+ }
2201
+
2202
+ /* Accent dot on the insight marker — gentle pulse (respect motion-reduce in markup). */
2203
+ @keyframes leo-chart-insight-dot {
2204
+ 0%, 100% { opacity: 0.9; transform: scale(1); }
2205
+ 50% { opacity: 1; transform: scale(1.35); }
2206
+ }
1864
2207
  }
1865
2208
 
1866
2209
  /* After all @layer rules: win over Tailwind preflight / layer merge so real controls show a pointer. */