@motion-proto/live-tokens 0.70.0 → 0.72.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 (66) hide show
  1. package/.claude/skills/live-tokens-check-compliance/SKILL.md +78 -0
  2. package/.claude/skills/live-tokens-create-component/SKILL.md +2 -2
  3. package/.claude/skills/live-tokens-create-component/references/contract-tests.md +99 -0
  4. package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +1 -2
  5. package/.claude/skills/live-tokens-create-component/references/token-naming.md +6 -0
  6. package/.claude/skills/live-tokens-fix-findings/SKILL.md +5 -2
  7. package/CHANGELOG.md +100 -0
  8. package/README.md +9 -2
  9. package/bin/check-component.mjs +2 -11
  10. package/bin/check-page.mjs +4 -3
  11. package/bin/cli.mjs +29 -1
  12. package/bin/lib/catalogue.mjs +6 -2
  13. package/bin/lib/findings.mjs +17 -0
  14. package/bin/lib/report.mjs +158 -0
  15. package/bin/lib/tokenVocabulary.mjs +20 -0
  16. package/dist-plugin/adjust/index.cjs +33 -6
  17. package/dist-plugin/adjust/index.d.cts +2 -2
  18. package/dist-plugin/adjust/index.d.ts +2 -2
  19. package/dist-plugin/adjust/index.js +7 -6
  20. package/dist-plugin/{chunk-2YNERPXY.js → chunk-RIXO2E55.js} +1 -1
  21. package/dist-plugin/{chunk-RVE3MNKM.js → chunk-W6Y4BWFB.js} +3 -1
  22. package/dist-plugin/{chunk-GPIBU44G.js → chunk-YLCOIGQC.js} +25 -1
  23. package/dist-plugin/{dataPaths-bJTCEO4H.d.ts → dataPaths-BhWzd5cL.d.cts} +4 -0
  24. package/dist-plugin/{dataPaths-bJTCEO4H.d.cts → dataPaths-BhWzd5cL.d.ts} +4 -0
  25. package/dist-plugin/fontPairing/index.cjs +3 -1
  26. package/dist-plugin/fontPairing/index.d.cts +1 -1
  27. package/dist-plugin/fontPairing/index.d.ts +1 -1
  28. package/dist-plugin/fontPairing/index.js +1 -1
  29. package/dist-plugin/generateColorsAndType/index.cjs +28 -2
  30. package/dist-plugin/generateColorsAndType/index.d.cts +1 -1
  31. package/dist-plugin/generateColorsAndType/index.d.ts +1 -1
  32. package/dist-plugin/generateColorsAndType/index.js +2 -2
  33. package/dist-plugin/index.cjs +28 -2
  34. package/dist-plugin/index.d.cts +1 -1
  35. package/dist-plugin/index.d.ts +1 -1
  36. package/dist-plugin/index.js +3 -3
  37. package/dist-plugin/migrateData/index.cjs +28 -2
  38. package/dist-plugin/migrateData/index.d.cts +1 -1
  39. package/dist-plugin/migrateData/index.d.ts +1 -1
  40. package/dist-plugin/migrateData/index.js +3 -3
  41. package/dist-plugin/tokensCssMigrations/index.cjs +3 -1
  42. package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
  43. package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
  44. package/dist-plugin/tokensCssMigrations/index.js +1 -1
  45. package/package.json +5 -1
  46. package/src/editor/component-editor/SectionDividerEditor.svelte +1 -11
  47. package/src/editor/component-editor/contract.ts +175 -0
  48. package/src/editor/component-editor/scaffolding/StateBlock.svelte +0 -8
  49. package/src/editor/component-editor/scaffolding/TokenLayout.svelte +5 -0
  50. package/src/editor/component-editor/scaffolding/TypeEditor.svelte +0 -21
  51. package/src/editor/component-editor/scaffolding/VariantGroup.svelte +2 -2
  52. package/src/editor/component-editor/scaffolding/types.ts +1 -7
  53. package/src/editor/core/components/aliasKinds.ts +6 -2
  54. package/src/editor/core/themes/migrations/2026-09-02-sectiondivider-drop-title-outline.ts +39 -0
  55. package/src/editor/core/themes/migrations/index.ts +2 -0
  56. package/src/live-tokens/data/themes/autumn.json +1 -7
  57. package/src/live-tokens/data/themes/halloween.json +1 -7
  58. package/src/live-tokens/data/themes/midnight-study.json +1 -7
  59. package/src/live-tokens/data/themes/ocean.json +1 -7
  60. package/src/live-tokens/data/themes/royal-velvet.json +1 -7
  61. package/src/live-tokens/data/themes/sketchy.json +1 -7
  62. package/src/live-tokens/data/themes/spring-meadow.json +1 -7
  63. package/src/live-tokens/data/themes/sunset.json +1 -7
  64. package/src/system/components/SectionDivider.svelte +3 -143
  65. package/src/system/components/FloatingTokenTags.css +0 -284
  66. package/src/system/components/FloatingTokenTags.svelte +0 -570
