@motion-proto/live-tokens 0.78.0 → 0.80.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 (172) hide show
  1. package/.claude/skills/live-tokens-check-compliance/SKILL.md +49 -38
  2. package/.claude/skills/live-tokens-create-component/SKILL.md +23 -28
  3. package/.claude/skills/live-tokens-create-component/references/contract-tests.md +61 -0
  4. package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +2 -2
  5. package/.claude/skills/live-tokens-create-component/references/token-naming.md +6 -15
  6. package/.claude/skills/live-tokens-create-page/SKILL.md +6 -4
  7. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
  8. package/.claude/skills/live-tokens-pick-component/SKILL.md +3 -3
  9. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +1 -1
  10. package/.claude/skills/live-tokens-set-geometry/SKILL.md +1 -1
  11. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +1 -1
  12. package/CHANGELOG.md +271 -0
  13. package/README.md +10 -16
  14. package/bin/check-component.mjs +154 -551
  15. package/bin/check-page.mjs +57 -541
  16. package/bin/cli.mjs +93 -16
  17. package/bin/contractRunner.mjs +37 -91
  18. package/bin/lib/buildChecks.mjs +32 -0
  19. package/bin/lib/catalogue.mjs +161 -34
  20. package/bin/lib/componentSource.mjs +152 -0
  21. package/bin/lib/cssValues.mjs +9 -0
  22. package/bin/lib/dataDir.mjs +126 -0
  23. package/bin/lib/findings.mjs +103 -12
  24. package/bin/lib/fixers.mjs +64 -0
  25. package/bin/lib/geometry.mjs +92 -0
  26. package/bin/lib/pageSource.mjs +230 -0
  27. package/bin/lib/report.mjs +57 -59
  28. package/bin/lib/tokenVocabulary.mjs +104 -34
  29. package/bin/migrate-build-script.mjs +66 -0
  30. package/bin/migrate.mjs +5 -0
  31. package/bin/rules/componentStructure.mjs +344 -0
  32. package/bin/rules/componentUse.mjs +313 -0
  33. package/bin/rules/importsAndRoutes.mjs +136 -0
  34. package/bin/rules/testRuns.mjs +122 -0
  35. package/bin/rules/tokens.mjs +426 -0
  36. package/bin/setup-claude.mjs +1 -2
  37. package/dist-plugin/{chunk-PDNL4NC5.js → chunk-D4WRIKEZ.js} +7 -2
  38. package/dist-plugin/{chunk-SWXRVZKT.js → chunk-REBHE3ZM.js} +414 -1
  39. package/dist-plugin/index.cjs +470 -19
  40. package/dist-plugin/index.d.cts +1 -0
  41. package/dist-plugin/index.d.ts +1 -0
  42. package/dist-plugin/index.js +87 -55
  43. package/dist-plugin/migrateData/index.cjs +422 -4
  44. package/dist-plugin/migrateData/index.js +2 -2
  45. package/dist-plugin/setColors/index.cjs +414 -1
  46. package/dist-plugin/setColors/index.d.cts +1 -1
  47. package/dist-plugin/setColors/index.d.ts +1 -1
  48. package/dist-plugin/setColors/index.js +1 -1
  49. package/dist-plugin/setGeometry/index.cjs +423 -13
  50. package/dist-plugin/setGeometry/index.d.cts +3 -3
  51. package/dist-plugin/setGeometry/index.d.ts +3 -3
  52. package/dist-plugin/setGeometry/index.js +10 -13
  53. package/dist-plugin/setType/index.d.cts +1 -1
  54. package/dist-plugin/setType/index.d.ts +1 -1
  55. package/dist-plugin/{themeTypes-BxRtuN5V.d.cts → themeTypes-B8_Idrp4.d.cts} +2 -2
  56. package/dist-plugin/{themeTypes-BxRtuN5V.d.ts → themeTypes-B8_Idrp4.d.ts} +2 -2
  57. package/package.json +2 -2
  58. package/src/editor/component-editor/CalloutEditor.svelte +2 -2
  59. package/src/editor/component-editor/CollapsibleSectionEditor.svelte +14 -15
  60. package/src/editor/component-editor/CornerBadgeEditor.svelte +14 -14
  61. package/src/editor/component-editor/DialogEditor.svelte +5 -5
  62. package/src/editor/component-editor/InlineEditActionsEditor.svelte +2 -2
  63. package/src/editor/component-editor/RadioButtonEditor.svelte +21 -21
  64. package/src/editor/component-editor/SectionDividerEditor.svelte +7 -7
  65. package/src/editor/component-editor/SegmentedControlEditor.svelte +5 -5
  66. package/src/editor/component-editor/SideNavigationEditor.svelte +25 -25
  67. package/src/editor/component-editor/TabBarEditor.svelte +6 -6
  68. package/src/editor/component-editor/TableEditor.svelte +6 -6
  69. package/src/editor/component-editor/ToggleEditor.svelte +2 -2
  70. package/src/editor/component-editor/index.ts +3 -0
  71. package/src/editor/component-editor/registry.ts +57 -1
  72. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +14 -14
  73. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +3 -0
  74. package/src/editor/component-editor/scaffolding/types.ts +15 -0
  75. package/src/editor/core/components/adjustAliases.ts +4 -4
  76. package/src/editor/core/components/aliasKinds.ts +20 -19
  77. package/src/editor/core/sketch/sketchLayer.ts +3 -3
  78. package/src/editor/core/themes/migrateComponentConfig.ts +14 -6
  79. package/src/editor/core/themes/migrations/2026-09-13-badge-brand.ts +42 -0
  80. package/src/editor/core/themes/migrations/2026-09-13-collapsiblesection-open.ts +33 -0
  81. package/src/editor/core/themes/migrations/2026-09-13-cornerbadge-prefix.ts +70 -0
  82. package/src/editor/core/themes/migrations/2026-09-13-hairline.ts +92 -0
  83. package/src/editor/core/themes/migrations/2026-09-13-indicator.ts +54 -0
  84. package/src/editor/core/themes/migrations/2026-09-13-sectiondivider-surface.ts +36 -0
  85. package/src/editor/core/themes/migrations/2026-09-13-selected-state.ts +124 -0
  86. package/src/editor/core/themes/migrations/2026-09-13-toggle-label.ts +31 -0
  87. package/src/editor/core/themes/migrations/index.ts +16 -0
  88. package/src/editor/core/themes/themeService.ts +3 -3
  89. package/src/editor/core/themes/themeTypes.ts +13 -15
  90. package/src/editor/docs/Docs.svelte +1 -1
  91. package/src/editor/docs/content/light-and-dark.md +3 -3
  92. package/src/editor/docs/content.generated.ts +1 -1
  93. package/src/editor/index.ts +1 -0
  94. package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
  95. package/src/editor/skill-atlas/SkillAtlas.svelte +4 -4
  96. package/src/editor/skill-atlas/TreeNodeCard.svelte +4 -4
  97. package/src/editor/skill-atlas/skillSources.generated.ts +11 -14
  98. package/src/editor/skill-atlas/skillTrees.ts +1 -3
  99. package/src/editor/skill-atlas/trees/check-compliance.ts +37 -149
  100. package/src/editor/skill-atlas/trees/create-component.ts +62 -64
  101. package/src/editor/skill-atlas/trees/create-page.ts +38 -17
  102. package/src/editor/skill-atlas/trees/pick-component.ts +3 -3
  103. package/src/editor/skill-atlas/trees/set-geometry.ts +1 -1
  104. package/src/editor/ui/UIPaletteSelector.svelte +11 -15
  105. package/src/editor/ui/variantScales.ts +8 -8
  106. package/src/live-tokens/data/themes/autumn.json +188 -188
  107. package/src/live-tokens/data/themes/halloween.json +188 -188
  108. package/src/live-tokens/data/themes/midnight-study.json +245 -245
  109. package/src/live-tokens/data/themes/ocean.json +188 -188
  110. package/src/live-tokens/data/themes/royal-velvet.json +188 -188
  111. package/src/live-tokens/data/themes/sketchy.json +188 -188
  112. package/src/live-tokens/data/themes/spring-meadow.json +188 -188
  113. package/src/live-tokens/data/themes/sunset.json +188 -188
  114. package/src/system/components/Badge.svelte +27 -23
  115. package/src/system/components/Button.svelte +13 -7
  116. package/src/system/components/Callout.svelte +16 -11
  117. package/src/system/components/Card.svelte +22 -15
  118. package/src/system/components/CodeSnippet.svelte +10 -6
  119. package/src/system/components/CollapsibleSection.svelte +81 -76
  120. package/src/system/components/CornerBadge.svelte +78 -72
  121. package/src/system/components/Dialog.svelte +21 -18
  122. package/src/system/components/IconButton.svelte +13 -9
  123. package/src/system/components/Image.svelte +14 -8
  124. package/src/system/components/ImageLightbox.svelte +10 -6
  125. package/src/system/components/InlineEditActions.svelte +17 -14
  126. package/src/system/components/Input.svelte +13 -7
  127. package/src/system/components/MenuSelect.svelte +13 -7
  128. package/src/system/components/Notification.svelte +17 -11
  129. package/src/system/components/Panel.svelte +13 -6
  130. package/src/system/components/ProgressBar.svelte +10 -5
  131. package/src/system/components/RadioButton.svelte +33 -30
  132. package/src/system/components/SectionDivider.svelte +28 -21
  133. package/src/system/components/SegmentedControl.svelte +27 -23
  134. package/src/system/components/SideNavigation.svelte +175 -171
  135. package/src/system/components/Slider.svelte +11 -7
  136. package/src/system/components/TabBar.svelte +53 -49
  137. package/src/system/components/Table.svelte +20 -15
  138. package/src/system/components/Toggle.svelte +14 -10
  139. package/src/system/components/Tooltip.svelte +10 -6
  140. package/src/system/styles/CONVENTIONS.md +3 -4
  141. package/src/testing-js/chunk-3UKGXCDL.js +48 -0
  142. package/src/testing-js/chunk-3UKGXCDL.js.map +1 -0
  143. package/src/testing-js/{chunk-FAFOAWYL.js → chunk-Q3YIAAG3.js} +17 -3
  144. package/src/testing-js/chunk-Q3YIAAG3.js.map +1 -0
  145. package/src/testing-js/{chunk-GNIUPIU2.js → chunk-U7OJE5DU.js} +18 -18
  146. package/src/testing-js/chunk-U7OJE5DU.js.map +1 -0
  147. package/src/testing-js/{chunk-4JQX6WWL.js → chunk-ZMZQZ33J.js} +474 -166
  148. package/src/testing-js/chunk-ZMZQZ33J.js.map +1 -0
  149. package/src/testing-js/component-behavior.contract.js +155 -0
  150. package/src/testing-js/component-behavior.contract.js.map +1 -0
  151. package/src/testing-js/component-editor.contract.js +6 -4
  152. package/src/testing-js/component-editor.contract.js.map +1 -1
  153. package/src/testing-js/component-render.contract.js +14 -10
  154. package/src/testing-js/component-render.contract.js.map +1 -1
  155. package/src/testing-js/index.d.ts +44 -4
  156. package/src/testing-js/index.js +13 -7
  157. package/src/testing-js/index.js.map +1 -1
  158. package/src/testing-js/page-compliance.contract.js +48 -10
  159. package/src/testing-js/page-compliance.contract.js.map +1 -1
  160. package/src/testing-js/registry.contract.js +5 -3
  161. package/src/testing-js/registry.contract.js.map +1 -1
  162. package/src/testing-js/{vitest-C-wNWcoA.d.ts → vitest-BMLIbDs2.d.ts} +8 -2
  163. package/src/testing-js/vitest.d.ts +1 -1
  164. package/src/testing-js/vitest.js +2 -1
  165. package/template/package.json +1 -2
  166. package/template/vite.config.ts +3 -2
  167. package/.claude/skills/live-tokens-create-component/SKILL copy.md +0 -196
  168. package/.claude/skills/live-tokens-fix-findings/SKILL.md +0 -105
  169. package/src/editor/skill-atlas/trees/fix-findings.ts +0 -504
  170. package/src/testing-js/chunk-4JQX6WWL.js.map +0 -1
  171. package/src/testing-js/chunk-FAFOAWYL.js.map +0 -1
  172. package/src/testing-js/chunk-GNIUPIU2.js.map +0 -1
