basalt-ui 1.25.0 → 1.27.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 (476) hide show
  1. package/AGENTS.md +8 -6
  2. package/CHANGELOG.md +26 -0
  3. package/MIGRATING.md +815 -23
  4. package/README.md +45 -32
  5. package/agent/rules/basalt-batteries.md +205 -0
  6. package/agent/rules/basalt-charts.md +125 -555
  7. package/agent/rules/basalt-controls.md +160 -0
  8. package/agent/rules/basalt-mantine.md +146 -439
  9. package/agent/rules/basalt-state.md +118 -96
  10. package/agent/rules/basalt-tokens.md +126 -288
  11. package/agent/skills/basalt-app/SKILL.md +70 -195
  12. package/agent/skills/basalt-charts/SKILL.md +54 -234
  13. package/agent/skills/basalt-design/SKILL.md +56 -248
  14. package/agent/templates/CLAUDE-block.md.tpl +31 -40
  15. package/agent/templates/DESIGN.md.tpl +22 -51
  16. package/configs/oxlint-plugin.js +1465 -36
  17. package/configs/oxlint-plugin.test.ts +1190 -11
  18. package/configs/oxlint.json +11 -3
  19. package/dist/charts/cursor/resolve.d.ts +18 -0
  20. package/dist/charts/cursor/resolve.d.ts.map +1 -1
  21. package/dist/charts/cursor/resolve.js +15 -6
  22. package/dist/charts/cursor/scope.d.ts +6 -3
  23. package/dist/charts/cursor/scope.d.ts.map +1 -1
  24. package/dist/charts/cursor/store.d.ts +5 -1
  25. package/dist/charts/cursor/store.d.ts.map +1 -1
  26. package/dist/charts/cursor/store.js +4 -4
  27. package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
  28. package/dist/charts/hooks/useChartCursor.js +9 -8
  29. package/dist/charts/index.d.ts +2 -2
  30. package/dist/charts/index.d.ts.map +1 -1
  31. package/dist/charts/primitives/ChartCard.d.ts +34 -9
  32. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  33. package/dist/charts/primitives/ChartCard.js +29 -114
  34. package/dist/charts/primitives/ChartCard.test.d.ts +2 -0
  35. package/dist/charts/primitives/ChartCard.test.d.ts.map +1 -0
  36. package/dist/charts/sparklines/BarSparkline.d.ts +26 -2
  37. package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
  38. package/dist/charts/sparklines/BarSparkline.js +18 -4
  39. package/dist/cli/check-coverage.test.d.ts +2 -0
  40. package/dist/cli/check-coverage.test.d.ts.map +1 -0
  41. package/dist/cli/index.d.ts +67 -4
  42. package/dist/cli/index.d.ts.map +1 -1
  43. package/dist/cli/index.js +225 -7
  44. package/dist/connectivity/connectivity-indicator.d.ts +4 -1
  45. package/dist/connectivity/connectivity-indicator.d.ts.map +1 -1
  46. package/dist/connectivity/connectivity-indicator.js +1 -1
  47. package/dist/content/index.d.ts +5 -3
  48. package/dist/content/index.d.ts.map +1 -1
  49. package/dist/content/index.js +4 -2
  50. package/dist/content/prose.module.css +7 -28
  51. package/dist/controls/actions.d.ts +169 -0
  52. package/dist/controls/actions.d.ts.map +1 -0
  53. package/dist/controls/actions.js +287 -0
  54. package/dist/controls/actions.module.css +62 -0
  55. package/dist/controls/actions.module.css.d.ts +13 -0
  56. package/dist/controls/actions.test.d.ts +2 -0
  57. package/dist/controls/actions.test.d.ts.map +1 -0
  58. package/dist/controls/actions.type-guard.test.d.ts +2 -0
  59. package/dist/controls/actions.type-guard.test.d.ts.map +1 -0
  60. package/dist/controls/compare-filter.d.ts +41 -0
  61. package/dist/controls/compare-filter.d.ts.map +1 -0
  62. package/dist/controls/compare-filter.js +23 -0
  63. package/dist/controls/control-group.d.ts +19 -0
  64. package/dist/controls/control-group.d.ts.map +1 -0
  65. package/dist/controls/control-group.js +20 -0
  66. package/dist/controls/control-group.test.d.ts +2 -0
  67. package/dist/controls/control-group.test.d.ts.map +1 -0
  68. package/dist/controls/controls.module.css +542 -0
  69. package/dist/controls/controls.module.css.d.ts +35 -0
  70. package/dist/controls/controls.router.test.d.ts +2 -0
  71. package/dist/controls/controls.router.test.d.ts.map +1 -0
  72. package/dist/controls/enum-filter.d.ts +39 -0
  73. package/dist/controls/enum-filter.d.ts.map +1 -0
  74. package/dist/controls/enum-filter.js +93 -0
  75. package/dist/controls/filter-context.d.ts +60 -0
  76. package/dist/controls/filter-context.d.ts.map +1 -0
  77. package/dist/controls/filter-context.js +69 -0
  78. package/dist/controls/filter-pill.d.ts +28 -0
  79. package/dist/controls/filter-pill.d.ts.map +1 -0
  80. package/dist/controls/filter-pill.js +70 -0
  81. package/dist/controls/filter-set.d.ts +13 -0
  82. package/dist/controls/filter-set.d.ts.map +1 -0
  83. package/dist/controls/filter-set.js +125 -0
  84. package/dist/controls/filter-set.test.d.ts +2 -0
  85. package/dist/controls/filter-set.test.d.ts.map +1 -0
  86. package/dist/controls/filter-sheet.d.ts +117 -0
  87. package/dist/controls/filter-sheet.d.ts.map +1 -0
  88. package/dist/controls/filter-sheet.js +146 -0
  89. package/dist/controls/glyphs.d.ts +27 -0
  90. package/dist/controls/glyphs.d.ts.map +1 -0
  91. package/dist/controls/glyphs.js +49 -0
  92. package/dist/controls/index.d.ts +20 -0
  93. package/dist/controls/index.d.ts.map +1 -0
  94. package/dist/controls/index.js +46 -0
  95. package/dist/controls/multi-select-filter.d.ts +23 -0
  96. package/dist/controls/multi-select-filter.d.ts.map +1 -0
  97. package/dist/controls/multi-select-filter.js +89 -0
  98. package/dist/controls/number-filter.d.ts +26 -0
  99. package/dist/controls/number-filter.d.ts.map +1 -0
  100. package/dist/controls/number-filter.js +143 -0
  101. package/dist/controls/peer-boundary.test.d.ts +2 -0
  102. package/dist/controls/peer-boundary.test.d.ts.map +1 -0
  103. package/dist/controls/props-contract.test.d.ts +2 -0
  104. package/dist/controls/props-contract.test.d.ts.map +1 -0
  105. package/dist/controls/range-filter.d.ts +43 -0
  106. package/dist/controls/range-filter.d.ts.map +1 -0
  107. package/dist/controls/range-filter.js +135 -0
  108. package/dist/controls/range-filter.type-guard.test.d.ts +2 -0
  109. package/dist/controls/range-filter.type-guard.test.d.ts.map +1 -0
  110. package/dist/controls/search-filter.d.ts +10 -0
  111. package/dist/controls/search-filter.d.ts.map +1 -0
  112. package/dist/controls/search-filter.js +81 -0
  113. package/dist/controls/select-filter.d.ts +74 -0
  114. package/dist/controls/select-filter.d.ts.map +1 -0
  115. package/dist/controls/select-filter.js +10 -0
  116. package/dist/controls/sync-button.d.ts +38 -0
  117. package/dist/controls/sync-button.d.ts.map +1 -0
  118. package/dist/controls/sync-button.js +119 -0
  119. package/dist/controls/sync-button.module.css +63 -0
  120. package/dist/controls/sync-button.module.css.d.ts +11 -0
  121. package/dist/controls/sync-button.test.d.ts +2 -0
  122. package/dist/controls/sync-button.test.d.ts.map +1 -0
  123. package/dist/controls/toggle-filter.d.ts +9 -0
  124. package/dist/controls/toggle-filter.d.ts.map +1 -0
  125. package/dist/controls/toggle-filter.js +42 -0
  126. package/dist/controls/view-tabs.d.ts +23 -0
  127. package/dist/controls/view-tabs.d.ts.map +1 -0
  128. package/dist/controls/view-tabs.js +59 -0
  129. package/dist/controls-dates/date-range-picker.d.ts +4 -0
  130. package/dist/controls-dates/date-range-picker.d.ts.map +1 -0
  131. package/dist/controls-dates/date-range-picker.js +18 -0
  132. package/dist/controls-dates/index.d.ts +9 -0
  133. package/dist/controls-dates/index.d.ts.map +1 -0
  134. package/dist/controls-dates/index.js +4 -0
  135. package/dist/dashboard/delta-badge.d.ts +6 -12
  136. package/dist/dashboard/delta-badge.d.ts.map +1 -1
  137. package/dist/dashboard/delta-badge.js +1 -50
  138. package/dist/dashboard/index.d.ts +1 -1
  139. package/dist/dashboard/index.d.ts.map +1 -1
  140. package/dist/dashboard/index.js +3 -1
  141. package/dist/dashboard/settings-section.d.ts +6 -4
  142. package/dist/dashboard/settings-section.d.ts.map +1 -1
  143. package/dist/dashboard/settings-section.js +23 -16
  144. package/dist/dashboard/settings-section.module.css +10 -0
  145. package/dist/dashboard/settings-section.module.css.d.ts +1 -0
  146. package/dist/dashboard/settings-section.test.d.ts +2 -0
  147. package/dist/dashboard/settings-section.test.d.ts.map +1 -0
  148. package/dist/dashboard/stat-card.d.ts +95 -9
  149. package/dist/dashboard/stat-card.d.ts.map +1 -1
  150. package/dist/dashboard/stat-card.js +108 -49
  151. package/dist/dashboard/stat-card.module.css +153 -0
  152. package/dist/dashboard/stat-card.module.css.d.ts +15 -0
  153. package/dist/data/data-table.d.ts +37 -15
  154. package/dist/data/data-table.d.ts.map +1 -1
  155. package/dist/data/data-table.js +96 -58
  156. package/dist/guard/grace.test.d.ts +20 -0
  157. package/dist/guard/grace.test.d.ts.map +1 -0
  158. package/dist/guard/index.d.ts +66 -3
  159. package/dist/guard/index.d.ts.map +1 -1
  160. package/dist/guard/index.js +78 -7
  161. package/dist/guard/types.d.ts +3 -3
  162. package/dist/guard/types.d.ts.map +1 -1
  163. package/dist/index.d.ts +13 -3
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +13 -10
  166. package/dist/nav/types.d.ts +78 -2
  167. package/dist/nav/types.d.ts.map +1 -1
  168. package/dist/notifications/bell.d.ts +4 -1
  169. package/dist/notifications/bell.d.ts.map +1 -1
  170. package/dist/notifications/index.d.ts +1 -1
  171. package/dist/router-tanstack/field.d.ts +14 -0
  172. package/dist/router-tanstack/field.d.ts.map +1 -0
  173. package/dist/router-tanstack/field.js +4 -0
  174. package/dist/router-tanstack/index.d.ts +6 -2
  175. package/dist/router-tanstack/index.d.ts.map +1 -1
  176. package/dist/router-tanstack/index.js +4 -0
  177. package/dist/router-tanstack/multi-search-param-store.d.ts +4 -52
  178. package/dist/router-tanstack/multi-search-param-store.d.ts.map +1 -1
  179. package/dist/router-tanstack/multi-search-param-store.js +19 -27
  180. package/dist/router-tanstack/search-param-store.d.ts +3 -87
  181. package/dist/router-tanstack/search-param-store.d.ts.map +1 -1
  182. package/dist/router-tanstack/search-param-store.js +16 -45
  183. package/dist/router-tanstack/search-store.d.ts +84 -0
  184. package/dist/router-tanstack/search-store.d.ts.map +1 -0
  185. package/dist/router-tanstack/search-store.js +271 -0
  186. package/dist/router-tanstack/search-store.router.test.d.ts +2 -0
  187. package/dist/router-tanstack/search-store.router.test.d.ts.map +1 -0
  188. package/dist/router-tanstack/search-store.test.d.ts +2 -0
  189. package/dist/router-tanstack/search-store.test.d.ts.map +1 -0
  190. package/dist/router-tanstack/use-nav.d.ts +0 -2
  191. package/dist/router-tanstack/use-nav.d.ts.map +1 -1
  192. package/dist/router-tanstack/use-nav.js +34 -12
  193. package/dist/router-tanstack/use-nav.test.d.ts +2 -0
  194. package/dist/router-tanstack/use-nav.test.d.ts.map +1 -0
  195. package/dist/section/index.d.ts +2 -0
  196. package/dist/section/index.d.ts.map +1 -0
  197. package/dist/section/index.js +4 -0
  198. package/dist/section/section.d.ts +24 -0
  199. package/dist/section/section.d.ts.map +1 -0
  200. package/dist/section/section.js +126 -0
  201. package/dist/section/section.module.css +104 -0
  202. package/dist/section/section.module.css.d.ts +11 -0
  203. package/dist/section/section.test.d.ts +2 -0
  204. package/dist/section/section.test.d.ts.map +1 -0
  205. package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
  206. package/dist/shell/app-breadcrumbs.js +18 -15
  207. package/dist/shell/app-header.module.css +77 -37
  208. package/dist/shell/app-header.module.css.d.ts +2 -1
  209. package/dist/shell/app-mobile-nav.d.ts +9 -2
  210. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  211. package/dist/shell/app-mobile-nav.js +98 -11
  212. package/dist/shell/app-mobile-nav.module.css +8 -0
  213. package/dist/shell/app-mobile-nav.module.css.d.ts +1 -0
  214. package/dist/shell/app-sidebar.d.ts +55 -28
  215. package/dist/shell/app-sidebar.d.ts.map +1 -1
  216. package/dist/shell/app-sidebar.js +116 -67
  217. package/dist/shell/app-sidebar.module.css +303 -20
  218. package/dist/shell/app-sidebar.module.css.d.ts +19 -1
  219. package/dist/shell/index.d.ts +55 -21
  220. package/dist/shell/index.d.ts.map +1 -1
  221. package/dist/shell/index.js +40 -18
  222. package/dist/shell/mobile-nav-model.d.ts +13 -2
  223. package/dist/shell/mobile-nav-model.d.ts.map +1 -1
  224. package/dist/shell/mobile-nav-model.js +15 -1
  225. package/dist/shell/nav-count-badge.d.ts +1 -1
  226. package/dist/shell/page-bar.d.ts +51 -0
  227. package/dist/shell/page-bar.d.ts.map +1 -0
  228. package/dist/shell/page-bar.js +154 -0
  229. package/dist/shell/page-bar.module.css +178 -0
  230. package/dist/shell/page-bar.module.css.d.ts +17 -0
  231. package/dist/shell/page-bar.test.d.ts +2 -0
  232. package/dist/shell/page-bar.test.d.ts.map +1 -0
  233. package/dist/shell/sidebar-block-model.d.ts +48 -0
  234. package/dist/shell/sidebar-block-model.d.ts.map +1 -0
  235. package/dist/shell/sidebar-block-model.js +39 -0
  236. package/dist/shell/sidebar-blocks.d.ts +32 -0
  237. package/dist/shell/sidebar-blocks.d.ts.map +1 -0
  238. package/dist/shell/sidebar-blocks.js +169 -0
  239. package/dist/shell/sidebar-search.d.ts +13 -1
  240. package/dist/shell/sidebar-search.d.ts.map +1 -1
  241. package/dist/shell/sidebar-search.js +34 -1
  242. package/dist/shell/sidebar-search.module.css +26 -0
  243. package/dist/shell/sidebar-search.module.css.d.ts +2 -0
  244. package/dist/state/fields.d.ts +565 -0
  245. package/dist/state/fields.d.ts.map +1 -0
  246. package/dist/state/fields.js +405 -0
  247. package/dist/state/fields.test.d.ts +2 -0
  248. package/dist/state/fields.test.d.ts.map +1 -0
  249. package/dist/state/persisted.d.ts +60 -0
  250. package/dist/state/persisted.d.ts.map +1 -0
  251. package/dist/state/persisted.js +123 -0
  252. package/dist/state/persisted.test.d.ts +2 -0
  253. package/dist/state/persisted.test.d.ts.map +1 -0
  254. package/dist/state.d.ts +11 -56
  255. package/dist/state.d.ts.map +1 -1
  256. package/dist/state.js +14 -120
  257. package/dist/styles.css +13 -0
  258. package/dist/surfaces.d.ts +106 -24
  259. package/dist/surfaces.d.ts.map +1 -1
  260. package/dist/surfaces.js +156 -19
  261. package/dist/theme/controls.module.css +16 -1
  262. package/dist/theme/ctl-theme.d.ts +32 -0
  263. package/dist/theme/ctl-theme.d.ts.map +1 -0
  264. package/dist/theme/ctl-theme.js +54 -0
  265. package/dist/theme/ctl-theme.test.d.ts +2 -0
  266. package/dist/theme/ctl-theme.test.d.ts.map +1 -0
  267. package/dist/theme/ctl-tier-coverage.test.d.ts +2 -0
  268. package/dist/theme/ctl-tier-coverage.test.d.ts.map +1 -0
  269. package/dist/theme/divider-law.test.d.ts +2 -0
  270. package/dist/theme/divider-law.test.d.ts.map +1 -0
  271. package/dist/theme/icon-slot.d.ts +44 -0
  272. package/dist/theme/icon-slot.d.ts.map +1 -0
  273. package/dist/theme/icon-slot.js +21 -0
  274. package/dist/theme/icon-slot.module.css +47 -0
  275. package/dist/theme/icon-slot.module.css.d.ts +8 -0
  276. package/dist/theme/icon-slot.test.d.ts +2 -0
  277. package/dist/theme/icon-slot.test.d.ts.map +1 -0
  278. package/dist/theme/index.d.ts +1 -0
  279. package/dist/theme/index.d.ts.map +1 -1
  280. package/dist/theme/index.js +82 -5
  281. package/dist/theme/layout-rhythm-css.test.d.ts +2 -0
  282. package/dist/theme/layout-rhythm-css.test.d.ts.map +1 -0
  283. package/dist/theme/segmented-control.module.css +20 -0
  284. package/dist/theme/shadow-surfaces.test.d.ts.map +1 -1
  285. package/dist/tokens/index.d.ts +12 -0
  286. package/dist/tokens/index.d.ts.map +1 -1
  287. package/dist/tokens/index.js +38 -8
  288. package/dist/tokens/palette.d.ts +97 -61
  289. package/dist/tokens/palette.d.ts.map +1 -1
  290. package/dist/tokens/palette.js +76 -38
  291. package/dist/tokens.css +10 -2
  292. package/dist/widget-header/delta-badge.d.ts +13 -0
  293. package/dist/widget-header/delta-badge.d.ts.map +1 -0
  294. package/dist/widget-header/delta-badge.js +29 -0
  295. package/dist/widget-header/delta-badge.test.d.ts +2 -0
  296. package/dist/widget-header/delta-badge.test.d.ts.map +1 -0
  297. package/dist/widget-header/index.d.ts +3 -0
  298. package/dist/widget-header/index.d.ts.map +1 -0
  299. package/dist/widget-header/index.js +6 -0
  300. package/dist/widget-header/no-mantine.test.d.ts +2 -0
  301. package/dist/widget-header/no-mantine.test.d.ts.map +1 -0
  302. package/dist/widget-header/widget-header.d.ts +67 -0
  303. package/dist/widget-header/widget-header.d.ts.map +1 -0
  304. package/dist/widget-header/widget-header.js +89 -0
  305. package/dist/widget-header/widget-header.module.css +350 -0
  306. package/dist/widget-header/widget-header.module.css.d.ts +25 -0
  307. package/dist/widget-header/widget-header.test.d.ts +2 -0
  308. package/dist/widget-header/widget-header.test.d.ts.map +1 -0
  309. package/llms.txt +30 -17
  310. package/package.json +14 -1
  311. package/src/charts/cursor/resolve.test.ts +29 -1
  312. package/src/charts/cursor/resolve.ts +38 -6
  313. package/src/charts/cursor/scope.tsx +6 -3
  314. package/src/charts/cursor/store.test.ts +19 -1
  315. package/src/charts/cursor/store.ts +10 -5
  316. package/src/charts/hooks/useChartCursor.ts +16 -8
  317. package/src/charts/index.ts +2 -2
  318. package/src/charts/primitives/CartesianChart.test.tsx +124 -0
  319. package/src/charts/primitives/ChartCard.test.tsx +66 -0
  320. package/src/charts/primitives/ChartCard.tsx +86 -146
  321. package/src/charts/sparklines/BarSparkline.tsx +43 -5
  322. package/src/cli/check-coverage.test.ts +297 -0
  323. package/src/cli/check-theme.test.ts +38 -14
  324. package/src/cli/index.ts +392 -16
  325. package/src/cli/init-sync.test.ts +97 -0
  326. package/src/connectivity/connectivity-indicator.tsx +16 -9
  327. package/src/content/index.ts +16 -3
  328. package/src/content/prose.module.css +7 -28
  329. package/src/content/prose.module.css.test.ts +8 -24
  330. package/src/controls/actions.module.css +62 -0
  331. package/src/controls/actions.module.css.d.ts +13 -0
  332. package/src/controls/actions.test.tsx +252 -0
  333. package/src/controls/actions.tsx +655 -0
  334. package/src/controls/actions.type-guard.test.ts +63 -0
  335. package/src/controls/compare-filter.tsx +64 -0
  336. package/src/controls/control-group.test.tsx +229 -0
  337. package/src/controls/control-group.tsx +63 -0
  338. package/src/controls/controls.module.css +542 -0
  339. package/src/controls/controls.module.css.d.ts +35 -0
  340. package/src/controls/controls.router.test.tsx +1053 -0
  341. package/src/controls/enum-filter.tsx +170 -0
  342. package/src/controls/filter-context.tsx +158 -0
  343. package/src/controls/filter-pill.tsx +120 -0
  344. package/src/controls/filter-set.test.tsx +472 -0
  345. package/src/controls/filter-set.tsx +225 -0
  346. package/src/controls/filter-sheet.tsx +285 -0
  347. package/src/controls/glyphs.tsx +81 -0
  348. package/src/controls/index.ts +49 -0
  349. package/src/controls/multi-select-filter.tsx +140 -0
  350. package/src/controls/number-filter.tsx +291 -0
  351. package/src/controls/peer-boundary.test.ts +85 -0
  352. package/src/controls/props-contract.test.tsx +137 -0
  353. package/src/controls/range-filter.tsx +237 -0
  354. package/src/controls/range-filter.type-guard.test.tsx +122 -0
  355. package/src/controls/search-filter.tsx +123 -0
  356. package/src/controls/select-filter.tsx +89 -0
  357. package/src/controls/sync-button.module.css +63 -0
  358. package/src/controls/sync-button.module.css.d.ts +11 -0
  359. package/src/controls/sync-button.test.tsx +183 -0
  360. package/src/controls/sync-button.tsx +197 -0
  361. package/src/controls/toggle-filter.tsx +60 -0
  362. package/src/controls/view-tabs.tsx +110 -0
  363. package/src/controls-dates/date-range-picker.tsx +42 -0
  364. package/src/controls-dates/index.ts +8 -0
  365. package/src/dashboard/delta-badge.tsx +4 -74
  366. package/src/dashboard/index.ts +6 -1
  367. package/src/dashboard/settings-section.module.css +10 -0
  368. package/src/dashboard/settings-section.module.css.d.ts +1 -0
  369. package/src/dashboard/settings-section.test.tsx +56 -0
  370. package/src/dashboard/settings-section.tsx +33 -30
  371. package/src/dashboard/stat-card.module.css +153 -0
  372. package/src/dashboard/stat-card.module.css.d.ts +15 -0
  373. package/src/dashboard/stat-card.test.tsx +298 -1
  374. package/src/dashboard/stat-card.tsx +289 -67
  375. package/src/data/data-table.test.tsx +96 -11
  376. package/src/data/data-table.tsx +228 -84
  377. package/src/guard/check-source.test.ts +159 -13
  378. package/src/guard/grace.test.ts +158 -0
  379. package/src/guard/index.ts +185 -29
  380. package/src/guard/types.ts +4 -2
  381. package/src/index.ts +51 -5
  382. package/src/nav/types.ts +84 -2
  383. package/src/notifications/bell.tsx +6 -3
  384. package/src/notifications/index.ts +1 -1
  385. package/src/router-tanstack/field.ts +35 -0
  386. package/src/router-tanstack/index.ts +28 -2
  387. package/src/router-tanstack/multi-search-param-store.test.ts +71 -3
  388. package/src/router-tanstack/multi-search-param-store.ts +46 -77
  389. package/src/router-tanstack/search-param-store.ts +42 -159
  390. package/src/router-tanstack/search-store.router.test.tsx +882 -0
  391. package/src/router-tanstack/search-store.test.ts +578 -0
  392. package/src/router-tanstack/search-store.ts +546 -0
  393. package/src/router-tanstack/use-nav.test.tsx +187 -0
  394. package/src/router-tanstack/use-nav.ts +72 -14
  395. package/src/section/index.ts +1 -0
  396. package/src/section/section.module.css +104 -0
  397. package/src/section/section.module.css.d.ts +11 -0
  398. package/src/section/section.test.tsx +204 -0
  399. package/src/section/section.tsx +220 -0
  400. package/src/shell/app-breadcrumbs.tsx +44 -31
  401. package/src/shell/app-header.module.css +77 -37
  402. package/src/shell/app-header.module.css.d.ts +2 -1
  403. package/src/shell/app-mobile-nav.module.css +8 -0
  404. package/src/shell/app-mobile-nav.module.css.d.ts +1 -0
  405. package/src/shell/app-mobile-nav.tsx +147 -8
  406. package/src/shell/app-sidebar-account.tsx +2 -2
  407. package/src/shell/app-sidebar.module.css +303 -20
  408. package/src/shell/app-sidebar.module.css.d.ts +19 -1
  409. package/src/shell/app-sidebar.test.tsx +456 -41
  410. package/src/shell/app-sidebar.tsx +276 -140
  411. package/src/shell/index.test.tsx +291 -5
  412. package/src/shell/index.tsx +137 -38
  413. package/src/shell/mobile-nav-model.test.ts +228 -7
  414. package/src/shell/mobile-nav-model.ts +53 -3
  415. package/src/shell/nav-count-badge.tsx +1 -1
  416. package/src/shell/page-bar.module.css +178 -0
  417. package/src/shell/page-bar.module.css.d.ts +17 -0
  418. package/src/shell/page-bar.test.tsx +316 -0
  419. package/src/shell/page-bar.tsx +315 -0
  420. package/src/shell/sidebar-block-model.ts +83 -0
  421. package/src/shell/sidebar-blocks.tsx +301 -0
  422. package/src/shell/sidebar-search.module.css +26 -0
  423. package/src/shell/sidebar-search.module.css.d.ts +2 -0
  424. package/src/shell/sidebar-search.tsx +71 -2
  425. package/src/state/fields.test.tsx +512 -0
  426. package/src/state/fields.ts +1150 -0
  427. package/src/state/persisted.test.ts +91 -0
  428. package/src/state/persisted.ts +261 -0
  429. package/src/state.ts +52 -240
  430. package/src/styles.css +13 -0
  431. package/src/surfaces.ts +204 -36
  432. package/src/theme/controls.module.css +16 -1
  433. package/src/theme/ctl-theme.test.tsx +275 -0
  434. package/src/theme/ctl-theme.tsx +138 -0
  435. package/src/theme/ctl-tier-coverage.test.ts +170 -0
  436. package/src/theme/density-relations.test.ts +106 -51
  437. package/src/theme/divider-law.test.ts +259 -0
  438. package/src/theme/icon-slot.module.css +47 -0
  439. package/src/theme/icon-slot.module.css.d.ts +8 -0
  440. package/src/theme/icon-slot.test.tsx +275 -0
  441. package/src/theme/icon-slot.tsx +59 -0
  442. package/src/theme/index.ts +165 -3
  443. package/src/theme/layout-rhythm-css.test.ts +72 -0
  444. package/src/theme/radius.test.ts +11 -1
  445. package/src/theme/segmented-control.module.css +20 -0
  446. package/src/theme/shadow-surfaces.test.ts +20 -7
  447. package/src/theme/spacing.test.ts +75 -27
  448. package/src/theme/use-basalt-spacing.ts +2 -2
  449. package/src/tokens/density.test.ts +7 -25
  450. package/src/tokens/index.ts +48 -8
  451. package/src/tokens/palette.ts +107 -73
  452. package/src/widget-header/delta-badge.test.tsx +60 -0
  453. package/src/widget-header/delta-badge.tsx +57 -0
  454. package/src/widget-header/index.ts +2 -0
  455. package/src/widget-header/no-mantine.test.ts +33 -0
  456. package/src/widget-header/widget-header.module.css +350 -0
  457. package/src/widget-header/widget-header.module.css.d.ts +25 -0
  458. package/src/widget-header/widget-header.test.tsx +187 -0
  459. package/src/widget-header/widget-header.tsx +213 -0
  460. package/agent/rules/basalt-agent.md +0 -452
  461. package/agent/rules/basalt-app.md +0 -246
  462. package/agent/rules/basalt-commands.md +0 -320
  463. package/agent/rules/basalt-content.md +0 -409
  464. package/agent/rules/basalt-data.md +0 -329
  465. package/agent/rules/basalt-forms.md +0 -186
  466. package/agent/rules/basalt-notifications.md +0 -264
  467. package/agent/rules/basalt-query.md +0 -187
  468. package/agent/rules/basalt-router.md +0 -336
  469. package/dist/content/article-filter-bar.d.ts +0 -40
  470. package/dist/content/article-filter-bar.d.ts.map +0 -1
  471. package/dist/content/article-filter-bar.js +0 -56
  472. package/dist/shell/page-header.d.ts +0 -13
  473. package/dist/shell/page-header.d.ts.map +0 -1
  474. package/dist/shell/page-header.js +0 -23
  475. package/src/content/article-filter-bar.tsx +0 -88
  476. package/src/shell/page-header.tsx +0 -35
