themelia-ui 3.0.0 → 3.2.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 (746) hide show
  1. package/.agents/skills/themelia-ui/SKILL.md +60 -33
  2. package/.agents/skills/themelia-ui/manifest.json +23 -0
  3. package/.agents/skills/themelia-ui/references/api-compatibility.md +5 -4
  4. package/.agents/skills/themelia-ui/references/blocks.md +123 -0
  5. package/.agents/skills/themelia-ui/references/composition-ladder.md +8 -8
  6. package/.agents/skills/themelia-ui/references/composition.md +100 -19
  7. package/.agents/skills/themelia-ui/references/forms.md +23 -3
  8. package/.agents/skills/themelia-ui/references/framework-wiring.md +41 -13
  9. package/.agents/skills/themelia-ui/references/i18n.md +4 -2
  10. package/.agents/skills/themelia-ui/references/imports.md +104 -104
  11. package/.agents/skills/themelia-ui/references/installation.md +60 -31
  12. package/.agents/skills/themelia-ui/references/migration.md +156 -5
  13. package/.agents/skills/themelia-ui/references/provider-and-scoping.md +37 -25
  14. package/.agents/skills/themelia-ui/references/reference-workflows.md +43 -0
  15. package/.agents/skills/themelia-ui/references/structure-and-spacing.md +147 -0
  16. package/.agents/skills/themelia-ui/references/theming.md +174 -131
  17. package/.agents/skills/themelia-ui/references/troubleshooting.md +88 -30
  18. package/.agents/skills/themelia-ui/references/verification.md +60 -5
  19. package/CHANGELOG.md +212 -0
  20. package/README.md +48 -60
  21. package/dist/accordion-CHuzMmWL.js +143 -0
  22. package/dist/{action-menu-BNLURfMK.js → action-menu-BwiL_F6I.js} +35 -33
  23. package/dist/{alert-dialog-BMVo6Z-8.js → alert-dialog-Cg2HhuBe.js} +1 -1
  24. package/dist/avatar-Dc_BNYfB.js +93 -0
  25. package/dist/badge-VlJVZjdm.js +45 -0
  26. package/dist/base/accordion.js +1 -1
  27. package/dist/base/action-menu.js +1 -1
  28. package/dist/base/alert-dialog.js +1 -1
  29. package/dist/base/aspect-ratio.js +3 -1
  30. package/dist/base/avatar.js +1 -1
  31. package/dist/base/badge.js +2 -2
  32. package/dist/base/batch-action-bar.js +1 -1
  33. package/dist/base/buttons.js +1 -1
  34. package/dist/base/cards.js +1 -1
  35. package/dist/base/carousel.js +6 -4
  36. package/dist/base/chart.js +1 -1
  37. package/dist/base/choice-inputs.js +1 -1
  38. package/dist/base/combobox.js +1 -1
  39. package/dist/base/command.js +1 -1
  40. package/dist/base/context-menu.js +22 -21
  41. package/dist/base/copyable.js +1 -1
  42. package/dist/base/date-pickers.js +1 -1
  43. package/dist/base/dialog.js +1 -1
  44. package/dist/base/display.js +1 -1
  45. package/dist/base/dropdown-menu.js +1 -1
  46. package/dist/base/feedback.js +1 -1
  47. package/dist/base/forms-numeric.js +1 -1
  48. package/dist/base/forms.js +1 -1
  49. package/dist/base/hover-card.js +26 -23
  50. package/dist/base/input-group.js +1 -1
  51. package/dist/base/item.js +1 -1
  52. package/dist/base/label.js +1 -1
  53. package/dist/base/menubar.js +20 -14
  54. package/dist/base/navigation-menu.js +47 -38
  55. package/dist/base/navigation.js +1 -1
  56. package/dist/base/otp-input.js +36 -30
  57. package/dist/base/overlay.js +1 -1
  58. package/dist/base/popover-menu.js +1 -1
  59. package/dist/base/popover.js +1 -1
  60. package/dist/base/qr-code.js +51 -47
  61. package/dist/base/repeaters.js +1 -1
  62. package/dist/base/resizable.js +2 -0
  63. package/dist/base/sheet.js +1 -1
  64. package/dist/base/sidebar.js +1 -1
  65. package/dist/base/skeleton.js +1 -1
  66. package/dist/base/spinner.js +1 -1
  67. package/dist/base/structure.js +1 -1
  68. package/dist/base/table.js +1 -1
  69. package/dist/base/text-inputs.js +1 -1
  70. package/dist/base/timeline.js +1 -1
  71. package/dist/base/toaster.js +1 -1
  72. package/dist/base/toggle.js +21 -15
  73. package/dist/base/toolbar.js +1 -1
  74. package/dist/base/tooltip.js +1 -1
  75. package/dist/base/typography.js +2 -2
  76. package/dist/base/upload.js +1 -1
  77. package/dist/base/value-inputs.js +1 -1
  78. package/dist/{batch-action-bar-BZYNKXdV.js → batch-action-bar-DZVMVW83.js} +11 -8
  79. package/dist/{admin/patterns → blocks/admin}/access.js +79 -76
  80. package/dist/blocks/admin/commerce.js +2493 -0
  81. package/dist/{patterns → blocks}/analytics.js +312 -303
  82. package/dist/{patterns → blocks}/onboarding.js +27 -23
  83. package/dist/{patterns → blocks}/timelines.js +1 -1
  84. package/dist/buttons-BX2JfL5X.js +173 -0
  85. package/dist/cards-Ddhz43Bz.js +279 -0
  86. package/dist/chart-BkK3Xm10.js +201 -0
  87. package/dist/choice-inputs-NwRxvmZN.js +694 -0
  88. package/dist/combobox-519ubijc.js +292 -0
  89. package/dist/command-JjApYFds.js +156 -0
  90. package/dist/comments-CCQ2QRaU.js +1443 -0
  91. package/dist/components/base/action-menu/action-menu.d.ts +1 -1
  92. package/dist/components/base/action-menu/action-menu.types.d.ts +2 -2
  93. package/dist/components/base/avatar/avatar.d.ts +5 -2
  94. package/dist/components/base/badge/badge.d.ts +10 -10
  95. package/dist/components/base/badge/badge.variants.d.ts +1 -2
  96. package/dist/components/base/badge/index.d.ts +1 -2
  97. package/dist/components/base/buttons/button.d.ts +9 -8
  98. package/dist/components/base/buttons/button.types.d.ts +2 -2
  99. package/dist/components/base/buttons/index.d.ts +1 -1
  100. package/dist/components/base/buttons/text-button.d.ts +1 -1
  101. package/dist/components/base/cards/card-actions.d.ts +1 -1
  102. package/dist/components/base/cards/card.d.ts +3 -1
  103. package/dist/components/base/cards/partials/card-header.d.ts +2 -1
  104. package/dist/components/base/choice-inputs/choice.types.d.ts +2 -2
  105. package/dist/components/base/choice-inputs/partials/choice-parts.d.ts +3 -3
  106. package/dist/components/base/command/command.d.ts +5 -2
  107. package/dist/components/base/display/icon-badge.d.ts +5 -3
  108. package/dist/components/base/display/index.d.ts +1 -1
  109. package/dist/components/base/display/metadata-list.d.ts +6 -6
  110. package/dist/components/base/display/metadata-value.d.ts +1 -1
  111. package/dist/components/base/display/separator.d.ts +2 -2
  112. package/dist/components/base/feedback/alert.d.ts +3 -2
  113. package/dist/components/base/feedback/empty.d.ts +5 -4
  114. package/dist/components/base/feedback/progress-circle.d.ts +2 -2
  115. package/dist/components/base/feedback/progress.d.ts +3 -1
  116. package/dist/components/base/forms/form-field.d.ts +2 -2
  117. package/dist/components/base/input-group/input-group.d.ts +8 -10
  118. package/dist/components/base/item/item.d.ts +2 -2
  119. package/dist/components/base/overlay/index.d.ts +1 -1
  120. package/dist/components/base/overlay/overlay.types.d.ts +7 -5
  121. package/dist/components/base/qr-code/qr-code.d.ts +4 -4
  122. package/dist/components/base/sheet/sheet.d.ts +1 -1
  123. package/dist/components/base/sidebar/sidebar.d.ts +9 -13
  124. package/dist/components/base/spinner/spinner.d.ts +2 -2
  125. package/dist/components/base/structure/adaptive-grid.d.ts +3 -3
  126. package/dist/components/base/structure/bleed.d.ts +4 -2
  127. package/dist/components/base/structure/grid.d.ts +10 -4
  128. package/dist/components/base/structure/index.d.ts +1 -1
  129. package/dist/components/base/structure/split.d.ts +4 -3
  130. package/dist/components/base/structure/stack.d.ts +5 -5
  131. package/dist/components/base/structure/structure.maps.d.ts +2 -1
  132. package/dist/components/base/structure/structure.types.d.ts +10 -4
  133. package/dist/components/base/toggle/toggle.d.ts +2 -2
  134. package/dist/components/base/toolbar/toolbar.d.ts +3 -3
  135. package/dist/components/base/typography/index.d.ts +2 -0
  136. package/dist/components/base/typography/rich-text/rich-text.variants.d.ts +9 -0
  137. package/dist/components/base/typography/text/index.d.ts +1 -0
  138. package/dist/components/base/typography/text/text.d.ts +15 -8
  139. package/dist/components/base/typography/text/text.variants.d.ts +41 -0
  140. package/dist/components/base/value-inputs/color-input.d.ts +1 -7
  141. package/dist/components/base/value-inputs/slider.d.ts +2 -7
  142. package/dist/components/{admin/patterns → blocks/admin}/commerce/vendor-profile.d.ts +2 -1
  143. package/dist/components/{patterns → blocks}/analytics/analytics.strings.d.ts +2 -5
  144. package/dist/components/features/actions/action-adapters.d.ts +3 -3
  145. package/dist/components/features/actions/actions.types.d.ts +3 -5
  146. package/dist/components/features/actions/index.d.ts +1 -1
  147. package/dist/components/features/activities/activities-feed.d.ts +1 -1
  148. package/dist/components/features/activities/activities.types.d.ts +4 -4
  149. package/dist/components/features/activities/activity-parts.d.ts +3 -3
  150. package/dist/components/features/activities/activity-row.d.ts +4 -4
  151. package/dist/components/features/activities/index.d.ts +1 -1
  152. package/dist/components/features/ai-chat/ai-chat.types.d.ts +10 -3
  153. package/dist/components/features/ai-chat/ai-message-surfaces.d.ts +1 -1
  154. package/dist/components/features/ai-chat/ai-work-surfaces.d.ts +1 -1
  155. package/dist/components/features/combobox/combobox.strings.d.ts +2 -2
  156. package/dist/components/features/combobox/fetching-combobox.d.ts +2 -1
  157. package/dist/components/features/combobox/resource-combobox.d.ts +3 -0
  158. package/dist/components/features/combobox/use-suggestions.d.ts +7 -0
  159. package/dist/components/features/event-calendar/event-calendar.types.d.ts +3 -0
  160. package/dist/components/features/media-library/index.d.ts +1 -1
  161. package/dist/components/features/media-library/media-library-parts.d.ts +4 -3
  162. package/dist/components/features/media-library/media-library-views.d.ts +4 -3
  163. package/dist/components/features/media-library/media-library.d.ts +1 -1
  164. package/dist/components/features/media-library/media-library.strings.d.ts +12 -13
  165. package/dist/components/features/media-library/media-library.types.d.ts +11 -9
  166. package/dist/components/features/media-library/media-resource-gallery.d.ts +1 -1
  167. package/dist/components/features/media-library/use-media-library.d.ts +1 -4
  168. package/dist/components/features/overlays/action-overlay-frame.d.ts +1 -1
  169. package/dist/components/features/overlays/index.d.ts +1 -1
  170. package/dist/components/features/overlays/overlay-parts.d.ts +3 -3
  171. package/dist/components/features/overlays/overlays.types.d.ts +8 -7
  172. package/dist/components/features/rich-text-editor/index.d.ts +0 -1
  173. package/dist/components/features/table/data-table-body.d.ts +1 -1
  174. package/dist/components/features/table/data-table-expanded-row.d.ts +27 -0
  175. package/dist/components/features/table/data-table-header.d.ts +1 -1
  176. package/dist/components/features/table/data-table-size.d.ts +1 -1
  177. package/dist/components/features/table/data-table.d.ts +1 -1
  178. package/dist/components/features/table/index.d.ts +1 -1
  179. package/dist/components/features/table/table-helpers.d.ts +9 -3
  180. package/dist/components/features/table/table.strings.d.ts +11 -0
  181. package/dist/components/features/table/table.types.d.ts +60 -2
  182. package/dist/components/features/theme-tweaker/index.d.ts +1 -1
  183. package/dist/components/features/theme-tweaker/theme-tweaker.strings.d.ts +1 -1
  184. package/dist/components/features/theme-tweaker/theme-tweaker.types.d.ts +6 -10
  185. package/dist/components/features/theme-tweaker/theme-tweaker.utils.d.ts +22 -6
  186. package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
  187. package/dist/components/layout/auth/auth.d.ts +1 -1
  188. package/dist/components/layout/auth/auth.types.d.ts +1 -1
  189. package/dist/components/primitives/value.d.ts +3 -1
  190. package/dist/containers-B8d8U9GS.js +2 -0
  191. package/dist/{copyable-H1TUEY-H.js → copyable-D9Okb1w6.js} +12 -11
  192. package/dist/core.css +2 -2
  193. package/dist/css/access.css +2 -1
  194. package/dist/css/accordion.css +2 -1
  195. package/dist/css/action-menu.css +2 -1
  196. package/dist/css/activities.css +2 -1
  197. package/dist/css/ai-chat.css +2 -1
  198. package/dist/css/analytics.css +2 -1
  199. package/dist/css/app-shell.css +2 -1
  200. package/dist/css/aspect-ratio.css +2 -1
  201. package/dist/css/async-preview.css +2 -1
  202. package/dist/css/auth.css +2 -1
  203. package/dist/css/avatar.css +2 -1
  204. package/dist/css/badge.css +2 -1
  205. package/dist/css/batch-action-bar.css +2 -1
  206. package/dist/css/buttons.css +2 -1
  207. package/dist/css/cards.css +2 -1
  208. package/dist/css/carousel.css +2 -1
  209. package/dist/css/chart.css +2 -1
  210. package/dist/css/choice-inputs.css +2 -1
  211. package/dist/css/combobox.css +2 -1
  212. package/dist/css/combobox2.css +2 -1
  213. package/dist/css/command.css +2 -1
  214. package/dist/css/comments.css +2 -1
  215. package/dist/css/commerce.css +2 -1
  216. package/dist/css/containers.css +2 -1
  217. package/dist/css/copyable.css +2 -1
  218. package/dist/css/data-view.css +2 -1
  219. package/dist/css/date-pickers.css +2 -1
  220. package/dist/css/display.css +2 -1
  221. package/dist/css/dropdown-menu.css +2 -1
  222. package/dist/css/event-calendar.css +2 -1
  223. package/dist/css/feedback.css +2 -1
  224. package/dist/css/filters.css +2 -1
  225. package/dist/css/forms-numeric.css +2 -1
  226. package/dist/css/forms.css +2 -1
  227. package/dist/css/global-search.css +2 -1
  228. package/dist/css/header.css +2 -1
  229. package/dist/css/hover-card.css +2 -1
  230. package/dist/css/input-group.css +2 -1
  231. package/dist/css/item.css +2 -1
  232. package/dist/css/kanban.css +2 -1
  233. package/dist/css/label.css +2 -1
  234. package/dist/css/map.css +2 -1
  235. package/dist/css/media-library.css +2 -1
  236. package/dist/css/mentions.css +2 -1
  237. package/dist/css/menubar.css +2 -1
  238. package/dist/css/navigation-menu.css +2 -1
  239. package/dist/css/navigation.css +2 -1
  240. package/dist/css/navigation2.css +2 -1
  241. package/dist/css/onboarding.css +2 -1
  242. package/dist/css/otp-input.css +2 -1
  243. package/dist/css/overlay.css +2 -1
  244. package/dist/css/overlays.css +2 -1
  245. package/dist/css/page.css +2 -1
  246. package/dist/css/popover-menu.css +2 -1
  247. package/dist/css/popover.css +2 -1
  248. package/dist/css/primitives.css +2 -1
  249. package/dist/css/products.css +2 -1
  250. package/dist/css/qr-code.css +2 -1
  251. package/dist/css/repeaters.css +2 -1
  252. package/dist/css/resizable.css +2 -1
  253. package/dist/css/resource-assignment.css +2 -1
  254. package/dist/css/resource.css +2 -1
  255. package/dist/css/rich-text-editor.css +2 -1
  256. package/dist/css/schema-form.css +2 -1
  257. package/dist/css/sidebar.css +2 -1
  258. package/dist/css/sidebar2.css +2 -1
  259. package/dist/css/skeleton.css +2 -1
  260. package/dist/css/spinner.css +2 -1
  261. package/dist/css/structure.css +2 -1
  262. package/dist/css/sync.css +2 -1
  263. package/dist/css/table.css +2 -1
  264. package/dist/css/table2.css +2 -1
  265. package/dist/css/text-inputs.css +2 -1
  266. package/dist/css/theme-tweaker.css +2 -1
  267. package/dist/css/timeline.css +2 -1
  268. package/dist/css/timelines.css +2 -1
  269. package/dist/css/toaster.css +2 -1
  270. package/dist/css/toggle.css +2 -1
  271. package/dist/css/toolbar.css +2 -1
  272. package/dist/css/tooltip.css +2 -1
  273. package/dist/css/typography.css +2 -1
  274. package/dist/css/upload.css +2 -1
  275. package/dist/css/value-inputs.css +2 -1
  276. package/dist/css/workspace.css +2 -1
  277. package/dist/css-graph.json +1027 -0
  278. package/dist/date-pickers-BwCwKIVM.js +685 -0
  279. package/dist/{dialog-CtFCuTUF.js → dialog-CAnwRNrm.js} +1 -1
  280. package/dist/display-a7AoX_u7.js +664 -0
  281. package/dist/dropdown-menu-Br8kvjrF.js +235 -0
  282. package/dist/empty.js +0 -0
  283. package/dist/features/actions.js +6 -6
  284. package/dist/features/activities.js +219 -216
  285. package/dist/features/ai-chat.js +593 -565
  286. package/dist/features/async-preview.js +105 -286
  287. package/dist/features/combobox.js +328 -314
  288. package/dist/features/comments.js +1 -1
  289. package/dist/features/data-view.js +56 -55
  290. package/dist/features/event-calendar.js +189 -185
  291. package/dist/features/filters.js +1 -1
  292. package/dist/features/global-search.js +259 -260
  293. package/dist/features/kanban.js +39 -37
  294. package/dist/features/map.js +357 -354
  295. package/dist/features/media-library.js +931 -931
  296. package/dist/features/mentions.js +1 -1
  297. package/dist/features/overlays.js +1 -1
  298. package/dist/features/products.js +950 -942
  299. package/dist/features/resource-assignment.js +39 -37
  300. package/dist/features/resource.js +70 -71
  301. package/dist/features/rich-text-editor.js +2 -2
  302. package/dist/features/schema-form.js +342 -338
  303. package/dist/features/sync.js +14 -12
  304. package/dist/features/table.js +1 -1
  305. package/dist/features/theme-tweaker.js +1002 -962
  306. package/dist/feedback-D4qVsKlD.js +430 -0
  307. package/dist/{filters-DOLKRSmb.js → filters-BhsTkWpZ.js} +386 -383
  308. package/dist/forms-C0WeNPFF.js +250 -0
  309. package/dist/forms-numeric-IwQ1ltNf.js +582 -0
  310. package/dist/hooks/use-native-dialog.d.ts +1 -1
  311. package/dist/index.js +2 -2
  312. package/dist/input-group-HS_Z0Ei_.js +119 -0
  313. package/dist/item-M2pmpWXh.js +150 -0
  314. package/dist/{label-DumoMDm6.js → label-HOBXAscw.js} +7 -5
  315. package/dist/layout/app-shell.js +4 -2
  316. package/dist/layout/auth.js +102 -100
  317. package/dist/layout/header.js +190 -180
  318. package/dist/layout/navigation.js +1 -1
  319. package/dist/layout/page.js +18 -16
  320. package/dist/layout/settings.js +2 -2
  321. package/dist/layout/sidebar.js +50 -46
  322. package/dist/layout/workspace.js +71 -69
  323. package/dist/lib/action-presentation.d.ts +3 -3
  324. package/dist/lib/component-vocabulary.d.ts +2 -2
  325. package/dist/lib/css-length.d.ts +2 -0
  326. package/dist/lib/responsive.d.ts +1 -1
  327. package/dist/lib/theming/index.d.ts +1 -0
  328. package/dist/lib/theming/recipes.d.ts +2 -2
  329. package/dist/lib/theming/themes/dense.d.ts +3 -0
  330. package/dist/lib/theming/themes/editorial.d.ts +3 -0
  331. package/dist/lib/theming/themes/index.d.ts +8 -0
  332. package/dist/lib/theming/themes/pair.d.ts +7 -0
  333. package/dist/lib/theming/themes/sharp.d.ts +3 -0
  334. package/dist/lib/theming/themes/soft.d.ts +3 -0
  335. package/dist/lib/theming/themes/types.d.ts +12 -0
  336. package/dist/lib/ui-provider/index.d.ts +1 -1
  337. package/dist/lib/ui-provider/scope.d.ts +5 -8
  338. package/dist/lib/ui-provider/tokens.d.ts +11 -3
  339. package/dist/lib/ui-provider/tokens.generated.d.ts +6 -4
  340. package/dist/lib/ui-provider/types.d.ts +17 -19
  341. package/dist/lib/ui-provider/ui-scope.d.ts +1 -1
  342. package/dist/{mentions-BbsEHlcH.js → mentions-BOxbigwp.js} +113 -111
  343. package/dist/navigation-Bgu7Vc0M.js +622 -0
  344. package/dist/navigation-DiYACqpE.js +216 -0
  345. package/dist/overlay-BuQOl8aP.js +356 -0
  346. package/dist/{overlays-DvVoS3td.js → overlays-1sULyytH.js} +77 -75
  347. package/dist/popover-CA7SP_iz.js +127 -0
  348. package/dist/popover-menu-QXgQeWeG.js +192 -0
  349. package/dist/{primitives-D0bdDozz.js → primitives-BskKlf35.js} +181 -178
  350. package/dist/primitives.js +1 -1
  351. package/dist/profiles/admin.json +6 -36
  352. package/dist/profiles/general.json +6 -96
  353. package/dist/repeaters-CeH20dvr.js +445 -0
  354. package/dist/rich-text-editor-D_Ppm8yh.js +491 -0
  355. package/dist/{sheet-CKcmRbJ9.js → sheet-CJ1-OAla.js} +3 -3
  356. package/dist/sidebar-D8uGqxio.js +421 -0
  357. package/dist/skeleton-BTKNKTdj.js +173 -0
  358. package/dist/spinner-Tc1QCnxM.js +30 -0
  359. package/dist/{structure-D0WGQAP3.js → structure-CynEZ-OY.js} +15 -23
  360. package/dist/style.css +1 -1
  361. package/dist/styles/TOKENS.md +116 -275
  362. package/dist/styles/animation.css +114 -0
  363. package/dist/styles/base.css +7 -6
  364. package/dist/styles/fields.css +45 -63
  365. package/dist/styles/focus.css +12 -0
  366. package/dist/styles/forced-colors.css +11 -10
  367. package/dist/styles/index.css +23 -30
  368. package/dist/styles/map.css +45 -34
  369. package/dist/styles/mentions.css +14 -52
  370. package/dist/styles/overlays.css +7 -7
  371. package/dist/styles/tailwind.css +76 -127
  372. package/dist/styles/targets.css +3 -3
  373. package/dist/styles/theme/colour.css +86 -0
  374. package/dist/styles/theme/density.css +31 -0
  375. package/dist/styles/theme/elevation.css +9 -0
  376. package/dist/styles/theme/layout.css +18 -0
  377. package/dist/styles/theme/motion.css +18 -0
  378. package/dist/styles/theme/shape.css +12 -0
  379. package/dist/styles/theme/size.css +10 -0
  380. package/dist/styles/theme/spacing.css +11 -0
  381. package/dist/styles/theme/typography.css +20 -0
  382. package/dist/styles/tone.css +61 -0
  383. package/dist/table-B7dtIFUx.js +1262 -0
  384. package/dist/table-Ds_eO9av.js +191 -0
  385. package/dist/tailwind.css +76 -127
  386. package/dist/text-inputs-BboE77nZ.js +395 -0
  387. package/dist/theming-C5ygF5uf.js +292 -0
  388. package/dist/theming.js +2 -2
  389. package/dist/{timeline-BdaGRyj-.js → timeline-BR_jNgvz.js} +57 -49
  390. package/dist/{timelines-BB7550mz.js → timelines-DXG1BfIN.js} +69 -67
  391. package/dist/{toaster-bBMgXm8z.js → toaster-CXL8L7Mm.js} +106 -99
  392. package/dist/tokens.json +1027 -636
  393. package/dist/toolbar-DBK-c4yy.js +74 -0
  394. package/dist/tooltip-BPYP-jUm.js +76 -0
  395. package/dist/{typography-BkxEiwQ1.js → typography-DmeR05Er.js} +87 -53
  396. package/dist/{ui-provider-Cmoq6i_D.js → ui-provider-DpzLUD12.js} +117 -69
  397. package/dist/ui-provider.js +1 -1
  398. package/dist/upload-CYuoJykZ.js +968 -0
  399. package/dist/use-async-preview-BFwf9ElY.js +188 -0
  400. package/dist/value-inputs-ng8aVJJZ.js +728 -0
  401. package/docs/README.md +13 -3
  402. package/docs/build/browser-composition-fixture.ts +28 -0
  403. package/docs/build/recipes.md +11484 -10723
  404. package/docs/generated/component-index.json +9809 -9169
  405. package/docs/generated/components/INDEX.md +5 -5
  406. package/docs/generated/components/base--accordion.md +51 -2
  407. package/docs/generated/components/base--action-menu.md +14 -15
  408. package/docs/generated/components/base--alert-dialog.md +3 -4
  409. package/docs/generated/components/base--aspect-ratio.md +3 -4
  410. package/docs/generated/components/base--avatar.md +7 -7
  411. package/docs/generated/components/base--badge.md +159 -27
  412. package/docs/generated/components/base--batch-action-bar.md +6 -7
  413. package/docs/generated/components/base--buttons.md +151 -47
  414. package/docs/generated/components/base--cards.md +107 -14
  415. package/docs/generated/components/base--carousel.md +1 -2
  416. package/docs/generated/components/base--chart.md +44 -8
  417. package/docs/generated/components/base--choice-inputs.md +10 -11
  418. package/docs/generated/components/base--combobox.md +3 -4
  419. package/docs/generated/components/base--command.md +6 -6
  420. package/docs/generated/components/base--context-menu.md +1 -2
  421. package/docs/generated/components/base--copyable.md +6 -7
  422. package/docs/generated/components/base--date-pickers.md +6 -7
  423. package/docs/generated/components/base--dialog.md +6 -7
  424. package/docs/generated/components/base--direction.md +1 -1
  425. package/docs/generated/components/base--display.md +234 -54
  426. package/docs/generated/components/base--dropdown-menu.md +6 -7
  427. package/docs/generated/components/base--feedback.md +71 -18
  428. package/docs/generated/components/base--forms-numeric.md +6 -7
  429. package/docs/generated/components/base--forms.md +84 -14
  430. package/docs/generated/components/base--hover-card.md +3 -4
  431. package/docs/generated/components/base--input-group.md +27 -30
  432. package/docs/generated/components/base--item.md +8 -9
  433. package/docs/generated/components/base--label.md +2 -3
  434. package/docs/generated/components/base--menubar.md +2 -4
  435. package/docs/generated/components/base--navigation-menu.md +2 -3
  436. package/docs/generated/components/base--navigation.md +2 -3
  437. package/docs/generated/components/base--otp-input.md +3 -4
  438. package/docs/generated/components/base--overlay.md +56 -47
  439. package/docs/generated/components/base--popover-menu.md +7 -8
  440. package/docs/generated/components/base--popover.md +9 -10
  441. package/docs/generated/components/base--qr-code.md +7 -8
  442. package/docs/generated/components/base--repeaters.md +6 -7
  443. package/docs/generated/components/base--resizable.md +2 -3
  444. package/docs/generated/components/base--sheet.md +12 -13
  445. package/docs/generated/components/base--sidebar.md +9 -11
  446. package/docs/generated/components/base--skeleton.md +6 -7
  447. package/docs/generated/components/base--slot.md +1 -1
  448. package/docs/generated/components/base--spinner.md +5 -7
  449. package/docs/generated/components/base--structure.md +320 -70
  450. package/docs/generated/components/base--table.md +61 -3
  451. package/docs/generated/components/base--text-inputs.md +17 -18
  452. package/docs/generated/components/base--timeline.md +45 -4
  453. package/docs/generated/components/base--toaster.md +43 -12
  454. package/docs/generated/components/base--toggle.md +11 -12
  455. package/docs/generated/components/base--toolbar.md +7 -8
  456. package/docs/generated/components/base--tooltip.md +5 -6
  457. package/docs/generated/components/base--typography.md +317 -32
  458. package/docs/generated/components/base--upload.md +8 -9
  459. package/docs/generated/components/base--value-inputs.md +9 -38
  460. package/docs/generated/components/{admin--patterns--access.md → blocks--admin--access.md} +15 -6
  461. package/docs/generated/components/{admin--patterns--commerce.md → blocks--admin--commerce.md} +40 -41
  462. package/docs/generated/components/{patterns--analytics.md → blocks--analytics.md} +57 -14
  463. package/docs/generated/components/{patterns--onboarding.md → blocks--onboarding.md} +6 -7
  464. package/docs/generated/components/{patterns--timelines.md → blocks--timelines.md} +6 -7
  465. package/docs/generated/components/features--actions.md +8 -18
  466. package/docs/generated/components/features--activities.md +31 -32
  467. package/docs/generated/components/features--ai-chat.md +15 -15
  468. package/docs/generated/components/features--async-preview.md +5 -6
  469. package/docs/generated/components/features--combobox.md +71 -5
  470. package/docs/generated/components/features--comments.md +0 -1
  471. package/docs/generated/components/features--data-view.md +63 -8
  472. package/docs/generated/components/features--event-calendar.md +1 -2
  473. package/docs/generated/components/features--filters.md +11 -2
  474. package/docs/generated/components/features--global-search.md +1 -2
  475. package/docs/generated/components/features--kanban.md +1 -2
  476. package/docs/generated/components/features--map.md +1 -2
  477. package/docs/generated/components/features--media-library.md +105 -38
  478. package/docs/generated/components/features--mentions.md +7 -7
  479. package/docs/generated/components/features--overlays.md +75 -22
  480. package/docs/generated/components/features--products.md +10 -11
  481. package/docs/generated/components/features--resource-assignment.md +2 -3
  482. package/docs/generated/components/features--resource.md +3 -4
  483. package/docs/generated/components/features--rich-text-editor.md +42 -13
  484. package/docs/generated/components/features--schema-form.md +1 -2
  485. package/docs/generated/components/features--sync.md +2 -3
  486. package/docs/generated/components/features--table.md +162 -12
  487. package/docs/generated/components/features--theme-tweaker.md +30 -15
  488. package/docs/generated/components/forms.md +2 -2
  489. package/docs/generated/components/layout--app-shell.md +41 -11
  490. package/docs/generated/components/layout--auth.md +8 -9
  491. package/docs/generated/components/layout--containers.md +40 -1
  492. package/docs/generated/components/layout--header.md +2 -3
  493. package/docs/generated/components/layout--navigation.md +0 -1
  494. package/docs/generated/components/layout--page.md +33 -5
  495. package/docs/generated/components/layout--settings.md +0 -1
  496. package/docs/generated/components/layout--sidebar.md +47 -7
  497. package/docs/generated/components/layout--workspace.md +3 -4
  498. package/docs/generated/components/primitives.md +128 -17
  499. package/docs/generated/components/theming.md +147 -4
  500. package/docs/generated/components/ui-provider.md +96 -78
  501. package/docs/generated/composition-ladder.md +8 -8
  502. package/docs/generated/consumer-contract.json +5736 -0
  503. package/docs/generated/imports.md +104 -104
  504. package/docs/generated/migration-broad-imports.json +267 -90
  505. package/docs/generated/migration-broad-imports.md +266 -101
  506. package/docs/generated/migration-codemod.json +365 -70
  507. package/docs/generated/migration.md +665 -95
  508. package/docs/generated/profiles.md +27 -27
  509. package/docs/generated/public-api.md +104 -102
  510. package/docs/generated/recipes.json +755 -810
  511. package/docs/generated/workflows/communications-overview/analytics/communications-reference.tsx +19 -0
  512. package/docs/generated/workflows/index.json +691 -0
  513. package/docs/generated/workflows/media-picking/media-library/media-picking-reference.tsx +63 -0
  514. package/docs/generated/workflows/media-picking/media-library/reference-data.ts +3 -0
  515. package/docs/generated/workflows/multi-section-form/form-workflow/multi-section-reference.tsx +46 -0
  516. package/docs/generated/workflows/nested-action-flow/action-overlays/nested-action-reference.tsx +39 -0
  517. package/docs/generated/workflows/record-detail/page-layout/record-detail-reference.tsx +24 -0
  518. package/docs/generated/workflows/resource-index/data-view/resource-index-reference.tsx +51 -0
  519. package/docs/generated/workflows/scoped-resource-selection/combobox/scoped-resource-reference.tsx +50 -0
  520. package/docs/generated/workflows/website-content-editor/media-library/reference-data.ts +3 -0
  521. package/docs/generated/workflows/website-content-editor/rich-text-editor/website-content-reference.tsx +33 -0
  522. package/docs/generated/workflows/workspace-navigation/app-shell/workspace-navigation-reference.tsx +26 -0
  523. package/docs/learn/api-compatibility.md +5 -4
  524. package/docs/learn/blocks.md +123 -0
  525. package/docs/learn/composition.md +100 -19
  526. package/docs/learn/forms.md +23 -3
  527. package/docs/learn/framework-wiring.md +41 -13
  528. package/docs/learn/i18n.md +4 -2
  529. package/docs/learn/installation.md +60 -31
  530. package/docs/learn/migration.md +156 -5
  531. package/docs/learn/provider-and-scoping.md +37 -25
  532. package/docs/learn/reference-workflows.md +43 -0
  533. package/docs/learn/structure-and-spacing.md +147 -0
  534. package/docs/learn/theming.md +174 -131
  535. package/docs/learn/troubleshooting.md +88 -30
  536. package/docs/learn/verification.md +60 -5
  537. package/package.json +42 -473
  538. package/scripts/consumer/codemod.mjs +50 -32
  539. package/scripts/consumer/contract-reader.mjs +42 -0
  540. package/scripts/consumer/css-scan.mjs +51 -0
  541. package/scripts/consumer/diagnose.mjs +136 -0
  542. package/scripts/consumer/find-component.mjs +30 -17
  543. package/scripts/consumer/install-skill.mjs +93 -11
  544. package/src/styles/TOKENS.md +116 -275
  545. package/dist/accordion-6YPJ9XRO.js +0 -135
  546. package/dist/admin/patterns/access.css +0 -15
  547. package/dist/admin/patterns/commerce.css +0 -29
  548. package/dist/admin/patterns/commerce.js +0 -2493
  549. package/dist/avatar-CS7zow2q.js +0 -85
  550. package/dist/badge-CxOuTfVr.js +0 -63
  551. package/dist/base/accordion.css +0 -3
  552. package/dist/base/action-menu.css +0 -6
  553. package/dist/base/alert-dialog.css +0 -4
  554. package/dist/base/aspect-ratio.css +0 -2
  555. package/dist/base/avatar.css +0 -4
  556. package/dist/base/badge.css +0 -2
  557. package/dist/base/batch-action-bar.css +0 -5
  558. package/dist/base/buttons.css +0 -4
  559. package/dist/base/cards.css +0 -13
  560. package/dist/base/carousel.css +0 -5
  561. package/dist/base/chart.css +0 -2
  562. package/dist/base/choice-inputs.css +0 -10
  563. package/dist/base/combobox.css +0 -3
  564. package/dist/base/command.css +0 -9
  565. package/dist/base/context-menu.css +0 -2
  566. package/dist/base/copyable.css +0 -6
  567. package/dist/base/date-pickers.css +0 -11
  568. package/dist/base/dialog.css +0 -4
  569. package/dist/base/display.css +0 -8
  570. package/dist/base/dropdown-menu.css +0 -2
  571. package/dist/base/feedback.css +0 -5
  572. package/dist/base/forms-numeric.css +0 -12
  573. package/dist/base/forms.css +0 -14
  574. package/dist/base/hover-card.css +0 -2
  575. package/dist/base/input-group.css +0 -6
  576. package/dist/base/item.css +0 -9
  577. package/dist/base/label.css +0 -3
  578. package/dist/base/menubar.css +0 -2
  579. package/dist/base/navigation-menu.css +0 -2
  580. package/dist/base/navigation.css +0 -12
  581. package/dist/base/otp-input.css +0 -9
  582. package/dist/base/overlay.css +0 -4
  583. package/dist/base/popover-menu.css +0 -11
  584. package/dist/base/popover.css +0 -3
  585. package/dist/base/qr-code.css +0 -2
  586. package/dist/base/repeaters.css +0 -18
  587. package/dist/base/resizable.css +0 -2
  588. package/dist/base/sheet.css +0 -4
  589. package/dist/base/sidebar.css +0 -12
  590. package/dist/base/skeleton.css +0 -9
  591. package/dist/base/spinner.css +0 -2
  592. package/dist/base/structure.css +0 -2
  593. package/dist/base/table.css +0 -3
  594. package/dist/base/text-inputs.css +0 -2
  595. package/dist/base/timeline.css +0 -9
  596. package/dist/base/toaster.css +0 -2
  597. package/dist/base/toggle.css +0 -2
  598. package/dist/base/toolbar.css +0 -5
  599. package/dist/base/tooltip.css +0 -2
  600. package/dist/base/typography.css +0 -2
  601. package/dist/base/upload.css +0 -10
  602. package/dist/base/value-inputs.css +0 -14
  603. package/dist/buttons-CqXKWty3.js +0 -179
  604. package/dist/cards-C6Ulbkw7.js +0 -271
  605. package/dist/chart-nomhJ87z.js +0 -193
  606. package/dist/choice-inputs-OUDn0kQw.js +0 -680
  607. package/dist/combobox-C8oP92bT.js +0 -266
  608. package/dist/command-Bp3B6pUu.js +0 -143
  609. package/dist/comments-CAnDlyXO.js +0 -1438
  610. package/dist/components/admin/patterns/index.d.ts +0 -2
  611. package/dist/components/features/rich-text-editor/exec-command-engine.d.ts +0 -2
  612. package/dist/components/patterns/index.d.ts +0 -3
  613. package/dist/css/styles.css +0 -1
  614. package/dist/date-pickers-DOwIT-Nk.js +0 -661
  615. package/dist/display-B3Q17h5z.js +0 -645
  616. package/dist/dropdown-menu-TyNLCLML.js +0 -223
  617. package/dist/features/actions.css +0 -11
  618. package/dist/features/activities.css +0 -25
  619. package/dist/features/ai-chat.css +0 -14
  620. package/dist/features/async-preview.css +0 -10
  621. package/dist/features/combobox.css +0 -12
  622. package/dist/features/comments.css +0 -24
  623. package/dist/features/data-view.css +0 -31
  624. package/dist/features/event-calendar.css +0 -17
  625. package/dist/features/filters.css +0 -24
  626. package/dist/features/global-search.css +0 -19
  627. package/dist/features/kanban.css +0 -7
  628. package/dist/features/map.css +0 -15
  629. package/dist/features/media-library.css +0 -27
  630. package/dist/features/mentions.css +0 -17
  631. package/dist/features/overlays.css +0 -11
  632. package/dist/features/products.css +0 -29
  633. package/dist/features/resource-assignment.css +0 -14
  634. package/dist/features/resource.css +0 -15
  635. package/dist/features/rich-text-editor.css +0 -8
  636. package/dist/features/schema-form.css +0 -22
  637. package/dist/features/sync.css +0 -11
  638. package/dist/features/table.css +0 -20
  639. package/dist/features/theme-tweaker.css +0 -27
  640. package/dist/feedback-DRerHGuV.js +0 -469
  641. package/dist/forms-CPrGGif_.js +0 -242
  642. package/dist/forms-numeric-CPVsL7Vf.js +0 -569
  643. package/dist/index.css +0 -3
  644. package/dist/input-group-BYe0rhoB.js +0 -126
  645. package/dist/item-B3yQ26as.js +0 -146
  646. package/dist/layout/app-shell.css +0 -13
  647. package/dist/layout/auth.css +0 -14
  648. package/dist/layout/containers.css +0 -2
  649. package/dist/layout/header.css +0 -20
  650. package/dist/layout/navigation.css +0 -11
  651. package/dist/layout/page.css +0 -15
  652. package/dist/layout/settings.css +0 -16
  653. package/dist/layout/sidebar.css +0 -16
  654. package/dist/layout/workspace.css +0 -15
  655. package/dist/navigation-CsqTA16F.js +0 -614
  656. package/dist/navigation-DzxzPuwg.js +0 -202
  657. package/dist/overlay-WQOsLd69.js +0 -345
  658. package/dist/patterns/analytics.css +0 -15
  659. package/dist/patterns/onboarding.css +0 -11
  660. package/dist/patterns/timelines.css +0 -11
  661. package/dist/popover-DriLnIFc.js +0 -123
  662. package/dist/popover-menu-C2UCMAe7.js +0 -189
  663. package/dist/primitives.css +0 -3
  664. package/dist/repeaters-DuP1N0nw.js +0 -438
  665. package/dist/rich-text-editor-BQXFe9oN.js +0 -595
  666. package/dist/sidebar-D0N6ckJL.js +0 -412
  667. package/dist/skeleton-DGR9df28.js +0 -172
  668. package/dist/spinner-CUAVFecI.js +0 -52
  669. package/dist/styles/FACTORS.md +0 -36
  670. package/dist/styles/SCOPES.md +0 -86
  671. package/dist/styles/themes/default.css +0 -164
  672. package/dist/styles/theming/animation.css +0 -143
  673. package/dist/styles/theming/colors.css +0 -97
  674. package/dist/styles/theming/feedback.css +0 -17
  675. package/dist/styles/theming/field.css +0 -21
  676. package/dist/styles/theming/focus.css +0 -88
  677. package/dist/styles/theming/layers.css +0 -13
  678. package/dist/styles/theming/layout.css +0 -21
  679. package/dist/styles/theming/motion.css +0 -42
  680. package/dist/styles/theming/overlay.css +0 -52
  681. package/dist/styles/theming/sizing.css +0 -118
  682. package/dist/styles/theming/text.css +0 -30
  683. package/dist/styles/theming/typography.css +0 -26
  684. package/dist/styles/tokens/components.css +0 -22
  685. package/dist/styles/tokens/foundation.css +0 -80
  686. package/dist/styles/tokens/layout.css +0 -19
  687. package/dist/styles/tokens/palette.css +0 -88
  688. package/dist/styles/tokens/primitives.css +0 -18
  689. package/dist/styles/tokens/states.css +0 -77
  690. package/dist/table-BC4qqsUb.js +0 -180
  691. package/dist/table-BHDpjajL.js +0 -982
  692. package/dist/text-inputs-DF_lD7pA.js +0 -385
  693. package/dist/theming-D6KRU7hO.js +0 -104
  694. package/dist/toolbar-DWRywF0R.js +0 -68
  695. package/dist/tooltip-t1VQQ2tZ.js +0 -73
  696. package/dist/upload-B38YZeFJ.js +0 -938
  697. package/dist/value-inputs-Q4ymjXlV.js +0 -716
  698. package/src/styles/FACTORS.md +0 -36
  699. package/src/styles/SCOPES.md +0 -86
  700. /package/dist/components/{admin/patterns → blocks/admin}/access/admin.strings.d.ts +0 -0
  701. /package/dist/components/{admin/patterns → blocks/admin}/access/credential-list.d.ts +0 -0
  702. /package/dist/components/{admin/patterns → blocks/admin}/access/index.d.ts +0 -0
  703. /package/dist/components/{admin/patterns → blocks/admin}/access/role-permissions.d.ts +0 -0
  704. /package/dist/components/{admin/patterns → blocks/admin}/access/sensitive-action.d.ts +0 -0
  705. /package/dist/components/{admin/patterns → blocks/admin}/commerce/account.d.ts +0 -0
  706. /package/dist/components/{admin/patterns → blocks/admin}/commerce/address-lines.d.ts +0 -0
  707. /package/dist/components/{admin/patterns → blocks/admin}/commerce/booking.d.ts +0 -0
  708. /package/dist/components/{admin/patterns → blocks/admin}/commerce/cart.d.ts +0 -0
  709. /package/dist/components/{admin/patterns → blocks/admin}/commerce/commerce.strings.d.ts +0 -0
  710. /package/dist/components/{admin/patterns → blocks/admin}/commerce/commerce.types.d.ts +0 -0
  711. /package/dist/components/{admin/patterns → blocks/admin}/commerce/format-amount.d.ts +0 -0
  712. /package/dist/components/{admin/patterns → blocks/admin}/commerce/index.d.ts +0 -0
  713. /package/dist/components/{admin/patterns → blocks/admin}/commerce/inventory-section.d.ts +0 -0
  714. /package/dist/components/{admin/patterns → blocks/admin}/commerce/invoice.d.ts +0 -0
  715. /package/dist/components/{admin/patterns → blocks/admin}/commerce/loyalty.d.ts +0 -0
  716. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-customer.d.ts +0 -0
  717. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-detail.d.ts +0 -0
  718. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-line-item.d.ts +0 -0
  719. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-transactions.d.ts +0 -0
  720. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order.d.ts +0 -0
  721. /package/dist/components/{admin/patterns → blocks/admin}/commerce/seo-listing.d.ts +0 -0
  722. /package/dist/components/{admin/patterns → blocks/admin}/commerce/seo-score.d.ts +0 -0
  723. /package/dist/components/{admin/patterns → blocks/admin}/commerce/summary-panel.d.ts +0 -0
  724. /package/dist/components/{patterns → blocks}/analytics/activity-heatmap.d.ts +0 -0
  725. /package/dist/components/{patterns → blocks}/analytics/analytics.types.d.ts +0 -0
  726. /package/dist/components/{patterns → blocks}/analytics/chart-card.d.ts +0 -0
  727. /package/dist/components/{patterns → blocks}/analytics/format-metric-value.d.ts +0 -0
  728. /package/dist/components/{patterns → blocks}/analytics/index.d.ts +0 -0
  729. /package/dist/components/{patterns → blocks}/analytics/metric-bar.d.ts +0 -0
  730. /package/dist/components/{patterns → blocks}/analytics/metric-comparison.d.ts +0 -0
  731. /package/dist/components/{patterns → blocks}/analytics/metric-gradient.d.ts +0 -0
  732. /package/dist/components/{patterns → blocks}/analytics/metric-grid.d.ts +0 -0
  733. /package/dist/components/{patterns → blocks}/analytics/metric-micro-grid.d.ts +0 -0
  734. /package/dist/components/{patterns → blocks}/analytics/metric-skeleton.d.ts +0 -0
  735. /package/dist/components/{patterns → blocks}/analytics/metric-trend-chip.d.ts +0 -0
  736. /package/dist/components/{patterns → blocks}/analytics/metric.d.ts +0 -0
  737. /package/dist/components/{patterns → blocks}/analytics/time-ruler.d.ts +0 -0
  738. /package/dist/components/{patterns → blocks}/onboarding/checklist.d.ts +0 -0
  739. /package/dist/components/{patterns → blocks}/onboarding/index.d.ts +0 -0
  740. /package/dist/components/{patterns → blocks}/onboarding/onboarding.strings.d.ts +0 -0
  741. /package/dist/components/{patterns → blocks}/timelines/changelog-timeline.d.ts +0 -0
  742. /package/dist/components/{patterns → blocks}/timelines/index.d.ts +0 -0
  743. /package/dist/components/{patterns → blocks}/timelines/milestones-timeline.d.ts +0 -0
  744. /package/dist/components/{patterns → blocks}/timelines/steps.d.ts +0 -0
  745. /package/dist/components/{patterns → blocks}/timelines/timelines.strings.d.ts +0 -0
  746. /package/dist/styles/{theming/breakpoints.css → breakpoints.css} +0 -0