@@ -1,33 +1,59 @@
1
1
  import type { Component } from 'svelte';
2
- import type { Token, IntrinsicSpec } from './scaffolding/types';
2
+ import type { CatalogueEntry, Token, IntrinsicSpec } from './scaffolding/types';
3
3
  import { registerComponentSchema } from '../core/store/editorStore';
4
4
 
5
5
  import BadgeEditor, { allTokens as badgeTokens } from './BadgeEditor.svelte';
6
+ import { catalogue as badgeCatalogue } from '../../system/components/Badge.svelte';
6
7
  import CalloutEditor, { allTokens as calloutTokens } from './CalloutEditor.svelte';
8
+ import { catalogue as calloutCatalogue } from '../../system/components/Callout.svelte';
7
9
  import CornerBadgeEditor, { allTokens as cornerBadgeTokens } from './CornerBadgeEditor.svelte';
10
+ import { catalogue as cornerBadgeCatalogue } from '../../system/components/CornerBadge.svelte';
8
11
  import ButtonEditor, { allTokens as buttonTokens } from './ButtonEditor.svelte';
12
+ import { catalogue as buttonCatalogue } from '../../system/components/Button.svelte';
9
13
  import IconButtonEditor, { allTokens as iconButtonTokens } from './IconButtonEditor.svelte';
