basalt-ui 1.40.3 → 2.0.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 (923) hide show
  1. package/AGENTS.md +50 -45
  2. package/CHANGELOG.md +543 -513
  3. package/MIGRATING.md +969 -37
  4. package/README.md +172 -367
  5. package/agent/rules/basalt-batteries.md +19 -74
  6. package/agent/rules/basalt-charts.md +21 -95
  7. package/agent/rules/basalt-controls.md +23 -131
  8. package/agent/rules/basalt-mantine.md +26 -99
  9. package/agent/rules/basalt-state.md +21 -103
  10. package/agent/rules/basalt-tokens.md +33 -114
  11. package/agent/skills/basalt-app/SKILL.md +229 -72
  12. package/agent/skills/basalt-charts/SKILL.md +23 -57
  13. package/agent/skills/basalt-design/SKILL.md +12 -70
  14. package/agent/templates/AGENTS-block.md.tpl +30 -0
  15. package/agent/templates/DESIGN.md.tpl +2 -2
  16. package/agent/templates/__root.tpl +9 -16
  17. package/agent/templates/main.tpl +21 -0
  18. package/agent/templates/nav.tpl +18 -0
  19. package/configs/check.yml +1 -1
  20. package/configs/oxlint-basalt.json +4 -10
  21. package/configs/oxlint-plugin.js +468 -847
  22. package/configs/oxlint-plugin.test.ts +662 -710
  23. package/configs/oxlint.json +10 -2
  24. package/dist/agent/ai-sdk-transport.d.ts +19 -7
  25. package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
  26. package/dist/agent/ai-sdk-transport.js +10 -7
  27. package/dist/{agent-chat → agent/chat}/composer.d.ts +16 -16
  28. package/dist/agent/chat/composer.d.ts.map +1 -0
  29. package/dist/{agent-chat → agent/chat}/composer.js +10 -9
  30. package/dist/{agent-chat → agent/chat}/message-affordances.d.ts +7 -6
  31. package/dist/agent/chat/message-affordances.d.ts.map +1 -0
  32. package/dist/agent/chat/relative-time.d.ts.map +1 -0
  33. package/dist/{agent-chat → agent/chat}/thread-feed-row.d.ts +18 -16
  34. package/dist/agent/chat/thread-feed-row.d.ts.map +1 -0
  35. package/dist/{agent-chat → agent/chat}/thread-feed-row.js +12 -11
  36. package/dist/{agent-chat → agent/chat}/thread-feed.d.ts +8 -8
  37. package/dist/agent/chat/thread-feed.d.ts.map +1 -0
  38. package/dist/{agent-chat → agent/chat}/thread-feed.js +12 -10
  39. package/dist/{agent-chat → agent/chat}/thread-message.d.ts +12 -9
  40. package/dist/agent/chat/thread-message.d.ts.map +1 -0
  41. package/dist/{agent-chat → agent/chat}/thread-message.js +15 -13
  42. package/dist/{agent-chat → agent/chat}/thread-outcome-card.d.ts +2 -2
  43. package/dist/agent/chat/thread-outcome-card.d.ts.map +1 -0
  44. package/dist/{agent-chat → agent/chat}/thread-outcome-card.js +3 -3
  45. package/dist/{agent-chat → agent/chat}/tool-chip.d.ts +5 -5
  46. package/dist/agent/chat/tool-chip.d.ts.map +1 -0
  47. package/dist/{agent-chat → agent/chat}/tool-chip.js +4 -4
  48. package/dist/agent/chat/use-keyboard-inset.d.ts.map +1 -0
  49. package/dist/{agent-chat → agent/chat}/use-keyboard-inset.js +1 -1
  50. package/dist/{agent-chat → agent/chat}/virtualize.d.ts +7 -7
  51. package/dist/agent/chat/virtualize.d.ts.map +1 -0
  52. package/dist/agent/error.d.ts +31 -0
  53. package/dist/agent/error.d.ts.map +1 -0
  54. package/dist/agent/error.js +18 -0
  55. package/dist/agent/foreign.d.ts +3 -2
  56. package/dist/agent/foreign.d.ts.map +1 -1
  57. package/dist/agent/history.d.ts +2 -36
  58. package/dist/agent/history.d.ts.map +1 -1
  59. package/dist/agent/history.js +0 -32
  60. package/dist/agent/id.d.ts +4 -5
  61. package/dist/agent/id.d.ts.map +1 -1
  62. package/dist/agent/index.d.ts +19 -52
  63. package/dist/agent/index.d.ts.map +1 -1
  64. package/dist/agent/index.js +10 -32
  65. package/dist/agent/outcome.d.ts +3 -14
  66. package/dist/agent/outcome.d.ts.map +1 -1
  67. package/dist/agent/outcome.js +0 -30
  68. package/dist/agent/part-list.d.ts +3 -3
  69. package/dist/agent/part-list.d.ts.map +1 -1
  70. package/dist/agent/parts.d.ts +23 -24
  71. package/dist/agent/parts.d.ts.map +1 -1
  72. package/dist/agent/run-committer.d.ts +23 -0
  73. package/dist/agent/run-committer.d.ts.map +1 -0
  74. package/dist/agent/run-committer.js +41 -0
  75. package/dist/agent/run-records.d.ts +77 -0
  76. package/dist/agent/run-records.d.ts.map +1 -0
  77. package/dist/agent/run-records.js +69 -0
  78. package/dist/agent/thread.d.ts +23 -47
  79. package/dist/agent/thread.d.ts.map +1 -1
  80. package/dist/agent/thread.js +3 -134
  81. package/dist/agent/transport.d.ts +6 -69
  82. package/dist/agent/transport.d.ts.map +1 -1
  83. package/dist/agent/transport.js +0 -18
  84. package/dist/agent/use-agent-thread-runs.d.ts +63 -26
  85. package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
  86. package/dist/agent/use-agent-thread-runs.js +202 -66
  87. package/dist/charts/BandStrip.d.ts +46 -0
  88. package/dist/charts/BandStrip.d.ts.map +1 -0
  89. package/dist/charts/BandStrip.js +151 -0
  90. package/dist/charts/Bars.d.ts +19 -0
  91. package/dist/charts/Bars.d.ts.map +1 -0
  92. package/dist/charts/Bars.js +77 -0
  93. package/dist/charts/CartesianChart.d.ts +57 -0
  94. package/dist/charts/CartesianChart.d.ts.map +1 -0
  95. package/dist/charts/CartesianChart.js +121 -0
  96. package/dist/charts/ChartCard.d.ts +34 -0
  97. package/dist/charts/ChartCard.d.ts.map +1 -0
  98. package/dist/charts/ChartCard.js +115 -0
  99. package/dist/charts/Donut.d.ts +25 -0
  100. package/dist/charts/Donut.d.ts.map +1 -0
  101. package/dist/charts/Donut.js +191 -0
  102. package/dist/charts/DualPanel.d.ts +47 -0
  103. package/dist/charts/DualPanel.d.ts.map +1 -0
  104. package/dist/charts/DualPanel.js +214 -0
  105. package/dist/charts/Heatmap.d.ts +41 -0
  106. package/dist/charts/Heatmap.d.ts.map +1 -0
  107. package/dist/charts/Heatmap.js +216 -0
  108. package/dist/charts/Lines.d.ts +11 -0
  109. package/dist/charts/Lines.d.ts.map +1 -0
  110. package/dist/charts/Lines.js +114 -0
  111. package/dist/charts/MirroredBars.d.ts +44 -0
  112. package/dist/charts/MirroredBars.d.ts.map +1 -0
  113. package/dist/charts/MirroredBars.js +190 -0
  114. package/dist/charts/Sparkline.d.ts +22 -0
  115. package/dist/charts/Sparkline.d.ts.map +1 -0
  116. package/dist/charts/Sparkline.js +129 -0
  117. package/dist/charts/StackedArea.d.ts +15 -0
  118. package/dist/charts/StackedArea.d.ts.map +1 -0
  119. package/dist/charts/StackedArea.js +46 -0
  120. package/dist/charts/box.d.ts +38 -0
  121. package/dist/charts/box.d.ts.map +1 -0
  122. package/dist/charts/box.js +72 -0
  123. package/dist/charts/card-context.d.ts +3 -0
  124. package/dist/charts/card-context.d.ts.map +1 -0
  125. package/dist/charts/card-context.js +7 -0
  126. package/dist/charts/chart-box.module.css +64 -0
  127. package/{src/content/article-card.module.css.d.ts → dist/charts/chart-box.module.css.d.ts} +5 -9
  128. package/dist/charts/chart-card.module.css +25 -0
  129. package/dist/{dashboard/widget-grid.module.css.d.ts → charts/chart-card.module.css.d.ts} +1 -3
  130. package/dist/charts/chart-legend.module.css +38 -0
  131. package/{src/dashboard/widget-grid.module.css.d.ts → dist/charts/chart-legend.module.css.d.ts} +3 -3
  132. package/dist/charts/compile.d.ts +62 -0
  133. package/dist/charts/compile.d.ts.map +1 -0
  134. package/dist/charts/compile.js +386 -0
  135. package/dist/charts/cursor.d.ts +50 -0
  136. package/dist/charts/cursor.d.ts.map +1 -0
  137. package/dist/charts/cursor.js +157 -0
  138. package/dist/charts/curves.d.ts +12 -0
  139. package/dist/charts/curves.d.ts.map +1 -0
  140. package/dist/charts/curves.js +86 -0
  141. package/dist/charts/donut.module.css +54 -0
  142. package/dist/{content/article-card.module.css.d.ts → charts/donut.module.css.d.ts} +2 -9
  143. package/dist/charts/host.d.ts +17 -0
  144. package/dist/charts/host.d.ts.map +1 -0
  145. package/dist/charts/host.js +35 -0
  146. package/dist/charts/index.d.ts +18 -53
  147. package/dist/charts/index.d.ts.map +1 -1
  148. package/dist/charts/index.js +17 -189
  149. package/dist/charts/legend.d.ts +23 -0
  150. package/dist/charts/legend.d.ts.map +1 -0
  151. package/dist/charts/legend.js +160 -0
  152. package/dist/charts/marks.d.ts +25 -0
  153. package/dist/charts/marks.d.ts.map +1 -0
  154. package/dist/charts/marks.js +128 -0
  155. package/dist/charts/panel.d.ts +56 -0
  156. package/dist/charts/panel.d.ts.map +1 -0
  157. package/dist/charts/panel.js +123 -0
  158. package/dist/charts/scales.d.ts +44 -0
  159. package/dist/charts/scales.d.ts.map +1 -0
  160. package/dist/charts/scales.js +163 -0
  161. package/dist/charts/sizing.d.ts +12 -0
  162. package/dist/charts/sizing.d.ts.map +1 -0
  163. package/dist/charts/sizing.js +33 -0
  164. package/dist/charts/state.d.ts +17 -0
  165. package/dist/charts/state.d.ts.map +1 -0
  166. package/dist/charts/state.js +53 -0
  167. package/dist/charts/theme.d.ts +38 -19
  168. package/dist/charts/theme.d.ts.map +1 -1
  169. package/dist/charts/theme.js +48 -26
  170. package/dist/charts/types.d.ts +227 -0
  171. package/dist/charts/types.d.ts.map +1 -0
  172. package/dist/charts/types.js +4 -0
  173. package/dist/cli/audit-allows.d.ts +4 -17
  174. package/dist/cli/audit-allows.d.ts.map +1 -1
  175. package/dist/cli/config.d.ts +14 -43
  176. package/dist/cli/config.d.ts.map +1 -1
  177. package/dist/cli/doctor-upgrade.d.ts +31 -0
  178. package/dist/cli/doctor-upgrade.d.ts.map +1 -0
  179. package/dist/cli/doctor-upgrade.js +269 -0
  180. package/dist/cli/doctor.d.ts +13 -26
  181. package/dist/cli/doctor.d.ts.map +1 -1
  182. package/dist/cli/doctor.js +79 -8
  183. package/dist/cli/help.d.ts.map +1 -1
  184. package/dist/cli/help.js +2 -4
  185. package/dist/cli/index.d.ts +68 -135
  186. package/dist/cli/index.d.ts.map +1 -1
  187. package/dist/cli/index.js +89 -76
  188. package/dist/cli/init.d.ts.map +1 -1
  189. package/dist/cli/init.js +43 -27
  190. package/dist/cli/sync.d.ts +5 -21
  191. package/dist/cli/sync.d.ts.map +1 -1
  192. package/dist/cli/sync.js +4 -6
  193. package/dist/cli/tokens-css.d.ts +7 -28
  194. package/dist/cli/tokens-css.d.ts.map +1 -1
  195. package/dist/commands/ShortcutsHelp.d.ts.map +1 -1
  196. package/dist/commands/ShortcutsHelp.js +4 -5
  197. package/dist/commands/define-commands.d.ts +15 -31
  198. package/dist/commands/define-commands.d.ts.map +1 -1
  199. package/dist/commands/define-commands.js +1 -11
  200. package/dist/commands/define-overlays.d.ts +5 -19
  201. package/dist/commands/define-overlays.d.ts.map +1 -1
  202. package/dist/commands/define-overlays.js +3 -11
  203. package/dist/commands/index.d.ts +10 -40
  204. package/dist/commands/index.d.ts.map +1 -1
  205. package/dist/commands/index.js +9 -46
  206. package/dist/{notifications → commands/notifications}/bell.d.ts +1 -1
  207. package/dist/commands/notifications/bell.d.ts.map +1 -0
  208. package/dist/{notifications → commands/notifications}/center.d.ts +2 -2
  209. package/dist/commands/notifications/center.d.ts.map +1 -0
  210. package/dist/{notifications → commands/notifications}/center.js +2 -2
  211. package/dist/{notifications → commands/notifications}/define-notifications.d.ts +3 -3
  212. package/dist/commands/notifications/define-notifications.d.ts.map +1 -0
  213. package/dist/commands/notifications/notify.d.ts +44 -0
  214. package/dist/commands/notifications/notify.d.ts.map +1 -0
  215. package/dist/commands/notifications/notify.js +79 -0
  216. package/dist/{notifications → commands/notifications}/store.d.ts +2 -0
  217. package/dist/commands/notifications/store.d.ts.map +1 -0
  218. package/dist/{notifications → commands/notifications}/store.js +4 -0
  219. package/dist/commands/projectors.d.ts +1 -131
  220. package/dist/commands/projectors.d.ts.map +1 -1
  221. package/dist/commands/projectors.js +2 -73
  222. package/dist/commands/shell-bridge.d.ts +3 -3
  223. package/dist/commands/shortcut-format.d.ts +5 -4
  224. package/dist/commands/shortcut-format.d.ts.map +1 -1
  225. package/dist/common/errors.d.ts +3 -3
  226. package/dist/common/use-measured-widths.d.ts.map +1 -1
  227. package/dist/common/use-measured-widths.js +5 -3
  228. package/dist/common/validate.d.ts +2 -2
  229. package/dist/content/article-layout.d.ts.map +1 -1
  230. package/dist/content/article-layout.js +3 -3
  231. package/dist/content/article-model.d.ts +1 -46
  232. package/dist/content/article-model.d.ts.map +1 -1
  233. package/dist/content/article-model.js +1 -29
  234. package/dist/content/copy-action.d.ts +1 -1
  235. package/dist/content/glyphs.d.ts +1 -1
  236. package/dist/content/index.d.ts +11 -41
  237. package/dist/content/index.d.ts.map +1 -1
  238. package/dist/content/index.js +3 -35
  239. package/dist/content/markdown.d.ts +1 -1
  240. package/dist/content/markdown.d.ts.map +1 -1
  241. package/dist/content/markdown.js +1 -1
  242. package/dist/content/mermaid.d.ts.map +1 -1
  243. package/dist/content/mermaid.js +7 -7
  244. package/dist/content/slug.d.ts +1 -8
  245. package/dist/content/slug.d.ts.map +1 -1
  246. package/dist/content/slug.js +1 -8
  247. package/dist/content/url-hardening.d.ts +2 -2
  248. package/dist/content/url-hardening.d.ts.map +1 -1
  249. package/dist/content/url-hardening.js +2 -0
  250. package/dist/controls/actions.d.ts +16 -1
  251. package/dist/controls/actions.d.ts.map +1 -1
  252. package/dist/controls/enum-filter.d.ts +1 -1
  253. package/dist/controls/enum-filter.d.ts.map +1 -1
  254. package/dist/controls/filter-context.d.ts.map +1 -1
  255. package/dist/controls/filter-context.js +3 -1
  256. package/dist/controls/filter-set.js +4 -6
  257. package/dist/controls/form-layout.d.ts +1 -1
  258. package/dist/controls/form-layout.d.ts.map +1 -1
  259. package/dist/controls/form-layout.js +1 -1
  260. package/dist/controls/glyphs.d.ts +0 -2
  261. package/dist/controls/glyphs.d.ts.map +1 -1
  262. package/dist/controls/glyphs.js +0 -7
  263. package/dist/controls/index.d.ts +12 -17
  264. package/dist/controls/index.d.ts.map +1 -1
  265. package/dist/controls/index.js +5 -39
  266. package/dist/controls/multi-select-filter.d.ts +4 -3
  267. package/dist/controls/multi-select-filter.d.ts.map +1 -1
  268. package/dist/controls/number-filter.d.ts +4 -3
  269. package/dist/controls/number-filter.d.ts.map +1 -1
  270. package/dist/controls/number-filter.js +3 -1
  271. package/dist/controls/range-filter.d.ts +4 -3
  272. package/dist/controls/range-filter.d.ts.map +1 -1
  273. package/dist/controls/search-filter.d.ts +4 -3
  274. package/dist/controls/search-filter.d.ts.map +1 -1
  275. package/dist/controls/search-filter.js +19 -14
  276. package/dist/controls/select-filter.d.ts +4 -3
  277. package/dist/controls/select-filter.d.ts.map +1 -1
  278. package/dist/controls/sync-button.d.ts.map +1 -1
  279. package/dist/controls/sync-button.js +12 -15
  280. package/dist/controls/toggle-filter.d.ts +4 -3
  281. package/dist/controls/toggle-filter.d.ts.map +1 -1
  282. package/dist/controls/uncontrolled.d.ts +12 -0
  283. package/dist/controls/uncontrolled.d.ts.map +1 -0
  284. package/dist/controls/view-tabs.d.ts +2 -2
  285. package/dist/controls/view-tabs.d.ts.map +1 -1
  286. package/dist/controls-dates/index.d.ts +0 -1
  287. package/dist/controls-dates/index.d.ts.map +1 -1
  288. package/dist/dashboard/index.d.ts +7 -9
  289. package/dist/dashboard/index.d.ts.map +1 -1
  290. package/dist/dashboard/index.js +3 -23
  291. package/dist/dashboard/section.d.ts +4 -6
  292. package/dist/dashboard/section.d.ts.map +1 -1
  293. package/dist/dashboard/section.js +4 -10
  294. package/dist/dashboard/stat-card.d.ts +4 -4
  295. package/dist/dashboard/stat-card.d.ts.map +1 -1
  296. package/dist/dashboard/stat-card.js +3 -3
  297. package/dist/dashboard/widget-header.module.css +9 -7
  298. package/dist/dev-dock.d.ts.map +1 -1
  299. package/dist/dev-dock.js +6 -1
  300. package/dist/format/date.d.ts +0 -34
  301. package/dist/format/date.d.ts.map +1 -1
  302. package/dist/format/date.js +0 -54
  303. package/dist/format/index.d.ts +7 -22
  304. package/dist/format/index.d.ts.map +1 -1
  305. package/dist/format/index.js +2 -43
  306. package/dist/format/number.d.ts +3 -14
  307. package/dist/format/number.d.ts.map +1 -1
  308. package/dist/format/number.js +0 -13
  309. package/dist/format/shared.d.ts +2 -3
  310. package/dist/format/shared.d.ts.map +1 -1
  311. package/dist/forms/index.d.ts +0 -11
  312. package/dist/forms/index.d.ts.map +1 -1
  313. package/dist/forms/index.js +1 -14
  314. package/dist/guard/index.d.ts +6 -21
  315. package/dist/guard/index.d.ts.map +1 -1
  316. package/dist/guard/index.js +27 -115
  317. package/dist/guard/types.d.ts +7 -18
  318. package/dist/guard/types.d.ts.map +1 -1
  319. package/dist/index.d.ts +16 -48
  320. package/dist/index.d.ts.map +1 -1
  321. package/dist/index.js +21 -117
  322. package/dist/provider/create-router.d.ts +44 -0
  323. package/dist/provider/create-router.d.ts.map +1 -0
  324. package/dist/provider/create-router.js +62 -0
  325. package/dist/provider/hotkeys.d.ts +8 -0
  326. package/dist/provider/hotkeys.d.ts.map +1 -0
  327. package/dist/provider/hotkeys.js +50 -0
  328. package/dist/provider/index.d.ts +33 -110
  329. package/dist/provider/index.d.ts.map +1 -1
  330. package/dist/provider/index.js +182 -82
  331. package/dist/provider/lab-theme.d.ts.map +1 -1
  332. package/dist/provider/route-transition.d.ts +76 -0
  333. package/dist/provider/route-transition.d.ts.map +1 -0
  334. package/dist/provider/route-transition.js +98 -0
  335. package/dist/provider/spotlight-actions.d.ts +10 -0
  336. package/dist/provider/spotlight-actions.d.ts.map +1 -0
  337. package/dist/provider/spotlight-actions.js +55 -0
  338. package/dist/provider/test-router.d.ts +6 -0
  339. package/dist/provider/test-router.d.ts.map +1 -0
  340. package/dist/provider/test-router.js +18 -0
  341. package/dist/query-client.d.ts +4 -20
  342. package/dist/query-client.d.ts.map +1 -1
  343. package/dist/query-client.js +2 -2
  344. package/dist/router-tanstack/index.d.ts +18 -64
  345. package/dist/router-tanstack/index.d.ts.map +1 -1
  346. package/dist/router-tanstack/index.js +2 -16
  347. package/dist/router-tanstack/nav.d.ts +12 -1
  348. package/dist/router-tanstack/nav.d.ts.map +1 -1
  349. package/dist/router-tanstack/nav.js +8 -1
  350. package/dist/router-tanstack/search-store.d.ts +1 -1
  351. package/dist/router-tanstack/search-store.d.ts.map +1 -1
  352. package/dist/router-tanstack/use-nav.d.ts +8 -9
  353. package/dist/router-tanstack/use-nav.d.ts.map +1 -1
  354. package/dist/router-tanstack/use-nav.js +20 -1
  355. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  356. package/dist/shell/app-sidebar.js +1 -1
  357. package/dist/shell/index.d.ts +31 -10
  358. package/dist/shell/index.d.ts.map +1 -1
  359. package/dist/shell/index.js +14 -3
  360. package/dist/shell/page-aside.d.ts +2 -2
  361. package/dist/shell/page-aside.d.ts.map +1 -1
  362. package/dist/shell/page-aside.js +31 -12
  363. package/dist/shell/page-bar.d.ts +2 -2
  364. package/dist/shell/page-bar.d.ts.map +1 -1
  365. package/dist/shell/page-bar.js +1 -1
  366. package/dist/state.d.ts +10 -12
  367. package/dist/state.d.ts.map +1 -1
  368. package/dist/state.js +4 -6
  369. package/dist/styles.css +107 -7
  370. package/dist/surfaces.d.ts +28 -103
  371. package/dist/surfaces.d.ts.map +1 -1
  372. package/dist/surfaces.js +54 -143
  373. package/dist/{data → table}/data-table-state.d.ts +1 -1
  374. package/dist/table/data-table-state.d.ts.map +1 -0
  375. package/dist/{data → table}/data-table-state.js +4 -3
  376. package/dist/{data → table}/data-table.d.ts +28 -49
  377. package/dist/table/data-table.d.ts.map +1 -0
  378. package/dist/{data → table}/data-table.js +74 -60
  379. package/dist/table/index.d.ts +18 -0
  380. package/dist/table/index.d.ts.map +1 -0
  381. package/dist/{data/table.js → table/index.js} +1 -1
  382. package/dist/table/query-branch.d.ts.map +1 -0
  383. package/dist/table/table-features.d.ts +69 -0
  384. package/dist/table/table-features.d.ts.map +1 -0
  385. package/dist/table/table-features.js +49 -0
  386. package/dist/telemetry.d.ts +77 -0
  387. package/dist/telemetry.d.ts.map +1 -0
  388. package/dist/telemetry.js +33 -0
  389. package/dist/theme/index.d.ts +10 -21
  390. package/dist/theme/index.d.ts.map +1 -1
  391. package/dist/theme/index.js +3 -14
  392. package/dist/theme/theme-toggle.d.ts.map +1 -1
  393. package/dist/theme/theme-toggle.js +7 -33
  394. package/dist/theme/theme-toggle.module.css +30 -0
  395. package/dist/theme/theme-toggle.module.css.d.ts +10 -0
  396. package/dist/theme-lab/derive-controls.d.ts.map +1 -1
  397. package/dist/theme-lab/derive-controls.js +5 -3
  398. package/dist/theme-lab/derive-state.d.ts.map +1 -1
  399. package/dist/theme-lab/derive-state.js +2 -1
  400. package/dist/tokens/core.d.ts +360 -0
  401. package/dist/tokens/core.d.ts.map +1 -0
  402. package/dist/tokens/core.js +708 -0
  403. package/dist/tokens/derive.d.ts +1 -1
  404. package/dist/tokens/derive.d.ts.map +1 -1
  405. package/dist/tokens/index.d.ts +5 -373
  406. package/dist/tokens/index.d.ts.map +1 -1
  407. package/dist/tokens/index.js +8 -700
  408. package/dist/tokens/palette.d.ts +2 -6
  409. package/dist/tokens/palette.d.ts.map +1 -1
  410. package/dist/tokens/palette.js +1 -4
  411. package/dist/vite.d.ts +4 -3
  412. package/dist/vite.d.ts.map +1 -1
  413. package/llms.txt +43 -85
  414. package/package.json +77 -170
  415. package/src/agent/ai-sdk-transport.ts +57 -37
  416. package/src/{agent-chat → agent/chat}/composer.tsx +29 -30
  417. package/src/{agent-chat → agent/chat}/message-affordances.ts +8 -5
  418. package/src/{agent-chat → agent/chat}/thread-feed-row.tsx +30 -35
  419. package/src/{agent-chat → agent/chat}/thread-feed.tsx +40 -35
  420. package/src/{agent-chat → agent/chat}/thread-message.tsx +37 -35
  421. package/src/{agent-chat → agent/chat}/thread-outcome-card.tsx +5 -5
  422. package/src/{agent-chat → agent/chat}/tool-chip.tsx +12 -12
  423. package/src/{agent-chat → agent/chat}/use-keyboard-inset.ts +1 -1
  424. package/src/{agent-chat → agent/chat}/virtualize.ts +5 -5
  425. package/src/agent/error.ts +43 -0
  426. package/src/agent/foreign.ts +3 -2
  427. package/src/agent/history.ts +2 -107
  428. package/src/agent/id.ts +4 -5
  429. package/src/agent/index.ts +23 -112
  430. package/src/agent/outcome.ts +3 -56
  431. package/src/agent/part-list.tsx +3 -3
  432. package/src/agent/parts.ts +23 -22
  433. package/src/agent/run-committer.ts +64 -0
  434. package/src/agent/run-records.ts +147 -0
  435. package/src/agent/thread.ts +24 -231
  436. package/src/agent/transport.ts +6 -96
  437. package/src/agent/use-agent-thread-runs.ts +364 -199
  438. package/src/charts/BandStrip.tsx +276 -0
  439. package/src/charts/Bars.tsx +141 -0
  440. package/src/charts/CartesianChart.tsx +206 -0
  441. package/src/charts/ChartCard.tsx +178 -0
  442. package/src/charts/Donut.tsx +256 -0
  443. package/src/charts/DualPanel.tsx +326 -0
  444. package/src/charts/Heatmap.tsx +282 -0
  445. package/src/charts/Lines.tsx +151 -0
  446. package/src/charts/MirroredBars.tsx +303 -0
  447. package/src/charts/Sparkline.tsx +176 -0
  448. package/src/charts/StackedArea.tsx +80 -0
  449. package/src/charts/box.tsx +96 -0
  450. package/src/charts/card-context.ts +11 -0
  451. package/src/charts/chart-box.module.css +64 -0
  452. package/src/charts/chart-box.module.css.d.ts +12 -0
  453. package/src/charts/chart-card.module.css +25 -0
  454. package/src/charts/chart-card.module.css.d.ts +8 -0
  455. package/src/charts/chart-legend.module.css +38 -0
  456. package/src/charts/chart-legend.module.css.d.ts +10 -0
  457. package/src/charts/compile.ts +585 -0
  458. package/src/charts/cursor.ts +282 -0
  459. package/src/charts/curves.ts +111 -0
  460. package/src/charts/donut.module.css +54 -0
  461. package/src/charts/donut.module.css.d.ts +9 -0
  462. package/src/charts/host.tsx +60 -0
  463. package/src/charts/index.ts +41 -178
  464. package/src/charts/legend.tsx +204 -0
  465. package/src/charts/marks.ts +201 -0
  466. package/src/charts/panel.tsx +227 -0
  467. package/src/charts/scales.ts +237 -0
  468. package/src/charts/sizing.ts +47 -0
  469. package/src/charts/state.tsx +80 -0
  470. package/src/charts/theme.ts +65 -0
  471. package/src/charts/types.ts +242 -0
  472. package/src/cli/audit-allows.ts +8 -30
  473. package/src/cli/config.ts +14 -43
  474. package/src/cli/doctor-upgrade.ts +392 -0
  475. package/src/cli/doctor.ts +120 -68
  476. package/src/cli/help.ts +2 -4
  477. package/src/cli/index.ts +161 -276
  478. package/src/cli/init.ts +60 -37
  479. package/src/cli/sync.ts +13 -45
  480. package/src/cli/tokens-css.ts +7 -28
  481. package/src/commands/ShortcutsHelp.tsx +8 -9
  482. package/src/commands/define-commands.ts +16 -43
  483. package/src/commands/define-overlays.ts +12 -36
  484. package/src/commands/index.ts +11 -94
  485. package/src/{notifications → commands/notifications}/bell.tsx +2 -2
  486. package/src/{notifications → commands/notifications}/center.tsx +7 -5
  487. package/src/{notifications → commands/notifications}/define-notifications.ts +3 -3
  488. package/src/commands/notifications/notify.tsx +158 -0
  489. package/src/{notifications → commands/notifications}/store.ts +10 -2
  490. package/src/commands/projectors.ts +5 -225
  491. package/src/commands/shell-bridge.ts +5 -5
  492. package/src/commands/shortcut-format.ts +5 -4
  493. package/src/common/errors.ts +3 -3
  494. package/src/common/use-measured-widths.ts +6 -3
  495. package/src/common/validate.ts +2 -2
  496. package/src/content/article-layout.tsx +37 -38
  497. package/src/content/article-model.ts +1 -84
  498. package/src/content/copy-action.tsx +1 -1
  499. package/src/content/glyphs.tsx +1 -1
  500. package/src/content/index.ts +12 -83
  501. package/src/content/markdown.tsx +4 -3
  502. package/src/content/mermaid.tsx +9 -7
  503. package/src/content/slug.ts +1 -16
  504. package/src/content/url-hardening.ts +8 -2
  505. package/src/controls/actions.tsx +24 -1
  506. package/src/controls/enum-filter.tsx +1 -1
  507. package/src/controls/filter-context.tsx +3 -1
  508. package/src/controls/filter-set.tsx +5 -7
  509. package/src/controls/form-layout.tsx +2 -2
  510. package/src/controls/glyphs.tsx +0 -10
  511. package/src/controls/index.ts +13 -64
  512. package/src/controls/multi-select-filter.tsx +5 -4
  513. package/src/controls/number-filter.tsx +8 -4
  514. package/src/controls/range-filter.tsx +5 -4
  515. package/src/controls/search-filter.tsx +25 -19
  516. package/src/controls/select-filter.tsx +5 -4
  517. package/src/controls/sync-button.tsx +18 -20
  518. package/src/controls/toggle-filter.tsx +5 -4
  519. package/src/controls/uncontrolled.ts +12 -0
  520. package/src/controls/view-tabs.tsx +3 -3
  521. package/src/controls-dates/date-range-picker.tsx +1 -1
  522. package/src/controls-dates/index.ts +0 -1
  523. package/src/dashboard/index.ts +7 -48
  524. package/src/dashboard/section.tsx +11 -40
  525. package/src/dashboard/stat-card.tsx +14 -16
  526. package/src/dashboard/widget-header.module.css +9 -7
  527. package/src/dev-dock.tsx +14 -27
  528. package/src/format/date.ts +2 -92
  529. package/src/format/index.ts +7 -53
  530. package/src/format/number.ts +3 -26
  531. package/src/format/shared.ts +2 -3
  532. package/src/forms/index.ts +0 -23
  533. package/src/guard/index.ts +37 -192
  534. package/src/guard/types.ts +6 -19
  535. package/src/index.ts +30 -282
  536. package/src/provider/create-router.tsx +138 -0
  537. package/src/provider/hotkeys.ts +70 -0
  538. package/src/provider/index.tsx +260 -230
  539. package/src/provider/lab-theme.ts +3 -2
  540. package/src/provider/route-transition.ts +199 -0
  541. package/src/provider/spotlight-actions.tsx +69 -0
  542. package/src/provider/test-router.tsx +25 -0
  543. package/src/query-client.ts +4 -22
  544. package/src/router-tanstack/index.ts +18 -112
  545. package/src/router-tanstack/nav.ts +28 -2
  546. package/src/router-tanstack/search-store.ts +9 -2
  547. package/src/router-tanstack/use-nav.ts +47 -13
  548. package/src/shell/app-mobile-nav.tsx +3 -2
  549. package/src/shell/app-sidebar.tsx +1 -1
  550. package/src/shell/aside-docking.ts +1 -1
  551. package/src/shell/index.tsx +61 -20
  552. package/src/shell/page-aside.tsx +47 -23
  553. package/src/shell/page-bar.tsx +3 -3
  554. package/src/shell/page-title.tsx +1 -1
  555. package/src/state.ts +11 -37
  556. package/src/styles.css +107 -7
  557. package/src/surfaces.ts +56 -151
  558. package/src/{data → table}/data-table-state.ts +5 -4
  559. package/src/{data → table}/data-table.tsx +170 -161
  560. package/src/table/index.ts +18 -0
  561. package/src/table/table-features.ts +102 -0
  562. package/src/telemetry.ts +110 -0
  563. package/src/theme/index.ts +22 -47
  564. package/src/theme/theme-toggle.module.css +30 -0
  565. package/src/theme/theme-toggle.module.css.d.ts +10 -0
  566. package/src/theme/theme-toggle.tsx +15 -43
  567. package/src/theme-lab/derive-controls.tsx +5 -3
  568. package/src/theme-lab/derive-state.ts +2 -1
  569. package/src/tokens/core.ts +1163 -0
  570. package/src/tokens/derive.ts +1 -1
  571. package/src/tokens/index.ts +14 -1181
  572. package/src/tokens/palette.ts +3 -7
  573. package/src/vite.ts +3 -3
  574. package/agent/templates/CLAUDE-block.md.tpl +0 -40
  575. package/agent/templates/query-client.ts.tpl +0 -26
  576. package/dist/agent/adapter.d.ts +0 -150
  577. package/dist/agent/adapter.d.ts.map +0 -1
  578. package/dist/agent/adapter.js +0 -482
  579. package/dist/agent/use-agent-stream.d.ts +0 -35
  580. package/dist/agent/use-agent-stream.d.ts.map +0 -1
  581. package/dist/agent/use-agent-stream.js +0 -59
  582. package/dist/agent-chat/composer.d.ts.map +0 -1
  583. package/dist/agent-chat/index.d.ts +0 -31
  584. package/dist/agent-chat/index.d.ts.map +0 -1
  585. package/dist/agent-chat/index.js +0 -19
  586. package/dist/agent-chat/message-affordances.d.ts.map +0 -1
  587. package/dist/agent-chat/relative-time.d.ts.map +0 -1
  588. package/dist/agent-chat/thread-detail-panel.d.ts +0 -28
  589. package/dist/agent-chat/thread-detail-panel.d.ts.map +0 -1
  590. package/dist/agent-chat/thread-detail-panel.js +0 -115
  591. package/dist/agent-chat/thread-feed-row.d.ts.map +0 -1
  592. package/dist/agent-chat/thread-feed.d.ts.map +0 -1
  593. package/dist/agent-chat/thread-message.d.ts.map +0 -1
  594. package/dist/agent-chat/thread-outcome-card.d.ts.map +0 -1
  595. package/dist/agent-chat/thread-workspace.d.ts +0 -44
  596. package/dist/agent-chat/thread-workspace.d.ts.map +0 -1
  597. package/dist/agent-chat/thread-workspace.js +0 -153
  598. package/dist/agent-chat/tool-chip.d.ts.map +0 -1
  599. package/dist/agent-chat/use-keyboard-inset.d.ts.map +0 -1
  600. package/dist/agent-chat/virtualize.d.ts.map +0 -1
  601. package/dist/charts/cursor/resolve.d.ts +0 -75
  602. package/dist/charts/cursor/resolve.d.ts.map +0 -1
  603. package/dist/charts/cursor/resolve.js +0 -91
  604. package/dist/charts/cursor/scope.d.ts +0 -20
  605. package/dist/charts/cursor/scope.d.ts.map +0 -1
  606. package/dist/charts/cursor/scope.js +0 -20
  607. package/dist/charts/cursor/store.d.ts +0 -35
  608. package/dist/charts/cursor/store.d.ts.map +0 -1
  609. package/dist/charts/cursor/store.js +0 -25
  610. package/dist/charts/cursor/touch-pin.d.ts +0 -45
  611. package/dist/charts/cursor/touch-pin.d.ts.map +0 -1
  612. package/dist/charts/cursor/touch-pin.js +0 -79
  613. package/dist/charts/hooks/use-discrete-cursor.d.ts +0 -66
  614. package/dist/charts/hooks/use-discrete-cursor.d.ts.map +0 -1
  615. package/dist/charts/hooks/use-discrete-cursor.js +0 -198
  616. package/dist/charts/hooks/use-hysteresis.d.ts +0 -18
  617. package/dist/charts/hooks/use-hysteresis.d.ts.map +0 -1
  618. package/dist/charts/hooks/use-hysteresis.js +0 -12
  619. package/dist/charts/hooks/useBandPlot.d.ts +0 -145
  620. package/dist/charts/hooks/useBandPlot.d.ts.map +0 -1
  621. package/dist/charts/hooks/useBandPlot.js +0 -178
  622. package/dist/charts/hooks/useChartCursor.d.ts +0 -75
  623. package/dist/charts/hooks/useChartCursor.d.ts.map +0 -1
  624. package/dist/charts/hooks/useChartCursor.js +0 -200
  625. package/dist/charts/hooks/useChartSize.d.ts +0 -29
  626. package/dist/charts/hooks/useChartSize.d.ts.map +0 -1
  627. package/dist/charts/hooks/useChartSize.js +0 -8
  628. package/dist/charts/kinds/BandStrip.d.ts +0 -132
  629. package/dist/charts/kinds/BandStrip.d.ts.map +0 -1
  630. package/dist/charts/kinds/BandStrip.js +0 -241
  631. package/dist/charts/kinds/Bars.d.ts +0 -141
  632. package/dist/charts/kinds/Bars.d.ts.map +0 -1
  633. package/dist/charts/kinds/Bars.js +0 -343
  634. package/dist/charts/kinds/Donut.d.ts +0 -77
  635. package/dist/charts/kinds/Donut.d.ts.map +0 -1
  636. package/dist/charts/kinds/Donut.js +0 -245
  637. package/dist/charts/kinds/DualPanel.d.ts +0 -111
  638. package/dist/charts/kinds/DualPanel.d.ts.map +0 -1
  639. package/dist/charts/kinds/DualPanel.js +0 -471
  640. package/dist/charts/kinds/Heatmap.d.ts +0 -85
  641. package/dist/charts/kinds/Heatmap.d.ts.map +0 -1
  642. package/dist/charts/kinds/Heatmap.js +0 -243
  643. package/dist/charts/kinds/MirroredBars.d.ts +0 -98
  644. package/dist/charts/kinds/MirroredBars.d.ts.map +0 -1
  645. package/dist/charts/kinds/MirroredBars.js +0 -292
  646. package/dist/charts/kinds/MultiLine.d.ts +0 -87
  647. package/dist/charts/kinds/MultiLine.d.ts.map +0 -1
  648. package/dist/charts/kinds/MultiLine.js +0 -176
  649. package/dist/charts/kinds/StackedArea.d.ts +0 -73
  650. package/dist/charts/kinds/StackedArea.d.ts.map +0 -1
  651. package/dist/charts/kinds/StackedArea.js +0 -135
  652. package/dist/charts/kinds/ZonedLine.d.ts +0 -97
  653. package/dist/charts/kinds/ZonedLine.d.ts.map +0 -1
  654. package/dist/charts/kinds/ZonedLine.js +0 -155
  655. package/dist/charts/kinds/band-chrome.d.ts +0 -31
  656. package/dist/charts/kinds/band-chrome.d.ts.map +0 -1
  657. package/dist/charts/kinds/band-chrome.js +0 -71
  658. package/dist/charts/kinds/donut-layout.d.ts +0 -47
  659. package/dist/charts/kinds/donut-layout.d.ts.map +0 -1
  660. package/dist/charts/kinds/donut-layout.js +0 -52
  661. package/dist/charts/layout/auto-margin.d.ts +0 -122
  662. package/dist/charts/layout/auto-margin.d.ts.map +0 -1
  663. package/dist/charts/layout/auto-margin.js +0 -81
  664. package/dist/charts/layout/end-labels.d.ts +0 -64
  665. package/dist/charts/layout/end-labels.d.ts.map +0 -1
  666. package/dist/charts/layout/end-labels.js +0 -76
  667. package/dist/charts/layout/log-ticks.d.ts +0 -27
  668. package/dist/charts/layout/log-ticks.d.ts.map +0 -1
  669. package/dist/charts/layout/log-ticks.js +0 -42
  670. package/dist/charts/primitives/AreaGradient.d.ts +0 -18
  671. package/dist/charts/primitives/AreaGradient.d.ts.map +0 -1
  672. package/dist/charts/primitives/AreaGradient.js +0 -13
  673. package/dist/charts/primitives/Axes.d.ts +0 -83
  674. package/dist/charts/primitives/Axes.d.ts.map +0 -1
  675. package/dist/charts/primitives/Axes.js +0 -168
  676. package/dist/charts/primitives/CartesianChart.d.ts +0 -257
  677. package/dist/charts/primitives/CartesianChart.d.ts.map +0 -1
  678. package/dist/charts/primitives/CartesianChart.js +0 -549
  679. package/dist/charts/primitives/ChartCard.d.ts +0 -66
  680. package/dist/charts/primitives/ChartCard.d.ts.map +0 -1
  681. package/dist/charts/primitives/ChartCard.js +0 -143
  682. package/dist/charts/primitives/ChartFrame.d.ts +0 -156
  683. package/dist/charts/primitives/ChartFrame.d.ts.map +0 -1
  684. package/dist/charts/primitives/ChartFrame.js +0 -241
  685. package/dist/charts/primitives/ChartLegend.d.ts +0 -67
  686. package/dist/charts/primitives/ChartLegend.d.ts.map +0 -1
  687. package/dist/charts/primitives/ChartLegend.js +0 -292
  688. package/dist/charts/primitives/ChartPending.d.ts +0 -113
  689. package/dist/charts/primitives/ChartPending.d.ts.map +0 -1
  690. package/dist/charts/primitives/ChartPending.js +0 -117
  691. package/dist/charts/primitives/ChartTooltip.d.ts +0 -59
  692. package/dist/charts/primitives/ChartTooltip.d.ts.map +0 -1
  693. package/dist/charts/primitives/ChartTooltip.js +0 -197
  694. package/dist/charts/primitives/Crosshair.d.ts +0 -26
  695. package/dist/charts/primitives/Crosshair.d.ts.map +0 -1
  696. package/dist/charts/primitives/Crosshair.js +0 -23
  697. package/dist/charts/primitives/HatchPattern.d.ts +0 -31
  698. package/dist/charts/primitives/HatchPattern.d.ts.map +0 -1
  699. package/dist/charts/primitives/HatchPattern.js +0 -31
  700. package/dist/charts/primitives/HoverOverlay.d.ts +0 -45
  701. package/dist/charts/primitives/HoverOverlay.d.ts.map +0 -1
  702. package/dist/charts/primitives/HoverOverlay.js +0 -72
  703. package/dist/charts/primitives/HoverOverlay.module.css +0 -13
  704. package/dist/charts/primitives/HoverOverlay.module.css.d.ts +0 -8
  705. package/dist/charts/primitives/XZoneRects.d.ts +0 -54
  706. package/dist/charts/primitives/XZoneRects.d.ts.map +0 -1
  707. package/dist/charts/primitives/XZoneRects.js +0 -65
  708. package/dist/charts/primitives/ZoneRects.d.ts +0 -38
  709. package/dist/charts/primitives/ZoneRects.d.ts.map +0 -1
  710. package/dist/charts/primitives/ZoneRects.js +0 -30
  711. package/dist/charts/primitives/chart-card-context.d.ts +0 -33
  712. package/dist/charts/primitives/chart-card-context.d.ts.map +0 -1
  713. package/dist/charts/primitives/chart-card-context.js +0 -18
  714. package/dist/charts/primitives/chart-frame-layout.d.ts +0 -185
  715. package/dist/charts/primitives/chart-frame-layout.d.ts.map +0 -1
  716. package/dist/charts/primitives/chart-frame-layout.js +0 -175
  717. package/dist/charts/primitives/chart-layout.d.ts +0 -112
  718. package/dist/charts/primitives/chart-layout.d.ts.map +0 -1
  719. package/dist/charts/primitives/chart-layout.js +0 -175
  720. package/dist/charts/primitives/chart-tier.d.ts +0 -16
  721. package/dist/charts/primitives/chart-tier.d.ts.map +0 -1
  722. package/dist/charts/primitives/chart-tier.js +0 -44
  723. package/dist/charts/primitives/legend-disclosure.d.ts +0 -27
  724. package/dist/charts/primitives/legend-disclosure.d.ts.map +0 -1
  725. package/dist/charts/primitives/legend-disclosure.js +0 -153
  726. package/dist/charts/series.d.ts +0 -189
  727. package/dist/charts/series.d.ts.map +0 -1
  728. package/dist/charts/series.js +0 -84
  729. package/dist/charts/sparklines/BarSparkline.d.ts +0 -37
  730. package/dist/charts/sparklines/BarSparkline.d.ts.map +0 -1
  731. package/dist/charts/sparklines/BarSparkline.js +0 -53
  732. package/dist/charts/sparklines/LineSparkline.d.ts +0 -15
  733. package/dist/charts/sparklines/LineSparkline.d.ts.map +0 -1
  734. package/dist/charts/sparklines/LineSparkline.js +0 -51
  735. package/dist/charts/sparklines/index.d.ts +0 -3
  736. package/dist/charts/sparklines/index.d.ts.map +0 -1
  737. package/dist/charts/sparklines/index.js +0 -6
  738. package/dist/charts/utils/domain.d.ts +0 -35
  739. package/dist/charts/utils/domain.d.ts.map +0 -1
  740. package/dist/charts/utils/domain.js +0 -12
  741. package/dist/charts/utils/format.d.ts +0 -8
  742. package/dist/charts/utils/format.d.ts.map +0 -1
  743. package/dist/charts/utils/format.js +0 -20
  744. package/dist/charts/utils/measure-text.d.ts +0 -25
  745. package/dist/charts/utils/measure-text.d.ts.map +0 -1
  746. package/dist/charts/utils/measure-text.js +0 -64
  747. package/dist/charts/utils/ticks.d.ts +0 -103
  748. package/dist/charts/utils/ticks.d.ts.map +0 -1
  749. package/dist/charts/utils/ticks.js +0 -92
  750. package/dist/commands/overlays-mount.d.ts +0 -122
  751. package/dist/commands/overlays-mount.d.ts.map +0 -1
  752. package/dist/commands/overlays-mount.js +0 -125
  753. package/dist/commands/useCommandHotkeys.d.ts +0 -14
  754. package/dist/commands/useCommandHotkeys.d.ts.map +0 -1
  755. package/dist/commands/useCommandHotkeys.js +0 -45
  756. package/dist/content/article-actions.d.ts +0 -39
  757. package/dist/content/article-actions.d.ts.map +0 -1
  758. package/dist/content/article-actions.js +0 -28
  759. package/dist/content/article-card.d.ts +0 -58
  760. package/dist/content/article-card.d.ts.map +0 -1
  761. package/dist/content/article-card.js +0 -79
  762. package/dist/content/article-card.module.css +0 -111
  763. package/dist/content/mdx.d.ts +0 -20
  764. package/dist/content/mdx.d.ts.map +0 -1
  765. package/dist/content/mdx.js +0 -64
  766. package/dist/controls/compare-filter.d.ts +0 -42
  767. package/dist/controls/compare-filter.d.ts.map +0 -1
  768. package/dist/controls/compare-filter.js +0 -38
  769. package/dist/controls/slider-control.d.ts +0 -36
  770. package/dist/controls/slider-control.d.ts.map +0 -1
  771. package/dist/controls/slider-control.js +0 -64
  772. package/dist/dashboard/widget-grid.d.ts +0 -27
  773. package/dist/dashboard/widget-grid.d.ts.map +0 -1
  774. package/dist/dashboard/widget-grid.js +0 -40
  775. package/dist/dashboard/widget-grid.module.css +0 -69
  776. package/dist/data/data-table-state.d.ts.map +0 -1
  777. package/dist/data/data-table.d.ts.map +0 -1
  778. package/dist/data/query-branch.d.ts.map +0 -1
  779. package/dist/data/table.d.ts +0 -24
  780. package/dist/data/table.d.ts.map +0 -1
  781. package/dist/data/virtual-list.d.ts +0 -133
  782. package/dist/data/virtual-list.d.ts.map +0 -1
  783. package/dist/data/virtual-list.js +0 -157
  784. package/dist/data/virtual.d.ts +0 -21
  785. package/dist/data/virtual.d.ts.map +0 -1
  786. package/dist/data/virtual.js +0 -4
  787. package/dist/forms/FormErrorSummary.d.ts +0 -30
  788. package/dist/forms/FormErrorSummary.d.ts.map +0 -1
  789. package/dist/forms/FormErrorSummary.js +0 -30
  790. package/dist/forms/use-field-array.d.ts +0 -60
  791. package/dist/forms/use-field-array.d.ts.map +0 -1
  792. package/dist/forms/use-field-array.js +0 -20
  793. package/dist/forms/use-form-draft.d.ts +0 -76
  794. package/dist/forms/use-form-draft.d.ts.map +0 -1
  795. package/dist/forms/use-form-draft.js +0 -92
  796. package/dist/forms/use-form-submit.d.ts +0 -88
  797. package/dist/forms/use-form-submit.d.ts.map +0 -1
  798. package/dist/forms/use-form-submit.js +0 -63
  799. package/dist/notifications/bell.d.ts.map +0 -1
  800. package/dist/notifications/center.d.ts.map +0 -1
  801. package/dist/notifications/define-notifications.d.ts.map +0 -1
  802. package/dist/notifications/index.d.ts +0 -40
  803. package/dist/notifications/index.d.ts.map +0 -1
  804. package/dist/notifications/index.js +0 -54
  805. package/dist/notifications/mount-guard.d.ts +0 -8
  806. package/dist/notifications/mount-guard.d.ts.map +0 -1
  807. package/dist/notifications/mount-guard.js +0 -18
  808. package/dist/notifications/notify.d.ts +0 -149
  809. package/dist/notifications/notify.d.ts.map +0 -1
  810. package/dist/notifications/notify.js +0 -171
  811. package/dist/notifications/store.d.ts.map +0 -1
  812. package/dist/provider/connectivity-indicator.d.ts +0 -13
  813. package/dist/provider/connectivity-indicator.d.ts.map +0 -1
  814. package/dist/provider/connectivity-indicator.js +0 -205
  815. package/dist/provider/connectivity-provider.d.ts +0 -7
  816. package/dist/provider/connectivity-provider.d.ts.map +0 -1
  817. package/dist/provider/connectivity-provider.js +0 -128
  818. package/dist/provider/connectivity-types.d.ts +0 -36
  819. package/dist/provider/connectivity-types.d.ts.map +0 -1
  820. package/dist/provider/use-connectivity.d.ts +0 -3
  821. package/dist/provider/use-connectivity.d.ts.map +0 -1
  822. package/dist/provider/use-connectivity.js +0 -14
  823. package/dist/query-devtools.d.ts +0 -21
  824. package/dist/query-devtools.d.ts.map +0 -1
  825. package/dist/query-devtools.js +0 -13
  826. package/src/agent/adapter.ts +0 -945
  827. package/src/agent/use-agent-stream.ts +0 -154
  828. package/src/agent-chat/index.ts +0 -54
  829. package/src/agent-chat/thread-detail-panel.tsx +0 -201
  830. package/src/agent-chat/thread-workspace.tsx +0 -279
  831. package/src/charts/cursor/resolve.ts +0 -198
  832. package/src/charts/cursor/scope.tsx +0 -35
  833. package/src/charts/cursor/store.ts +0 -58
  834. package/src/charts/cursor/touch-pin.ts +0 -138
  835. package/src/charts/hooks/use-discrete-cursor.ts +0 -335
  836. package/src/charts/hooks/use-hysteresis.ts +0 -26
  837. package/src/charts/hooks/useBandPlot.ts +0 -383
  838. package/src/charts/hooks/useChartCursor.ts +0 -367
  839. package/src/charts/hooks/useChartSize.ts +0 -35
  840. package/src/charts/kinds/BandStrip.tsx +0 -449
  841. package/src/charts/kinds/Bars.tsx +0 -589
  842. package/src/charts/kinds/Donut.tsx +0 -368
  843. package/src/charts/kinds/DualPanel.tsx +0 -712
  844. package/src/charts/kinds/Heatmap.tsx +0 -396
  845. package/src/charts/kinds/MirroredBars.tsx +0 -469
  846. package/src/charts/kinds/MultiLine.tsx +0 -322
  847. package/src/charts/kinds/StackedArea.tsx +0 -267
  848. package/src/charts/kinds/ZonedLine.tsx +0 -301
  849. package/src/charts/kinds/band-chrome.tsx +0 -91
  850. package/src/charts/kinds/donut-layout.ts +0 -82
  851. package/src/charts/layout/auto-margin.ts +0 -242
  852. package/src/charts/layout/end-labels.ts +0 -135
  853. package/src/charts/layout/log-ticks.ts +0 -90
  854. package/src/charts/primitives/AreaGradient.tsx +0 -26
  855. package/src/charts/primitives/Axes.tsx +0 -271
  856. package/src/charts/primitives/CartesianChart.tsx +0 -1002
  857. package/src/charts/primitives/ChartCard.tsx +0 -280
  858. package/src/charts/primitives/ChartFrame.tsx +0 -493
  859. package/src/charts/primitives/ChartLegend.tsx +0 -422
  860. package/src/charts/primitives/ChartPending.tsx +0 -243
  861. package/src/charts/primitives/ChartTooltip.tsx +0 -265
  862. package/src/charts/primitives/Crosshair.tsx +0 -43
  863. package/src/charts/primitives/HatchPattern.tsx +0 -55
  864. package/src/charts/primitives/HoverOverlay.module.css +0 -13
  865. package/src/charts/primitives/HoverOverlay.module.css.d.ts +0 -8
  866. package/src/charts/primitives/HoverOverlay.tsx +0 -109
  867. package/src/charts/primitives/XZoneRects.tsx +0 -132
  868. package/src/charts/primitives/ZoneRects.tsx +0 -67
  869. package/src/charts/primitives/chart-card-context.ts +0 -46
  870. package/src/charts/primitives/chart-frame-layout.ts +0 -430
  871. package/src/charts/primitives/chart-layout.ts +0 -318
  872. package/src/charts/primitives/chart-tier.tsx +0 -76
  873. package/src/charts/primitives/legend-disclosure.tsx +0 -178
  874. package/src/charts/series.ts +0 -276
  875. package/src/charts/sparklines/BarSparkline.tsx +0 -94
  876. package/src/charts/sparklines/LineSparkline.tsx +0 -71
  877. package/src/charts/sparklines/index.ts +0 -2
  878. package/src/charts/theme.tsx +0 -53
  879. package/src/charts/utils/domain.ts +0 -41
  880. package/src/charts/utils/format.ts +0 -19
  881. package/src/charts/utils/measure-text.ts +0 -109
  882. package/src/charts/utils/ticks.ts +0 -239
  883. package/src/commands/overlays-mount.tsx +0 -333
  884. package/src/commands/useCommandHotkeys.ts +0 -114
  885. package/src/content/article-actions.ts +0 -72
  886. package/src/content/article-card.module.css +0 -111
  887. package/src/content/article-card.tsx +0 -174
  888. package/src/content/mdx.tsx +0 -127
  889. package/src/controls/compare-filter.tsx +0 -81
  890. package/src/controls/slider-control.tsx +0 -159
  891. package/src/dashboard/widget-grid.module.css +0 -69
  892. package/src/dashboard/widget-grid.tsx +0 -146
  893. package/src/data/table.ts +0 -39
  894. package/src/data/virtual-list.tsx +0 -356
  895. package/src/data/virtual.ts +0 -26
  896. package/src/forms/FormErrorSummary.tsx +0 -71
  897. package/src/forms/use-field-array.ts +0 -94
  898. package/src/forms/use-form-draft.ts +0 -262
  899. package/src/forms/use-form-submit.ts +0 -199
  900. package/src/notifications/index.ts +0 -88
  901. package/src/notifications/mount-guard.ts +0 -38
  902. package/src/notifications/notify.tsx +0 -379
  903. package/src/provider/connectivity-indicator.tsx +0 -267
  904. package/src/provider/connectivity-provider.tsx +0 -189
  905. package/src/provider/connectivity-types.ts +0 -42
  906. package/src/provider/use-connectivity.ts +0 -26
  907. package/src/query-devtools.tsx +0 -40
  908. /package/dist/{agent-chat → agent/chat}/message-affordances.js +0 -0
  909. /package/dist/{agent-chat → agent/chat}/relative-time.d.ts +0 -0
  910. /package/dist/{agent-chat → agent/chat}/relative-time.js +0 -0
  911. /package/dist/{agent-chat → agent/chat}/use-keyboard-inset.d.ts +0 -0
  912. /package/dist/{agent-chat → agent/chat}/virtualize.js +0 -0
  913. /package/dist/{notifications → commands/notifications}/bell.js +0 -0
  914. /package/dist/{notifications → commands/notifications}/define-notifications.js +0 -0
  915. /package/dist/{provider/connectivity-types.js → controls/uncontrolled.js} +0 -0
  916. /package/dist/{data → table}/data-table.module.css +0 -0
  917. /package/dist/{data → table}/data-table.module.css.d.ts +0 -0
  918. /package/dist/{data → table}/query-branch.d.ts +0 -0
  919. /package/dist/{data → table}/query-branch.js +0 -0
  920. /package/src/{agent-chat → agent/chat}/relative-time.ts +0 -0
  921. /package/src/{data → table}/data-table.module.css +0 -0
  922. /package/src/{data → table}/data-table.module.css.d.ts +0 -0
  923. /package/src/{data → table}/query-branch.ts +0 -0