@@ -0,0 +1,158 @@
1
+ // The project as facts. Every section is deterministic: what the tokens.css
2
+ // declares, what each component reads, which component each page renders, and
3
+ // what the two checkers report under the project's severities and under
4
+ // --strict. Nothing here interprets; the check skill narrates it and the fix
5
+ // skill acts on it. Reads files only, like the vocabulary it is built on.
6
+
7
+ import { readFileSync } from 'node:fs';
8
+ import { relative } from 'node:path';
9
+ import { COMPONENT_RULES, checkComponent, discoverComponents } from '../check-component.mjs';
10
+ import { COMPONENT_IMPORT, PAGE_RULES, checkPages, discoverPages } from '../check-page.mjs';
11
+ import { applySeverity, readChecksConfig } from './findings.mjs';
12
+ import { extractGlobalRootBlocks } from './tokenVocabulary.mjs';
13
+
14
+ const SIDES = ['-top', '-right', '-bottom', '-left'];
15
+
16
+ /**
17
+ * Tokens a component declares that nothing in its file reads. A read is the
18
+ * name appearing outside the `:global(:root)` block: in a `var()`, in a `style:`
19
+ * directive, or as the string a padding mixin takes. SCSS interpolation
20
+ * (`--badge-#{$v}-surface`) reads every token the pattern covers. A per-side
21
+ * padding is read through its parent.
22
+ */
23
+ export function unreadTokens(source, tokens) {
24
+ let body = source.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/<!--[\s\S]*?-->/g, ' ');
25
+ for (const block of extractGlobalRootBlocks(body)) body = body.replace(block, ' ');
26
+ const patterns = [...body.matchAll(/--[a-z0-9-]*(?:#\{[^}]*\}[a-z0-9-]*)+/g)].map(
27
+ (m) => new RegExp(`^${m[0].replace(/[.*+?^()|[\]\\]/g, '\\$&').replace(/#\{[^}]*\}/g, '[a-z0-9-]+')}$`),
28
+ );
29
+ const isRead = (name) => body.includes(name) || patterns.some((re) => re.test(name));
30
+ return [...tokens].filter((name) => {
31
+ const side = SIDES.find((s) => name.endsWith(s));
32
+ return !isRead(name) && !(side && isRead(name.slice(0, -side.length)));
33
+ });
34
+ }
35
+
36
+ function countByRule(findings) {
37
+ const out = {};
38
+ for (const f of findings) out[f.rule] = (out[f.rule] ?? 0) + 1;
39
+ return out;
40
+ }
41
+
42
+ function summarise(findings, rules, config) {
43
+ const resolved = applySeverity(findings, rules, {}, config);
44
+ const strict = applySeverity(findings, rules, { strict: true }, config);
45
+ return {
46
+ errors: resolved.filter((f) => f.severity === 'error').length,
47
+ warnings: resolved.filter((f) => f.severity === 'warn').length,
48
+ strictErrors: strict.filter((f) => f.severity === 'error').length,
49
+ byRule: countByRule(resolved),
50
+ items: resolved.map((f) => ({ rule: f.rule, severity: f.severity, file: f.file, line: f.line, message: f.message })),
51
+ };
52
+ }
53
+
54
+ export function buildReport(vocab, { root = process.cwd() } = {}) {
55
+ const config = readChecksConfig(root);
56
+
57
+ const components = [...vocab.components.values()].map((c) => {
58
+ const source = readFileSync(c.file, 'utf8');
59
+ return {
60
+ id: c.id,
61
+ name: c.name,
62
+ origin: c.origin,
63
+ file: relative(root, c.file),
64
+ registered: vocab.builtIn.has(c.id) || vocab.registered.has(c.id),
65
+ described: /^\s*<!--[\s\S]*?-->/.test(source),
66
+ tokens: c.tokens.size,
67
+ unread: unreadTokens(source, c.tokens.keys()),
68
+ };
69
+ });
70
+
71
+ const pageFiles = discoverPages(root);
72
+ const byPage = [];
73
+ const pagesOf = new Map();
74
+ for (const file of pageFiles) {
75
+ if (!file.endsWith('.svelte')) continue;
76
+ const text = readFileSync(file, 'utf8').replace(/<style[^>]*>[\s\S]*?<\/style>/g, ' ');
77
+ const used = [];
78
+ for (const m of text.matchAll(/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g)) {
79
+ const comp = m[2].match(COMPONENT_IMPORT);
80
+ if (!comp) continue;
81
+ const id = comp[1].toLowerCase();
82
+ const rendered = [...text.matchAll(new RegExp(`<${m[1]}(?=[\\s/>])`, 'g'))].length;
83
+ used.push({ id, rendered });
84
+ if (!pagesOf.has(id)) pagesOf.set(id, []);
85
+ pagesOf.get(id).push(relative(root, file));
86
+ }
87
+ byPage.push({ file: relative(root, file), components: used });
88
+ }
89
+ const byComponent = components.map((c) => ({ id: c.id, origin: c.origin, pages: pagesOf.get(c.id) ?? [] }));
90
+
91
+ const pageFindings = checkPages(pageFiles, { root, vocabulary: vocab }).findings;
92
+ const authored = discoverComponents(root);
93
+ const componentFindings = authored.flatMap((id) => checkComponent(id, root, { vocabulary: vocab }).findings);
94
+
95
+ return {
96
+ project: {
97
+ root,
98
+ tokensCss: vocab.tokensCssPath ? relative(root, vocab.tokensCssPath) : null,
99
+ themeTokens: vocab.themeTokens.size,
100
+ components: components.length,
101
+ pages: pageFiles.length,
102
+ },
103
+ components,
104
+ usage: {
105
+ byPage,
106
+ byComponent,
107
+ unusedShipped: byComponent.filter((c) => c.origin === 'shipped' && c.pages.length === 0).map((c) => c.id),
108
+ customUnregistered: components.filter((c) => c.origin === 'custom' && !c.registered).map((c) => c.id),
109
+ customUnused: byComponent.filter((c) => c.origin === 'custom' && c.pages.length === 0).map((c) => c.id),
110
+ },
111
+ findings: {
112
+ pages: summarise(pageFindings, PAGE_RULES, config),
113
+ components: { checked: authored, ...summarise(componentFindings, COMPONENT_RULES, config) },
114
+ },
115
+ };
116
+ }
117
+
118
+ const list = (items, max = 20) =>
119
+ items.length <= max ? items.join(', ') : `${items.slice(0, max).join(', ')}, +${items.length - max} more`;
120
+
121
+ export function formatReport(r) {
122
+ const out = [];
123
+ out.push(`Project: ${r.project.pages} page file(s), ${r.project.components} component(s), ${r.project.themeTokens} theme tokens from ${r.project.tokensCss ?? '(no tokens.css)'}`);
124
+ if (r.migrations) {
125
+ out.push('');
126
+ out.push(`Migrations: ${r.migrations.status}${r.migrations.pending?.length ? ` (${list(r.migrations.pending)})` : ''}`);
127
+ }
128
+
129
+ out.push('');
130
+ out.push('Components');
131
+ const unread = r.components.filter((c) => c.unread.length);
132
+ out.push(` tokens declared and read by their own CSS: ${r.components.reduce((n, c) => n + c.tokens - c.unread.length, 0)} of ${r.components.reduce((n, c) => n + c.tokens, 0)}`);
133
+ for (const c of unread) out.push(` ${c.id}: ${c.unread.length} unread (${list(c.unread, 6)})`);
134
+ const custom = r.components.filter((c) => c.origin === 'custom');
135
+ out.push(` custom: ${custom.length}${custom.length ? ` (${list(custom.map((c) => c.id))})` : ''}`);
136
+ if (r.usage.customUnregistered.length) out.push(` not registered: ${list(r.usage.customUnregistered)}`);
137
+ const undescribed = custom.filter((c) => !c.described).map((c) => c.id);
138
+ if (undescribed.length) out.push(` no description comment: ${list(undescribed)}`);
139
+
140
+ out.push('');
141
+ out.push('Usage');
142
+ for (const p of r.usage.byPage) {
143
+ if (p.components.length === 0) continue;
144
+ out.push(` ${p.file}: ${p.components.map((c) => `${c.id}×${c.rendered}`).join(', ')}`);
145
+ }
146
+ out.push(` pages rendering no catalogue component: ${r.usage.byPage.filter((p) => p.components.length === 0).length}`);
147
+ out.push(` shipped components used nowhere: ${r.usage.unusedShipped.length}${r.usage.unusedShipped.length ? ` (${list(r.usage.unusedShipped)})` : ''}`);
148
+ if (r.usage.customUnused.length) out.push(` custom components used nowhere: ${list(r.usage.customUnused)}`);
149
+
150
+ const section = (label, s) => {
151
+ out.push('');
152
+ out.push(`${label}: ${s.errors} error(s), ${s.warnings} warning(s); ${s.strictErrors} under --strict`);
153
+ for (const [rule, n] of Object.entries(s.byRule).sort((a, b) => b[1] - a[1])) out.push(` ${rule}: ${n}`);
154
+ };
155
+ section('check-page', r.findings.pages);
156
+ section(`check-component (${r.findings.components.checked.length} authored)`, r.findings.components);
157
+ return out.join('\n');
158
+ }
@@ -164,6 +164,24 @@ function componentFiles(roots) {
164
164
  return files;
165
165
  }
166
166
 
167
+ /** The package's own component ids, read from the frozen registry that declares
168
+ them. A shipped component is registered by the package rather than by the
169
+ project, so it never appears in the project's own `registerComponent` scan. */
170
+ const BUILT_IN_REGISTRY = 'src/editor/component-editor/registry.ts';
171
+
172
+ export function builtInIds(root = process.cwd(), pkgRoot = PKG_ROOT) {
173
+ const ids = new Set();
174
+ for (const base of [pkgRoot, root]) {
175
+ const path = join(base, BUILT_IN_REGISTRY);
176
+ if (!existsSync(path)) continue;
177
+ const block = readFileSync(path, 'utf8')
178
+ .match(/builtInRegistry[^=]*=\s*Object\.freeze\(\{([\s\S]*?)\n\}\);/);
179
+ if (!block) continue;
180
+ for (const m of block[1].matchAll(/\bid:\s*'([a-z][a-z0-9]*)'/g)) ids.add(m[1]);
181
+ }
182
+ return ids;
183
+ }
184
+
167
185
  function registeredIds(root) {
168
186
  const ids = new Set();
169
187
  for (const file of walk(join(root, 'src'), ['.ts', '.js', '.mjs', '.svelte'])) {
@@ -223,12 +241,14 @@ export function loadVocabulary({ root = process.cwd(), pkgRoot = PKG_ROOT } = {}
223
241
  });
224
242
  }
225
243
  const registered = registeredIds(root);
244
+ const builtIn = builtInIds(root, pkgRoot);
226
245
 
227
246
  return {
228
247
  themeTokens,
229
248
  componentTokens,
230
249
  components,
231
250
  registered,
251
+ builtIn,
232
252
  tokensCssPath,
233
253
  /** True when `name` resolves to something real at runtime. */
234
254
  knows(name) {
@@ -81,6 +81,10 @@ var KIND_RULES = [
81
81
  prefix: ["--border-width-"]
82
82
  },
83
83
  { kind: "border", suffix: ["-border"], prefix: ["--border-"] },
84
+ // A dimension with no more specific name behind it — a panel's width, an
85
+ // avatar's size. Last of the geometry rules, so every `-border-width`,
86
+ // `-divider-height`, `-icon-size` and the rest claim their token first.
87
+ { kind: "length", suffix: ["-width", "-height", "-size"] },
84
88
  // Fills. A tint is a wash over a surface, so it takes the surface picker: the
85
89
  // full palette with an alpha, not just the tint stops it defaults to.
86
90
  {
@@ -95,10 +99,7 @@ var KIND_RULES = [
95
99
  "-accent",
96
100
  "-color",
97
101
  "-tint",
98
- "-opacity",
99
- "-width",
100
- "-height",
101
- "-size"
102
+ "-opacity"
102
103
  ],
103
104
  prefix: ["--surface-", "--tint", "--color-"]
104
105
  }
@@ -281,7 +282,9 @@ var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
281
282
  "componentConfigsDir",
282
283
  "themesDir",
283
284
  "manifestsDir",
284
- "tokensCssPath"
285
+ "tokensCssPath",
286
+ "componentDirs",
287
+ "checks"
285
288
  ]);
286
289
  var cached = null;
287
290
  function readLiveTokensConfig() {
@@ -1125,6 +1128,29 @@ var componentMigration_2026_09_01_gateSuffixEnabled = {
1125
1128
  }
1126
1129
  };
1127
1130
 
1131
+ // src/editor/core/themes/migrations/2026-09-02-sectiondivider-drop-title-outline.ts
1132
+ var DROPPED2 = new Set(
1133
+ ["lg", "md", "sm"].flatMap((v) => [
1134
+ `--sectiondivider-${v}-title-outline-width`,
1135
+ `--sectiondivider-${v}-title-outline-color`
1136
+ ])
1137
+ );
1138
+ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
1139
+ id: "2026-09-02-sectiondivider-drop-title-outline",
1140
+ fromVersion: 25,
1141
+ toVersion: 26,
1142
+ appliesTo: "component-config",
1143
+ apply(rawVars, meta) {
1144
+ if (meta.component !== "sectiondivider") return { ...rawVars };
1145
+ const out = {};
1146
+ for (const [key, value] of Object.entries(rawVars)) {
1147
+ if (DROPPED2.has(key)) continue;
1148
+ out[key] = value;
1149
+ }
1150
+ return out;
1151
+ }
1152
+ };
1153
+
1128
1154
  // src/editor/core/themes/migrations/index.ts