14
+ import { catalogue as iconButtonCatalogue } from '../../system/components/IconButton.svelte';
10
15
  import CardEditor, { allTokens as cardTokens, intrinsics as cardIntrinsics } from './CardEditor.svelte';
16
+ import { catalogue as cardCatalogue } from '../../system/components/Card.svelte';
11
17
  import CodeSnippetEditor, { allTokens as codeSnippetTokens } from './CodeSnippetEditor.svelte';
18
+ import { catalogue as codeSnippetCatalogue } from '../../system/components/CodeSnippet.svelte';
12
19
  import CollapsibleSectionEditor, { allTokens as collapsibleSectionTokens } from './CollapsibleSectionEditor.svelte';
20
+ import { catalogue as collapsibleSectionCatalogue } from '../../system/components/CollapsibleSection.svelte';
13
21
  import DialogEditor, { allTokens as dialogTokens } from './DialogEditor.svelte';
22
+ import { catalogue as dialogCatalogue } from '../../system/components/Dialog.svelte';
14
23
  import ImageEditor, { allTokens as imageTokens, intrinsics as imageIntrinsics } from './ImageEditor.svelte';
24
+ import { catalogue as imageCatalogue } from '../../system/components/Image.svelte';
15
25
  import ImageLightboxEditor, { allTokens as imageLightboxTokens } from './ImageLightboxEditor.svelte';
26
+ import { catalogue as imageLightboxCatalogue } from '../../system/components/ImageLightbox.svelte';
16
27
  import InlineEditActionsEditor, { allTokens as inlineEditActionsTokens } from './InlineEditActionsEditor.svelte';
28
+ import { catalogue as inlineEditActionsCatalogue } from '../../system/components/InlineEditActions.svelte';
17
29
  import InputEditor, { allTokens as inputTokens } from './InputEditor.svelte';
30
+ import { catalogue as inputCatalogue } from '../../system/components/Input.svelte';
18
31
  import MenuSelectEditor, { allTokens as menuSelectTokens } from './MenuSelectEditor.svelte';
32
+ import { catalogue as menuSelectCatalogue } from '../../system/components/MenuSelect.svelte';
19
33
  import NotificationEditor, { allTokens as notificationTokens } from './NotificationEditor.svelte';
34
+ import { catalogue as notificationCatalogue } from '../../system/components/Notification.svelte';
20
35
  import PanelEditor, { allTokens as panelTokens } from './PanelEditor.svelte';
36
+ import { catalogue as panelCatalogue } from '../../system/components/Panel.svelte';
21
37
  import ProgressBarEditor, { allTokens as progressBarTokens } from './ProgressBarEditor.svelte';
38
+ import { catalogue as progressBarCatalogue } from '../../system/components/ProgressBar.svelte';
22
39
  import SliderEditor, { allTokens as sliderTokens } from './SliderEditor.svelte';
40
+ import { catalogue as sliderCatalogue } from '../../system/components/Slider.svelte';
23
41
  import RadioButtonEditor, { allTokens as radioButtonTokens } from './RadioButtonEditor.svelte';
42
+ import { catalogue as radioButtonCatalogue } from '../../system/components/RadioButton.svelte';
24
43
  import SectionDividerEditor, { allTokens as sectionDividerTokens, intrinsics as sectionDividerIntrinsics } from './SectionDividerEditor.svelte';
44
+ import { catalogue as sectionDividerCatalogue } from '../../system/components/SectionDivider.svelte';
25
45
  import SegmentedControlEditor, { allTokens as segmentedControlTokens } from './SegmentedControlEditor.svelte';
46
+ import { catalogue as segmentedControlCatalogue } from '../../system/components/SegmentedControl.svelte';
26
47
  import SideNavigationEditor, { allTokens as sideNavigationTokens } from './SideNavigationEditor.svelte';
48
+ import { catalogue as sideNavigationCatalogue } from '../../system/components/SideNavigation.svelte';
27
49
  import TableEditor, { allTokens as tableTokens } from './TableEditor.svelte';
50
+ import { catalogue as tableCatalogue } from '../../system/components/Table.svelte';
28
51
  import TabBarEditor, { allTokens as tabBarTokens } from './TabBarEditor.svelte';