@@ -1,1185 +1,18 @@
1
1
  /**
2
- * Mantine-free token + palette layer.
3
- *
4
- * This module is PURE DATA + string helpers — ZERO `@mantine/*` imports (lint-enforced).
5
- * Colors are CSS custom properties under the `--vx-*` prefix (do NOT rename the prefix).
6
- * They resolve per color scheme in CSS, so `VX.*` works in components AND in non-component
7
- * files. Apply opacity via `alpha(token, a)` (never raw `rgba()`) so the hue keeps resolving.
8
- *
9
- * Grounded in argo `packages/charts/src/{tokens,palette,theme-vars,utils/color}.ts`.
2
+ * `basalt-ui/tokens` — the Mantine-free token layer's public surface. The implementation lives in
3
+ * `./core` (internal: the provider, CLI and theme import it from there); only what a consumer
4
+ * names is re-exported here.
10
5
  */
11
-
12
- import {
13
- buildPaletteData,
14
- RADIUS,
15
- RADIUS_STEP,
16
- ROW_LINE_HEIGHT,
17
- SHADOW,
18
- SPACE,
19
- SPACE_SCALE,
20
- SPACE_STEP,
21
- } from './palette'
22
- import type { PaletteData, RadiusValues, SpaceValues } from './palette'
23
- import { SIZE_CLASSES, sizeClassMaxEm } from './size-classes'
24
- import { HIT_COARSE, HIT_FINE } from '../common/hit-floor'
25
- import { BASALT_VX_FAMILIES } from '../common/vx-families'
26
- import { vxFamilyOf } from '../common/vx-family'
27
-
28
- // The raw hue families + pair-picker — the building blocks a consumer's series module composes
29
- // (`hrv: p(BP.blue)`). The doctrine sends every consumer here, so they are public surface, not
30
- // palette internals; dropping them from this barrel hard-fails the consumer's build (1.0.0 bug,
31
- // pinned by scripts/export-surface.json).
32
6
  export { BP, p } from './palette'