1129
1155
  var MIGRATIONS = [
1130
1156
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -1158,7 +1184,8 @@ var MIGRATIONS = [
1158
1184
  colorsAndTypeMigration_2026_09_01_tintRename,
1159
1185
  componentMigration_2026_09_01_tintRename,
1160
1186
  componentMigration_2026_09_01_tabbarActiveTint,
1161
- componentMigration_2026_09_01_gateSuffixEnabled
1187
+ componentMigration_2026_09_01_gateSuffixEnabled,
1188
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline
1162
1189
  ];
1163
1190
  function countFor(kind) {
1164
1191
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -1,5 +1,5 @@
1
1
  import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-DSV3Zisf.cjs';
2
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-bJTCEO4H.cjs';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.cjs';
3
3
  export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.cjs';
4
4
 
5
5
  type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width';
@@ -37,7 +37,7 @@ interface AdjustResult {
37
37
  }
38
38
  declare function adjustAliases(configs: Record<string, ComponentConfig>, ops: readonly AdjustOp[], now: string): AdjustResult;
39
39
 
40
- type TokenKind = 'surface' | 'border' | 'border-width' | 'radius' | 'divider-width' | 'divider-height' | 'divider-inset' | 'dot-size' | 'blur' | 'scale' | 'shadow' | 'font-family' | 'font-weight' | 'font-size' | 'line-height' | 'letter-spacing' | 'padding' | 'gap' | 'duration' | 'easing' | 'text-color';
40
+ type TokenKind = 'surface' | 'border' | 'border-width' | 'radius' | 'divider-width' | 'divider-height' | 'divider-inset' | 'dot-size' | 'length' | 'blur' | 'scale' | 'shadow' | 'font-family' | 'font-weight' | 'font-size' | 'line-height' | 'letter-spacing' | 'padding' | 'gap' | 'duration' | 'easing' | 'text-color';
41
41
  /** Side-aware kind test. Per-side paddings (`--card-default-body-padding-top`)
42
42
  are written by UIPaddingSelector and never declared as editor tokens, so
43
43
  `rawKind` never meets one; the CLI does, and they belong with their parent. */
@@ -1,5 +1,5 @@
1
1
  import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-DSV3Zisf.js';
2
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-bJTCEO4H.js';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.js';
3
3
  export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.js';
4
4
 
5
5
  type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width';
@@ -37,7 +37,7 @@ interface AdjustResult {
37
37
  }
38
38
  declare function adjustAliases(configs: Record<string, ComponentConfig>, ops: readonly AdjustOp[], now: string): AdjustResult;
39
39
 
40
- type TokenKind = 'surface' | 'border' | 'border-width' | 'radius' | 'divider-width' | 'divider-height' | 'divider-inset' | 'dot-size' | 'blur' | 'scale' | 'shadow' | 'font-family' | 'font-weight' | 'font-size' | 'line-height' | 'letter-spacing' | 'padding' | 'gap' | 'duration' | 'easing' | 'text-color';
40
+ type TokenKind = 'surface' | 'border' | 'border-width' | 'radius' | 'divider-width' | 'divider-height' | 'divider-inset' | 'dot-size' | 'length' | 'blur' | 'scale' | 'shadow' | 'font-family' | 'font-weight' | 'font-size' | 'line-height' | 'letter-spacing' | 'padding' | 'gap' | 'duration' | 'easing' | 'text-color';
41
41
  /** Side-aware kind test. Per-side paddings (`--card-default-body-padding-top`)
42
42
  are written by UIPaddingSelector and never declared as editor tokens, so
43
43
  `rawKind` never meets one; the CLI does, and they belong with their parent. */
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  CURRENT_COMPONENT_SCHEMA_VERSION
3
- } from "../chunk-GPIBU44G.js";
3
+ } from "../chunk-YLCOIGQC.js";
4
4
  import {
5
5
  readLiveTokensConfig,
6
6
  resolveDataDirs
7
- } from "../chunk-RVE3MNKM.js";
7
+ } from "../chunk-W6Y4BWFB.js";
8
8
 