52
+ import { catalogue as tabBarCatalogue } from '../../system/components/TabBar.svelte';
29
53
  import ToggleEditor, { allTokens as toggleTokens } from './ToggleEditor.svelte';
54
+ import { catalogue as toggleCatalogue } from '../../system/components/Toggle.svelte';
30
55
  import TooltipEditor, { allTokens as tooltipTokens } from './TooltipEditor.svelte';
56
+ import { catalogue as tooltipCatalogue } from '../../system/components/Tooltip.svelte';
31
57
 
32
58
  /** Internal narrowed union of the first-party component ids. Not exposed publicly. */
33
59
  type BuiltInComponentId =
@@ -81,6 +107,10 @@ export interface RegistryEntry {
81
107
  most components have none. When present, each spec's per-variant default is
82
108
  pinned to the runtime `:global(:root)` by intrinsicsContract.test. */
83
109
  intrinsics?: IntrinsicSpec[];
110
+ /** What the component is, what to use it for, and what not to use it for.
111
+ Imported from the runtime file's own `catalogue` export — never copied —
112
+ so registryContract.test's identity check pins it to that one source. */
113
+ catalogue: CatalogueEntry;
84
114
  /** `'system'` for first-party entries; `'custom'` for entries added via `registerComponent()`. */
85
115
  origin: 'system' | 'custom';
86
116
  }
@@ -100,6 +130,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
100
130
  sourceFile: 'src/system/components/SegmentedControl.svelte',
101
131
  editorComponent: SegmentedControlEditor,
102
132
  schema: segmentedControlTokens,
133
+ catalogue: segmentedControlCatalogue,
103
134
  origin: 'system',
104
135
  },
105
136
  button: {
@@ -109,6 +140,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
109
140
  sourceFile: 'src/system/components/Button.svelte',
110
141
  editorComponent: ButtonEditor,
111
142
  schema: buttonTokens,
143
+ catalogue: buttonCatalogue,
112
144
  origin: 'system',
113
145
  },
114
146
  iconbutton: {
@@ -118,6 +150,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
118
150
  sourceFile: 'src/system/components/IconButton.svelte',
119
151
  editorComponent: IconButtonEditor,
120
152
  schema: iconButtonTokens,
153
+ catalogue: iconButtonCatalogue,
121
154
  origin: 'system',
122
155
  },
123
156
  notification: {
@@ -127,6 +160,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
127
160
  sourceFile: 'src/system/components/Notification.svelte',
128
161
  editorComponent: NotificationEditor,
129
162
  schema: notificationTokens,
163
+ catalogue: notificationCatalogue,
130
164
  origin: 'system',
131
165
  },
132
166
  dialog: {
@@ -136,6 +170,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
136
170
  sourceFile: 'src/system/components/Dialog.svelte',
137
171
  editorComponent: DialogEditor,
138
172
  schema: dialogTokens,
173
+ catalogue: dialogCatalogue,
139
174
  origin: 'system',
140
175
  },
141
176
  radiobutton: {
@@ -145,6 +180,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
145
180
  sourceFile: 'src/system/components/RadioButton.svelte',
146
181
  editorComponent: RadioButtonEditor,
147
182
  schema: radioButtonTokens,
183
+ catalogue: radioButtonCatalogue,
148
184
  origin: 'system',
149
185
  },
150
186
  card: {
@@ -155,6 +191,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
155
191
  editorComponent: CardEditor,
156
192
  schema: cardTokens,
157
193
  intrinsics: cardIntrinsics,
194
+ catalogue: cardCatalogue,
158
195
  origin: 'system',
159
196
  },
160
197
  badge: {
@@ -164,6 +201,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
164
201
  sourceFile: 'src/system/components/Badge.svelte',
165
202
  editorComponent: BadgeEditor,
166
203
  schema: badgeTokens,
204
+ catalogue: badgeCatalogue,
167
205
  origin: 'system',
168
206
  },
169
207
  callout: {
@@ -173,6 +211,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
173
211
  sourceFile: 'src/system/components/Callout.svelte',
174
212
  editorComponent: CalloutEditor,
175
213
  schema: calloutTokens,
214
+ catalogue: calloutCatalogue,
176
215
  origin: 'system',
177
216
  },
178
217
  codesnippet: {
@@ -182,6 +221,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
182
221
  sourceFile: 'src/system/components/CodeSnippet.svelte',
183
222
  editorComponent: CodeSnippetEditor,
184
223
  schema: codeSnippetTokens,
224
+ catalogue: codeSnippetCatalogue,
185
225
  origin: 'system',
186
226
  },
187
227
  cornerbadge: {
@@ -191,6 +231,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
191
231
  sourceFile: 'src/system/components/CornerBadge.svelte',
192
232
  editorComponent: CornerBadgeEditor,
193
233
  schema: cornerBadgeTokens,
234
+ catalogue: cornerBadgeCatalogue,
194
235
  origin: 'system',
195
236
  },
196
237
  image: {
@@ -201,6 +242,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
201
242
  editorComponent: ImageEditor,
202
243
  schema: imageTokens,
203
244
  intrinsics: imageIntrinsics,
245
+ catalogue: imageCatalogue,
204
246
  origin: 'system',
205
247
  },
206
248
  imagelightbox: {
@@ -210,6 +252,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
210
252
  sourceFile: 'src/system/components/ImageLightbox.svelte',
211
253
  editorComponent: ImageLightboxEditor,
212
254
  schema: imageLightboxTokens,
255
+ catalogue: imageLightboxCatalogue,
213
256
  origin: 'system',
214
257
  },
215
258
  inlineeditactions: {
@@ -219,6 +262,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
219
262
  sourceFile: 'src/system/components/InlineEditActions.svelte',
220
263
  editorComponent: InlineEditActionsEditor,
221
264
  schema: inlineEditActionsTokens,
265
+ catalogue: inlineEditActionsCatalogue,
222
266
  origin: 'system',
223
267
  },