33
-
34
- // The six-knob derive engine — the generator behind the shipped default palette. Exposed so a
35
- // consumer can retune the palette identity via `createBasaltTheme(overrides, { derive })` (see
36
- // `../theme`) without hand-picking hexes. `buildPaletteData`/`PaletteData` stay internal (not
37
- // re-exported here) — a consumer reaches a derived palette through `createBasaltTheme`, not by
38
- // building `--vx-*` CSS for a custom config directly.
39
- export { DEFAULT_DERIVE_CONFIG, deriveTokens, resolveDeriveConfig } from './derive'
40
- export type { DeriveConfig, DerivedPalette } from './derive'
41
-
42
- // The radius analog of the derive engine — the law behind `createBasaltTheme(overrides, { radius })`
43
- // (see `../theme`). `RADIUS`/`RADIUS_STEP` stay internal to the theme layer; a consumer retunes the
44
- // two anchors through `createBasaltTheme`, not by calling `deriveRadius` directly (it is exposed for
45
- // the law itself to be inspectable/testable, same rationale as `deriveTokens`).
46
- export { deriveRadius } from './palette'
47
- export type { RadiusValues } from './palette'
48
-
49
- // The density analog of the derive engine — the law behind `createBasaltTheme(overrides, {
50
- // density })` (see `../theme`). `SPACE`/`SPACE_SCALE`/`SPACE_STEP`/`ROW_LINE_HEIGHT` stay internal
51
- // to the theme layer; a consumer retunes them through `createBasaltTheme`, not by calling
52
- // `deriveSpacing` directly (it is exposed for the law itself to be inspectable/testable, same
53
- // rationale as `deriveRadius`).
54
- export { deriveSpacing } from './palette'
55
- export type { SpaceValues } from './palette'
56
-
57
- // The two responsive tables — MIGRATING recipes and the raw-breakpoint guard messages send
58
- // consumers here for them; `migrating-imports.test.ts` pins that every documented import resolves.
7
+ export { CONTAINER_CLASSES, CONTAINER_GRID_BREAKPOINTS, CONTAINER_KEYS } from './size-classes'
59
8
  export {
60
- CONTAINER_CLASSES,
61
- CONTAINER_GRID_BREAKPOINTS,
62
- CONTAINER_KEYS,
63
- resolveContainerClass,
64
- SIZE_CLASSES,
65
- } from './size-classes'
66
- export type { ContainerClass } from './size-classes'
67
-
68
- /** A per-theme color pair: a hue keeps its identity but shifts shade across schemes. */
69
- export type ColorPair = { light: string; dark: string }
70
-
71
- /** A map of token name → per-theme color pair (the input shape for series/group builders). */
72
- export type SeriesMap = Record<string, ColorPair>
73
-
74
- /**
75
- * Apply opacity to any palette token, theme-aware. Use instead of raw `rgba()` so the
76
- * underlying hue still resolves per color scheme.
77
- *
78
- * alpha(VX.neutral, 0.5) // muted hairline
79
- * alpha(VX.status.warn, 0.1) // zone-band fill
80
- */
81
- export const alpha = (token: string, a: number): string =>
82
- `color-mix(in srgb, ${token} ${Math.round(a * 100)}%, transparent)`
83
-
84
- /**
85
- * VX tokens — `var(--vx-*)` string refs + non-color sizing constants. Colors resolve per
86
- * color scheme in CSS, so `VX.*` works in components AND in non-component files. Never
87
- * reference raw hex in chart files — use `VX.*` / `alpha()`.
88
- *
89
- * The framework ships ONLY generic primitives — no domain `VX.series` tree (apps rebuild
90
- * that with `seriesTokens` / `groupTokens` against their own series maps).
91
- */
92
- /**
93
- * The type scale — the ONE owned ladder, in px.
94
- *
95
- * Type is a token axis like color / spacing / radius / motion: a single edit point, never a
96
- * hardcoded literal at a call site. Every font-size in the framework resolves to a step here.
97
- *
98
- * Two representations are DERIVED from this one object, so they cannot drift:
99
- * • `VX.text.*` — plain numbers, for inline `style` objects and visx SVG props (React appends
100
- * `px`; SVG presentation attributes can't resolve `var()`, so a ref string would break charts).
101
- * • `--vx-text-*` — the CSS-var form (`11px`, …), for CSS modules and the Mantine theme.
102
- *
103
- * The Mantine theme additionally re-expresses the ladder through Mantine's `rem()` (see
104
- * `theme/index.ts`), so the component surface scales with the user's browser font-size AND with
105
- * `--mantine-scale`. `md` is the body step; `lg` is pinned at exactly 16px because it doubles as
106
- * the iOS input floor (see the `styles.css` floor — Safari zooms the viewport on focus below 16px).
107
- *
108
- * ## Adding a rung
109
- *
110
- * The ladder is hand-tuned per ROLE, not generated — but it is not arbitrary either, and the
111
- * constraint is what keeps a "just add the size I need" request from dissolving it. Every adjacent
112
- * pair sits between **1.06× and 1.17×**, so a new rung must too:
113
- *
114
- * • Below the range, two rungs are visually the same size and the ladder stops being a choice —
115
- * the guard would then report a size for which two tokens are equally "right".
116
- * • Above it, the jump reads as a different type system rather than the next step of this one.
117
- *
118
- * That test is what admitted `nano` (11/10 = 1.10) and `display` (30/26 = 1.154, the second-widest
119
- * step, which is the shape a display tier is supposed to have), and what rejected a 20px rung
120
- * between `xl` (18) and `h2` (21): 21/20 = 1.05 is below the floor, and `h2` is already 1px away
121
- * from any 20px site. A size the ladder declines to grow a rung for is a size that should snap to
122
- * its nearest step — not a `theme-allow`.
123
- *
124
- * A rung is also a ROLE, not just a number. `nano` and `display` are both deliberately named for
125
- * where they belong (a label engraved inside a drawn object; a numeral read from across a room)
126
- * rather than for a position, because the failure mode of a bare `xxs`/`xxl` is that it becomes the
127
- * escape hatch for every size the ladder was meant to prevent.
128
- */
129
- const TEXT = {
130
- nano: 10, // engraved/graphic label INSIDE a drawn object (a plate face, a dial, a chip) — never UI copy or prose
131
- micro: 11, // mono uppercase micro-label (table th, Menu.Label, sidebar/section headers, axis ticks)
132
- xs: 12.5, // delta badges, tooltip meta, dense chrome, StatCard labels
133
- sm: 13.5, // table/stat numerals, chart tooltip, legend
134
- md: 15, // BODY — nav rows, menu items, timeline, labels, prose; chart/card titles
135
- lg: 16, // breadcrumb current — ALSO the iOS input floor (do not lower)
136
- xl: 18, // section titles
137
- h2: 21, // article-density Prose h2 (docs/CONTENT-SPEC.md §5)
138
- kpi: 24, // the StatCard hero numeral (density pass: 31 → 24, tighter/less shouty)
139
- h1: 26, // article-density Prose h1 (docs/CONTENT-SPEC.md §5)
140
- display: 30, // a numeral read at arm's length (a keypad readout, a timer, a kiosk figure) — not a heading
141
- } as const
142
-
143
- export const VX = {
144
- // Non-color sizing constants
145
- // Stroke WEIGHTS, not spacing — deliberately fixed, never density-tracking (see
146
- // `SPACE_STEP_BASE`'s "charts" group doc in tokens/palette.ts).
147
- lineWidth: 2.5,
148
- line2Width: 2,
149
- axisFont: TEXT.micro,
150
- // A discrete visual footprint (not a stroke weight), so — unlike `lineWidth`/`line2Width` above —
151
- // it DOES track density; single-sourced from `SPACE_STEP.chartDotR` (see that constant's doc).
152
- dotR: SPACE_STEP.chartDotR,
153
- // The ONE dashed pattern — plotted stroke, legend swatch, tooltip swatch all read this.
154
- dashArray: '6 4' as const,
155
- // Legend layout — single-sourced from `SPACE_STEP.chartLegendGap` (density-tracking; see that
156
- // constant's doc). Still a raw number here (not `var()`) — ChartLegend applies it via inline
157
- // `style`, and this is the one static (level-0) value; `createBasaltTheme({ density })` has no
158
- // wiring into chart render props yet, so this number does NOT move live with the knob (same
159
- // "dev slider/production JS defaultProps" gap as Timeline's `bulletSize` — see `deriveSpacing`'s
160
- // doc in tokens/palette.ts).
161
- legendGap: SPACE_STEP.chartLegendGap,
162
- legendFontSize: TEXT.sm,
163
-
164
- // The type scale (px numbers — see TEXT above). Use in inline styles and visx SVG props;
165
- // use `var(--vx-text-*)` in CSS modules.
166
- text: TEXT,
167
-
168
- // Single source for the card corner radius — shared by the Mantine-free ChartCard and the
169
- // Mantine chrome (Card/Paper resolve to this SAME token). One knob, so cards never diverge.
170
- radiusCard: 'var(--vx-radius-card)',
171
- // Single source for the control corner radius (inputs, search, buttons, segmented track).
172
- radiusCtrl: 'var(--vx-radius-ctrl)',
173
- // Fully-rounded pill affordance (scroll-to-bottom button, chips) — fixed, does not track the
174
- // radius knob (see `RADIUS_STEP.pill`'s doc in `tokens/palette.ts`).
175
- radiusPill: 'var(--vx-radius-pill)',
176
- // The pointer-tier hit floor: 44px under `(pointer: coarse)` (WCAG 2.5.5), 24px otherwise
177
- // (2.5.8). Density-exempt; `[data-basalt-hit]::after` in `styles.css` reads it.
178
- hit: 'var(--vx-hit)',
179
-
180
- // Controls tier sizing (`docs/CONTROLS-SPEC.md` §5) — `var()` refs onto the density-tracking
181
- // `--vx-space-*` declarations `spaceDecls` emits above (same ref pattern as `radiusCard`/
182
- // `radiusCtrl`), so a home/control reads ONE source for its tier height whether it's Mantine
183
- // chrome (`cssVariablesResolver`/`CTL_THEME`) or a Mantine-free composed layout.
184
- space: {
185
- controlHeightTag: 'var(--vx-space-control-height-tag)',
186
- controlHeightWidget: 'var(--vx-space-control-height-widget)',
187
- controlHeightCtl: 'var(--vx-space-control-height-ctl)',
188
- pageBarRowHeight: 'var(--vx-space-page-bar-row-height)',
189
- sectionHeaderHeight: 'var(--vx-space-section-header-height)',
190
- widgetHeaderHeight: 'var(--vx-space-widget-header-height)',
191
- sidebarBlockRowHeight: 'var(--vx-space-sidebar-block-row-height)',
192
- controlGap: 'var(--vx-space-control-gap)',
193
- sheetRowHeight: 'var(--vx-space-sheet-row-height)',
194
- },
195
-
196
- // Secondary-line color (back-compat alias; now theme-aware via --vx-line2)
197
- line2Dark: 'var(--vx-line2)',
198
-
199
- // Semantic fills — consistent opacity across all charts
200
- good: 'var(--vx-good)',
201
- goodSoft: 'var(--vx-good-soft)',
202
- bad: 'var(--vx-bad)',
203
- warn: 'var(--vx-warn)',
204
- goodSolid: 'var(--vx-good-solid)',
205
- badSolid: 'var(--vx-bad-solid)',
206
- warnSolid: 'var(--vx-warn-solid)',
207
-
208
- // Reference/dashed lines for thresholds
209
- goodRef: 'var(--vx-good-ref)',
210
- badRef: 'var(--vx-bad-ref)',
211
- warnRef: 'var(--vx-warn-ref)',
212
-
213
- // Neutral primary line/text color — the default for single-series, no-signal marks
214
- // ("white/gray per theme"). Same value as the NEUTRAL.line pair.
215
- line: 'var(--vx-line)',
216
- line2: 'var(--vx-line2)',
217
-
218
- // Axis label + axis stroke colors (theme-aware). Exposed as flat refs so a bespoke chart that
219
- // renders raw <text> labels or axis lines (without the Axis* primitives) needs no hook.
220
- axis: 'var(--vx-axis)',
221
- axisStroke: 'var(--vx-axis-stroke)',
222
-
223
- // Grid, hover, legend
224
- grid: 'var(--vx-grid)',
225
- crosshair: 'var(--vx-crosshair)',
226
- dotStroke: 'var(--vx-dot-stroke)',
227
- legendText: 'var(--vx-legend-text)',
228
-
229
- // Tooltip chrome — muted (secondary) text inside a bespoke tooltip. The other tooltip vars
230
- // (bg/text/border/shadow) are only exposed via `useVxTheme()` (see `charts/theme.tsx`); this
231
- // one is flattened onto `VX` too because bespoke-tooltip authors reached for `VX.muted` (the
232
- // general ink-ramp muted) instead and got the wrong token — same pattern as `VX.muted` below.
233
- tooltipMuted: 'var(--vx-tooltip-muted)',
234
-
235
- // Base neutral for hairlines / muted text / overlays — apply opacity via alpha()
236
- neutral: 'var(--vx-neutral)',
237
-
238
- // Ink text ramp (docs/DESIGN-SPEC.md §2) — primary/emphasis/secondary/tertiary body text.
239
- ink: 'var(--vx-ink)',
240
- ink2: 'var(--vx-ink2)',
241
- muted: 'var(--vx-muted)',
242
- faint: 'var(--vx-faint)',
243
-
244
- // The accent as INK — primary series, active-nav icon, links, focus rings. Read against the PAGE,
245
- // so it inverts across schemes (light on dark, deep on light).
246
- accent: 'var(--vx-accent)',
247
- accentHover: 'var(--vx-accent-hover)',
248
- // The accent as SURFACE — a filled control that carries a label. Squeezed between white-text
249
- // contrast and page contrast, so it is the same hex in both schemes (see ACCENT in palette.ts).
250
- // Mantine's `--mantine-color-<primary>-filled` is bridged onto this, so it drives ALL filled
251
- // chrome; a raw `--vx-accent` fill would be unreadable on dark. Fills use THIS, never `accent`.
252
- accentFill: 'var(--vx-accent-fill)',
253
- accentFillHover: 'var(--vx-accent-fill-hover)',
254
- onAccent: 'var(--vx-on-accent)',
255
-
256
- // Layout separators (header bottom rule, sidebar child indent) — distinct from `surface.border`.
257
- divider: 'var(--vx-divider)',
258
-
259
- // Depth shadows — a whisper shadow + a 1px ring baked into the value (never a `border` prop).
260
- shadowCard: 'var(--vx-shadow-card)',
261
- shadowCtrl: 'var(--vx-shadow-ctrl)',
262
- // Raised interactive controls — drop + a 1px INSET edge, the one depth every raised Button/
263
- // ActionIcon variant shares (works over a fill, a tint or a panel alike; see SHADOW.raised).
264
- shadowRaised: 'var(--vx-shadow-raised)',
265
- // Floating-layer elevation (menus, popovers, tooltips, modals, drawers) — a real drop shadow.
266
- shadowOverlay: 'var(--vx-shadow-overlay)',
267
-
268
- // App surfaces (cards, borders) — shared with the Mantine chrome
269
- surface: {
270
- bg: 'var(--vx-surface-bg)',
271
- panel: 'var(--vx-surface-panel)',
272
- panelHover: 'var(--vx-surface-panel-hover)',
273
- elevated: 'var(--vx-surface-elevated)',
274
- subtle: 'var(--vx-surface-subtle)',
275
- overlay: 'var(--vx-surface-overlay)', // floating layer (menus, popovers, modals, drawers)
276
- field: 'var(--vx-surface-field)', // input field surface (slightly inset on a panel)
277
- border: 'var(--vx-surface-border)', // "line" — strong border
278
- hairline: 'var(--vx-surface-hairline)', // card ring only
279
- },
280
-
281
- // Score / zone status scale (excellent → poor)
282
- status: {
283
- excellent: 'var(--vx-status-excellent)',
284
- good: 'var(--vx-status-good)',
285
- warn: 'var(--vx-status-warn)',
286
- bad: 'var(--vx-status-bad)',
287
- neutral: 'var(--vx-status-neutral)',
288
- },
289
-
290
- // Shared sizing — single-sourced from `SPACE_STEP.chartMargin*` (density-tracking; same
291
- // static-value/no-live-wiring note as `legendGap` above).
292
- margin: {
293
- top: SPACE_STEP.chartMarginTop,
294
- right: SPACE_STEP.chartMarginRight,
295
- bottom: SPACE_STEP.chartMarginBottom,
296
- left: SPACE_STEP.chartMarginLeft,
297
- },
298
- minPxPerTick: 55,
299
- /**
300
- * Floor on a chart's plot rect height, in px (`ChartFrame`). A legend wrapping to five rows at
301
- * phone width used to eat a fixed `height={240}` toward zero and the plot simply stopped
302
- * rendering — the plot never shrinks past this, the frame grows instead (or, under `fill`, the
303
- * legend rolls up).
304
- */
305
- minPlotHeight: 120,
306
- /** Every floating chart overlay portalled to `document.body` — a pinned tooltip, the legend's
307
- * `All N` disclosure and its backdrop — shares one stacking value, so they always stack the same
308
- * way relative to page chrome and to each other. */
309
- zIndexFloating: 9999,
310
- } as const
311
-
312
- /**
313
- * Layout breakpoints, in px, for the places CSS cannot read a custom property.
314
- *
315
- * A `@media` query's condition is resolved before custom properties exist, so
316
- * `@media (max-width: var(--x))` is invalid CSS — a stylesheet with a responsive rule has no
317
- * choice but to write the number. This constant is the other half of that literal: the CSS states
318
- * the number and names the token beside it, and a test asserts the two agree
319
- * (`content/article-layout.breakpoint.test.ts`, the same "literal must match the token" idiom as
320
- * `styles.floor.test.ts`).
321
- *
322
- * Only breakpoints that are genuinely a CSS-authored `@media` belong here. A component that can
323
- * measure its own box uses the measurement instead (`CONTAINER_CLASSES`), and Mantine chrome uses
324
- * `theme.breakpoints`.
325
- */
326
- export const BREAKPOINTS = {
327
- /**
328
- * `content/article-layout.module.css` — below this the TOC rail is dropped and the article
329
- * collapses to a single centred column. Well above the `sm` (52.5em/840px) shell breakpoint on
330
- * purpose: the rail needs the prose measure PLUS its own width plus the column gap, which runs
331
- * out long before the shell goes mobile.
332
- */
333
- article: 1200,
334
- } as const
335
-
336
- /** Resolved chart plot-area margins — the return shape of {@link chartMargin}. */
337
- export type ChartMargin = { top: number; right: number; bottom: number; left: number }
338
-
339
- /**
340
- * Chart plot-area margins — `VX.margin` widened for an `AxisRightNumeric`'s tick labels, and/or
341
- * overridden per side. A token can't express "only when a right axis is rendered", so this is a
342
- * function, not a second static token — also the seam that could one day track `density`
343
- * (`VX.margin` itself is frozen at the level-0 snapshot; see `deriveSpacing`'s JSDoc).
344
- *
345
- * Law, applied in this order: start from `VX.margin`; when `rightAxis` is true, widen `right` to
346
- * `Math.max(VX.margin.right, <right-axis minimum>)` (`SPACE_STEP.chartMarginRightAxis`); then any
347
- * explicitly passed side wins last (including overriding `rightAxis`'s widened `right`).
348
- * `chartMargin()` with no args deep-equals `VX.margin`.
349
- *
350
- * Returns a NEW object every call — memoize at the call site (`useMemo`), the same way `Bars`
351
- * already memoizes its own margin.
352
- */
353
- export function chartMargin(opts?: {
354
- /** Reserve room for an `AxisRightNumeric`'s tick labels. */
355
- rightAxis?: boolean
356
- top?: number
357
- right?: number
358
- bottom?: number
359
- left?: number
360
- }): ChartMargin {
361
- const widenedRight = opts?.rightAxis
362
- ? Math.max(VX.margin.right, SPACE_STEP.chartMarginRightAxis)
363
- : VX.margin.right
364
- return {
365
- top: opts?.top ?? VX.margin.top,
366
- right: opts?.right ?? widenedRight,
367
- bottom: opts?.bottom ?? VX.margin.bottom,
368
- left: opts?.left ?? VX.margin.left,
369
- }
370
- }
371
-
372
- type Side = 'light' | 'dark'
373
-
374
- /** A CSS declaration line for a single `--vx-*` custom property. */
375
- const decl = (name: string, value: string): string => ` --vx-${name}: ${value};`
376
-
377
- /**
378
- * A px number expressed as the plain rem STRING literal (16px base: `pxRem(6)` → `'0.375rem'`) —
379
- * NOT Mantine's own `rem()` helper, which instead emits a `calc(...)` expression bound to
380
- * `--mantine-scale` (a different value; that scaling happens at the Mantine-coupled call site
381
- * instead — see `theme/index.ts`'s `Input.extend` `vars` for why `--vx-space-input-height` needs
382
- * both halves). The SINGLE source for this conversion — `theme/index.ts` imports this instead of
383
- * keeping its own copy, so the radius/spacing size-scale steps and this module's own rem-emitting
384
- * vars (`--vx-space-input-height`) can never compute the conversion two different ways.
385
- */
386
- export function pxRem(px: number): string {
387
- return `${px / 16}rem`
388
- }
389
-
390
- /** Emit one prefixed group of pairs for a given scheme side. */
391
- const groupSide = (prefix: string, map: SeriesMap, side: Side): string =>
392
- Object.entries(map)
393
- .map(([key, pair]) => decl(`${prefix}${key}`, pair[side]))
394
- .join('\n')
395
-
396
- /**
397
- * The 16 deprecated camelCase aliases for `frameworkPrimitives`' per-scheme canonicals, each
398
- * defined as `var(--vx-<canonical-kebab-name>)` so it can never drift from the value above it.
399
- * Emitted as its own commented, trailing group (never interleaved with the canonicals) — gated by
400
- * {@link BuildPaletteOpts.legacyAliases}, default on. See that option's doc for the migration
401
- * rationale (1.4.0 kebab-case normalization).
402
- */
403
- function frameworkPrimitivesAliases(): string {
404
- return [
405
- ' /* Deprecated camelCase aliases — removed in a future minor; migrate to the kebab names above. */',
406
- decl('goodSolid', 'var(--vx-good-solid)'),
407
- decl('badSolid', 'var(--vx-bad-solid)'),
408
- decl('warnSolid', 'var(--vx-warn-solid)'),
409
- decl('axisStroke', 'var(--vx-axis-stroke)'),
410
- decl('dotStroke', 'var(--vx-dot-stroke)'),
411
- decl('tooltipBg', 'var(--vx-tooltip-bg)'),
412
- decl('tooltipText', 'var(--vx-tooltip-text)'),
413
- decl('tooltipMuted', 'var(--vx-tooltip-muted)'),
414
- decl('tooltipBorder', 'var(--vx-tooltip-border)'),
415
- decl('tooltipShadow', 'var(--vx-tooltip-shadow)'),
416
- decl('legendText', 'var(--vx-legend-text)'),
417
- decl('accentHover', 'var(--vx-accent-hover)'),
418
- decl('accentFill', 'var(--vx-accent-fill)'),
419
- decl('accentFillHover', 'var(--vx-accent-fill-hover)'),
420
- decl('onAccent', 'var(--vx-on-accent)'),
421
- decl('surface-panelHover', 'var(--vx-surface-panel-hover)'),
422
- ].join('\n')
423
- }
424
-
425
- /**
426
- * Built-in framework primitives for a given scheme side — STATUS group, semantic solids,
427
- * neutral line/axis/grid/tooltip chrome, legend text, and the surface ramp. Domain series
428
- * (SERIES/ACTIVITY/USAGE) are NOT shipped — apps append them via `opts.groups`.
429
- */
430
- function frameworkPrimitives(side: Side, data: PaletteData, legacyAliases: boolean): string {
431
- const n = data.NEUTRAL
432
- const s = data.SEMANTIC
433
- const su = data.SURFACE
434
- const ink = data.INK
435
- const ac = data.ACCENT
436
- const canonical = [
437
- groupSide('status-', data.STATUS as SeriesMap, side),
438
- decl('good-solid', s.good[side]),
439
- decl('bad-solid', s.bad[side]),
440
- decl('warn-solid', s.warn[side]),
441
- decl('neutral', n.neutral[side]),
442
- decl('line', n.line[side]),
443
- decl('line2', n.line2[side]),
444
- decl('axis', n.axis[side]),
445
- decl('axis-stroke', n.axisStroke[side]),
446
- decl('grid', n.grid[side]),
447
- decl('crosshair', n.crosshair[side]),
448
- decl('dot-stroke', n.dotStroke[side]),
449
- decl('tooltip-bg', n.tooltipBg[side]),
450
- decl('tooltip-text', n.tooltipText[side]),
451
- decl('tooltip-muted', n.tooltipMuted[side]),
452
- decl('tooltip-border', n.tooltipBorder[side]),
453
- decl('tooltip-shadow', n.tooltipShadow[side]),
454
- decl('legend-text', n.legendText[side]),
455
- decl('ink', ink.ink[side]),
456
- decl('ink2', ink.ink2[side]),
457
- decl('muted', ink.muted[side]),
458
- decl('faint', ink.faint[side]),
459
- decl('accent', ac.accent[side]),
460
- decl('accent-hover', ac.accentHover[side]),
461
- decl('accent-fill', ac.accentFill[side]),
462
- decl('accent-fill-hover', ac.accentFillHover[side]),
463
- decl('on-accent', ac.onAccent[side]),
464
- decl('divider', su.divider[side]),
465
- decl('shadow-card', SHADOW.card[side]),
466
- decl('shadow-ctrl', SHADOW.ctrl[side]),
467
- decl('shadow-raised', SHADOW.raised[side]),
468
- decl('shadow-overlay', SHADOW.overlay[side]),
469
- decl('surface-bg', su.bg[side]),
470
- decl('surface-panel', su.panel[side]),
471
- decl('surface-panel-hover', su.panelHover[side]),
472
- decl('surface-elevated', su.elevated[side]),
473
- decl('surface-subtle', su.subtle[side]),
474
- decl('surface-overlay', su.overlay[side]),
475
- decl('surface-field', su.field[side]),
476
- decl('surface-border', su.border[side]),
477
- decl('surface-hairline', su.hairline[side]),
478
- ].join('\n')
479
- return legacyAliases ? `${canonical}\n${frameworkPrimitivesAliases()}` : canonical
480
- }
481
-
482
- /**
483
- * The `--vx-space-*` declaration list for a resolved {@link SpaceValues} — every anchor and one-off
484
- * that has at least one real `var()` consumer, plus the row line-height. Shared by
485
- * `frameworkDerived` (emits the shipped defaults unconditionally, called with `DEFAULT_SPACE_
486
- * VALUES`) and {@link buildDensityCss} (emits an OVERRIDING block for a retuned density level), so
487
- * the two lists can never drift apart — mirrors `frameworkDerived`'s own single-source reasoning for
488
- * the radii.
489
- *
490
- * The nine controls-tier anchors/one-offs (`controlHeightTag`/`Widget`/`Ctl`,
491
- * `pageBarRowHeight`, `sectionHeaderHeight`, `widgetHeaderHeight`, `sidebarBlockRowHeight`,
492
- * `controlGap`, `sheetRowHeight` — `docs/CONTROLS-SPEC.md` §5) are a DELIBERATE exception to the
493
- * "has at least one real consumer today" rule below: `theme/ctl-theme.tsx`'s `CTL_THEME` and the
494
- * `cssVariablesResolver`'s `-ctl`/`-icon` var sets consume the four control-height anchors this
495
- * commit; `PageBar`/`WidgetHeader`/the sidebar blocks (wave 3/4) consume the six one-offs. Emitted
496
- * now, ahead of that second wave, rather than left as JS-only — unlike the seventeen genuinely
497
- * dead-weight keys below, these are forward-declared framework surface, not vestigial.
498
- *
499
- * `SPACE_FIXED` (Timeline `lineWidth`, 1px borders, the ReadingProgress bar height, SegmentedControl's
500
- * `segmentedTrackInset`) is deliberately NEVER part of this list — it never moves, so a var would
501
- * only invite someone to think it does.
502
- *
503
- * Deliberately DOES NOT emit a var for every `SpaceValues` number — `space.scale.*` (the generic
504
- * Mantine spacing scale) and seventeen `space.step.*` keys have ZERO `var()` consumers anywhere in
505
- * the framework or its tests beyond the CSS-emission test itself. Each is read straight off the
506
- * resolved `SpaceValues` as a JS NUMBER instead, in one of three ways:
507
- * `{timelineBullet,progressBarSize}` are Mantine `defaultProps` (`theme/index.ts`'s Timeline/
508
- * Progress); `{sidebarAccountMenuWidth,sidebarSettingsMenuWidth,mobileNavMenuWidth,
509
- * appShellHeaderHeight,appShellNavbarWidth,appShellNavbarRailWidth,appShellAsideWidth,
510
- * appShellAsideRailWidth,
511
- * mobileNavBarHeight}` are numeric Mantine component props (Menu `width`, AppShell `header`/
512
- * `navbar`/`footer`); and `{chartLegendGap,chartMarginTop,chartMarginRight,chartMarginRightAxis,
513
- * chartMarginBottom,chartMarginLeft,chartDotR}` are visx SVG props via
514
- * `VX.legendGap`/`VX.margin`/`VX.dotR` in this file's own `VX` object. The full list is locked
515
- * against the `SpaceValues` key set by `tokens/density.test.ts`'s declaration-set test, so adding a
516
- * one-off silently omits nothing. A `--vx-space-*` declaration for any of them would be dead weight
517
- * that only looked like the fix for
518
- * the dev-slider/production gap those JS reads actually have (see `deriveSpacing`'s JSDoc in
519
- * `tokens/palette.ts` for the real scope of that gap — it is materially bigger than "a var these
520
- * numbers could round-trip through"). `theme.spacing` (the generic scale, JS) already resolves
521
- * through `--mantine-spacing-*` on the PRODUCTION `createBasaltTheme({ density })` path
522
- * (`theme/index.ts`'s `buildTheme`), so nothing downstream of the generic scale actually needed
523
- * `--vx-space-scale-*` either — deleted along with the rest rather than kept as an unread alias.
524
- */
525
- function spaceDecls(space: SpaceValues): string[] {
526
- return [
527
- decl('space-row-inset-x', `${space.anchors.rowInsetX}px`),
528
- decl('space-row-inset-y', `${space.anchors.rowInsetY}px`),
529
- // Additive law, not the multiplier — see `deriveSpacing`'s doc in `tokens/palette.ts`. No unit:
530
- // `line-height` is a unitless CSS value.
531
- decl('space-row-line-height', `${space.rowLineHeight}`),
532
- // A `size: 'md'` Input's resolved height. Mantine's own `--input-height-md` is
533
- // `calc(2.625rem * var(--mantine-scale))` (BOTH `styles.css` and `styles.layer.css`, verified
534
- // in the installed package) — REM-relative to the root font size AND scale-aware, not a flat
535
- // px. Emitting this in REM (via `pxRem`, not a bare `${…}px`) preserves the rem half; the
536
- // `* var(--mantine-scale))` half is reconstructed at the Mantine-coupled call site
537
- // (`theme/index.ts`'s `Input.extend` `vars`, which wraps this var in the matching `calc(...)`)
538
- // — this module stays Mantine-free, so it cannot reference `--mantine-scale` itself. Flattening
539
- // either half into a flat px would desync input height from the user's root font size (an
540
- // accessibility regression) and from Mantine's global `--mantine-scale` knob.
541
- decl('space-input-height', pxRem(space.anchors.inputHeight)),
542
- // A `size: 'md'` Button's/ActionIcon's resolved height — SAME rem-plus-scale reasoning and
543
- // reconstruction as `space-input-height` above (`theme/index.ts`'s `Button.extend`/
544
- // `ActionIcon.extend` `vars`), single-sourced from the SAME `controlHeight` anchor
545
- // `space-input-height` reads from (`SPACE_ANCHORS_BASE`'s doc in `tokens/palette.ts`).
546
- decl('space-control-height', pxRem(space.anchors.controlHeight)),
547
- // Controls tier heights (`docs/CONTROLS-SPEC.md` §5) — same rem-plus-`--mantine-scale`
548
- // reconstruction as `space-input-height`/`space-control-height` above; `theme/ctl-theme.tsx`'s
549
- // `CTL_THEME` and the `cssVariablesResolver`'s `-ctl`/`-icon` var sets both wrap these in the
550
- // matching `calc(... * var(--mantine-scale))`.
551
- decl('space-control-height-tag', pxRem(space.anchors.controlHeightTag)),
552
- decl('space-control-height-widget', pxRem(space.anchors.controlHeightWidget)),
553
- decl('space-control-height-ctl', pxRem(space.anchors.controlHeightCtl)),
554
- decl('space-stack-xs', `${space.anchors.stackXs}px`),
555
- decl('space-stack-sm', `${space.anchors.stackSm}px`),
556
- decl('space-stack-md', `${space.anchors.stackMd}px`),
557
- decl('space-stack-lg', `${space.anchors.stackLg}px`),
558
- decl('space-stack-xl', `${space.anchors.stackXl}px`),
559
- // The CSS-module spacing sweep's one-offs (docs/STATUS.md) — same single-source reasoning,
560
- // grouped to match `SPACE_STEP_BASE`'s own grouping in tokens/palette.ts.
561
- // ONE value at every viewport since 1.26.0 — the AppShell header is a single
562
- // `appShellHeaderHeight` row (law C14), so the `-mobile` override of the old Decision-3
563
- // responsive pair is gone.
564
- decl('space-sticky-header-clearance', `${space.step.stickyHeaderClearance}px`),
565
- decl('space-nav-icon-gap', `${space.step.navIconGap}px`),
566
- decl('space-sidebar-region-gap', `${space.step.sidebarRegionGap}px`),
567
- decl('space-prose-quote-inset-y', `${space.step.proseQuoteInsetY}px`),
568
- decl('space-prose-quote-indent', `${space.step.proseQuoteIndent}px`),
569
- decl('space-prose-inline-code-inset-y', `${space.step.proseInlineCodeInsetY}px`),
570
- decl('space-prose-inline-code-inset-x', `${space.step.proseInlineCodeInsetX}px`),
571
- decl('space-prose-code-block-inset-y', `${space.step.proseCodeBlockInsetY}px`),
572
- decl('space-prose-code-block-inset-x', `${space.step.proseCodeBlockInsetX}px`),
573
- decl('space-prose-heading-anchor-gap', `${space.step.proseHeadingAnchorGap}px`),
574
- decl('space-prose-table-cell-inset-y', `${space.step.proseTableCellInsetY}px`),
575
- decl('space-prose-table-cell-inset-x', `${space.step.proseTableCellInsetX}px`),
576
- decl('space-prose-chat-list-gap-bottom', `${space.step.proseChatListGapBottom}px`),
577
- decl('space-prose-chat-list-indent', `${space.step.proseChatListIndent}px`),
578
- decl('space-prose-chat-list-item-gap', `${space.step.proseChatListItemGap}px`),
579
- decl('space-prose-chat-nested-list-gap', `${space.step.proseChatNestedListGap}px`),
580
- decl('space-prose-chat-heading-gap-top', `${space.step.proseChatHeadingGapTop}px`),
581
- decl('space-prose-chat-heading-gap-bottom', `${space.step.proseChatHeadingGapBottom}px`),
582
- decl('space-prose-article-paragraph-gap', `${space.step.proseArticleParagraphGap}px`),
583
- decl('space-prose-article-list-gap-top', `${space.step.proseArticleListGapTop}px`),
584
- decl('space-prose-article-list-gap-bottom', `${space.step.proseArticleListGapBottom}px`),
585
- decl('space-prose-article-list-indent', `${space.step.proseArticleListIndent}px`),
586
- decl('space-prose-article-h1-gap-top', `${space.step.proseArticleH1GapTop}px`),
587
- decl('space-prose-article-h1-gap-bottom', `${space.step.proseArticleH1GapBottom}px`),
588
- decl('space-prose-article-heading-gap-top', `${space.step.proseArticleHeadingGapTop}px`),
589
- decl('space-prose-article-heading-gap-bottom', `${space.step.proseArticleHeadingGapBottom}px`),
590
- decl('space-prose-article-h2-rule-gap', `${space.step.proseArticleH2RuleGap}px`),
591
- decl('space-prose-article-block-gap', `${space.step.proseArticleBlockGap}px`),
592
- decl('space-article-column-gap', `${space.step.articleColumnGap}px`),
593
- decl('space-article-toc-rail-width', `${space.step.articleTocRailWidth}px`),
594
- decl('space-article-header-gap', `${space.step.articleHeaderGap}px`),
595
- decl('space-article-header-padding-bottom', `${space.step.articleHeaderPaddingBottom}px`),
596
- decl('space-article-header-margin-bottom', `${space.step.articleHeaderMarginBottom}px`),
597
- decl('space-article-meta-row-gap', `${space.step.articleMetaRowGap}px`),
598
- decl('space-article-footer-gap', `${space.step.articleFooterGap}px`),
599
- decl('space-article-footer-margin-top', `${space.step.articleFooterMarginTop}px`),
600
- decl('space-article-footer-padding-top', `${space.step.articleFooterPaddingTop}px`),
601
- decl('space-article-nav-target-gap', `${space.step.articleNavTargetGap}px`),
602
- decl('space-code-block-header-gap', `${space.step.codeBlockHeaderGap}px`),
603
- decl('space-code-block-header-inset-y', `${space.step.codeBlockHeaderInsetY}px`),
604
- decl('space-code-block-header-inset-right', `${space.step.codeBlockHeaderInsetRight}px`),
605
- decl('space-code-block-content-inset-x', `${space.step.codeBlockContentInsetX}px`),
606
- decl('space-code-block-header-right-gap', `${space.step.codeBlockHeaderRightGap}px`),
607
- decl('space-code-block-body-inset-y', `${space.step.codeBlockBodyInsetY}px`),
608
- decl('space-code-block-floating-copy-offset', `${space.step.codeBlockFloatingCopyOffset}px`),
609
- decl('space-callout-inset-y', `${space.step.calloutInsetY}px`),
610
- decl('space-callout-inset-x', `${space.step.calloutInsetX}px`),
611
- decl('space-callout-title-row-gap', `${space.step.calloutTitleRowGap}px`),
612
- decl('space-toc-root-gap', `${space.step.tocRootGap}px`),
613
- decl('space-toc-link-inset-y', `${space.step.tocLinkInsetY}px`),
614
- decl('space-toc-link-indent', `${space.step.tocLinkIndent}px`),
615
- decl('space-toc-sub-indent', `${space.step.tocSubIndent}px`),
616
- decl('space-article-card-tags-gap', `${space.step.articleCardTagsGap}px`),
617
- decl('space-article-card-tag-inset-y', `${space.step.articleCardTagInsetY}px`),
618
- decl('space-article-card-tag-inset-x', `${space.step.articleCardTagInsetX}px`),
619
- decl('space-article-card-meta-gap-top', `${space.step.articleCardMetaGapTop}px`),
620
- decl('space-guide-body-gap-bottom', `${space.step.guideBodyGapBottom}px`),
621
- decl('space-guide-footer-gap-top', `${space.step.guideFooterGapTop}px`),
622
- decl('space-guide-footer-inset-top', `${space.step.guideFooterInsetTop}px`),
623
- decl('space-sidebar-search-gap', `${space.step.sidebarSearchGap}px`),
624
- decl('space-sidebar-search-trigger-height', `${space.step.sidebarSearchTriggerHeight}px`),
625
- decl('space-settings-row-inset-y', `${space.step.settingsRowInsetY}px`),
626
- decl('space-settings-row-gap', `${space.step.settingsRowGap}px`),
627
- decl('space-mermaid-container-inset', `${space.step.mermaidContainerInset}px`),
628
- decl('space-sidebar-brand-inset-x', `${space.step.sidebarBrandInsetX}px`),
629
- decl('space-sidebar-section-gap', `${space.step.sidebarSectionGap}px`),
630
- decl('space-sidebar-account-inset-top', `${space.step.sidebarAccountInsetTop}px`),
631
- decl('space-sidebar-account-inset-x', `${space.step.sidebarAccountInsetX}px`),
632
- decl('space-sidebar-account-inset-bottom', `${space.step.sidebarAccountInsetBottom}px`),
633
- decl('space-sidebar-avatar-size', `${space.step.sidebarAvatarSize}px`),
634
- decl('space-sidebar-section-label-gap', `${space.step.sidebarSectionLabelGap}px`),
635
- decl('space-sidebar-child-list-gap-top', `${space.step.sidebarChildListGapTop}px`),
636
- decl('space-sidebar-child-list-gap-bottom', `${space.step.sidebarChildListGapBottom}px`),
637
- decl('space-sidebar-child-list-indent', `${space.step.sidebarChildListIndent}px`),
638
- decl('space-sidebar-child-row-inset-y', `${space.step.sidebarChildRowInsetY}px`),
639
- decl('space-sidebar-child-row-indent', `${space.step.sidebarChildRowIndent}px`),
640
- // The page gutter — the ONE `appShell*` dimension that IS emitted, against the JS-number-only
641
- // rule its five neighbours follow (see the note at the bottom of this list). It earns the
642
- // exception because it is the most visible spacing number the framework ships — every page's
643
- // left edge — and it was, until now, the one number the `--vx-*` layer did not expose at all, so
644
- // a consumer retuning its identity through `createBasaltTheme` could not reach it and had to
645
- // reach past the token layer into `AppShell.Main`'s own styles. Emitted in PLAIN PX, like every
646
- // other inset/gap in this list and unlike the `pxRem` heights above it: the rem-plus-
647
- // `var(--mantine-scale)` reconstruction exists so a CONTROL's box tracks the root font size and
648
- // Mantine's global scale knob; a page gutter is a layout margin against a viewport, not a box
649
- // sized to text, so scaling it with the font would make a large-type user's content column
650
- // narrower rather than more legible.
651
- decl('space-app-shell-inset', `${space.step.appShellInset}px`),
652
- decl('space-app-shell-inset-mobile', `${space.step.appShellInsetMobile}px`),
653
- // The header's breadcrumb floor — emitted for the same reason as the gutter pair above it and
654
- // not for the JS-number reason its `appShell*` neighbours below are withheld for: this one has
655
- // a real CSS consumer (`shell/app-header.module.css`'s `.lead`), which is the whole test this
656
- // list applies. Plain px, like every other layout dimension here.
657
- decl('space-app-shell-header-lead-min', `${space.step.appShellHeaderLeadMin}px`),
658
- decl('space-mobile-nav-tab-gap', `${space.step.mobileNavTabGap}px`),
659
- decl('space-mobile-nav-icon-size', `${space.step.mobileNavIconSize}px`),
660
- decl('space-mobile-nav-tab-inset-y', `${space.step.mobileNavTabInsetY}px`),
661
- decl('space-mobile-nav-tab-inset-x', `${space.step.mobileNavTabInsetX}px`),
662
- decl('space-mobile-nav-row-height', `${space.step.mobileNavRowHeight}px`),
663
- decl('space-agent-rail-inset-x', `${space.step.agentRailInsetX}px`),
664
- decl('space-agent-part-gap-top', `${space.step.agentPartGapTop}px`),
665
- decl('space-agent-code-inset', `${space.step.agentCodeInset}px`),
666
- decl('space-agent-error-inset-y', `${space.step.agentErrorInsetY}px`),
667
- decl('space-agent-error-inset-x', `${space.step.agentErrorInsetX}px`),
668
- decl('space-agent-scroll-button-gap-top', `${space.step.agentScrollButtonGapTop}px`),
669
- decl('space-agent-message-inset-y', `${space.step.agentMessageInsetY}px`),
670
- decl('space-agent-message-inset-x', `${space.step.agentMessageInsetX}px`),
671
- decl('space-agent-transcript-inset', `${space.step.agentTranscriptInset}px`),
672
- decl('space-badge-inset-y', `${space.step.badgeInsetY}px`),
673
- decl('space-badge-inset-x', `${space.step.badgeInsetX}px`),
674
- decl('space-stat-card-gap', `${space.step.statCardGap}px`),
675
- // The card/section inset ladder — the three values `spaceMobileDecls` below re-points at `< sm`
676
- // (see its doc for where the law lives and why it lives there).
677
- decl('space-card-inset-y', `${space.step.cardInsetY}px`),
678
- decl('space-card-inset-x', `${space.step.cardInsetX}px`),
679
- decl('space-section-gap', `${space.step.sectionGap}px`),
680
- decl('space-virtual-row-inset-y', `${space.step.virtualRowInsetY}px`),
681
- decl('space-virtual-row-inset-x', `${space.step.virtualRowInsetX}px`),
682
- // Controls tier row/gap heights (`docs/CONTROLS-SPEC.md` §5) — the current commit's consumers
683
- // are `theme/ctl-theme.tsx` (`--vx-space-control-gap`) and the wave-3/4 homes (`PageBar`,
684
- // `WidgetHeader`, sidebar blocks, the mobile `Filters (n)` sheet) landing next.
685
- decl('space-page-bar-row-height', pxRem(space.step.pageBarRowHeight)),
686
- decl('space-section-header-height', pxRem(space.step.sectionHeaderHeight)),
687
- decl('space-widget-header-height', pxRem(space.step.widgetHeaderHeight)),
688
- decl('space-sidebar-block-row-height', pxRem(space.step.sidebarBlockRowHeight)),
689
- decl('space-control-gap', `${space.step.controlGap}px`),
690
- decl('space-sheet-row-height', pxRem(space.step.sheetRowHeight)),
691
- // `chartLegendGap`/`chartMarginTop`/`chartMarginRight`/`chartMarginBottom`/`chartMarginLeft`/
692
- // `chartDotR`/`progressBarSize`/`timelineBullet` are DELIBERATELY absent — see this function's
693
- // doc for why (JS-number-only consumers, zero `var()` reads). `appShellHeaderHeight`/
694
- // `appShellNavbarWidth`/`appShellNavbarRailWidth`/`appShellAsideWidth`/`appShellAsideRailWidth`
695
- // join that list — but NOT `appShellInset`/`appShellInsetMobile`/`appShellHeaderLeadMin`, which
696
- // are emitted above and carry their own reason for the exception —
697
- // `shell/index.tsx` reads all five as JS numbers via `useBasaltSpacing()` (Mantine's `AppShell`
698
- // `header`/`navbar`/`aside` props take numbers, not `var()` strings), so a `--vx-space-app-shell-*`
699
- // decl here would have had zero consumers, framework-wide, the same dead-weight shape this function's
700
- // doc already calls out for the chart/Progress/Timeline group. `sidebarAccountMenuWidth`/
701
- // `sidebarSettingsMenuWidth` join it too — `app-sidebar-account.tsx`/`app-sidebar.tsx` read both
702
- // as JS numbers via `useBasaltSpacing()` (Mantine's `<Menu width={…}>` also takes a number).
703
- ]
704
- }
705
-
706
- /**
707
- * The `--vx-space-*` names that survive `only: 'core'` — DERIVED from the `SPACE` anchor keys, never
708
- * hand-listed, so a new `SPACE_STEP` one-off is excluded the moment it is added and a renamed anchor
709
- * follows automatically. `SPACE` is the generic ladder (the stack rhythm, the two control heights,
710
- * the row insets); everything else `spaceDecls` emits is named for a basalt COMPONENT and is dead
711
- * weight outside this framework — including `--vx-space-row-line-height`, which is the NavLink row's
712
- * line-height rather than a general anchor and so is (deliberately) in neither set.
713
- */
714
- const CORE_SPACE_VARS = new Set(
715
- Object.keys(SPACE).map((key) => `space-${key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)}`),
716
- )
717
-
718
- /**
719
- * Does this `spaceDecls` line declare a core anchor? The name is read back out of the emitted line
720
- * because {@link decl} is the single formatter for every one of them — the shape is fixed at one
721
- * call site, so parsing it cannot drift, whereas tagging 104 declarations by hand could.
722
- */
723
- function isCoreSpaceDecl(line: string): boolean {
724
- const name = /^ {2}--vx-([\w-]+):/.exec(line)?.[1]
725
- return name !== undefined && CORE_SPACE_VARS.has(name)
726
- }
727
-
728
- /** The shipped, level-0 spacing values — `frameworkDerived`'s `spaceDecls(...)` call below. No
729
- * `createBasaltTheme({ density })` retuning applies here; that path calls `buildDensityCss` with a
730
- * different resolved {@link SpaceValues} instead (see `../theme` and `../provider`). */
731
- const DEFAULT_SPACE_VALUES: SpaceValues = {
732
- anchors: SPACE,
733
- scale: SPACE_SCALE,
734
- step: SPACE_STEP,
735
- rowLineHeight: ROW_LINE_HEIGHT,
736
- }
737
-
738
- /**
739
- * The 16 deprecated camelCase aliases for `frameworkDerived`'s theme-independent (`:root`)
740
- * canonicals — the 12 `fill-hover-<family>` fills plus `good-soft`/`good-ref`/`bad-ref`/`warn-ref`.
741
- * Each is a `var(--vx-<canonical-kebab-name>)` ref so it can never drift. Emitted as its own
742
- * commented, trailing group — gated by {@link BuildPaletteOpts.legacyAliases}, default on.
743
- */
744
- function frameworkDerivedAliases(data: PaletteData): string {
745
- return [
746
- ' /* Deprecated camelCase aliases — removed in a future minor; migrate to the kebab names above. */',
747
- ...Object.keys(data.FILL).map((name) =>
748
- decl(`fillHover-${name}`, `var(--vx-fill-hover-${name})`),
749
- ),
750
- decl('goodSoft', 'var(--vx-good-soft)'),
751
- decl('goodRef', 'var(--vx-good-ref)'),
752
- decl('badRef', 'var(--vx-bad-ref)'),
753
- decl('warnRef', 'var(--vx-warn-ref)'),
754
- ].join('\n')
755
- }
756
-
757
- /**
758
- * Theme-independent scalars + semantic fills, defined once on `:root`.
759
- *
760
- * Area-gradient strength is a global knob (the theme lab overrides these two on `:root`
761
- * to retune every line-area fill live). 0%/0% disables gradients app-wide.
762
- */
763
- function frameworkDerived(data: PaletteData, only: 'core' | 'all', legacyAliases: boolean): string {
764
- const space = spaceDecls(DEFAULT_SPACE_VALUES)
765
- const canonical = [
766
- decl('radius-card', `${RADIUS.card}px`),
767
- decl('radius-ctrl', `${RADIUS.ctrl}px`),
768
- // The two offset tiers (SegmentedControl indicator/Kbd/Code, Progress/scale-sm) — added so a
769
- // component's inline `styles`/`style` can read the SAME source as `RADIUS_STEP.tight`/`.fine`
770
- // instead of a hand-typed literal (see `theme/index.ts`'s component sweep).
771
- decl('radius-tight', `${RADIUS_STEP.tight}px`),
772
- decl('radius-fine', `${RADIUS_STEP.fine}px`),
773
- // The floating tier (Modal/Tooltip/Popover/Notification, content code/mermaid blocks).
774
- decl('radius-floating', `${RADIUS_STEP.floating}px`),
775
- // The pill affordance (scroll-to-bottom button, chips) — fixed, level-invariant, so it lives
776
- // only in this static block, never in `buildRadiusCss`'s dynamic override (see
777
- // `RADIUS_STEP.pill`'s doc).
778
- decl('radius-pill', `${RADIUS_STEP.pill}px`),
779
- // The pointer tier's fine default — density-EXEMPT, so it lives only in this static block
780
- // (same law as `radius-pill` above). `coarseHitBlock` re-points it to 44px.
781
- decl('hit', `${HIT_FINE}px`),
782
- ...(only === 'core' ? space.filter(isCoreSpaceDecl) : space),
783
- // Article-density Prose measure (docs/CONTENT-SPEC.md §5) — theme-independent, like the radii.
784
- decl('prose-measure', '72ch'),
785
- // The fill band (see FILL in palette.ts). Emitted on `:root`, NOT per scheme — a filled surface
786
- // is the same hex in both, which is the whole point: it is squeezed between its white label and
787
- // the page behind it, and only one luminance band satisfies both on both pages.
788
- ...Object.entries(data.FILL).map(([name, hex]) => decl(`fill-${name}`, hex)),
789
- // Hover is DERIVED from the fill, so retuning a fill (in the theme lab, or here) carries its
790
- // hover along instead of leaving a stale pair. 88% of the fill over black lands ~0.128 luminance:
791
- // a visible press-darkening that still clears AA for the white label (~5.9:1).
792
- ...Object.keys(data.FILL).map((name) =>
793
- decl(`fill-hover-${name}`, `color-mix(in srgb, var(--vx-fill-${name}) 88%, #000)`),
794
- ),
795
- // The type scale, emitted from the SAME `TEXT` object `VX.text` reads — CSS modules and the
796
- // Mantine theme consume these; inline styles / visx read the numbers. One ladder, two forms.
797
- ...Object.entries(TEXT).map(([step, px]) => decl(`text-${step}`, `${px}px`)),
798
- decl('area-top', '22%'),
799
- decl('area-bottom', '1%'),
800
- decl('good', 'color-mix(in srgb, var(--vx-good-solid) 18%, transparent)'),
801
- decl('good-soft', 'color-mix(in srgb, var(--vx-good-solid) 8%, transparent)'),
802
- decl('bad', 'color-mix(in srgb, var(--vx-bad-solid) 18%, transparent)'),
803
- decl('warn', 'color-mix(in srgb, var(--vx-warn-solid) 8%, transparent)'),
804
- decl('good-ref', 'color-mix(in srgb, var(--vx-good-solid) 30%, transparent)'),
805
- decl('bad-ref', 'color-mix(in srgb, var(--vx-bad-solid) 30%, transparent)'),
806
- decl('warn-ref', 'color-mix(in srgb, var(--vx-warn-solid) 20%, transparent)'),
807
- ].join('\n')
808
- return legacyAliases ? `${canonical}\n${frameworkDerivedAliases(data)}` : canonical
809
- }
810
-
811
- /**
812
- * Throw on a consumer series/group name inside a basalt-owned `--vx-*` family (`surface`, `space`,
813
- * `ink`, …): `check-theme`'s `unknown-vx-token` judges every name there against what basalt emits,
814
- * which is sound only while no consumer REF points there. Dev builds only (the call sits behind a
815
- * literal NODE_ENV read); `unknown-vx-token` left the grace ledger at 1.36.0, which is when this
816
- * went from a once-per-name warning to a throw. The families are the guard's own generated
817
- * `BASALT_VX_FAMILIES`. Checked on the refs, not in `buildPaletteCss`, which runs on every first
818
- * paint.
819
- */
820
- function assertConsumerVxName(name: string): void {
821
- const family = vxFamilyOf(name)
822
- if (!BASALT_VX_FAMILIES.includes(family)) return
823
- throw new Error(
824
- `[basalt] ${name} is inside basalt's own --vx-${family} family — name your series group something basalt does not own (groupTokens('app', …)).`,
825
- )
826
- }
827
-
828
- /**
829
- * Wrap a map of `{ name: ColorPair }` into `var(--vx-<prefix><name>)` token refs — the runtime
830
- * companion to `buildPaletteCss`. Lets a consumer define its own series and read stable refs.
831
- *
832
- * Returns an exact-keyed object: the return type mirrors the keys of the input map, so a renamed
833
- * or removed key becomes a tsc error rather than silently widening to `Record<string, string>`.
834
- */
835
- export function seriesTokens<const T extends SeriesMap>(
836
- map: T,
837
- prefix = '',
838
- ): { [K in keyof T]: string } {
839
- const out = {} as { [K in keyof T]: string }
840
- for (const key of Object.keys(map) as (keyof T)[]) {
841
- // Literal read at the branch, so a production bundle drops the check (common/dev-gate.test.ts).
842
- if (process.env.NODE_ENV !== 'production') assertConsumerVxName(`--vx-${prefix}${String(key)}`)
843
- out[key] = `var(--vx-${prefix}${String(key)})`
844
- }
845
- return out
846
- }
847
-
848
- /**
849
- * Define a named series map. Identity passthrough — gives consumers a typed authoring entry
850
- * point and preserves the exact literal keys of the input (const-generic so callers get back T,
851
- * not the widened SeriesMap, enabling downstream exact-key checks in groupTokens / seriesTokens).
852
- */
853
- export function defineSeries<const T extends SeriesMap>(map: T): T {
854
- return map
855
- }
856
-
857
- /**
858
- * Build a single namespaced group's token refs (`var(--vx-<name>-<key>)`).
859
- *
860
- * Returns an exact-keyed object matching the keys of `map` — a stale or renamed key is a tsc
861
- * error at the call site rather than a silent `Record<string, string>` widening.
862
- */
863
- export function groupTokens<const T extends SeriesMap>(
864
- name: string,
865
- map: T,
866
- ): { [K in keyof T]: string } {
867
- return seriesTokens(map, `${name}-`)
868
- }
869
-
870
- /**
871
- * The attribute + values the per-scheme blocks key off. Defaults reproduce Mantine's own toggle
872
- * (`data-mantine-color-scheme` = `dark` / `light`), so a consumer only names the axis it differs
873
- * on. Supplying this object at all switches the emitter onto the framework-neutral selector shape
874
- * — see {@link BuildPaletteOpts.scheme}.
875
- */
876
- export type ColorSchemeSelector = {
877
- attribute?: string
878
- darkValue?: string
879
- lightValue?: string
880
- }
881
-
882
- /** Options for {@link buildPaletteCss}. */
883
- export type BuildPaletteOpts = {
884
- /** Extra named series maps to emit under the given prefixes (e.g. `{ '': SERIES, 'activity-': ACTIVITY }`). */
885
- groups?: Record<string, SeriesMap>
886
- /** Theme-independent derived declarations (gradients, semantic fills) emitted once on `:root`. */
887
- derived?: string[]
888
- /**
889
- * Attribute + values the per-scheme blocks key off — for a consumer whose scheme toggle is not
890
- * Mantine's (a static site on `data-theme`, say). Default: Mantine's own
891
- * `data-mantine-color-scheme` = `dark` / `light`.
892
- *
893
- * Setting ANY of `scheme` / `defaultScheme` / `mediaFallback` moves the emitter off the legacy
894
- * `html[…]` selector onto `:root[…]`. That is deliberate and load-bearing, NOT cosmetic:
895
- *
896
- * `:root[data-theme='dark']` 0-2-0 ← what this path emits
897
- * `html[data-theme='dark']` 0-1-1
898
- * `[data-theme='dark']` 0-1-0 ← same as a bare `:root`, so source order decides
899
- *
900
- * A light-default site whose own `:root` block happens to come last would beat the third form
901
- * outright — dark mode silently does nothing. `:root[…]` sits above both a bare `:root` and
902
- * `html[…]`, and carries no assumption about the element the attribute lands on.
903
- *
904
- * The no-options path keeps emitting `html[data-mantine-color-scheme='…']` verbatim, because a
905
- * basalt consumer may already override `--vx-*` under that exact selector — raising basalt's own
906
- * specificity would silently win over their override.
907
- */
908
- scheme?: ColorSchemeSelector
909
- /**
910
- * Which scheme rides along on the bare `:root` block — the one that applies when the attribute
911
- * is absent. Default: `'dark'` (the framework's own default scheme).
912
- *
913
- * `'none'` emits no bare-`:root` primitives at all: each scheme gets only its attribute block,
914
- * and an unattributed document falls back to the theme-independent scalars alone. Pair it with
915
- * `mediaFallback` unless the consumer always sets the attribute.
916
- */
917
- defaultScheme?: 'dark' | 'light' | 'none'
918
- /**
919
- * Also emit an `@media (prefers-color-scheme: …)` block for every scheme that is not the bare
920
- * `:root` default, so a document with no attribute set follows the OS. Default: `false`.
921
- *
922
- * The block is a bare `:root` (0-1-0), so an explicit attribute block (0-2-0) always wins over
923
- * it regardless of source order — the OS preference is a fallback, never an override.
924
- */
925
- mediaFallback?: boolean
926
- /**
927
- * How much of the SPACING set to emit. Default: `'all'` (every one of the 108 `--vx-space-*`
928
- * declarations the framework's own components read).
929
- *
930
- * `'core'` keeps the 9 generic anchors — the stack rhythm, the two control heights, the row
931
- * insets — and drops the 99 named for a specific basalt component
932
- * (`--vx-space-agent-transcript-inset`, `--vx-space-toc-sub-indent`, …), taking the emitted set
933
- * from 204 variables to 105. Nothing outside basalt's own React components reads those, so a
934
- * framework-free consumer is carrying them for nothing.
935
- *
936
- * This is a SPACING filter only: color, radius, shadow, type and status variables are identical
937
- * in both modes. The partition is derived from the `SPACE` key set rather than a maintained list
938
- * — see {@link CORE_SPACE_VARS}.
939
- */
940
- only?: 'core' | 'all'
941
- /**
942
- * Whether to also emit the 32 deprecated camelCase aliases (`--vx-accentFill`, `--vx-tooltipBg`,
943
- * `--vx-fillHover-gray`, …) alongside the canonical kebab-case names the 1.4.0 normalization
944
- * introduced. Default: `true`, so an existing consumer's hand-written CSS referencing a
945
- * camelCase name keeps resolving. Each alias is defined as `var(--vx-<canonical>)` — it can
946
- * never drift from the value it aliases. Pass `false` once every reference in your own code has
947
- * migrated to the kebab names to drop the extra 32 lines.
948
- */
949
- legacyAliases?: boolean
950
- }
951
-
952
- /** Mantine's own color-scheme attribute — the default {@link ColorSchemeSelector.attribute}. */
953
- const MANTINE_SCHEME_ATTRIBUTE = 'data-mantine-color-scheme'
954
-
955
- /** Indent an already-2-space-indented declaration block one level deeper (for `@media` nesting). */
956
- const indent = (block: string): string =>
957
- block
958
- .split('\n')
959
- .map((line) => (line === '' ? line : ` ${line}`))
960
- .join('\n')
961
-
962
- /**
963
- * The `< sm` breakpoint, written the way a stylesheet has to write it — the SAME literal every
964
- * basalt CSS module spells (`shell/app-header.module.css`, `dashboard/section.module.css`, …), and
965
- * for the same reason `BREAKPOINTS` above exists: a `@media` condition is resolved before custom
966
- * properties exist, so the number cannot be a `var()`. Held here as a constant rather than inlined
967
- * so the emitter and the modules can be grepped as one set.
968
- */
969
- const MOBILE_MEDIA = `@media (max-width: ${sizeClassMaxEm(SIZE_CLASSES.medium)})`
970
-
971
- const coarseHitBlock = `@media (pointer: coarse) {\n :root {\n --vx-hit: ${HIT_COARSE}px;\n }\n}`
972
-
973
- /**
974
- * The MOBILE INSET LADDER, and this function is its ONE home — framework-wide, not per module.
975
- *
976
- * The problem it answers: the desktop-shell pass took the page gutter from 20 to 8 below `sm`
977
- * (`appShellInsetMobile`), and the card ladder INSIDE that gutter never moved — card insets stayed
978
- * `xs`/`sm` and a `Section`'s gaps stayed `stackMd` at every width — so a 390px phone still read
979
- * "content spacing too big" after the gutter fix. Two rungs close it: the card's horizontal inset
980
- * steps `sm` -> `xs`, and the Section's gap steps `stackMd` -> `stackSm`.
981
- *
982
- * Why it lives HERE and not in the three CSS files that consume it: two of those three sites are
983
- * INLINE styles in TSX (`dashboard/stat-card.tsx`, `charts/primitives/ChartCard.tsx`), and an
984
- * inline style cannot carry a media query at all. The only surface that reaches all three is a
985
- * custom property whose VALUE moves at the breakpoint, and the only stylesheet guaranteed present
986
- * wherever those components render is this one — `BasaltProvider` injects `buildPaletteCss()`, and
987
- * a component's own CSS module is loaded only if a bundler kept that module. So the law is one
988
- * `@media` block emitted beside the base declarations it overrides, and every consuming site is a
989
- * plain `var()` read with no breakpoint knowledge. A media query copied into three files (or into
990
- * one component stylesheet reaching for `:global(:root)`) was the alternative, and it fails the
991
- * same way twice: three copies drift, and one copy in a tree-shakeable module is a law that
992
- * sometimes does not ship.
993
- *
994
- * This does NOT make the token layer responsive in general. It stays what `BREAKPOINTS`'s doc says
995
- * it is — the layer that owns the NUMBER a media query has to write — and this is the one law whose
996
- * consuming sites cannot write that query themselves. A dimension whose consumer is a CSS module
997
- * keeps making the choice in that module (`appShellInset`/`appShellInsetMobile` still do).
998
- */
999
- function spaceMobileDecls(space: SpaceValues): string[] {
1000
- return [
1001
- decl('space-card-inset-x', `${space.scale.xs}px`),
1002
- decl('space-section-gap', `${space.anchors.stackSm}px`),
1003
- ]
1004
- }
1005
-
1006
- /** {@link spaceMobileDecls} as the `@media` block that overrides the base `:root` declarations —
1007
- * same specificity, later in source order, so it wins below `sm` and nowhere else. */
1008
- function mobileLadderBlock(space: SpaceValues): string {
1009
- return `${MOBILE_MEDIA} {\n :root {\n${indent(spaceMobileDecls(space).join('\n'))}\n }\n}`
1010
- }
1011
-
1012
- /**
1013
- * Emit the `--vx-*` stylesheet: a `:root` block of theme-independent scalars, then the
1014
- * dark (default) and light primitive blocks under `html[data-mantine-color-scheme='…']`.
1015
- *
1016
- * The framework chrome (STATUS/SEMANTIC/SURFACE pairs + the framework DERIVED defaults) is
1017
- * built in, so an empty `buildPaletteCss()` already emits every framework var. Consumer
1018
- * `opts.groups` / `opts.derived` append on top (e.g. argo's domain SERIES/ACTIVITY/USAGE).
1019
- *
1020
- * `data` defaults to the static, shipped palette (`buildPaletteData()` at `DEFAULT_DERIVE_CONFIG`)
1021
- * — pass the result of `buildPaletteData(config)` to emit CSS for a retuned derive config instead
1022
- * (this is how `BasaltProvider` follows `createBasaltTheme`'s `{ derive }` option; see `../theme`
1023
- * and `../provider`).
1024
- *
1025
- * Dark is the default (`:root`) since the framework defaults to dark; the
1026
- * `[data-mantine-color-scheme]` selectors track Mantine's toggle on `<html>`.
1027
- *
1028
- * A non-Mantine consumer retargets all three of those choices — the attribute, which scheme rides
1029
- * the bare `:root`, and whether the OS preference is honoured — via `opts.scheme` /
1030
- * `opts.defaultScheme` / `opts.mediaFallback`. Setting any of them also moves the per-scheme
1031
- * selector from `html[…]` to the framework-neutral, higher-specificity `:root[…]`; see
1032
- * `BuildPaletteOpts.scheme` for why that is not cosmetic. With none of them set the output is
1033
- * byte-identical to what the framework has always emitted (pinned by
1034
- * `tests/palette-css.test.ts`).
1035
- */
1036
- export function buildPaletteCss(
1037
- opts: BuildPaletteOpts = {},
1038
- data: PaletteData = buildPaletteData(),
1039
- ): string {
1040
- const groups = opts.groups ?? {}
1041
- const legacyAliases = opts.legacyAliases ?? true
1042
- const only = opts.only ?? 'all'
1043
- const extraDerived = (opts.derived ?? []).map((d) => ` ${d}`).join('\n')
1044
- const derivedBlock = frameworkDerived(data, only, legacyAliases)
1045
- const derived = extraDerived ? `${derivedBlock}\n${extraDerived}` : derivedBlock
1046
- const side = (s: Side): string => {
1047
- const extra = Object.entries(groups)
1048
- .map(([prefix, map]) => groupSide(prefix, map, s))
1049
- .join('\n')
1050
- const framework = frameworkPrimitives(s, data, legacyAliases)
1051
- return extra ? `${framework}\n${extra}` : framework
1052
- }
1053
- // The scalars, then the ONE `@media` block that re-points two of them below `sm` (see
1054
- // `spaceMobileDecls`). Dropped under `only: 'core'` for the same reason the declarations it
1055
- // overrides are: both vars are component-named one-offs, not `SPACE` anchors, so a core-only
1056
- // consumer never receives the base pair the block exists to override.
1057
- const rootBlock =
1058
- only === 'core'
1059
- ? `:root {\n${derived}\n}\n${coarseHitBlock}`
1060
- : `:root {\n${derived}\n}\n${mobileLadderBlock(DEFAULT_SPACE_VALUES)}\n${coarseHitBlock}`
1061
-
1062
- // The legacy shape — kept verbatim, and only reachable when the caller asked for nothing.
1063
- if (opts.scheme === undefined && opts.defaultScheme === undefined && !opts.mediaFallback) {
1064
- return `${rootBlock}
1065
- :root,
1066
- html[data-mantine-color-scheme='dark'] {
1067
- ${side('dark')}
1068
- }
1069
- html[data-mantine-color-scheme='light'] {
1070
- ${side('light')}
1071
- }`
1072
- }
1073
-
1074
- const attribute = opts.scheme?.attribute ?? MANTINE_SCHEME_ATTRIBUTE
1075
- const value: Record<Side, string> = {
1076
- dark: opts.scheme?.darkValue ?? 'dark',
1077
- light: opts.scheme?.lightValue ?? 'light',
1078
- }
1079
- const defaultScheme = opts.defaultScheme ?? 'dark'
1080
- // Default scheme first, so its attribute block can absorb the bare `:root` instead of repeating
1081
- // ~40 declarations; `'none'` keeps the framework's dark-then-light order.
1082
- const order: Side[] = defaultScheme === 'light' ? ['light', 'dark'] : ['dark', 'light']
1083
-
1084
- const blocks = [rootBlock]
1085
- for (const s of order) {
1086
- const selector =
1087
- s === defaultScheme
1088
- ? `:root,\n:root[${attribute}='${value[s]}']`
1089
- : `:root[${attribute}='${value[s]}']`
1090
- // The OS fallback for a scheme goes immediately before that scheme's own attribute block. It is
1091
- // a bare `:root` (0-1-0), so the attribute block (0-2-0) outranks it on specificity rather than
1092
- // on order — an explicit toggle always beats the OS preference, and the OS preference always
1093
- // beats the hardcoded default that a bare `:root` above it carries.
1094
- if (opts.mediaFallback === true && s !== defaultScheme) {
1095
- blocks.push(`@media (prefers-color-scheme: ${s}) {\n :root {\n${indent(side(s))}\n }\n}`)
1096
- }
1097
- blocks.push(`${selector} {\n${side(s)}\n}`)
1098
- }
1099
- return blocks.join('\n')
1100
- }
1101
-
1102
- /**
1103
- * The `fonts` option's resolved shape — a full CSS font-family stack string per slot (with its own
1104
- * fallback chain), riding the `--basalt-font-sans/head/mono` override seam `styles.css` ships
1105
- * fallbacks for. Omitted keys keep the shipped fallback untouched. Lives here (not in `../theme`,
1106
- * which only RE-EXPORTS it) because its builder `buildFontsCss` below is a pure, Mantine-free
1107
- * string builder that belongs in the tokens layer — see `../theme`'s
1108
- * `CreateBasaltThemeOptions.fonts` for the production entry point that sets it.
1109
- */
1110
- export type BasaltFontsConfig = {
1111
- sans?: string
1112
- head?: string
1113
- mono?: string
1114
- }
1115
-
1116
- /** `{ basaltFonts key → --basalt-font-* var name }` — the one place the mapping is spelled out. */
1117
- const FONT_VAR_NAMES = {
1118
- sans: '--basalt-font-sans',
1119
- head: '--basalt-font-head',
1120
- mono: '--basalt-font-mono',
1121
- } as const satisfies Record<keyof BasaltFontsConfig, string>
1122
-
1123
- /**
1124
- * Build the `:root` block of `--basalt-font-*` declarations for a resolved `basaltFonts` config —
1125
- * only for the keys the consumer actually set (`createBasaltTheme(overrides, { fonts })`); an
1126
- * omitted key keeps the shipped `styles.css` fallback chain untouched. Empty string when `fonts` is
1127
- * absent or every key is omitted, so callers can unconditionally concatenate the result. Importable
1128
- * from `basalt-ui/tokens` — `BasaltProvider`'s bridge (`../provider`) calls this directly to append
1129
- * declarations to its injected `<style>`; an SSR/custom-injection consumer with
1130
- * `injectPalette={false}` calls it themselves (see the JSDoc on that prop).
1131
- */
1132
- export function buildFontsCss(fonts: BasaltFontsConfig | undefined): string {
1133
- if (!fonts) return ''
1134
- const decls = (Object.keys(FONT_VAR_NAMES) as (keyof BasaltFontsConfig)[])
1135
- .filter((key) => fonts[key] !== undefined)
1136
- .map((key) => {
1137
- const value = fonts[key] as string
1138
- // A font stack is a plain declaration value — `{`/`}`/`;`/comment openers would let a
1139
- // config string break out of the emitted `<style>` declaration. Throw, don't sanitize,
1140
- // per the repo's validation convention (see `deriveTokens`'s accent-hex assert).
1141
- if (/[{};]|\/\*/.test(value)) {
1142
- throw new Error(
1143
- `Invalid fonts.${key}: a font-family stack must not contain "{", "}", ";" or "/*" — got ${JSON.stringify(value)}`,
1144
- )
1145
- }
1146
- return ` ${FONT_VAR_NAMES[key]}: ${value};`
1147
- })
1148
- if (decls.length === 0) return ''
1149
- return `:root {\n${decls.join('\n')}\n}`
1150
- }
1151
-
1152
- /**
1153
- * Build the `:root` block of overriding `--vx-radius-*` declarations for a resolved
1154
- * `basaltRadius` value (`createBasaltTheme(overrides, { radius })`) — analog of {@link buildFontsCss}.
1155
- * Empty string when `radius` is absent (the default level-0 path never sets `theme.other.basaltRadius`
1156
- * in the first place), so callers can unconditionally concatenate the result. Importable from
1157
- * `basalt-ui/tokens`, same SSR/custom-injection use as `buildFontsCss` above.
1158
- */
1159
- export function buildRadiusCss(radius: RadiusValues | undefined): string {
1160
- if (!radius) return ''
1161
- return `:root {
1162
- --vx-radius-card: ${radius.card}px;
1163
- --vx-radius-ctrl: ${radius.ctrl}px;
1164
- --vx-radius-tight: ${radius.tight}px;
1165
- --vx-radius-fine: ${radius.fine}px;
1166
- --vx-radius-floating: ${radius.floating}px;
1167
- }`
1168
- }
1169
-
1170
- /**
1171
- * Build the `:root` block of overriding `--vx-space-*` declarations for a resolved `basaltDensity`
1172
- * value (`createBasaltTheme(overrides, { density })`) — analog of {@link buildRadiusCss}, reusing
1173
- * the SAME `spaceDecls` list `frameworkDerived` emits the shipped defaults from (so the two can
1174
- * never drift). Empty string when `space` is absent (the default level-0 path never sets
1175
- * `theme.other.basaltDensity` in the first place), so callers can unconditionally concatenate the
1176
- * result. Importable from `basalt-ui/tokens`, same SSR/custom-injection use as `buildRadiusCss`
1177
- * above.
1178
- */
1179
- export function buildDensityCss(space: SpaceValues | undefined): string {
1180
- if (!space) return ''
1181
- // The `< sm` ladder rides along, at the retuned level — without it a phone at `density: 2` would
1182
- // take the level-0 mobile inset from the static stylesheet and the level-2 base from this one,
1183
- // which is the only way the two rungs of one ladder could ever come from different levels.
1184
- return `:root {\n${spaceDecls(space).join('\n')}\n}\n${mobileLadderBlock(space)}`
1185
- }
9
+ alpha,
10
+ buildPaletteCss,
11
+ defineSeries,
12
+ groupTokens,
13
+ seriesTokens,
14
+ VX,
15
+ type ColorPair,
16
+ type SeriesGroup,
17
+ type SeriesMap,
18
+ } from './core'