9
9
  // src/editor/core/components/aliasKinds.ts
10
10
  var KIND_RULES = [
@@ -49,6 +49,10 @@ var KIND_RULES = [
49
49
  prefix: ["--border-width-"]
50
50
  },
51
51
  { kind: "border", suffix: ["-border"], prefix: ["--border-"] },
52
+ // A dimension with no more specific name behind it — a panel's width, an
53
+ // avatar's size. Last of the geometry rules, so every `-border-width`,
54
+ // `-divider-height`, `-icon-size` and the rest claim their token first.
55
+ { kind: "length", suffix: ["-width", "-height", "-size"] },
52
56
  // Fills. A tint is a wash over a surface, so it takes the surface picker: the
53
57
  // full palette with an alpha, not just the tint stops it defaults to.
54
58
  {
@@ -63,10 +67,7 @@ var KIND_RULES = [
63
67
  "-accent",
64
68
  "-color",
65
69
  "-tint",
66
- "-opacity",
67
- "-width",
68
- "-height",
69
- "-size"
70
+ "-opacity"
70
71
  ],
71
72
  prefix: ["--surface-", "--tint", "--color-"]
72
73
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CURRENT_COMPONENT_SCHEMA_VERSION,
3
3
  runMigrations
4
- } from "./chunk-GPIBU44G.js";
4
+ } from "./chunk-YLCOIGQC.js";
5
5
 