224
268
  input: {
@@ -228,6 +272,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
228
272
  sourceFile: 'src/system/components/Input.svelte',
229
273
  editorComponent: InputEditor,
230
274
  schema: inputTokens,
275
+ catalogue: inputCatalogue,
231
276
  origin: 'system',
232
277
  },
233
278
  menuselect: {
@@ -237,6 +282,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
237
282
  sourceFile: 'src/system/components/MenuSelect.svelte',
238
283
  editorComponent: MenuSelectEditor,
239
284
  schema: menuSelectTokens,
285
+ catalogue: menuSelectCatalogue,
240
286
  origin: 'system',
241
287
  },
242
288
  panel: {
@@ -246,6 +292,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
246
292
  sourceFile: 'src/system/components/Panel.svelte',
247
293
  editorComponent: PanelEditor,
248
294
  schema: panelTokens,
295
+ catalogue: panelCatalogue,
249
296
  origin: 'system',
250
297
  },
251
298
  sectiondivider: {
@@ -256,6 +303,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
256
303
  editorComponent: SectionDividerEditor,
257
304
  schema: sectionDividerTokens,
258
305
  intrinsics: sectionDividerIntrinsics,
306
+ catalogue: sectionDividerCatalogue,
259
307
  origin: 'system',
260
308
  },
261
309
  collapsiblesection: {
@@ -265,6 +313,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
265
313
  sourceFile: 'src/system/components/CollapsibleSection.svelte',
266
314
  editorComponent: CollapsibleSectionEditor,
267
315
  schema: collapsibleSectionTokens,
316
+ catalogue: collapsibleSectionCatalogue,
268
317
  origin: 'system',
269
318
  },
270
319
  sidenavigation: {
@@ -274,6 +323,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
274
323
  sourceFile: 'src/system/components/SideNavigation.svelte',
275
324
  editorComponent: SideNavigationEditor,
276
325
  schema: sideNavigationTokens,
326
+ catalogue: sideNavigationCatalogue,
277
327
  origin: 'system',
278
328
  },
279
329
  table: {
@@ -283,6 +333,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
283
333
  sourceFile: 'src/system/components/Table.svelte',
284
334
  editorComponent: TableEditor,
285
335
  schema: tableTokens,
336
+ catalogue: tableCatalogue,
286
337
  origin: 'system',
287
338
  },
288
339
  tabbar: {
@@ -292,6 +343,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
292
343
  sourceFile: 'src/system/components/TabBar.svelte',
293
344
  editorComponent: TabBarEditor,
294
345
  schema: tabBarTokens,
346
+ catalogue: tabBarCatalogue,
295
347
  origin: 'system',
296
348
  },
297
349
  toggle: {
@@ -301,6 +353,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
301
353
  sourceFile: 'src/system/components/Toggle.svelte',
302
354
  editorComponent: ToggleEditor,
303
355
  schema: toggleTokens,
356
+ catalogue: toggleCatalogue,
304
357
  origin: 'system',
305
358
  },
306
359
  tooltip: {
@@ -310,6 +363,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
310
363
  sourceFile: 'src/system/components/Tooltip.svelte',
311
364
  editorComponent: TooltipEditor,
312
365
  schema: tooltipTokens,
366
+ catalogue: tooltipCatalogue,
313
367
  origin: 'system',
314
368
  },
315
369
  progressbar: {
@@ -319,6 +373,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
319
373
  sourceFile: 'src/system/components/ProgressBar.svelte',
320
374
  editorComponent: ProgressBarEditor,
321
375
  schema: progressBarTokens,
376
+ catalogue: progressBarCatalogue,
322
377
  origin: 'system',
323
378
  },
324
379
  slider: {
@@ -328,6 +383,7 @@ const builtInRegistry: Readonly<Record<BuiltInComponentId, RegistryEntry>> = Obj
328
383
  sourceFile: 'src/system/components/Slider.svelte',
329
384
  editorComponent: SliderEditor,
330
385
  schema: sliderTokens,
386
+ catalogue: sliderCatalogue,
331
387
  origin: 'system',
332
388
  },
333
389
  });
@@ -9,7 +9,7 @@
9
9
  import UIPaddingSelector from '../../ui/UIPaddingSelector.svelte';
10
10
  import UILetterSpacingSelector from '../../ui/UILetterSpacingSelector.svelte';
11
11
  import UIEasingSelector from '../../ui/UIEasingSelector.svelte';
12
- import { BLUR, BORDER_WIDTH, DOT_SIZE, DURATION, RADIUS, SCALE, SHADOW, DIVIDER_HEIGHT, DIVIDER_INSET } from '../../ui/variantScales';
12
+ import { BLUR, BORDER_WIDTH, DOT_SIZE, DURATION, RADIUS, SCALE, SHADOW, TRACK_HEIGHT, HAIRLINE_INSET } from '../../ui/variantScales';
13
13
  import {
14
14
  editorState,
15
15
  getComponentPropertySiblings,
@@ -68,8 +68,8 @@
68
68
  'font-size',
69
69
  'line-height',
70
70
  'letter-spacing',
71
- 'divider-height',
72
- 'divider-inset',
71
+ 'track-height',
72
+ 'hairline-inset',
73
73
  'dot-size',
74
74
  'length',
75
75
  'radius',
@@ -84,8 +84,8 @@
84
84
  'text-color',
85
85
  'surface',
86
86
  'border-width',
87
- 'divider-width',
88
- 'accent-width',
87
+ 'hairline-width',
88
+ 'indicator-width',
89
89
  'border',
90
90
  ];