@@ -2,14 +2,15 @@
2
2
  /*
3
3
  * Installs the themelia-ui agent skill (which component to use, its exact import, what to
4
4
  * avoid) into a project's .agents/ and/or .claude/ skills. Offline: reads the copy shipped
5
- * in this package. Replaces a previous install atomically; never a hand-written skill.
5
+ * in this package. Stages replacements and rolls back caught write failures; never replaces a hand-written skill.
6
6
  * node node_modules/themelia-ui/scripts/consumer/install-skill.mjs --project=. [--target=agents|claude|both]
7
7
  */
8
8
  import {
9
9
  cpSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync,
10
- statSync,
10
+ lstatSync,
11
11
  } from 'node:fs'
12
- import { dirname, join, relative, resolve } from 'node:path'
12
+ import { createHash } from 'node:crypto'
13
+ import { dirname, join, relative, resolve, sep } from 'node:path'
13
14
  import { fileURLToPath } from 'node:url'
14
15
 
15
16
  const HERE = dirname(fileURLToPath(import.meta.url))
@@ -30,17 +31,78 @@ export const TARGET_DIRECTORIES = {
30
31
 
31
32
  /** Whether a destination may be replaced: absent, or carrying our marker. */
32
33
  export function mayOverwrite(destination) {
34
+ if (existsSync(destination) && lstatSync(destination).isSymbolicLink()) return false
33
35
  const skill = join(destination, 'SKILL.md')
34
- if (!existsSync(skill)) return true
36
+ if (!existsSync(skill)) return !existsSync(destination) || readdirSync(destination).length === 0
35
37
  return readFileSync(skill, 'utf8').includes(GENERATED_MARKER)
36
38
  }
37
39
 
38
- export function installSkill({ project = '.', target = 'both', source = SOURCE } = {}) {
40
+ const hashFile = (file) => createHash('sha256').update(readFileSync(file)).digest('hex')
41
+ const inside = (root, file) => {
42
+ const path = relative(realpathSync(root), realpathSync(file))
43
+ return path !== '..' && !path.startsWith('../') && !path.startsWith('..\\')
44
+ }
45
+
46
+ /** A manifest is data, never permission to read paths outside the skill directory. */
47
+ export function readSkillManifest(root) {
48
+ const manifest = JSON.parse(readFileSync(join(root, 'manifest.json'), 'utf8'))
49
+ if (manifest.schemaVersion !== 1 || typeof manifest.packageVersion !== 'string' || !manifest.files || typeof manifest.files !== 'object' || Array.isArray(manifest.files)) throw new Error('unsupported skill manifest')
50
+ if (!manifest.files['SKILL.md']) throw new Error('skill manifest has no SKILL.md')
51
+ for (const [path, hash] of Object.entries(manifest.files)) {
52
+ if (!path || path === 'manifest.json' || path.startsWith('/') || path.includes('\\') || path.split('/').some((part) => !part || part === '.' || part === '..') || !/^[a-f0-9]{64}$/.test(hash)) throw new Error(`invalid skill manifest path or hash: ${path}`)
53
+ }
54
+ return manifest
55
+ }
56
+
57
+ /** Inspect installed copies without changing application policy or generated bytes. */
58
+ export function checkSkill({ project = '.', target = 'both', source = SOURCE } = {}) {
59
+ const names = target === 'both' ? ['agents', 'claude'] : [target]
60
+ if (names.some((name) => !(name in TARGET_DIRECTORIES))) throw new Error(`unknown --target=${target}; expected agents, claude or both`)
61
+ let expected
62
+ try {
63
+ expected = readSkillManifest(source)
64
+ const recorded = Object.keys(expected.files).sort()
65
+ const actual = listFiles(source).filter(file => file !== 'manifest.json')
66
+ if (JSON.stringify(recorded) !== JSON.stringify(actual)) throw new Error('packaged skill inventory differs from its manifest')
67
+ for (const [file, hash] of Object.entries(expected.files)) {
68
+ const path = join(source, file)
69
+ if (!inside(source, path) || hashFile(path) !== hash) throw new Error(`packaged skill differs from its manifest: ${file}`)
70
+ }
71
+ } catch (error) { return { packageVersion: null, targets: [], error: error.message, exitCode: 2 } }
72
+ const targets = names.map((name) => {
73
+ const destination = resolve(project, TARGET_DIRECTORIES[name])
74
+ const item = { target: name, status: 'missing', installedVersion: null, changedFiles: [], locallyModifiedFiles: [] }
75
+ if (!existsSync(destination)) return item
76
+ if (!mayOverwrite(destination)) return { ...item, status: 'unmanaged' }
77
+ let installed
78
+ try { installed = readSkillManifest(destination) } catch {
79
+ item.locallyModifiedFiles = listFiles(destination).filter(file => file !== 'manifest.json').filter(file => {
80
+ try { return !expected.files[file] || !inside(destination, join(destination, file)) || hashFile(join(destination, file)) !== expected.files[file] } catch { return true }
81
+ })
82
+ return { ...item, status: 'stale', changedFiles: ['manifest.json', ...item.locallyModifiedFiles] }
83
+ }
84
+ item.installedVersion = installed.packageVersion
85
+ item.locallyModifiedFiles = [...new Set([...Object.keys(installed.files), ...listFiles(destination).filter(file => file !== 'manifest.json')])].filter(file => {
86
+ try { return !installed.files[file] || !inside(destination, join(destination, file)) || hashFile(join(destination, file)) !== installed.files[file] } catch { return true }
87
+ }).sort()
88
+ const files = new Set([...Object.keys(expected.files), ...listFiles(destination).filter(file => file !== 'manifest.json')])
89
+ item.changedFiles = [...files].filter((file) => {
90
+ try { return !expected.files[file] || !inside(destination, join(destination, file)) || hashFile(join(destination, file)) !== expected.files[file] } catch { return true }
91
+ }).sort()
92
+ if (JSON.stringify(installed.files) !== JSON.stringify(expected.files)) item.changedFiles.push('manifest.json')
93
+ item.status = installed.packageVersion !== expected.packageVersion ? 'stale' : item.changedFiles.length ? 'modified' : 'current'
94
+ return item
95
+ })
96
+ return { packageVersion: expected.packageVersion, targets, exitCode: targets.every((item) => item.status === 'current') ? 0 : 1 }
97
+ }
98
+
99
+ export function installSkill({ project = '.', target = 'both', source = SOURCE, overwriteModified = false } = {}) {
39
100
  const targets = target === 'both' ? ['agents', 'claude'] : [target]
40
101
  if (targets.some((name) => !(name in TARGET_DIRECTORIES))) {
41
102
  throw new Error(`unknown --target=${target}; expected agents, claude or both`)
42
103
  }
43
104
  if (!existsSync(source)) throw new Error(`the packaged skill is missing at ${source}`)
105
+ for (const file of listFiles(source)) if (lstatSync(join(source, file)).isSymbolicLink()) throw new Error(`skill source contains a symlink: ${file}`)
44
106
 
45
107
  const nonce = `${process.pid}-${Date.now()}`
46
108
  const destinations = targets.map((name, index) => {
@@ -67,6 +129,10 @@ export function installSkill({ project = '.', target = 'both', source = SOURCE }
67
129
  )
68
130
  }
69
131
  }
132
+ const freshness = checkSkill({ project, target, source })
133
+ if (freshness.exitCode === 2) throw new Error(`invalid packaged skill metadata: ${freshness.error}`)
134
+ const modified = freshness.targets.filter(item => item.locallyModifiedFiles?.length)
135
+ if (modified.length && !overwriteModified) throw new Error(`modified generated files: ${modified.map(item => `${item.target}: ${item.locallyModifiedFiles.join(', ')}`).join('; ')}. Review these changes and preserve application policy separately; --overwrite-modified explicitly replaces them.`)
70
136
 
71
137
  try {
72
138
  for (const item of destinations) {
@@ -78,8 +144,6 @@ export function installSkill({ project = '.', target = 'both', source = SOURCE }
78
144
  renameSync(item.stage, item.destination)
79
145
  item.committed = true
80
146
  }
81
- for (const item of destinations) rmSync(item.backup, { recursive: true, force: true })
82
- return destinations.map(({ destination }) => destination)
83
147
  } catch (error) {
84
148
  for (const item of [...destinations].reverse()) {
85
149
  rmSync(item.stage, { recursive: true, force: true })
@@ -88,6 +152,12 @@ export function installSkill({ project = '.', target = 'both', source = SOURCE }
88
152
  }
89
153
  throw error
90
154
  }
155
+ // Commit is complete; discarded backups cannot support a later rollback.
156
+ for (const item of destinations) {
157
+ try { rmSync(item.backup, { recursive: true, force: true }) }
158
+ catch (error) { throw new Error(`Skill copies installed; backup cleanup failed at ${item.backup}: ${error.message}`) }
159
+ }
160
+ return destinations.map(({ destination }) => destination)
91
161
  }
92
162
 
93
163
  /** Every file under a directory, relative and sorted — for tests and for the summary. */
@@ -96,8 +166,8 @@ export function listFiles(root) {
96
166
  const walk = (dir) => {
97
167
  for (const entry of readdirSync(dir)) {
98
168
  const full = join(dir, entry)
99
- if (statSync(full).isDirectory()) walk(full)
100
- else out.push(relative(root, full))
169
+ if (lstatSync(full).isDirectory()) walk(full)
170
+ else out.push(relative(root, full).split(sep).join('/'))
101
171
  }
102
172
  }
103
173
  if (existsSync(root)) walk(root)
@@ -122,10 +192,13 @@ function runFromCommandLine(moduleUrl) {
122
192
 
123
193
  const invokedDirectly = runFromCommandLine(import.meta.url)
124
194
  if (invokedDirectly) {
125
- const USAGE = `usage: install-skill.mjs [--project=<directory>] [--target=agents|claude|both]
195
+ const USAGE = `usage: install-skill.mjs [--project=<directory>] [--target=agents|claude|both] [--check] [--json] [--overwrite-modified]
126
196
 
127
197
  Copies the packaged themelia-ui consumer skill into a project. Existing generated
128
- copies are replaced atomically; a same-named hand-written skill is never overwritten.`
198
+ copies are staged before replacement; caught write failures restore their backups.
199
+ A same-named hand-written skill is never overwritten.
200
+ --check is read-only: 0 current, 1 missing/drift/unmanaged, 2 invalid package metadata.
201
+ --overwrite-modified replaces reviewed local changes in a generated copy; unmanaged skills remain protected.`
129
202
  try {
130
203
  const options = { project: '.', target: 'both' }
131
204
  for (const argument of process.argv.slice(2)) {
@@ -133,10 +206,19 @@ copies are replaced atomically; a same-named hand-written skill is never overwri
133
206
  console.log(USAGE)
134
207
  process.exit(0)
135
208
  }
209
+ if (argument === '--check' || argument === '--json') { options[argument.slice(2)] = true; continue }
210
+ if (argument === '--overwrite-modified') { options.overwriteModified = true; continue }
136
211
  const match = argument.match(/^--(project|target)=(.+)$/)
137
212
  if (!match) throw new Error(`unknown argument ${argument}\n\n${USAGE}`)
138
213
  options[match[1]] = match[2]
139
214
  }
215
+ if (options.json && !options.check) throw new Error('--json requires --check')
216
+ if (options.check) {
217
+ const report = checkSkill(options)
218
+ console.log(options.json ? JSON.stringify(report, null, 2) : report.error ?? report.targets.map(item => `${item.target}: ${item.status} (installed ${item.installedVersion ?? 'unknown'}, package ${report.packageVersion})${item.changedFiles.length ? ` — ${item.changedFiles.join(', ')}` : ''}`).join('\n'))
219
+ if (report.exitCode === 1 && !options.json) console.log('Review modified/unmanaged copies; reinstall generated copies with install-skill.mjs --project=<directory>. Application policy stays in a separate skill.')
220
+ process.exit(report.exitCode)
221
+ }
140
222
  const installed = installSkill(options)
141
223
  for (const destination of installed) {
142
224
  console.log(`installed ${listFiles(destination).length} file(s) into ${relative(process.cwd(), destination) || '.'}`)
@@ -1,281 +1,122 @@
1
- # The token contract
2
-
3
- The theme is `themes/default.css` plus `tokens/*.css`: the global contract. The rest is
4
- cross-cutting wiring and component-owned measurements a theme author does not need to touch.
5
-
6
- **The theme surface is the global contract, not every token.** Only the contract is a theme
7
- surface: a theme author sets it and every component follows, because a component token is
8
- either derived from it or a measurement a rebrand has no opinion about.
9
-
10
- **A component's variables live with the component**: in its own module when one component
11
- reads them, in `styles/theming/` only when many do.
12
-
13
- The package's token checks fail on a `var()` nothing defines, a token JavaScript reads but no
14
- stylesheet declares, and a literal colour, radius, spacing or hairline in a component module.
15
-
16
- ## What earns a component token
17
-
18
- One of three things, and a name that does none of them is noise:
19
-
20
- * **arithmetic** — `--heatmap-pitch: calc(var(--heatmap-cell) + var(--space-2xs))`
21
- * **a variant or scope re-points it** — `--badge-hue`, declared once per tone
22
- * **JS writes it** — `style={{ "--micro-bar": "62%" }}`, the interface a chart arrives through
23
-
24
- A name like `--sidebar-p: var(--space-md)` does none: however often it is read, it is one
25
- name in front of one step, and every reader can say `--space-md`.
26
-
27
- Two exemptions. A **token family with a member re-declared in another file** is an
28
- extension point: inlining `--text-role-main` breaks the inverse Alert that re-points it for
29
- its own subtree. A token **named in TSX or a test** has a reader a `var()` scan cannot see.
30
-
31
- ## What a theme owns
32
-
33
- `themes/default.css` is shadcn-shaped, so a shadcn theme drops in.
34
-
35
- **Colour** resolves through the ramp in `tokens/palette.css`. The theme file holds no
36
- literals, so a rebrand moves the ramp rather than forty separate values.
37
-
38
- ```css
39
- --background --foreground --card --popover --primary --secondary
40
- --muted --accent --destructive --border --input --ring
41
- --chart-1…5 --sidebar-*
42
- ```
43
-
44
- **Edge** — the three properties that describe every border in the kit, kept together
45
- because they are one decision:
46
-
47
- ```css
48
- --border: var(--neutral-200); /* colour */
49
- --border-width: 1px; /* weight */
50
- --radius: 1rem; /* corner */
51
- ```
52
-
53
- **Shape** is two values. `--radius` rounds whatever holds other rounded things;
54
- `--radius-sm` rounds everything inside one or smaller than one. Both are plain values
55
- declared once at `:root`, and nothing derives one from the other, so a theme that changes
56
- one usually sets both. A container holding `--radius-sm` items insets them by the
57
- difference (`--space-md` at the defaults), so outer = inner + inset. There is no third
58
- radius token:
59
-
60
- | token | used by |
61
- |---|---|
62
- | `--radius` | wrappers: cards, dialogs, sheets, popovers, menus, listboxes, panels, columns, dropzones, framed media and maps, choice cards |
63
- | `--radius-sm` | items: buttons at every size, fields, checkboxes, glyph buttons, tabs, badges, chips and tags, rows, menu items, tooltips, calendar cells, thumbnails, icon tiles, bubbles, gallery tiles, and every wrapper nested inside a Card |
64
- | `--radius-pill` | shapes rather than corners: switches, tracks, skeleton bars, status dots, series swatches, a count overlaid on an icon |
65
- | `50%` | true circles only: avatars, radios, spinners, a circular IconBadge |
66
-
67
- Every other corner is arithmetic on the two radii:
68
-
69
- * an edge-to-edge child of a bordered wrapper: `calc(var(--radius) - var(--border-width))`
70
- * an item inset inside an item frame: `calc(var(--radius-sm) - <inset>)`
71
- * an item parked in a wrapper's corner at `--space-md`: plain `--radius-sm`, concentric by construction
72
- * data marks and arrow tips, which are not controls: `calc(var(--radius-sm) / 4)`
73
-
74
- A control is never smaller than its corner: an 18px checkbox and a 16px clear glyph take
75
- `--radius-sm` like a button, so a theme's item radius reaches every control.
76
-
77
- A state never sets a radius: hover, focus, open, active and invalid keep the resting corner.
78
- `--button-radius` is a hook that only ever takes one of the expressions above.
79
-
80
- ## What the ramps own
81
-
82
- `tokens/` holds the ladders the theme resolves against: the colour ramp, the type scale
83
- (`--text-xs` … `--text-2xl` and its paired line heights), the spacing scale, the content
84
- widths, and the raw tunables — `--height-control`, `--control-x`, `--row-x/y`,
85
- `--surface-x/y`, `--icon`, `--avatar`, `--scale`.
86
-
87
- **Spacing sits on a 2px grid.** Every length under `4rem` is a multiple of `0.125rem`, so
88
- neighbouring insets cannot land a pixel apart.
89
-
90
- **Type is exempt from the grid**, because a type ramp is geometric — `0.75`, `0.8125`,
91
- `0.875`, `1`, `1.125` — and lands off a 2px grid by construction. `0.8125rem` is the
92
- `--text-pxs` step, not a stray 13px.
1
+ # The theme contract
2
+
3
+ The theme is `src/styles/theme/*.css`: about eighty variables, declared once at `:root`. Every
4
+ colour is `light-dark(light, dark)`, and the element's `color-scheme` (set by `.light`,
5
+ `.dark`, `data-theme` or the operating system) picks the half. Component styles inherit
6
+ theme defaults rather than redeclaring them. Explicit scope overrides and density presets
7
+ replace the corresponding inherited values on their regions. A dark region inside a light
8
+ page needs no second set of colour declarations.
9
+
10
+ Components read the theme and compute the rest in the rule that uses it. The package's checks
11
+ fail on a `var()` nothing defines, a literal colour, radius, spacing or hairline in a
12
+ component module, and a rule keyed on `.dark` or `prefers-color-scheme`.
13
+
14
+ ## What the theme owns
15
+
16
+ | File | Variables |
17
+ | --- | --- |
18
+ | `colour.css` | `--background`, `--foreground`, `--card`, `--popover`, `--muted`, `--accent`, `--border`, `--input`, `--ring`, the tones and their foregrounds, `--link`, `--chart-1`…`5`, the `--sidebar-*` set, `--overlay-backdrop`, and the tint strengths `--tint` and `--tint-strong` |
19
+ | `shape.css` | `--radius`, `--radius-sm`, `--radius-pill`, `--border-width` |
20
+ | `spacing.css` | `--padding`, `--padding-sm`, `--gap`, `--gap-sm` |
21
+ | `size.css` | `--control-height`, `--control-height-sm`, `--icon-size`, `--icon-size-sm` |
22
+ | `typography.css` | the font stacks, the type steps `--text-xs`…`--text-2xl`, and the type factor `--text-scale` |
23
+ | `elevation.css` | `--shadow`, `--shadow-lg` |
24
+ | `motion.css` | `--duration-fast`, `--duration`, `--ease`, `--disabled-opacity` |
25
+ | `layout.css` | the z tiers, `--sidebar-width`, `--header-height`, `--content-width`, `--overlay-backdrop-filter` |
26
+ | `density.css` | the `compact`, `default` and `comfortable` presets, keyed on `data-density` |
27
+
28
+ The colour names are shadcn's, so a shadcn theme drops in.
29
+
30
+ ## Two of each
31
+
32
+ Every length, shadow, tint and duration comes as a pair. A value between or beyond them is
33
+ arithmetic on the pair in the rule that needs it, never a third variable.
34
+
35
+ | Pair | The first | The second |
36
+ | --- | --- | --- |
37
+ | `--radius`, `--radius-sm` | containers: cards, dialogs, popovers, menus, panels | anything inside one, or smaller: controls, rows, chips, badges, tooltips |
38
+ | `--padding`, `--padding-sm` | container insets | item insets: rows, cells, chips, fields |
39
+ | `--gap`, `--gap-sm` | between groups: fields, cards, sections | inside a group: icon and label, title and description |
40
+ | `--control-height`, `-sm` | every button, field, select and trigger | the dense step |
41
+ | `--icon-size`, `-sm` | icons beside text and in controls | icons in dense rows and chips |
42
+ | `--shadow`, `--shadow-lg` | raised: a framed card, a raised chip, a thumb, a hover lift | floating: popovers, menus, dialogs, toasts |
43
+ | `--tint`, `--tint-strong` | a soft fill: a selected row, a soft badge, a wash | a tinted line or edge |
44
+ | `--duration-fast`, `--duration` | state changes: hover, press, colour | entrances: popups, dialogs, panels |
45
+
46
+ **Corners.** `--radius-pill` is a shape, not a corner: switches, tracks, status dots. True
47
+ circles are `50%`. Every other corner is arithmetic: a nested corner is its container's
48
+ radius less the inset (`calc(var(--radius) - var(--padding-sm))`), an edge-to-edge child of a
49
+ bordered container is `calc(var(--radius) - var(--border-width))`, and a data mark or an
50
+ arrow tip is `calc(var(--radius-sm) / 4)`. A control is never smaller than its corner, and a
51
+ state (hover, focus, open, invalid) never sets a radius.
52
+
53
+ **Hairlines.** Every edge is `--border-width`; a mark (a quote bar, a drop line) and the
54
+ focus outline are twice it.
55
+
56
+ ## Colour roles
57
+
58
+ **Grounds.** `--background` is the page, the app shell and content dialogs; `--card` every
59
+ in-flow framed region; `--popover` anchored popups and palettes; `--sidebar` the shell
60
+ sidebar. A surface that paints a ground sets `--surface-ground` to it, and a sticky cell or a
61
+ fade reads `var(--surface-ground, var(--background))` to match what it sits on.
62
+
63
+ **Fills.** `--muted` is a well or a placeholder. A strip (a card footer, a zebra stripe) is
64
+ `--muted` at `--tint-strong`; a track or a skeleton is `--foreground` at `--tint`, which lifts
65
+ off any ground.
66
+
67
+ **State.** `--accent` is the one hover and current fill: control hover, the menu cursor, an
68
+ open trigger, the current navigation item, row hover. Selected is `--primary` at `--tint`
69
+ (a large surface adds a `--primary` edge), and a checked mark is solid `--primary`. Selection
70
+ outranks hover. Current navigation is neutral; the brand colour is for a value the user chose.
71
+
72
+ **Tones.** A component with a `tone` renders `data-tone`, and the tone rule
73
+ (`src/styles/tone.css`) gives it three variables instead of a colour name: `--tone` (the
74
+ hue: a solid fill, a tint, a line), `--tone-foreground` (text on the solid fill) and
75
+ `--tone-ink` (the hue as text or a glyph, on the page or on its own tint). The ink is the hue
76
+ itself in dark mode; in light mode it mixes toward the text colour as far as the hue needs to
77
+ hold 4.5:1.
78
+
79
+ **Edges.** `--border` is every divider and frame; `--input` the frame of a control, and a
80
+ control's hover edge mixes it toward `--foreground`. An invalid control's edge and outline
81
+ are `--destructive`.
82
+
83
+ **Focus.** One rule (`src/styles/focus.css`) outlines every focused element in `--ring` at
84
+ twice the hairline, offset by the same. A component that clips its content draws the outline
85
+ inside (`outline-offset: calc(var(--border-width) * -2)`); one that shows focus another way (a
86
+ menu's highlight) removes the outline only beside that equivalent.
87
+
88
+ **Contrast.** `src/lib/theming/theme-contrast.test.ts` measures the theme's text and focus
89
+ pairs in both modes and fails below WCAG AA.
90
+
91
+ ## Type
92
+
93
+ Type goes through `Text` and `Heading`. A module sets no `font-size`, `font-weight`,
94
+ `line-height`, `letter-spacing` or `font-family`; an element `Text` cannot wrap (a native
95
+ control, a button's label, a table cell) takes `textClassName({ size, weight, … })`. Each step
96
+ is `calc(var(--text-X) * var(--text-scale))` with its own line box, and colour reaches a
97
+ `Text` through its `type` prop, never a class.
98
+
99
+ ## Density and scale
100
+
101
+ A `data-density` preset sets the four lengths and the two control heights on its element, so
102
+ a region is denser or roomier and type keeps its size. The provider's `scale` computes the
103
+ same lengths, the icon sizes and the type factor in JavaScript and writes them, rounded to
104
+ whole pixels; CSS multiplies one factor, `--text-scale`, inside Text.
93
105
 
94
106
  ## What components own
95
107
 
96
- **A component reads the theme directly**: `background-color: var(--foreground)` in the
97
- module, not `--tooltip-bg: var(--foreground)` somewhere else and `var(--tooltip-bg)` here.
98
- A name with one reader is indirection. Where a component adjusts a theme value, it does the
99
- arithmetic in its own rule — `calc(var(--space-lg) * 2)` — rather than minting a name.
100
-
101
- A token earns a NAME only when one of these is true:
102
-
103
- | | |
104
- |---|---|
105
- | **arithmetic read by two or more rules** | a `calc()` whose readers must stay equal; a bare `var(--step)` is a pass-through however often it is read |
106
- | **an extension point** | another file re-declares it, so inlining kills the override |
107
- | **read from TS/TSX** | a runtime hook; the indirection is the API |
108
- | **an `--animate-*`** | CSS Modules scope keyframe names; inlined, the animation dies |
109
- | **a bare length a module may not hold** | a module may not hold raw px or rem spacing |
110
-
111
- Everything else belongs in the rule that uses it, and still may not hold a colour literal:
112
- colour always resolves through the palette.
113
-
114
- **An extension point is anything another file re-declares**, including a one-line rule:
115
- `.columns4 { --choice-card-min: 9rem; }` is how a variant re-points a token, and inlining
116
- the default silently kills all three column variants.
117
-
118
- There is no per-component scale factor. See [FACTORS.md](./FACTORS.md) for the three global
119
- factors, and [SCOPES.md](./SCOPES.md) for why derived values are declared at every scope
120
- boundary rather than once at `:root`.
121
-
122
- ## One token per role
123
-
124
- Every visual role has one token or one recipe. Reach for the role, not for a value that
125
- happens to look right, and never spell an ad hoc `color-mix()` step in a module: a pair the
126
- kit uses is declared once in `theming/colors.css`.
127
-
128
- **Grounds.** What a surface is painted with.
129
-
130
- | token | role |
131
- |---|---|
132
- | `--background` | the page, the app shell, and content dialogs, sheets and drawers |
133
- | `--card` | every in-flow framed region: Card, DataTable and DataView frames, the EventCalendar grid, panels |
134
- | `--popover` | anchored popups, command palettes (CommandDialog, GlobalSearchDialog), a raised segmented chip |
135
- | `--sidebar` | the shell sidebar |
136
- | `--field-bg` | the resting fill of every field and box control (transparent by default) |
137
-
138
- The **modal ground** is deliberate: a content dialog is the page brought forward and sits on
139
- `--background`; a palette is a popup that happens to be modal and sits on `--popover`. A
140
- dark lift for cards belongs in the theme's `--card`, never in one module.
141
-
142
- `--surface-ground` is "the surface I sit on". A surface that paints a ground (Card, popups,
143
- the sidebar, table and data-view frames) sets it; a sticky cell, a cut-out ring, an opaque
144
- halo or a fade reads `var(--surface-ground, var(--background))`, so it matches whatever it
145
- lands on. It is unset by default and reset at every colour island (SCOPES.md).
146
-
147
- **Neutral fills.**
148
-
149
- | token | role |
150
- |---|---|
151
- | `--muted` | a solid placeholder: media and thumbnail fallback, map canvas, QR fallback |
152
- | `--muted-50` | a recessed well: muted ContentBlock and Item, summary and diff panels, code, table head and foot cells, segmented and enclosed-tab tracks, unread rows, the secondary Alert |
153
- | `--muted-20` | a strip: Card, Overlay and GlobalSearch footers, zebra stripes, column-group bands, optional sections |
154
- | `--muted-40` `-60` `-80` | the empty-state illustration ramp, nothing else |
155
- | `--foreground-8` | a small neutral fill that must lift on any ground: avatar fallback, neutral IconBadge, tile or medallion, neutral chip, tag or mention, read-only plate |
156
- | `--foreground-10` | skeletons |
157
- | `--foreground-20` | every track or unfilled segment: Progress, Slider, Upload, metric and chip progress |
158
-
159
- There is no muted step between these: a well is `-50`, a strip `-20`.
160
-
161
- **State fills.** `--muted-*` and `--foreground-*` are never state fills.
162
-
163
- | token | role |
164
- |---|---|
165
- | `--accent` | control hover (Toggle and clear or remove glyphs included), the popup cursor, a pressed toggle, an open popup trigger, the current navigation item |
166
- | `--accent-50` | row and large-surface hover, add-slot hover, an open accordion item |
167
- | `--sidebar-accent` `--sidebar-accent-50` | the same two roles inside the sidebar |
168
- | `--primary-5` with a `--primary` edge | a selected large surface: choice card, switch card, locale tile, drop target |
169
- | `--primary-10` | a selected row |
170
- | `--primary` | a checked mark and solid selection |
171
- | `--primary-accent` | state ink: check and busy icons, today, the radio ring |
172
-
173
- Selection outranks hover: a selected item does not change on hover. Current navigation is
174
- neutral (`--accent`, foreground ink, medium weight); the brand ladder is for a value the user
175
- chose.
176
-
177
- **Tone ladder.** For T in primary, info, success, warning and destructive:
178
-
179
- | role | step | readers |
180
- |---|---|---|
181
- | solid fill | `--T` with `--T-foreground` | solid Button, Badge and IconBadge |
182
- | ink | `--primary-accent`, `--info`, `--success`, `--warning-accent`, `--destructive-accent` | text, glyphs, dots, sparklines and bars on the page or on a tint |
183
- | wash | `T-5`, warning `-10` | large panels: Alert, AI confirmation, a failed row, an applied coupon |
184
- | soft | `T-10` | chips and tiles: Badge soft, mentions, IconBadge, trend and diff chips, calendar chips, timeline discs, ghost and outline hover |
185
- | soft hover, halo | `T-20` | a linked soft chip's hover, the current-step and status halos |
186
- | line | `T-30`, warning `-40` | callouts, soft chips, outline Buttons and Badges, metric panels, applied filters |
187
-
188
- Warning's steps sit one higher because amber is light: a 10% amber wash lands where the
189
- other hues land at 5%. `--primary-15`, `--primary-25` and `--primary-40` are not tone steps:
190
- they belong to the range band, the analytics ruler and the media-tile selection ring.
191
- There is no other soft or wash step in any hue. Badge and mention
192
- chips do the arithmetic on one re-pointed hue (`--badge-hue`, `--ref-hue`) with the same
193
- percentages.
194
-
195
- **Edges.**
196
-
197
- | token | role |
198
- |---|---|
199
- | `--border-width` | every hairline, rail and connector |
200
- | `--border-width-strong` | marks only: a quote bar, the active-nav bar, a dot ring, a drop line |
201
- | `--focus-ring-width` | focus only |
202
- | `--border` | an outer edge: frames on the page, overlays, page-chrome bars, the Separator, rails, thumbnails |
203
- | `--border-60` | an inner edge: header, footer and toolbar bands, section rules, nested frames, row rules, menu separators |
204
- | `--control-border` `--control-border-hover` | the frame of a control in a row with fields: outline toggles and ToggleGroup, pill groups, filter pills, interactive chips, dashed add slots. Mixed separately for dark. A divider inside a control (a ButtonGroup separator, a filter pill's segments) is an inner rule, `--border-60` |
205
- | `--foreground-20` | the hover edge of a clickable surface |
206
- | `--invalid-ring-border` with `--invalid-ring` | every invalid edge. Focus adds the ring, invalid keeps its border, and hover never repaints it |
207
-
208
- There is no edge colour between the two. No literal `1.5px` or `3px` edge.
209
-
210
- **Elevation.**
211
-
212
- | token | role |
213
- |---|---|
214
- | none | bordered or flat surfaces, field shells, sticky bars |
215
- | `--shadow-xs` | resting lift: a framed Card's bezel, a raised chip, a thumb, a floating sidebar |
216
- | `--shadow-sm` | hover lift for every clickable card and tile; controls over artwork |
217
- | `--popover-shadow` | every anchored popup (select, combobox, mention panel, chart tooltip, map popup), never with a real border |
218
- | `--shadow-lg` | free-floating transients: toast, drag ghost, floating batch bar, submenu |
219
- | `--shadow-xl` | modals and palettes |
220
-
221
- `--shadow-2xs`, `--shadow` and `--shadow-2xl` are kept for shadcn compatibility; no kit
222
- surface reads them. A frosted sticky bar is opaque `--background`, then `--background-70`
223
- with `blur(12px)` under `@supports`.
224
-
225
- **Focus.** Controls take `--focus-ring`, or `--focus-ring-inset` under a clip. Fields and
226
- field shells take `--field-focus-ring` with a `--focus-ring-color` border, keyed on the
227
- control's `:focus-visible`; the rich-text editor and the AI composer are the multi-control
228
- exception and light on `:focus-within`. Never read `--ring` directly. Every Sidebar
229
- surface re-points `--focus-ring-color` to the theme's `--sidebar-ring` through the same
230
- recipe (mixed toward `--sidebar-foreground` in light, unmixed in dark) and composes
231
- `--focus-ring`, `--focus-ring-inset` and `--field-focus-ring` again from it. It also sets
232
- `--surface-ground: var(--sidebar)`.
233
-
234
- **Type.** Sizes come with their paired leading. `--leading-none` for fixed-height controls
235
- and glyphs, `--leading-tight` for titles at base size and up, `--leading-relaxed` for prose;
236
- `--leading-snug` never on `xs` or `sm`. Weight: normal for body; medium for labels, headers,
237
- controls, badges, row and accordion titles; semibold for surface titles, Heading, card
238
- titles and headline figures; bold for strong text and grand totals. `--tracking-widest` is
239
- for uppercase and shortcuts, `--tracking-tight` for Heading `xl` and `2xl` only. Colour
240
- reaches a `Text` through its `type` prop, never a module rule. Links read `--link-color` and
241
- `--link-underline-offset`.
242
-
243
- **Size.** Control heights and paddings go in matching pairs from the control ladder; a 24px
244
- glyph button is `--control-h-2xs`. A chevron inside a control is `--size-icon`, a caret after
245
- text `--size-icon-sm`. A head-of-row thumbnail is `--size-medallion`; a nav or menu row icon
246
- is `--size-icon`; a status dot is `--space-md`. Gaps: control icon to label `--space-sm`, chip
247
- icon to label `--space-xs`, sibling actions `--space-md`. Every derived multiple is rounded
248
- to a whole pixel and lands on the 2px grid.
249
-
250
- **Dark and inverse.** Small inverse chips flip with the theme (Tooltip, solid neutral
251
- controls). Large inverse slabs stay dark in both modes: the inverse Alert and the toast read
252
- `--inverse-*`, and the auth showcase panel is a `data-theme="dark"` scope. A QR code always
253
- renders dark modules on light through `--inverse-background` and `--inverse-foreground`.
254
-
255
- **Menus in dark.** `overlay.darkMenus` (default `true`) renders dropdown and context menus in
256
- the dark scheme on a light page. It applies to command menus only: listboxes, selects,
257
- comboboxes and pickers belong to the field that opened them and follow the page, like every
258
- other popup.
259
-
260
- ## Shared surface and content rhythm
261
-
262
- Retheme surface padding with `--surface-x` and `--surface-y`. Cards, choice cards, framed
263
- ContentBlocks, popovers, hover cards, the form actions bar and overlay bodies share these
264
- insets. Overlay headers and footers, and CardFooter, use 0.75 of the vertical inset
265
- (`round(calc(var(--surface-py) * 0.75), 1px)`) and the body's horizontal inset; the overlay
266
- header adds one `--space-2xs` above its title. Bands (a toolbar or header row inside a frame)
267
- are `--row-py` by `--surface-px`; edge-to-edge rows, table cells included, take `--surface-px`
268
- inline; list rows are `--row-py` by `--row-px`. Compact collection shells use half the inset.
108
+ A component's own variables are private and named `--_x`, declared on its root class or
109
+ inlined where used. A private name earns its place with one of:
269
110
 
270
- Title/description pairs in CardHeader, ContentBlock and OverlayHeader use the same
271
- `Stack gap="xs"`. CardFooter and OverlayFooter use a wrapping horizontal Stack with
272
- `gap="md"`. Ordinary label/value rows belong to MetadataList, including activity changes
273
- with custom before/after values. Specialized timelines and ledgers keep their own geometry.
111
+ - **arithmetic** read by two or more rules that must stay equal;
112
+ - **a variant** that re-points it (`.columns4 { --_min: 9rem; }`);
113
+ - **JavaScript** that writes it (`style={{ "--_progress-fill": … }}`);
114
+ - **another module** that sets it: `--_button-height`, `--_button-radius`, `--_card-px` and
115
+ `--_card-py`, `--_icon-badge-size`, `--_content-block-gap`, `--_overlay-max-width`.
274
116
 
275
- `--content-block-p` and `--overlay-region-p` are optional local overrides. They are unset
276
- (`initial`) by default, so each axis follows the shared surface controls; setting either
277
- sets both axes for that surface. Do not add another component-specific padding variable for
278
- the same job.
117
+ A bare `var(--gap)` behind another name is none of these; read the theme directly.
279
118
 
280
- Set fonts at the theme root or an explicit scope. Dark regions inherit the font family;
281
- switching colour mode does not restore the package's default font.
119
+ Animations name global keyframes through `--keyframes-*` (CSS Modules would rename a bare
120
+ name) and state their own timing: `animation: var(--keyframes-spin) 1s linear infinite`. The
121
+ keyframes are named `themelia-*`, so Tailwind's and tw-animate-css's `spin` or `enter` never
122
+ replace them.