6
6
  // vite-plugin/files/versionedFileResourceServer.ts
7
7
  import fs from "fs";
@@ -8,7 +8,9 @@ var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
8
8
  "componentConfigsDir",
9
9
  "themesDir",
10
10
  "manifestsDir",
11
- "tokensCssPath"
11
+ "tokensCssPath",
12
+ "componentDirs",
13
+ "checks"
12
14
  ]);
13
15
  var cached = null;
14
16
  function readLiveTokensConfig() {
@@ -803,6 +803,29 @@ var componentMigration_2026_09_01_gateSuffixEnabled = {
803
803
  }
804
804
  };
805
805
 
806
+ // src/editor/core/themes/migrations/2026-09-02-sectiondivider-drop-title-outline.ts
807
+ var DROPPED2 = new Set(
808
+ ["lg", "md", "sm"].flatMap((v) => [
809
+ `--sectiondivider-${v}-title-outline-width`,
810
+ `--sectiondivider-${v}-title-outline-color`
811
+ ])
812
+ );
813
+ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
814
+ id: "2026-09-02-sectiondivider-drop-title-outline",
815
+ fromVersion: 25,
816
+ toVersion: 26,
817
+ appliesTo: "component-config",
818
+ apply(rawVars, meta) {
819
+ if (meta.component !== "sectiondivider") return { ...rawVars };
820
+ const out = {};
821
+ for (const [key, value] of Object.entries(rawVars)) {
822
+ if (DROPPED2.has(key)) continue;
823
+ out[key] = value;
824
+ }
825
+ return out;
826
+ }
827
+ };
828
+
806
829
  // src/editor/core/themes/migrations/index.ts