91
91
  const orderRank: Record<Kind, number> = Object.fromEntries(
@@ -135,10 +135,10 @@
135
135
  'line-height': { component: UILineHeightSelector },
136
136
  'letter-spacing': { component: UILetterSpacingSelector },
137
137
  'border-width': { component: UIVariantSelector, extra: () => ({ ...BORDER_WIDTH }) },
138
- 'divider-width': { component: UIVariantSelector, extra: () => ({ ...BORDER_WIDTH }) },
139
- 'accent-width': { component: UIVariantSelector, extra: () => ({ ...BORDER_WIDTH }) },
140
- 'divider-height': { component: UIVariantSelector, extra: () => ({ ...DIVIDER_HEIGHT }) },
141
- 'divider-inset': { component: UIVariantSelector, extra: () => ({ ...DIVIDER_INSET }) },
138
+ 'hairline-width': { component: UIVariantSelector, extra: () => ({ ...BORDER_WIDTH }) },
139
+ 'indicator-width': { component: UIVariantSelector, extra: () => ({ ...BORDER_WIDTH }) },
140
+ 'track-height': { component: UIVariantSelector, extra: () => ({ ...TRACK_HEIGHT }) },
141
+ 'hairline-inset': { component: UIVariantSelector, extra: () => ({ ...HAIRLINE_INSET }) },
142
142
  'dot-size': { component: UIVariantSelector, extra: () => ({ ...DOT_SIZE }) },
143
143
  'radius': { component: UIVariantSelector, extra: () => ({ ...RADIUS }) },
144
144
  'padding': { component: UIPaddingSelector, extra: (t) => ({ mode: 'single', splittable: t.splittable !== false }) },
@@ -167,7 +167,7 @@
167
167
  };
168
168
 
169
169
  /** Multi-col rank: same as `orderRank` but with `text-color` hoisted between
170
- `line-height` and `divider-height` so typography reads as one logical block
170
+ `line-height` and `track-height` so typography reads as one logical block
171
171
  in column flow. Single-col mode keeps `orderRank` (linked-first sort
172
172
  already segregates text-color to the bottom). */
173
173
  const multiColRank: Record<Kind, number> = (() => {
@@ -178,8 +178,8 @@
178
178
  'line-height',
179
179
  'letter-spacing',
180
180
  'text-color',
181
- 'divider-height',
182
- 'divider-inset',
181
+ 'track-height',
182
+ 'hairline-inset',
183
183
  'dot-size',
184
184
  'length',
185
185
  'radius',
@@ -193,8 +193,8 @@
193
193
  'shadow',
194
194
  'surface',
195
195
  'border-width',
196
- 'divider-width',
197
- 'accent-width',
196
+ 'hairline-width',
197
+ 'indicator-width',
198
198
  'border',
199
199
  ];
200
200
  return Object.fromEntries(reordered.map((k, i) => [k, i])) as Record<Kind, number>;
@@ -621,6 +621,9 @@
621
621
  align-items: center;
622
622
  gap: var(--ui-space-24);
623
623
  flex-wrap: wrap;
624
+ /* The overlay's collapsed pill publishes its inset while it rests in the
625
+ top band; once this header pins under it, the tabs wrap clear. */
626
+ padding-right: var(--lt-pill-inset, 0px);
624
627
  }
625
628
 