package/dist/surfaces.js CHANGED
@@ -1,3 +1,28 @@
1
+ const PLUGIN_RULE_ID_LIST = [
2
+ "no-raw-font-size",
3
+ "raw-size-literal",
4
+ "card-inset",
5
+ "chart-in-raw-surface",
6
+ "hand-rolled-plot",
7
+ "chart-legend-literal",
8
+ "shadow-basalt-export",
9
+ "hand-rolled-shell",
10
+ "raw-scroll-container",
11
+ "hand-rolled-filter",
12
+ "control-outside-home",
13
+ "control-size-literal",
14
+ "page-bar-budget",
15
+ "in-body-page-title",
16
+ "responsive-twin",
17
+ "search-literal-link",
18
+ "use-search-from-literal",
19
+ "visx-boundary",
20
+ "visx-tooltip",
21
+ "token-layer-boundary",
22
+ "agent-resume-guard",
23
+ "agent-no-raw-usechat",
24
+ "ai-sdk-major"
25
+ ];
1
26
  const v = (spec, message, extra) => ({
2
27
  spec,
3
28
  match: "path",
@@ -27,9 +52,29 @@ const SURFACES = {
27
52
  "card-with-border",
28
53
  "raw-form-control",
29
54
  "sub-16-input-font",
30
- "mantine-shade-index"
55
+ "mantine-shade-index",
56
+ // The text lane of the kinds whose remedy IS a Mantine primitive or a Mantine-owned prop:
57
+ // C8's page title (same id as the plugin rule, so one annotation waives both lanes), the
58
+ // spacing props, and the layout primitives an inline `display`/raw element replaces.
59
+ "in-body-page-title",
60
+ "raw-spacing",
61
+ "inline-spacing",
62
+ "inline-display",
63
+ "raw-html-layout",
64
+ "hidden-inline-style"
65
+ ],
66
+ // The chrome half of the plugin: the shell, the card idiom, the page title and the scroll
67
+ // doctrine. `hand-rolled-shell` sits here rather than on a shell-shaped surface because
68
+ // `BasaltShell` IS the root barrel's promise (docs/CONTROLS-SPEC.md §6 wave 6).
69
+ pluginRules: [
70
+ "hand-rolled-shell",
71
+ "card-inset",
72
+ "in-body-page-title",
73
+ "raw-scroll-container",
74
+ "page-bar-budget",
75
+ "shadow-basalt-export"
31
76
  ],
32
- description: "BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone)",
77
+ description: "BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone)",
33
78
  optionalPeers: [
34
79
  "react-markdown",
35
80
  "remark-gfm",
@@ -46,7 +91,20 @@ const SURFACES = {
46
91
  layer: "headless",
47
92
  rule: "charts",
48
93
  skill: ["basalt-charts"],
49
- guardKinds: ["raw-hex", "raw-color-fn", "raw-visx-axis", "unframed-chart"],
94
+ guardKinds: [
95
+ "raw-hex",
96
+ "raw-color-fn",
97
+ "raw-visx-axis",
98
+ "unframed-chart",
99
+ "chart-missing-aria-label"
100
+ ],
101
+ pluginRules: [
102
+ "hand-rolled-plot",
103
+ "chart-legend-literal",
104
+ "chart-in-raw-surface",
105
+ "visx-boundary",
106
+ "visx-tooltip"
107
+ ],
50
108
  description: "CartesianChart + visx chart primitives, kinds, sparklines, hooks, and token re-exports (Mantine-free)",
51
109
  globs: {
52
110
  shipped: ["**/charts/**"],
@@ -64,7 +122,28 @@ const SURFACES = {
64
122
  layer: "headless",
65
123
  rule: "tokens",
66
124
  skill: ["basalt-design", "basalt-charts"],
67
- guardKinds: ["raw-hex", "raw-color-fn", "off-identity-accent", "off-system-surface-var"],
125
+ guardKinds: [
126
+ "raw-hex",
127
+ "raw-color-fn",
128
+ "off-identity-accent",
129
+ "off-system-surface-var",
130
+ // The rest of the value lane: every kind whose remedy is a `--vx-*` token or a theme knob,
131
+ // in TSX and in kebab CSS alike.
132
+ "raw-font-family",
133
+ "raw-radius",
134
+ "raw-surface",
135
+ "inline-font-size",
136
+ "css-raw-surface",
137
+ "surface-shadow-override",
138
+ // Not a token kind — the kind that judges the ANNOTATION rather than the code. It lands here
139
+ // because `agent/rules/basalt-tokens.md` is where the `theme-allow` grammar is documented
140
+ // (said once, on purpose), so this is the header that must name its enforcement.
141
+ "theme-allow-unscoped"
142
+ ],
143
+ // The type-scale rules live with the tokens, not with `.`: both police a value that left the
144
+ // `--vx-*` system, which is this surface's whole subject. `token-layer-boundary` is the
145
+ // repo-local-only rule that keeps the layer upstream of Mantine (see below).
146
+ pluginRules: ["no-raw-font-size", "raw-size-literal", "token-layer-boundary"],
68
147
  description: "VX token refs, buildPaletteCss, defineSeries, seriesTokens, groupTokens, alpha (Mantine-free)",
69
148
  globs: {
70
149
  shipped: ["**/tokens/**"],
@@ -102,9 +181,10 @@ const SURFACES = {
102
181
  "./query": {
103
182
  kind: "doctrine",
104
183
  layer: "headless",
105
- rule: "query",
184
+ rule: "batteries",
106
185
  skill: ["basalt-app"],
107
186
  guardKinds: [],
187
+ pluginRules: [],
108
188
  description: "createBasaltQueryClient, transport-agnostic unwrap, lazy BasaltQueryDevtools",
109
189
  optionalPeers: ["@tanstack/react-query-devtools"],
110
190
  globs: {
@@ -117,10 +197,12 @@ const SURFACES = {
117
197
  "./router-tanstack": {
118
198
  kind: "doctrine",
119
199
  layer: "headless",
120
- rule: "router",
200
+ rule: "state",
121
201
  skill: ["basalt-app"],
122
202
  guardKinds: [],
123
- description: "TanStack Router bridge: defineNav/navGroup/navTarget (one typed nav definition) + useNav (sections + mobileNav, spread onto BasaltShell) + useBasaltNav (active route) + useRouterBreadcrumbs + createSearchParamStore (single-select URL-state store) + createMultiSearchParamStore (multi-select URL-state store)",
203
+ // Law C10 — a nav link's `search` and a reader's `from` are both this bridge's contract.
204
+ pluginRules: ["search-literal-link", "use-search-from-literal"],
205
+ description: "TanStack Router bridge: defineNav/navGroup/navTarget (one typed nav definition) + useNav (sections + mobileNav, spread onto BasaltShell) + useBasaltNav (active route) + useRouterBreadcrumbs + createSearchStore (typed URL > localStorage > fallback store over field.enum/multi/range/number/boolean/string; deprecated createSearchParamStore/createMultiSearchParamStore wrappers until 1.29.0)",
124
206
  optionalPeers: ["@tanstack/react-router"],
125
207
  globs: {
126
208
  shipped: [],
@@ -132,9 +214,10 @@ const SURFACES = {
132
214
  "./forms": {
133
215
  kind: "doctrine",
134
216
  layer: "mantine-coupled",
135
- rule: "forms",
217
+ rule: "batteries",
136
218
  skill: ["basalt-design"],
137
219
  guardKinds: [],
220
+ pluginRules: [],
138
221
  description: "Mantine form adapter: useBasaltForm, field, FormErrorSummary, useFormDraft (Standard Schema)",
139
222
  optionalPeers: ["@mantine/form"],
140
223
  forbiddenImports: []
@@ -142,9 +225,10 @@ const SURFACES = {
142
225
  "./notifications": {
143
226
  kind: "doctrine",
144
227
  layer: "mantine-coupled",
145
- rule: "notifications",
228
+ rule: "batteries",
146
229
  skill: ["basalt-app"],
147
230
  guardKinds: [],
231
+ pluginRules: [],
148
232
  description: "Mantine notifications: notify helpers, typed registry, persisted history, NotificationBell, NotificationCenter",
149
233
  optionalPeers: ["@mantine/notifications"],
150
234
  forbiddenImports: []
@@ -152,9 +236,10 @@ const SURFACES = {
152
236
  "./commands": {
153
237
  kind: "doctrine",
154
238
  layer: "mantine-coupled",
155
- rule: "commands",
239
+ rule: "batteries",
156
240
  skill: ["basalt-app"],
157
241
  guardKinds: [],
242
+ pluginRules: [],
158
243
  description: "typed command bus + overlay controller, toSpotlightActions, ShortcutsHelp, BasaltOverlays",
159
244
  optionalPeers: ["@mantine/spotlight", "@mantine/modals", "@tanstack/react-hotkeys"],
160
245
  forbiddenImports: []
@@ -162,9 +247,10 @@ const SURFACES = {
162
247
  "./data": {
163
248
  kind: "doctrine",
164
249
  layer: "mantine-coupled",
165
- rule: "data",
250
+ rule: "batteries",
166
251
  skill: ["basalt-design"],
167
252
  guardKinds: [],
253
+ pluginRules: [],
168
254
  description: "Convenience barrel pulling both TanStack Table + Virtual peer groups: BasaltDataTable, BasaltVirtualList (Mantine-rendered) \u2014 prefer ./data/table or ./data/virtual for per-feature opt-in",
169
255
  optionalPeers: ["@tanstack/react-table", "@tanstack/react-virtual"],
170
256
  forbiddenImports: []
@@ -172,9 +258,10 @@ const SURFACES = {
172
258
  "./data/table": {
173
259
  kind: "doctrine",
174
260
  layer: "mantine-coupled",
175
- rule: "data",
261
+ rule: "batteries",
176
262
  skill: ["basalt-design"],
177
263
  guardKinds: [],
264
+ pluginRules: [],
178
265
  description: "BasaltDataTable: a sortable data table over TanStack Table, rendered with Mantine (Mantine-rendered)",
179
266
  optionalPeers: ["@tanstack/react-table"],
180
267
  forbiddenImports: []
@@ -182,9 +269,10 @@ const SURFACES = {
182
269
  "./data/virtual": {
183
270
  kind: "doctrine",
184
271
  layer: "mantine-coupled",
185
- rule: "data",
272
+ rule: "batteries",
186
273
  skill: ["basalt-design"],
187
274
  guardKinds: [],
275
+ pluginRules: [],
188
276
  description: "BasaltVirtualList: a windowed virtual list over TanStack Virtual, rendered with Mantine (Mantine-rendered)",
189
277
  optionalPeers: ["@tanstack/react-virtual"],
190
278
  forbiddenImports: []
@@ -192,9 +280,11 @@ const SURFACES = {
192
280
  "./agent": {
193
281
  kind: "doctrine",
194
282
  layer: "headless",
195
- rule: "agent",
283
+ rule: "batteries",
196
284
  skill: ["basalt-app"],
197
285
  guardKinds: [],
286
+ // The three agent-chat correctness rules — they honour `basalt-agent-allow`, not `theme-allow`.
287
+ pluginRules: ["agent-resume-guard", "agent-no-raw-usechat", "ai-sdk-major"],
198
288
  description: "Headless streaming-chat layer: useAgentStream, aiSdkTransport (recommended default) + edenTransport, isResumable/ResumableAgentTransport (stream-resumption seam), PartList, coalesceParts, the ForeignPart/definePartRenderers/narrowAgentPart open part-registry seam, plus the multi-thread createThreadsStore + useAgentThreadRuns + outcome-resolver seam (Mantine-free)",
199
289
  optionalPeers: ["ai", "use-stick-to-bottom"],
200
290
  globs: {
@@ -207,9 +297,10 @@ const SURFACES = {
207
297
  "./agent-chat": {
208
298
  kind: "doctrine",
209
299
  layer: "mantine-coupled",
210
- rule: "agent",
300
+ rule: "batteries",
211
301
  skill: ["basalt-app"],
212
302
  guardKinds: [],
303
+ pluginRules: [],
213
304
  description: 'Mantine-styled thread-chat components over basalt-ui/agent: ThreadWorkspace, ThreadFeed (variant/renderRow), ThreadFeedRow (inline-expanding Slack row, lazily mounted + kept mounted), ThreadOutcomeCard, ThreadDetailPanel, Composer, ThreadTranscript (open part-renderer registry via its renderers/fallbackRenderer props, per-message MessageAffordances, groupConsecutive, and an optional virtualize/height windowing mode whose VirtualizeOptions carry overscan/estimateSize/initialScroll \u2014 a virtualized transcript opens scrolled to the newest message unless initialScroll is "start"), threadPartRenderers, ToolChip (Mantine-coupled). motion is required, not optional \u2014 ThreadFeed/ThreadDetailPanel import motion/react eagerly, so this subpath fails to resolve without it installed even though peerDependenciesMeta marks it optional (npm has no per-subpath optionality). remend is genuinely optional here \u2014 ThreadTranscript reaches it only through the lazy dynamic import() inside content/markdown.tsx, and @tanstack/react-virtual the same way through the lazy import() behind ThreadTranscript virtualize (absent peer degrades to an unwindowed, height-bound pane).',
214
305
  optionalPeers: [
215
306
  "ai",
@@ -229,10 +320,11 @@ const SURFACES = {
229
320
  "./content": {
230
321
  kind: "doctrine",
231
322
  layer: "mantine-coupled",
232
- rule: "content",
323
+ rule: "batteries",
233
324
  skill: ["basalt-design"],
234
325
  guardKinds: [],
235
- description: 'Prose (article/chat typography), CodeBlock (shiki, optional peer), Callout, TableOfContents, ReadingProgress, Markdown (react-markdown + remark-gfm, optional peers; `streaming` is a rendering mode ONLY \u2014 `contentTrust` is the independent security input, and any surface rendering agent/model output must pin `contentTrust="untrusted"`, the sole input to the image-origin allowlist; a `fenceRenderers` registry \u2014 settledOnly/FenceRenderer/FenceRenderers/FenceRenderContext; `sanitizeSchema`, an additions-only SanitizeSchemaExtension merged over BASALT_SANITIZE_SCHEMA via mergeSanitizeSchema; the remend streaming-repair pass is now a lazy optional peer), MermaidDiagram (beautiful-mermaid, optional peer), mdxComponents/createMdxComponents, ArticleLayout (docs-page frame), ArticleCard/ArticleGrid (overview cards), Article model (sortArticles/filterArticles/formatArticleDate), ArticleFilterBar (category/tags filter UI), toArticleActions (Spotlight projector, @mantine/spotlight type-only), GuideLink/GuideDrawer (contextual-help drawer) \u2014 the content/prose surface',
326
+ pluginRules: [],
327
+ description: 'Prose (article/chat typography), CodeBlock (shiki, optional peer), Callout, TableOfContents, ReadingProgress, Markdown (react-markdown + remark-gfm, optional peers; `streaming` is a rendering mode ONLY \u2014 `contentTrust` is the independent security input, and any surface rendering agent/model output must pin `contentTrust="untrusted"`, the sole input to the image-origin allowlist; a `fenceRenderers` registry \u2014 settledOnly/FenceRenderer/FenceRenderers/FenceRenderContext; `sanitizeSchema`, an additions-only SanitizeSchemaExtension merged over BASALT_SANITIZE_SCHEMA via mergeSanitizeSchema; the remend streaming-repair pass is now a lazy optional peer), MermaidDiagram (beautiful-mermaid, optional peer), mdxComponents/createMdxComponents, ArticleLayout (docs-page frame), ArticleCard/ArticleGrid (overview cards), Article model (sortArticles/filterArticles/formatArticleDate), FilterSet/ViewTabs/MultiSelectFilter re-exported from ./controls (they replaced the controlled ArticleFilterBar), toArticleActions (Spotlight projector, @mantine/spotlight type-only), GuideLink/GuideDrawer (contextual-help drawer) \u2014 the content/prose surface',
236
328
  optionalPeers: [
237
329
  "shiki",
238
330
  "@shikijs/langs",
@@ -246,13 +338,55 @@ const SURFACES = {
246
338
  ],
247
339
  forbiddenImports: []
248
340
  },
341
+ "./controls": {
342
+ kind: "doctrine",
343
+ layer: "mantine-coupled",
344
+ rule: "controls",
345
+ skill: ["basalt-design"],
346
+ // The text lane of law C1 — the plugin's `control-outside-home` seen through a 12-line host-tag
347
+ // window, since a regex scan has no ancestry. Same law, same wave, same promotion.
348
+ guardKinds: ["raw-selection-control"],
349
+ // The control tier itself (laws C1/C3/C5/C9). `hand-rolled-filter`, `control-size-literal` and
350
+ // `responsive-twin` all ship `error`; `control-outside-home` is the one grace entry left in
351
+ // `PLUGIN_RULE_GRACE`, re-dated to 1.28.0 against the wave-7 measurement (see its `why`).
352
+ // The budget rules live on `.` with `PageBar` itself.
353
+ pluginRules: [
354
+ "hand-rolled-filter",
355
+ "control-outside-home",
356
+ "control-size-literal",
357
+ "responsive-twin"
358
+ ],
359
+ // docs/CONTROLS-SPEC.md §6 "Honest coverage" — verbatim, because a generated header claiming
360
+ // otherwise is D8 again.
361
+ advisoryLaws: [
362
+ "C1 as a cross-file law (a control placed in one file, its home declared in another)",
363
+ 'hand-rolled section headings (argo writes `<Text fw={600} size="sm">` + children, which no AST heuristic matches without false positives)',
364
+ "C11 \u2014 a table/list stating its count when it is not a BasaltDataTable",
365
+ "C12 \u2014 one shape for refresh/sync (SyncButton); only the alias table sees a renamed copy"
366
+ ],
367
+ description: 'The control tier (docs/CONTROLS-SPEC.md \xA73): FilterSet (nowrap row + measured +N fold + the mobile Filters (n) sheet), RangeFilter/CompareFilter/SelectFilter/MultiSelectFilter/NumberFilter/SearchFilter/ToggleFilter (each bound to a FieldHandle \u2014 no value/onChange/size, law C2/C5; NumberFilter is the field.number lane, a radio list over `options` or a stepper without), ViewTabs, and the action/sync family (ActionGroup, OverflowMenu, SyncButton, BarAction/GlobalAction). Every control owns its own desktop/mobile swap in CSS (C9) and renders size="ctl" internally. Resolves and renders with NO @mantine/dates installed \u2014 the custom date picker is injected through RangeFilter.customPicker from ./controls-dates.',
368
+ optionalPeers: [],
369
+ forbiddenImports: []
370
+ },
371
+ "./controls-dates": {
372
+ kind: "doctrine",
373
+ layer: "mantine-coupled",
374
+ rule: "controls",
375
+ skill: ["basalt-design"],
376
+ guardKinds: [],
377
+ pluginRules: [],
378
+ description: "DateRangePicker \u2014 the @mantine/dates implementation of RangeFilter's customPicker seam. Its own subpath because @mantine/dates is an optional peer and basaltViteConfig pre-bundles the whole @mantine scope, so a consumer without the peer (linewatch) must never resolve it: nothing under src/controls may import it, statically or lazily (docs/CONTROLS-SPEC.md \xA73).",
379
+ optionalPeers: ["@mantine/dates"],
380
+ forbiddenImports: []
381
+ },
249
382
  "./state": {
250
383
  kind: "doctrine",
251
384
  layer: "headless",
252
385
  rule: "state",
253
386
  skill: ["basalt-design"],
254
387
  guardKinds: ["localstorage-theme"],
255
- description: "createPersistedState (versioned localStorage) + useOnlineStatus \u2014 Mantine-free state primitives",
388
+ pluginRules: [],
389
+ description: "createPersistedState (versioned localStorage) + the store field vocabulary (field.enum/multi/range/number/boolean/string, FieldHandle, lanes) + createLocalStore, the router-free store \u2014 Mantine-free state primitives",
256
390
  optionalPeers: [],
257
391
  // Consumers import basalt-ui/state from node_modules (lint-ignored), so there is nothing to
258
392
  // enforce consumer-side, and a shipped **/state* glob would wrongly hit consumers' own
@@ -270,6 +404,7 @@ const SURFACES = {
270
404
  rule: "mantine",
271
405
  skill: ["basalt-app"],
272
406
  guardKinds: [],
407
+ pluginRules: [],
273
408
  description: "ConnectivityProvider (aggregates browser online/offline, React Query onlineManager, SSE, and health-check pings into one status), useConnectivity, and ConnectivityIndicator \u2014 auto-mounted by BasaltProvider",
274
409
  optionalPeers: [],
275
410
  forbiddenImports: []
@@ -304,9 +439,10 @@ const SURFACES = {
304
439
  // synthetic global app-wide ban layer — the src/**+app/** glob
305
440
  kind: "doctrine",
306
441
  layer: "app-global",
307
- rule: "app",
442
+ rule: "batteries",
308
443
  skill: ["basalt-app"],
309
444
  guardKinds: [],
445
+ pluginRules: [],
310
446
  globs: {
311
447
  // Shipped is a catch-all (not just src/**+app/**) so consumer code under components/, lib/,
312
448
  // features/, etc. is also covered. The @visx/*-only-in-charts and Mantine-free charts/tokens
@@ -348,6 +484,7 @@ function hasTokenLayerBoundaryRegistered(rules) {
348
484
  return rules?.["basalt/token-layer-boundary"] === "error";
349
485
  }
350
486
  export {
487
+ PLUGIN_RULE_ID_LIST,
351
488
  RULE_NAMES,
352
489
  SKILL_NAMES,
353
490
  SURFACES,
@@ -204,7 +204,8 @@ html[data-mantine-color-scheme] .inputWrapper[data-variant='default']:not([data-
204
204
  /*
205
205
  * Reduced motion drops the fade, never the shadow: a static shadow is not motion, and removing it
206
206
  * would strip the very hierarchy this pass exists to establish from the users who asked for less
207
- * animation. `subtle`'s hover depth still lands — it just lands instantly.
207
+ * animation. `default`/`filled`/`light`/`outline`'s hover depth still lands — it just lands
208
+ * instantly. `subtle` stays flat regardless, as it does in every other state (see above).
208
209
  */
209
210
  @media (prefers-reduced-motion: reduce) {
210
211
  .buttonRoot,
@@ -282,3 +283,17 @@ html[data-mantine-color-scheme] .tabsRoot {
282
283
  html .tableRoot {
283
284
  --table-border-color: var(--vx-surface-hairline);
284
285
  }
286
+
287
+ /*
288
+ * The LAST row's separator is dropped — exactly the rule (and exactly the reasoning) the Accordion
289
+ * above already carries: a separator BETWEEN items is information, and the same line drawn after the
290
+ * final item is an outer border pretending to be one. It mattered more once `BasaltDataTable`'s
291
+ * `withTableBorder` went to `false` by default, because the two used to sit on top of each other and
292
+ * the doubling hid which of them was drawing the line.
293
+ *
294
+ * Scoped to `tbody`: a `tfoot` (a totals row) is separated FROM the body by the rule above it, which
295
+ * is a between rule and stays.
296
+ */
297
+ html .tableRoot tbody tr:last-of-type {
298
+ border-bottom: none;
299
+ }
@@ -0,0 +1,32 @@
1
+ import type { MantineThemeOverride } from '@mantine/core';
2
+ import type { ReactNode } from 'react';
3
+ /** The `MantineThemeOverride` a `<CtlSlot>` provides — see this module's doc for the merge/
4
+ * precedence contract. Exported so a consumer composing its own slot (a bespoke home not covered
5
+ * by `PageBar`/`Section`/the sidebar blocks) can reach the SAME tier without re-declaring it. */
6
+ export declare const CTL_THEME: MantineThemeOverride;
7
+ export type CtlSlotProps = {
8
+ children: ReactNode;
9
+ /**
10
+ * Which tier the slot imposes. `ctl` (the default) is the 30px control tier every home's control
11
+ * row uses. `widget` is the 24px ActionIcon step a `WidgetHeader tier="widget"` header row can
12
+ * hold — see {@link WIDGET_THEME} for the misalignment that makes it a separate tier rather than
13
+ * a caller's `size` prop.
14
+ *
15
+ * The values are the TIER names, matching the `data-basalt-tier` attribute the slot emits and the
16
+ * one `ChartCard` already writes by hand (it lives inside the Mantine-free `charts/` boundary and
17
+ * so cannot mount this component). `widget` maps to Mantine's `size="icon"`; the two vocabularies
18
+ * differ and that is upstream's, not basalt's.
19
+ *
20
+ * @default 'ctl'
21
+ */
22
+ tier?: 'ctl' | 'widget';
23
+ };
24
+ /**
25
+ * Wrap a home's SLOT (never its body) to render every Mantine control inside it at the `ctl` tier.
26
+ * The marker is a Mantine `Box` (not a raw `<div>` — `basalt/raw-html-layout` flags inline
27
+ * layout/surface styling on a bare HTML tag), `display: contents` keeps it out of the slot's own
28
+ * flex/grid layout while leaving the `data-basalt-tier="ctl"` attribute queryable/testable
29
+ * (`docs/CONTROLS-SPEC.md` §5) without the wrapper participating in flow.
30
+ */
31
+ export declare function CtlSlot({ children, tier }: CtlSlotProps): ReactNode;
32
+ //# sourceMappingURL=ctl-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctl-theme.d.ts","sourceRoot":"","sources":["../../src/theme/ctl-theme.tsx"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;;iGAEiG;AACjG,eAAO,MAAM,SAAS,EAAE,oBAyBvB,CAAA;AA0BD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAA;IACnB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAY,EAAE,EAAE,YAAY,GAAG,SAAS,CAQ3E"}
@@ -0,0 +1,54 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import {
3
+ ActionIcon,
4
+ Box,
5
+ Button,
6
+ Checkbox,
7
+ Input,
8
+ MantineThemeProvider,
9
+ MultiSelect,
10
+ NativeSelect,
11
+ Radio,
12
+ SegmentedControl,
13
+ Select,
14
+ Switch,
15
+ TextInput
16
+ } from "@mantine/core";
17
+ const CTL_THEME = {
18
+ components: {
19
+ Button: Button.extend({ defaultProps: { size: "ctl" } }),
20
+ ActionIcon: ActionIcon.extend({ defaultProps: { size: "ctl" } }),
21
+ Input: Input.extend({ defaultProps: { size: "ctl" } }),
22
+ TextInput: TextInput.extend({ defaultProps: { size: "ctl" } }),
23
+ Select: Select.extend({ defaultProps: { size: "ctl" } }),
24
+ MultiSelect: MultiSelect.extend({ defaultProps: { size: "ctl" } }),
25
+ SegmentedControl: SegmentedControl.extend({ defaultProps: { size: "ctl" } }),
26
+ NativeSelect: NativeSelect.extend({ defaultProps: { size: "ctl" } }),
27
+ // The theme keys are the component names Mantine's own `useProps` looks up — `RadioGroup`, not
28
+ // `Radio.Group` (`RadioGroup.mjs`: `useProps("RadioGroup", …)`).
29
+ Radio: Radio.extend({ defaultProps: { size: "ctl" } }),
30
+ // Mantine types `RadioGroup.size` as a CLOSED `MantineSize`, while `Radio`, `Checkbox`,
31
+ // `Checkbox.Group`, `Switch` and `Switch.Group` all type theirs OPEN
32
+ // (`MantineSize | (string & {})`) — verified in the installed 9.3.0 `.d.ts` files, so this is an
33
+ // upstream inconsistency, not a statement that `RadioGroup` cannot take a custom tier. At
34
+ // runtime `getSize` interpolates the string identically for all six. The cast restores what
35
+ // every sibling type already allows; it widens nothing.
36
+ RadioGroup: Radio.Group.extend({ defaultProps: { size: "ctl" } }),
37
+ Checkbox: Checkbox.extend({ defaultProps: { size: "ctl" } }),
38
+ CheckboxGroup: Checkbox.Group.extend({ defaultProps: { size: "ctl" } }),
39
+ Switch: Switch.extend({ defaultProps: { size: "ctl" } }),
40
+ SwitchGroup: Switch.Group.extend({ defaultProps: { size: "ctl" } })
41
+ }
42
+ };
43
+ const WIDGET_THEME = {
44
+ components: {
45
+ ActionIcon: ActionIcon.extend({ defaultProps: { size: "icon" } })
46
+ }
47
+ };
48
+ function CtlSlot({ children, tier = "ctl" }) {
49
+ return /* @__PURE__ */ jsx(MantineThemeProvider, { inherit: true, theme: tier === "widget" ? WIDGET_THEME : CTL_THEME, children: /* @__PURE__ */ jsx(Box, { "data-basalt-tier": tier, style: { display: "contents" }, children }) });
50
+ }
51
+ export {
52
+ CTL_THEME,
53
+ CtlSlot
54
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ctl-theme.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctl-theme.test.d.ts","sourceRoot":"","sources":["../../src/theme/ctl-theme.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ctl-tier-coverage.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctl-tier-coverage.test.d.ts","sourceRoot":"","sources":["../../src/theme/ctl-tier-coverage.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=divider-law.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"divider-law.test.d.ts","sourceRoot":"","sources":["../../src/theme/divider-law.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `IconSlot` — the ONE box every `icon` prop in the public API renders through
3
+ * (`docs/CONTROLS-SPEC.md` §3).
4
+ *
5
+ * basalt ships no icon dependency, so every `icon` slot takes a `ReactNode` the consumer fills —
6
+ * and a consumer's glyph arrives at whatever geometry its own icon set chose: `width="24"` from
7
+ * Tabler's defaults, no `width` at all from a hand-written `<svg viewBox="0 0 20 20">`, a
8
+ * `stroke-width` tuned for a 24px box, or an `<img>` off a sprite sheet. Passing that node straight
9
+ * into Mantine's `leftSection` (which is a bare `flex` box with no size of its own) lets the CALLER
10
+ * decide the height of a basalt control's row. That is the class of bug this component closes: the
11
+ * icon's box is the framework's, and there is no prop on it.
12
+ *
13
+ * **Derived, not configured.** There is no `size` prop, on purpose — a size at a call site is the
14
+ * same C5 violation a `size="xs"` on a Button is. The box reads `--vx-space-icon-size` (default
15
+ * 16px, the control tier's mark), and the only thing entitled to set that var is a HOME's own CSS:
16
+ * `WidgetHeader` sets it per `data-tier`, so a `tier="widget"` heading draws 14px icons and a
17
+ * `tier="section"` heading draws 16px, with every call site unchanged.
18
+ *
19
+ * Mantine-free and dependency-free (one CSS module, one `<span>`), so `src/widget-header/**` — which
20
+ * `ChartCard` composes from inside `src/charts/**` — can deep-import it without pulling
21
+ * `@mantine/*` into the charts graph (`scripts/check-dist-layering.mjs`). Deep-import it as
22
+ * `../theme/icon-slot`, never through the `./theme` barrel, for exactly that reason. INTERNAL: it is
23
+ * not on any barrel. A consumer never needs it — passing `icon` IS the contract, and this is what
24
+ * makes that contract hold.
25
+ *
26
+ * `data-basalt-icon` is the queryable marker, the same idiom `CtlSlot` uses for `data-basalt-tier`:
27
+ * a CSS-module class name is a build-time hash, so it is not something a test — or a consumer
28
+ * debugging a misaligned row — can select on.
29
+ *
30
+ * @example
31
+ * // A control's icon slot — no size anywhere at the call site.
32
+ * <Button leftSection={<IconSlot>{icon}</IconSlot>}>{label}</Button>
33
+ */
34
+ import type { ReactNode } from 'react';
35
+ export type IconSlotProps = {
36
+ readonly children: ReactNode;
37
+ /**
38
+ * Composed ONTO the slot class, never in place of it — a home adds colour/state rules (the pill's
39
+ * muted-then-ink icon, a header's faint one) and the geometry stays the slot's.
40
+ */
41
+ readonly className?: string;
42
+ };
43
+ export declare function IconSlot({ children, className }: IconSlotProps): ReactNode;
44
+ //# sourceMappingURL=icon-slot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-slot.d.ts","sourceRoot":"","sources":["../../src/theme/icon-slot.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,aAAa,GAAG,SAAS,CAa1E"}
@@ -0,0 +1,21 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import classes from "./icon-slot.module.css";
3
+ function IconSlot({ children, className }) {
4
+ return (
5
+ // `aria-hidden` unconditionally: an icon in a basalt control is DECORATIVE by construction —
6
+ // every control that takes one also carries a label or an `aria-label`, so a named icon would
7
+ // double the announced name. A caller wanting a meaningful graphic names the control, not this.
8
+ /* @__PURE__ */ jsx(
9
+ "span",
10
+ {
11
+ className: className === void 0 ? classes.slot : `${classes.slot} ${className}`,
12
+ "data-basalt-icon": true,
13
+ "aria-hidden": "true",
14
+ children
15
+ }
16
+ )
17
+ );
18
+ }
19
+ export {
20
+ IconSlot
21
+ };
@@ -0,0 +1,47 @@
1
+ /*
2
+ * The framework's ONE icon box (`docs/CONTROLS-SPEC.md` §3) — see `icon-slot.tsx` for why every
3
+ * `icon` prop in the public API renders through it.
4
+ *
5
+ * The box is a FIXED square, not a shrink-to-fit inline box: `width`/`height` are declared on the
6
+ * slot itself so the row's geometry is decided by the SLOT and never by the glyph the caller
7
+ * happened to pass. `--vx-space-icon-size` is the host's override hook (a `WidgetHeader` tier, a
8
+ * collapsed rail), defaulting to the 16px the control tier draws; it is deliberately NOT a
9
+ * `--vx-space-*` token declared by `tokens/index.ts` — no home needs it globally, and a token would
10
+ * invite a call site to set it.
11
+ */
12
+ .slot {
13
+ display: inline-flex;
14
+ flex: none;
15
+ align-items: center;
16
+ justify-content: center;
17
+ width: var(--vx-space-icon-size, 1rem);
18
+ height: var(--vx-space-icon-size, 1rem);
19
+ /* The glyph is `display: block` below, so the slot has no text to lead — a residual line box is
20
+ * what pushed a 16px icon a fraction below the optical centre of a 30px button. */
21
+ line-height: 0;
22
+ }
23
+
24
+ /*
25
+ * `width`/`height: 100%` is what makes ANY consumer glyph land on the tier. An inline `<svg>`
26
+ * carries its own `width`/`height` attributes (14, 20, 24 — or none at all, which paints at the
27
+ * `viewBox`'s intrinsic size, or 300×150 with no `viewBox` either), and those attributes are
28
+ * PRESENTATION attributes: they lose to any CSS declaration. So the slot restates them from the
29
+ * box, and the caller's own numbers stop mattering.
30
+ *
31
+ * `display: block` removes the baseline the glyph would otherwise sit on. An inline `<svg>` aligns
32
+ * its own bottom edge to the parent's text baseline, which leaves the descender gap BELOW it inside
33
+ * the box — the icon then paints high or low of centre by a fraction of the line box, and by a
34
+ * DIFFERENT fraction per font stack. `object-fit: contain` keeps a non-square glyph whole rather
35
+ * than stretching it to the square box.
36
+ *
37
+ * `img` and `picture` are covered too: an icon slot filled from a sprite sheet or a remote asset is
38
+ * the same geometry problem, and a consumer's icon set is as likely to be one as the other.
39
+ */
40
+ .slot > svg,
41
+ .slot > img,
42
+ .slot > picture {
43
+ display: block;
44
+ width: 100%;
45
+ height: 100%;
46
+ object-fit: contain;
47
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Typed CSS-module declaration (the S4 CSS-modules path). Named string props — not an index
3
+ * signature — so dot access stays verbatim under the package's strict flags.
4
+ */
5
+ declare const classes: {
6
+ readonly slot: string
7
+ }
8
+ export default classes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=icon-slot.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-slot.test.d.ts","sourceRoot":"","sources":["../../src/theme/icon-slot.test.tsx"],"names":[],"mappings":""}
@@ -10,6 +10,7 @@ import type { BasaltFontsConfig } from '../tokens/index.js';
10
10
  */
11
11
  export type { BasaltFontsConfig } from '../tokens/index.js';
12
12
  export { useBasaltSpacing } from './use-basalt-spacing.js';
13
+ export { CTL_THEME, CtlSlot, type CtlSlotProps } from './ctl-theme.js';
13
14
  declare module '@mantine/core' {
14
15
  interface MantineThemeOther {
15
16
  basaltDerive?: DeriveConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EACV,oBAAoB,EAGpB,oBAAoB,EAErB,MAAM,eAAe,CAAA;AAStB,OAAO,KAAK,EAAe,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAOlD;;;;;GAKG;AACH,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAIlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AASvD,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,iBAAiB;QACzB,YAAY,CAAC,EAAE,YAAY,CAAA;QAC3B,WAAW,CAAC,EAAE,iBAAiB,CAAA;QAC/B,YAAY,CAAC,EAAE,YAAY,CAAA;QAC3B,aAAa,CAAC,EAAE,WAAW,CAAA;KAC5B;CACF;AAm5BD;+EAC+E;AAC/E,eAAO,MAAM,SAAS,EAAE,oBAAuD,CAAA;AAmJ/E;;8FAE8F;AAC9F,eAAO,MAAM,oBAAoB,EAAE,oBACc,CAAA;AAEjD,kEAAkE;AAClE,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAE9B;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAA;IAEzB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAYD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,CAAC,EAAE,oBAAoB,EAChC,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CA+BtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AA+DA,OAAO,KAAK,EACV,oBAAoB,EAGpB,oBAAoB,EAErB,MAAM,eAAe,CAAA;AAStB,OAAO,KAAK,EAAe,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAOlD;;;;;GAKG;AACH,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAIlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAIvD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AASnE,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,iBAAiB;QACzB,YAAY,CAAC,EAAE,YAAY,CAAA;QAC3B,WAAW,CAAC,EAAE,iBAAiB,CAAA;QAC/B,YAAY,CAAC,EAAE,YAAY,CAAA;QAC3B,aAAa,CAAC,EAAE,WAAW,CAAA;KAC5B;CACF;AA26BD;+EAC+E;AAC/E,eAAO,MAAM,SAAS,EAAE,oBAAuD,CAAA;AAyR/E;;8FAE8F;AAC9F,eAAO,MAAM,oBAAoB,EAAE,oBACc,CAAA;AAEjD,kEAAkE;AAClE,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAE9B;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAA;IAEzB;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAYD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,CAAC,EAAE,oBAAoB,EAChC,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CA+BtB"}