807
830
  var MIGRATIONS = [
808
831
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -836,7 +859,8 @@ var MIGRATIONS = [
836
859
  colorsAndTypeMigration_2026_09_01_tintRename,
837
860
  componentMigration_2026_09_01_tintRename,
838
861
  componentMigration_2026_09_01_tabbarActiveTint,
839
- componentMigration_2026_09_01_gateSuffixEnabled
862
+ componentMigration_2026_09_01_gateSuffixEnabled,
863
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline
840
864
  ];
841
865
  function countFor(kind) {
842
866
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -16,6 +16,10 @@ interface LiveTokensFileConfig {
16
16
  * migrate` CLI has no plugin options, so it reads this key to locate the file.
17
17
  */
18
18
  tokensCssPath?: string;
19
+ /** Extra directories the component checkers and the registry query discover. */
20
+ componentDirs?: string[];
21
+ /** Checker settings: `rules` per-rule severities, `exclude` paths to skip. */
22
+ checks?: Record<string, unknown>;
19
23
  }
20
24
  interface ResolveDataDirsInput {
21
25
  dataDir?: string;
@@ -16,6 +16,10 @@ interface LiveTokensFileConfig {
16
16
  * migrate` CLI has no plugin options, so it reads this key to locate the file.
17
17
  */
18
18
  tokensCssPath?: string;
19
+ /** Extra directories the component checkers and the registry query discover. */
20
+ componentDirs?: string[];
21
+ /** Checker settings: `rules` per-rule severities, `exclude` paths to skip. */
22
+ checks?: Record<string, unknown>;
19
23
  }
20
24
  interface ResolveDataDirsInput {
21
25
  dataDir?: string;
@@ -382,7 +382,9 @@ var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
382
382
  "componentConfigsDir",
383
383
  "themesDir",
384
384
  "manifestsDir",
385
- "tokensCssPath"
385
+ "tokensCssPath",
386
+ "componentDirs",
387
+ "checks"
386
388
  ]);
387
389
  var cached = null;
388
390
  function readLiveTokensConfig() {
@@ -1,5 +1,5 @@
1
1
  import { c as FontStackVariable, C as ColorsAndType, b as FontStack, F as FontSource } from '../themeTypes-DSV3Zisf.cjs';
2
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-bJTCEO4H.cjs';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.cjs';
3
3
 
4
4
  type PairingSlot = 'display' | 'body' | 'serif' | 'mono' | 'editorial';
5
5
  interface PairingFace {
@@ -1,5 +1,5 @@
1
1
  import { c as FontStackVariable, C as ColorsAndType, b as FontStack, F as FontSource } from '../themeTypes-DSV3Zisf.js';
2
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-bJTCEO4H.js';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.js';
3
3
 
4
4
  type PairingSlot = 'display' | 'body' | 'serif' | 'mono' | 'editorial';
5
5
  interface PairingFace {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readLiveTokensConfig,
3
3
  resolveDataDirs
4
- } from "../chunk-RVE3MNKM.js";
4
+ } from "../chunk-W6Y4BWFB.js";
5
5
 
6
6
  // src/editor/core/fonts/fontParse.ts
7
7
  function parseGoogleFontsUrl(url2) {
@@ -1651,6 +1651,29 @@ var componentMigration_2026_09_01_gateSuffixEnabled = {
1651
1651
  }
1652
1652
  };
1653
1653
 
1654
+ // src/editor/core/themes/migrations/2026-09-02-sectiondivider-drop-title-outline.ts
1655
+ var DROPPED2 = new Set(
1656
+ ["lg", "md", "sm"].flatMap((v) => [
1657
+ `--sectiondivider-${v}-title-outline-width`,
1658
+ `--sectiondivider-${v}-title-outline-color`
1659
+ ])
1660
+ );
1661
+ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
1662
+ id: "2026-09-02-sectiondivider-drop-title-outline",
1663
+ fromVersion: 25,
1664
+ toVersion: 26,
1665
+ appliesTo: "component-config",
1666
+ apply(rawVars, meta) {
1667
+ if (meta.component !== "sectiondivider") return { ...rawVars };
1668
+ const out = {};
1669
+ for (const [key, value] of Object.entries(rawVars)) {
1670
+ if (DROPPED2.has(key)) continue;
1671
+ out[key] = value;
1672
+ }
1673
+ return out;
1674
+ }
1675
+ };
1676
+
1654
1677
  // src/editor/core/themes/migrations/index.ts
1655
1678
  var MIGRATIONS = [
1656
1679
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -1684,7 +1707,8 @@ var MIGRATIONS = [
1684
1707
  colorsAndTypeMigration_2026_09_01_tintRename,
1685
1708
  componentMigration_2026_09_01_tintRename,
1686
1709
  componentMigration_2026_09_01_tabbarActiveTint,
1687
- componentMigration_2026_09_01_gateSuffixEnabled
1710
+ componentMigration_2026_09_01_gateSuffixEnabled,
1711
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline
1688
1712
  ];
1689
1713
  function countFor(kind) {
1690
1714
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -1999,7 +2023,9 @@ var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
1999
2023
  "componentConfigsDir",
2000
2024
  "themesDir",
2001
2025
  "manifestsDir",
2002
- "tokensCssPath"
2026
+ "tokensCssPath",
2027
+ "componentDirs",
2028
+ "checks"
2003
2029
  ]);
2004
2030
  var cached = null;
2005
2031
  function readLiveTokensConfig() {
@@ -1,5 +1,5 @@
1
1
  import { F as FontSource, b as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, C as ColorsAndType } from '../themeTypes-DSV3Zisf.cjs';
2
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-bJTCEO4H.cjs';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.cjs';
3
3
  export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.cjs';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { F as FontSource, b as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, C as ColorsAndType } from '../themeTypes-DSV3Zisf.js';
2
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-bJTCEO4H.js';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.js';
3
3
  export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.js';
4
4
 
5
5
  /**
@@ -19,7 +19,7 @@ import {
19
19
  import {
20
20
  CURRENT_COLORS_AND_TYPE_SCHEMA_VERSION,
21
21
  CURRENT_COMPONENT_SCHEMA_VERSION
22
- } from "../chunk-GPIBU44G.js";
22
+ } from "../chunk-YLCOIGQC.js";
23
23
  import {
24
24
  cssColorToOklch,
25
25
  gamutClamp,
@@ -30,7 +30,7 @@ import {
30
30
  import {
31
31
  readLiveTokensConfig,
32
32
  resolveDataDirs
33
- } from "../chunk-RVE3MNKM.js";
33
+ } from "../chunk-W6Y4BWFB.js";
34
34
 
35
35
  // src/editor/core/store/editorCore.ts
36
36
  import { writable, derived, get } from "svelte/store";
@@ -1587,6 +1587,29 @@ var componentMigration_2026_09_01_gateSuffixEnabled = {
1587
1587
  }
1588
1588
  };
1589
1589
 
1590
+ // src/editor/core/themes/migrations/2026-09-02-sectiondivider-drop-title-outline.ts
1591
+ var DROPPED2 = new Set(
1592
+ ["lg", "md", "sm"].flatMap((v) => [
1593
+ `--sectiondivider-${v}-title-outline-width`,
1594
+ `--sectiondivider-${v}-title-outline-color`
1595
+ ])
1596
+ );
1597
+ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
1598
+ id: "2026-09-02-sectiondivider-drop-title-outline",
1599
+ fromVersion: 25,
1600
+ toVersion: 26,
1601
+ appliesTo: "component-config",
1602
+ apply(rawVars, meta) {
1603
+ if (meta.component !== "sectiondivider") return { ...rawVars };
1604
+ const out = {};
1605
+ for (const [key, value] of Object.entries(rawVars)) {
1606
+ if (DROPPED2.has(key)) continue;
1607
+ out[key] = value;
1608
+ }
1609
+ return out;
1610
+ }
1611
+ };
1612
+
1590
1613
  // src/editor/core/themes/migrations/index.ts
1591
1614
  var MIGRATIONS = [
1592
1615
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -1620,7 +1643,8 @@ var MIGRATIONS = [
1620
1643
  colorsAndTypeMigration_2026_09_01_tintRename,
1621
1644
  componentMigration_2026_09_01_tintRename,
1622
1645
  componentMigration_2026_09_01_tabbarActiveTint,
1623
- componentMigration_2026_09_01_gateSuffixEnabled
1646
+ componentMigration_2026_09_01_gateSuffixEnabled,
1647
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline
1624
1648
  ];
1625
1649
  function countFor(kind) {
1626
1650
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -2601,7 +2625,9 @@ var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
2601
2625
  "componentConfigsDir",
2602
2626
  "themesDir",
2603
2627
  "manifestsDir",
2604
- "tokensCssPath"
2628
+ "tokensCssPath",
2629
+ "componentDirs",
2630
+ "checks"
2605
2631
  ]);
2606
2632
  var cached = null;
2607
2633
  function readLiveTokensConfig() {
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from 'vite';
2
2
  export { ComponentSource, MissingToken, RunResult, TOKENS_CSS_MIGRATIONS, TokensCssMigration, ValidateInput, runTokensCssMigrations, validateTokensCss } from './tokensCssMigrations/index.cjs';
3
- import './dataPaths-bJTCEO4H.cjs';
3
+ import './dataPaths-BhWzd5cL.cjs';
4
4
 
5
5
  interface ThemeFileApiOptions {
6
6
  tokensCssPath: string;
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from 'vite';
2
2
  export { ComponentSource, MissingToken, RunResult, TOKENS_CSS_MIGRATIONS, TokensCssMigration, ValidateInput, runTokensCssMigrations, validateTokensCss } from './tokensCssMigrations/index.js';
3
- import './dataPaths-bJTCEO4H.js';
3
+ import './dataPaths-BhWzd5cL.js';
4
4
 
5
5
  interface ThemeFileApiOptions {
6
6
  tokensCssPath: string;
@@ -13,10 +13,10 @@ import {
13
13
  nextAvailableName,
14
14
  normalizeTheme,
15
15
  versionedFileResourceServer
16
- } from "./chunk-2YNERPXY.js";
16
+ } from "./chunk-RIXO2E55.js";
17
17
  import {
18
18
  CURRENT_COMPONENT_SCHEMA_VERSION
19
- } from "./chunk-GPIBU44G.js";
19
+ } from "./chunk-YLCOIGQC.js";
20
20
  import {
21
21
  TOKENS_CSS_MIGRATIONS,
22
22
  extractGlobalRootBody,
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-7TQQTHI6.js";
32
32
  import {
33
33
  resolveDataDirs
34
- } from "./chunk-RVE3MNKM.js";
34
+ } from "./chunk-W6Y4BWFB.js";
35
35
 
36
36
  // vite-plugin/themeFileApi.ts
37
37
  import fs from "fs";