626
629
  .preview-actions {
@@ -1,3 +1,18 @@
1
+ /** A component's catalogue entry: what it is, what to use it for, what not
2
+ to use it for, and what any guidance-bearing prop's values mean. Exported
3
+ as `catalogue` from the runtime file's `<script module>` block — the
4
+ Svelte compiler drops a leading HTML comment before it reaches the
5
+ running editor, so this is the one form every reader (CLI, registry,
6
+ consumer) can read. */
7
+ export type CatalogueEntry = {
8
+ /** One sentence: what the component is. */
9
+ description: string;
10
+ useFor: string;
11
+ notFor: string;
12
+ /** Keyed by prop name; the value explains that prop's values. */
13
+ props?: Record<string, string>;
14
+ };
15
+
1
16
  /** Editor token: a single CSS custom property the user can theme. */
2
17
  export type Token = {
3
18
  label: string;
@@ -1,7 +1,7 @@
1
1
  import { matchesKind, stripSide } from './aliasKinds';
2
2
  import type { AliasDiskValue, ComponentConfig } from '../themes/themeTypes';
3
3
 
4
- export type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width' | 'divider-width' | 'accent-width';
4
+ export type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width' | 'hairline-width' | 'indicator-width';
5
5
 
6
6
  export interface AdjustOp {
7
7
  /** Component id; omitted applies the op to every config. */
@@ -88,7 +88,7 @@ const BORDER_WIDTH_SETTABLE = [
88
88
  const STROKE_STEPS = BORDER_WIDTH_SETTABLE.slice(1);
89
89
 
90
90
  /** Three stroke roles ride the one `--border-width-*` scale. A border
91
- encloses, a divider separates, an accent emphasises, and an intent
91
+ encloses, a hairline separates, an indicator emphasises, and an intent
92
92
  such as "hairline rules" names one role without the others. */
93
93
  const STROKE_SCALE = {
94
94
  steps: STROKE_STEPS,
@@ -105,8 +105,8 @@ const SCALES: Record<AdjustKind, { steps: string[]; settable: string[]; family:
105
105
  padding: { steps: SPACE_STEPS, settable: SPACE_SETTABLE, family: SPACE_FAMILY },
106
106
  gap: { steps: SPACE_STEPS, settable: SPACE_SETTABLE, family: SPACE_FAMILY },
107
107
  'border-width': STROKE_SCALE,
108
- 'divider-width': STROKE_SCALE,
109
- 'accent-width': STROKE_SCALE,
108
+ 'hairline-width': STROKE_SCALE,
109
+ 'indicator-width': STROKE_SCALE,
110
110
  };
111
111
 
112
112
  const TOKEN_NAME = /^--[a-z0-9-]+$/;
@@ -2,11 +2,11 @@ export type TokenKind =
2
2
  | 'surface'
3
3
  | 'border'
4
4
  | 'border-width'
5
- | 'divider-width'
6
- | 'accent-width'
5
+ | 'hairline-width'
6
+ | 'indicator-width'
7
7
  | 'radius'
8
- | 'divider-height'
9
- | 'divider-inset'
8
+ | 'track-height'
9
+ | 'hairline-inset'
10
10
  | 'dot-size'
11
11
  | 'length'
12
12
  | 'blur'
@@ -25,14 +25,15 @@ export type TokenKind =
25
25
 
26
26
  /** Suffix and prefix data mapped to kinds — the one source of truth for the
27
27
  editor's selector layout, the `adjust` CLI, and `check-component`'s naming
28
- rule, so the three cannot drift. `bin/check-component.mjs` reads the
28
+ rule, so the three cannot drift. `bin/lib/componentSource.mjs` reads the
29
29
  `suffix:` arrays out of this file, which is why they are plain literals.
30
30
 
31
- Order matters: `-text` must run before `-border`/`-surface`, and
32
- `-accent-width` before `-accent` and `-width`, because the first match wins. A variable
33
- matching nothing falls through to `text-color` (a palette picker), but that
34
- fall-through is a smell — `check-component` rejects an unrecognised suffix,
35
- so add the name here rather than letting it drift. */
31
+ Order matters: `-text` must run before `-border`/`-surface`, and every
32
+ named `-width` before the bare `length` rule, because the first match
33
+ wins. A variable matching nothing falls through to `text-color` (a
34
+ palette picker), but that fall-through is a smell — `check-component`
35
+ rejects an unrecognised suffix, so add the name here rather than letting
36
+ it drift. */
36
37
  export const KIND_RULES: ReadonlyArray<{
37
38
  kind: TokenKind;
38
39
  suffix?: readonly string[];
@@ -49,11 +50,12 @@ export const KIND_RULES: ReadonlyArray<{
49
50
  prefix: ['--text-'] },
50
51
  { kind: 'radius', suffix: ['-radius'], prefix: ['--radius-'] },
51
52
  // Three stroke roles share the `--border-width-*` scale: a border encloses,
52
- // a divider separates, an accent emphasises. `set-geometry` moves each role
53
- // on its own, so a suffix has to say which line it names.
54
- { kind: 'divider-width', suffix: ['-divider-width', '-divider-thickness', '-hairline-thickness', '-thickness'] },
55
- { kind: 'divider-height', suffix: ['-divider-height', '-track-height'] },
56
- { kind: 'divider-inset', suffix: ['-divider-inset', '-inset'] },
53
+ // a hairline separates, an indicator emphasises. `set-geometry` moves each
54
+ // role on its own, so a suffix has to say which line it names.
55
+ { kind: 'hairline-width', suffix: ['-hairline-width'] },
56
+ { kind: 'indicator-width', suffix: ['-indicator-width'] },
57
+ { kind: 'track-height', suffix: ['-track-height'] },
58
+ { kind: 'hairline-inset', suffix: ['-hairline-inset'] },
57
59
  { kind: 'dot-size', suffix: ['-dot-size'] },
58
60
  { kind: 'blur', suffix: ['-blur'], prefix: ['--blur-'] },
59
61
  { kind: 'scale', suffix: ['-scale'], prefix: ['--scale-'] },
@@ -62,17 +64,16 @@ export const KIND_RULES: ReadonlyArray<{
62
64
  { kind: 'gap', suffix: ['-gap'] },
63
65
  { kind: 'duration', suffix: ['-duration'], prefix: ['--duration-'] },
64
66
  { kind: 'easing', suffix: ['-easing'], prefix: ['--ease-'] },
65
- { kind: 'accent-width', suffix: ['-accent-width', '-indicator-width'] },
66
67
  { kind: 'border-width', suffix: ['-border-width'], prefix: ['--border-width-'] },
67
68
  { kind: 'border', suffix: ['-border'], prefix: ['--border-'] },
68
69
  // A dimension with no more specific name behind it — a panel's width, an
69
70
  // avatar's size. Last of the geometry rules, so every `-border-width`,
70
- // `-divider-height`, `-icon-size` and the rest claim their token first.
71
+ // `-track-height`, `-icon-size` and the rest claim their token first.
71
72
  { kind: 'length', suffix: ['-width', '-height', '-size'] },
72
73
  // Fills. A tint is a wash over a surface, so it takes the surface picker: the
73
74
  // full palette with an alpha, not just the tint stops it defaults to.
74
- { kind: 'surface', suffix: ['-surface', '-fill', '-divider', '-background', '-indicator',
75
- '-thumb', '-accent', '-color', '-tint', '-opacity'],
75
+ { kind: 'surface', suffix: ['-surface', '-fill', '-indicator',
76
+ '-thumb', '-color', '-tint', '-opacity'],
76
77
  prefix: ['--surface-', '--tint', '--color-'] },
77
78
  ];
78
79
 
@@ -95,7 +95,7 @@ interface PartSpec {
95
95
  }
96
96
 
97
97
  const BADGE_VARIANTS = [
98
- 'primary', 'accent', 'special', 'neutral', 'alternate',
98
+ 'brand', 'accent', 'special', 'neutral', 'alternate',
99
99
  'canvas', 'info', 'success', 'warning', 'danger',
100
100
  ];
101
101
  /** `outline` is filled by its border alone, so it is listed separately. */
@@ -169,7 +169,7 @@ const PART_SPECS: readonly PartSpec[] = [
169
169
  },
170
170
  {
171
171
  sel: '.es-root.variant-container > .section-content',
172
- fill: 'var(--collapsiblesection-container-expanded-surface)', stroke: 'transparent',
172
+ fill: 'var(--collapsiblesection-container-open-surface)', stroke: 'transparent',
173
173
  hatch: 'var(--collapsiblesection-container-frame-border)',
174
174
  },
175
175
  {
@@ -218,7 +218,7 @@ const PART_SPECS: readonly PartSpec[] = [
218
218
  unmasked: true,
219
219
  },
220
220
  { sel: '.tab', stem: 'tabbar-default', radius: 'var(--tabbar-default-tab-top-radius, 0px)' },
221
- { sel: '.tab.active', stem: 'tabbar-active', radius: 'var(--tabbar-active-tab-top-radius, 0px)' },
221
+ { sel: '.tab.selected', stem: 'tabbar-selected', radius: 'var(--tabbar-selected-tab-top-radius, 0px)' },
222
222
  {
223
223
  sel: '.segmented-control',
224
224
  fill: 'var(--segmentedcontrol-bar-surface)',
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Component-config migration, disk-shape in and disk-shape out. Extracted
3
- * from `editorStore.ts` (Wave 1 of `docs/plans/theme-completeness.md`) so the
4
- * server (`normalizeTheme`) can run the same migration an embedded theme
3
+ * from `editorStore.ts` so the server (`normalizeTheme`) can run the same
4
+ * migration an embedded theme
5
5
  * config gets on the client, instead of reading it raw.
6
6
  */
7
7
 
@@ -98,7 +98,7 @@ function renameSectionDividerObjectSlots(
98
98
  }
99
99
 
100
100
  // If we found a canvas gradient (any era), fan it into the three new
101
- // per-variant background slots and drop every other family's gradient.
101
+ // per-variant surface slots and drop every other family's gradient.
102
102
  // If no canvas gradient is found, pass through non-family keys verbatim
103
103
  // so non-migration data (theme tokens, other components) isn't touched.
104
104
  const out: Record<string, AliasDiskValue> = {};
@@ -116,14 +116,22 @@ function renameSectionDividerObjectSlots(
116
116
  break;
117
117
  }
118
118
  }
119
- // Pass through anything that's already at the final lg/md/sm shape so
120
- // re-running the migration is idempotent.
121
119
  if (isFamilyGradient) continue;
120
+ // A size-keyed `-background` slot is the pre-surface-rename shape (the
121
+ // migration runner only sees string keys, so an object-valued one never
122
+ // reaches it); carry its value forward under `-surface`.
123
+ const backgroundVariant = SIZE_VARIANTS.find((v) => key === `--sectiondivider-${v}-background`);
124
+ if (backgroundVariant) {
125
+ out[`--sectiondivider-${backgroundVariant}-surface`] = value;
126
+ continue;
127
+ }
128
+ // Pass through anything that's already at the final lg/md/sm `-surface`
129
+ // shape so re-running the migration is idempotent.
122
130
  out[key] = value;
123
131
  }
124
132
  if (canvasGradient !== undefined) {
125
133
  for (const v of SIZE_VARIANTS) {
126
- out[`--sectiondivider-${v}-background`] = canvasGradient;
134
+ out[`--sectiondivider-${v}-surface`] = canvasGradient;
127
135
  }
128
136
  }
129
137
  return out;
@@ -0,0 +1,42 @@
1
+ import type { Migration } from './index';
2
+
3
+ /**
4
+ * Badge and CornerBadge say brand (2026-09-13).
5
+ *
6
+ * `primary` meant two things: the one primary action on Button and
7
+ * IconButton, and the brand color family on Badge and CornerBadge. The
8
+ * badges take the name their tokens already carry (`--surface-brand`);
9
+ * Button's and IconButton's `primary` is untouched. Values are unchanged, so
10
+ * this is a pure key rename.
11
+ */
12
+ const BADGE_SUFFIXES = [
13
+ 'surface', 'text', 'border',
14
+ 'text-font-family', 'text-font-size', 'text-font-weight', 'text-line-height',
15
+ 'border-width', 'radius', 'padding', 'shadow', 'blur', 'icon-size',
16
+ ];
17
+ const CORNERBADGE_SUFFIXES = ['surface', 'border', 'text'];
18
+
19
+ const RENAMES: Record<string, Record<string, string>> = {
20
+ badge: Object.fromEntries(
21
+ BADGE_SUFFIXES.map((s) => [`--badge-primary-${s}`, `--badge-brand-${s}`]),
22
+ ),
23
+ cornerbadge: Object.fromEntries(
24
+ CORNERBADGE_SUFFIXES.map((s) => [`--cornerbadge-primary-${s}`, `--cornerbadge-brand-${s}`]),
25
+ ),
26
+ };
27
+
28
+ export const componentMigration_2026_09_13_badgeBrand: Migration = {
29
+ id: '2026-09-13-badge-brand',
30
+ fromVersion: 34,
31
+ toVersion: 35,
32
+ appliesTo: 'component-config',
33
+ apply(rawVars, meta) {
34
+ const renames = meta.component ? RENAMES[meta.component] : undefined;
35
+ if (!renames) return { ...rawVars };
36
+ const out: Record<string, string> = {};
37
+ for (const [key, value] of Object.entries(rawVars)) {
38
+ out[renames[key] ?? key] = value;
39
+ }
40
+ return out;
41
+ },
42
+ };
@@ -0,0 +1,33 @@
1
+ import type { Migration } from './index';
2
+
3
+ /**
4
+ * CollapsibleSection's expanded state reads open (2026-09-13).
5
+ *
6
+ * `expanded` is a prop rename to `open`, matching Dialog and Tooltip. The
7
+ * four `-expanded-` properties read `-open-`. Values are unchanged, so this
8
+ * is a pure key rename.
9
+ */
10
+ const RENAMES: Record<string, Record<string, string>> = {
11
+ collapsiblesection: {
12
+ '--collapsiblesection-chromeless-expanded-padding': '--collapsiblesection-chromeless-open-padding',
13
+ '--collapsiblesection-hairline-expanded-padding': '--collapsiblesection-hairline-open-padding',
14
+ '--collapsiblesection-container-expanded-surface': '--collapsiblesection-container-open-surface',
15
+ '--collapsiblesection-container-expanded-padding': '--collapsiblesection-container-open-padding',
16
+ },
17
+ };
18
+
19
+ export const componentMigration_2026_09_13_collapsiblesectionOpen: Migration = {
20
+ id: '2026-09-13-collapsiblesection-open',
21
+ fromVersion: 33,
22
+ toVersion: 34,
23
+ appliesTo: 'component-config',
24
+ apply(rawVars, meta) {
25
+ const renames = meta.component ? RENAMES[meta.component] : undefined;
26
+ if (!renames) return { ...rawVars };
27
+ const out: Record<string, string> = {};
28
+ for (const [key, value] of Object.entries(rawVars)) {
29
+ out[renames[key] ?? key] = value;
30
+ }
31
+ return out;
32
+ },
33
+ };