@motion-proto/live-tokens 0.73.0 → 0.74.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 (73) hide show
  1. package/.claude/skills/live-tokens-build-page/SKILL.md +2 -2
  2. package/.claude/skills/live-tokens-check-compliance/SKILL.md +2 -2
  3. package/.claude/skills/live-tokens-create-component/SKILL.md +4 -4
  4. package/.claude/skills/live-tokens-create-theme/SKILL.md +80 -0
  5. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +94 -0
  6. package/.claude/skills/live-tokens-set-colors/SKILL.md +140 -0
  7. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +80 -0
  8. package/.claude/skills/{live-tokens-adjust-geometry → live-tokens-set-geometry}/SKILL.md +12 -7
  9. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +61 -0
  10. package/.claude/skills/{live-tokens-pair-fonts → live-tokens-set-type}/SKILL.md +18 -15
  11. package/.claude/skills/live-tokens-set-type/references/type-anchors.md +60 -0
  12. package/CHANGELOG.md +91 -0
  13. package/README.md +24 -15
  14. package/bin/check-page.mjs +3 -3
  15. package/bin/cli.mjs +92 -55
  16. package/bin/lib/liveState.mjs +110 -0
  17. package/bin/save-theme.mjs +177 -0
  18. package/bin/set-colors.mjs +191 -0
  19. package/bin/{adjust.mjs → set-geometry.mjs} +18 -50
  20. package/bin/{set-fonts.mjs → set-type.mjs} +21 -55
  21. package/dist-plugin/{chunk-RIXO2E55.js → chunk-7VRTBGJT.js} +1 -1
  22. package/dist-plugin/{chunk-YLCOIGQC.js → chunk-V3YF6CGT.js} +56 -2
  23. package/dist-plugin/index.cjs +58 -3
  24. package/dist-plugin/index.js +11 -11
  25. package/dist-plugin/migrateData/index.cjs +56 -1
  26. package/dist-plugin/migrateData/index.js +2 -2
  27. package/dist-plugin/{generateColorsAndType → setColors}/index.cjs +1109 -1071
  28. package/dist-plugin/{generateColorsAndType → setColors}/index.d.cts +33 -24
  29. package/dist-plugin/{generateColorsAndType → setColors}/index.d.ts +33 -24
  30. package/dist-plugin/{generateColorsAndType → setColors}/index.js +45 -63
  31. package/dist-plugin/{adjust → setGeometry}/index.cjs +60 -5
  32. package/dist-plugin/{adjust → setGeometry}/index.d.cts +1 -1
  33. package/dist-plugin/{adjust → setGeometry}/index.d.ts +1 -1
  34. package/dist-plugin/{adjust → setGeometry}/index.js +1 -1
  35. package/dist-plugin/{fontPairing → setType}/index.cjs +4 -4
  36. package/dist-plugin/{fontPairing → setType}/index.d.cts +1 -1
  37. package/dist-plugin/{fontPairing → setType}/index.d.ts +1 -1
  38. package/dist-plugin/{themeTypes-DSV3Zisf.d.cts → themeTypes-BxRtuN5V.d.cts} +1 -1
  39. package/dist-plugin/{themeTypes-DSV3Zisf.d.ts → themeTypes-BxRtuN5V.d.ts} +1 -1
  40. package/package.json +2 -1
  41. package/src/editor/core/themes/{generateColorsAndType.ts → buildColors.ts} +82 -96
  42. package/src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts +62 -0
  43. package/src/editor/core/themes/migrations/index.ts +2 -0
  44. package/src/editor/docs/content/themes-workflow.md +2 -2
  45. package/src/editor/docs/content.generated.ts +1 -1
  46. package/src/editor/overlay/LiveEditorOverlay.svelte +519 -28
  47. package/src/editor/skill-atlas/SkillAtlas.svelte +2 -2
  48. package/src/editor/skill-atlas/skillSources.generated.ts +19 -15
  49. package/src/editor/skill-atlas/skillTrees.ts +785 -632
  50. package/src/live-tokens/data/colors-and-type/autumn.json +1 -37
  51. package/src/live-tokens/data/colors-and-type/default.json +1 -37
  52. package/src/live-tokens/data/colors-and-type/halloween.json +1 -37
  53. package/src/live-tokens/data/colors-and-type/midnight-study.json +1 -37
  54. package/src/live-tokens/data/colors-and-type/ocean.json +1 -37
  55. package/src/live-tokens/data/colors-and-type/royal-velvet.json +1 -37
  56. package/src/live-tokens/data/colors-and-type/sketchy.json +1 -37
  57. package/src/live-tokens/data/colors-and-type/spring-meadow.json +1 -37
  58. package/src/live-tokens/data/colors-and-type/sunset.json +1 -37
  59. package/src/live-tokens/data/themes/autumn.json +1 -37
  60. package/src/live-tokens/data/themes/halloween.json +1 -37
  61. package/src/live-tokens/data/themes/midnight-study.json +1 -37
  62. package/src/live-tokens/data/themes/ocean.json +1 -37
  63. package/src/live-tokens/data/themes/royal-velvet.json +1 -37
  64. package/src/live-tokens/data/themes/sketchy.json +1 -37
  65. package/src/live-tokens/data/themes/spring-meadow.json +1 -37
  66. package/src/live-tokens/data/themes/sunset.json +1 -37
  67. package/src/live-tokens/data/tokens.generated.css +0 -36
  68. package/.claude/skills/live-tokens-generate-theme/SKILL.md +0 -156
  69. package/.claude/skills/live-tokens-generate-theme/references/mood-vocabulary.md +0 -43
  70. package/.claude/skills/live-tokens-generate-theme/references/named-themes.md +0 -18
  71. package/.claude/skills/live-tokens-generate-theme/references/style-vocabulary.md +0 -35
  72. package/bin/generate-theme.mjs +0 -260
  73. /package/dist-plugin/{fontPairing → setType}/index.js +0 -0
@@ -1,7 +1,7 @@
1
- // `live-tokens set-fonts` worker.
1
+ // `live-tokens set-type` worker.
2
2
  //
3
- // Reads a pairing brief (JSON), verifies each family against Google Fonts,
4
- // binds it to a font stack via the compiled engine (dist-plugin/fontPairing —
3
+ // Reads a pairing file (JSON), verifies each family against Google Fonts,
4
+ // binds it to a font stack via the compiled engine (dist-plugin/setType —
5
5
  // the CLI never imports TS sources), and writes the result into
6
6
  // `colors-and-type/_working.json`: the same buffer the editor's own font edits
7
7
  // land in, so a retype is an unsaved edit the user saves into a theme when they
@@ -12,11 +12,11 @@ import { existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
12
12
  import { dirname, join, relative, resolve } from 'node:path';
13
13
  import { fileURLToPath } from 'node:url';
14
14
 
15
+ import { readActiveTheme, readLiveColorsAndType, readSavedColorsAndType, sameContent } from './lib/liveState.mjs';
15
16
  import { resolveTokensCssPath } from './migrate.mjs';
16
17
 
17
18
  const pkgRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
18
- const ENGINE = resolve(pkgRoot, 'dist-plugin/fontPairing/index.js');
19
- const packageDataDir = join(pkgRoot, 'src/live-tokens/data');
19
+ const ENGINE = resolve(pkgRoot, 'dist-plugin/setType/index.js');
20
20
 
21
21
  // Google serves a different stylesheet per user agent; ask as a browser would
22
22
  // so the weight census matches what the page will actually load.
@@ -32,7 +32,7 @@ const SOURCE_LABELS = {
32
32
  async function loadEngine() {
33
33
  if (!existsSync(ENGINE)) {
34
34
  throw new Error(
35
- `font pairing engine not found at ${relative(process.cwd(), ENGINE)}. ` +
35
+ `setType engine not found at ${relative(process.cwd(), ENGINE)}. ` +
36
36
  `Build the plugin first (npm run build:plugin).`,
37
37
  );
38
38
  }
@@ -43,53 +43,22 @@ function readJson(path) {
43
43
  return JSON.parse(readFileSync(path, 'utf8'));
44
44
  }
45
45
 
46
- function readJsonIfExists(path) {
47
- return existsSync(path) ? readJson(path) : null;
48
- }
49
-
50
46
  function browserFetch(url) {
51
47
  return fetch(url, { headers: { 'user-agent': BROWSER_UA } });
52
48
  }
53
49
 
54
- /** The open theme, read the way every other door reads it: the local file
55
- * first, then the copy the installed package ships. */
56
- function readActiveTheme(themesDir) {
57
- const slug = readJsonIfExists(join(themesDir, '_active.json'))?.activeFile ?? 'default';
58
- const theme =
59
- readJsonIfExists(join(themesDir, `${slug}.json`)) ??
60
- readJsonIfExists(join(packageDataDir, 'themes', `${slug}.json`));
61
- return theme ? { slug, theme } : null;
62
- }
63
-
64
- /** Mirrors the dev server's live colors-and-type resolution: the unsaved
65
- * buffer, then the open theme's own copy, then the package default. */
66
- function readLiveColorsAndType(colorsAndTypeDir, active) {
67
- const working = readJsonIfExists(join(colorsAndTypeDir, '_working.json'));
68
- if (working) return { colorsAndType: working, source: 'working' };
69
- if (active?.theme?.colorsAndType) return { colorsAndType: active.theme.colorsAndType, source: 'theme' };
70
- const shipped =
71
- readJsonIfExists(join(colorsAndTypeDir, 'default.json')) ??
72
- readJsonIfExists(join(packageDataDir, 'colors-and-type', 'default.json'));
73
- if (!shipped) throw new Error(`no colors and type to read at ${colorsAndTypeDir}`);
74
- return { colorsAndType: shipped, source: 'default' };
75
- }
76
-
77
50
  function normalizeFace(slot, value) {
78
51
  if (typeof value === 'string') return { name: value };
79
52
  if (value && typeof value === 'object' && typeof value.name === 'string') {
80
53
  return { name: value.name, ...(value.url ? { url: value.url } : {}) };
81
54
  }
82
- throw new Error(`brief slot "${slot}" must be a family name or { "name": "...", "url": "..." }`);
83
- }
84
-
85
- function sameJson(a, b) {
86
- return JSON.stringify(a) === JSON.stringify(b);
55
+ throw new Error(`pairing slot "${slot}" must be a family name or { "name": "...", "url": "..." }`);
87
56
  }
88
57
 
89
58
  /** `engine` and `fetcher` are test seams; the CLI always runs the compiled
90
59
  * bundle against the live API. */
91
- export async function runSetFonts({
92
- briefPath,
60
+ export async function runSetType({
61
+ pairingPath,
93
62
  dryRun = false,
94
63
  verify = true,
95
64
  root = process.cwd(),
@@ -110,21 +79,21 @@ export async function runSetFonts({
110
79
  resolveDataDirs,
111
80
  } = engine ?? (await loadEngine());
112
81
 
113
- const briefFull = resolve(root, briefPath);
114
- if (!existsSync(briefFull)) throw new Error(`brief file not found at ${relative(root, briefFull)}`);
115
- let brief;
82
+ const fullPath = resolve(root, pairingPath);
83
+ if (!existsSync(fullPath)) throw new Error(`pairing file not found at ${relative(root, fullPath)}`);
84
+ let input;
116
85
  try {
117
- brief = readJson(briefFull);
86
+ input = readJson(fullPath);
118
87
  } catch (err) {
119
- throw new Error(`brief file is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
88
+ throw new Error(`pairing file is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
120
89
  }
121
90
 
122
- const requested = SLOT_ORDER.filter((slot) => brief[slot] !== undefined).map((slot) => ({
91
+ const requested = SLOT_ORDER.filter((slot) => input[slot] !== undefined).map((slot) => ({
123
92
  slot,
124
- face: normalizeFace(slot, brief[slot]),
93
+ face: normalizeFace(slot, input[slot]),
125
94
  }));
126
95
  if (requested.length === 0) {
127
- throw new Error(`brief names no slot. Use one or more of: ${SLOT_ORDER.join(', ')}.`);
96
+ throw new Error(`pairing names no slot. Use one or more of: ${SLOT_ORDER.join(', ')}.`);
128
97
  }
129
98
 
130
99
  const resolved = colorsAndTypeDir && themesDir ? null : resolveDataDirs();
@@ -176,14 +145,11 @@ export async function runSetFonts({
176
145
  }
177
146
 
178
147
  const workingPath = join(colorsDir, '_working.json');
179
- const savedColorsAndType =
180
- active?.theme?.colorsAndType ??
181
- readJsonIfExists(join(colorsDir, 'default.json')) ??
182
- readJsonIfExists(join(packageDataDir, 'colors-and-type', 'default.json'));
148
+ const savedColorsAndType = readSavedColorsAndType(colorsDir, active);
183
149
 
184
150
  // Returning the buffer to what the open theme already holds is a discard,
185
151
  // not an edit — the same call the dev server's own PUT makes.
186
- const backToSaved = savedColorsAndType !== null && sameJson(next, savedColorsAndType);
152
+ const backToSaved = savedColorsAndType !== null && sameContent(next, savedColorsAndType);
187
153
  let wrote = null;
188
154
  if (!dryRun && report.changed) {
189
155
  if (backToSaved) {
@@ -196,7 +162,7 @@ export async function runSetFonts({
196
162
  }
197
163
 
198
164
  return {
199
- briefPath: briefFull,
165
+ pairingPath: fullPath,
200
166
  colorsAndTypeDir: colorsDir,
201
167
  workingPath,
202
168
  openTheme: active?.slug ?? null,
@@ -212,7 +178,7 @@ export async function runSetFonts({
212
178
  };
213
179
  }
214
180
 
215
- export function formatSetFontsResult(result) {
181
+ export function formatSetTypeResult(result) {
216
182
  const root = process.cwd();
217
183
  const lines = [];
218
184
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CURRENT_COMPONENT_SCHEMA_VERSION,
3
3
  runMigrations
4
- } from "./chunk-YLCOIGQC.js";
4
+ } from "./chunk-V3YF6CGT.js";
5
5
 
6
6
  // vite-plugin/files/versionedFileResourceServer.ts
7
7
  import fs from "fs";
@@ -826,6 +826,60 @@ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
826
826
  }
827
827
  };
828
828
 
829
+ // src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts
830
+ var DROPPED3 = /* @__PURE__ */ new Set([
831
+ "--badge-trait-surface",
832
+ "--badge-trait-text",
833
+ "--badge-trait-text-font-family",
834
+ "--badge-trait-text-font-size",
835
+ "--badge-trait-text-font-weight",
836
+ "--badge-trait-text-line-height",
837
+ "--badge-trait-border",
838
+ "--badge-trait-border-width",
839
+ "--badge-trait-shadow",
840
+ "--sectiondivider-title",
841
+ "--sectiondivider-title-font-family",
842
+ "--sectiondivider-title-font-size",
843
+ "--sectiondivider-title-font-weight",
844
+ "--sectiondivider-title-line-height",
845
+ "--sectiondivider-title-border-width",
846
+ "--sectiondivider-title-stroke-color",
847
+ "--sectiondivider-description",
848
+ "--sectiondivider-description-font-family",
849
+ "--sectiondivider-description-font-size",
850
+ "--sectiondivider-description-font-weight",
851
+ "--sectiondivider-description-line-height",
852
+ "--dialog-primary-default-surface",
853
+ "--dialog-primary-default-text",
854
+ "--dialog-primary-default-border",
855
+ "--dialog-primary-default-border-width",
856
+ "--dialog-primary-hover-surface",
857
+ "--dialog-primary-hover-text",
858
+ "--dialog-primary-hover-border",
859
+ "--dialog-primary-hover-border-width",
860
+ "--dialog-secondary-default-text",
861
+ "--dialog-secondary-default-border",
862
+ "--dialog-secondary-default-border-width",
863
+ "--dialog-secondary-hover-surface",
864
+ "--dialog-secondary-hover-text",
865
+ "--dialog-secondary-hover-border",
866
+ "--dialog-secondary-hover-border-width"
867
+ ]);
868
+ var colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys = {
869
+ id: "2026-09-03-drop-legacy-component-keys",
870
+ fromVersion: 7,
871
+ toVersion: 8,
872
+ appliesTo: "colors-and-type",
873
+ apply(rawVars) {
874
+ const out = {};
875
+ for (const [key, value] of Object.entries(rawVars)) {
876
+ if (DROPPED3.has(key)) continue;
877
+ out[key] = value;
878
+ }
879
+ return out;
880
+ }
881
+ };
882
+
829
883
  // src/editor/core/themes/migrations/index.ts
830
884
  var MIGRATIONS = [
831
885
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -860,7 +914,8 @@ var MIGRATIONS = [
860
914
  componentMigration_2026_09_01_tintRename,
861
915
  componentMigration_2026_09_01_tabbarActiveTint,
862
916
  componentMigration_2026_09_01_gateSuffixEnabled,
863
- componentMigration_2026_09_02_sectiondividerDropTitleOutline
917
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline,
918
+ colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys
864
919
  ];
865
920
  function countFor(kind) {
866
921
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -877,7 +932,6 @@ function runMigrations(kind, fileVersion, rawVars, meta = {}) {
877
932
  }
878
933
 
879
934
  export {
880
- CURRENT_COLORS_AND_TYPE_SCHEMA_VERSION,
881
935
  CURRENT_COMPONENT_SCHEMA_VERSION,
882
936
  runMigrations
883
937
  };
@@ -1610,6 +1610,60 @@ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
1610
1610
  }
1611
1611
  };
1612
1612
 
1613
+ // src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts
1614
+ var DROPPED3 = /* @__PURE__ */ new Set([
1615
+ "--badge-trait-surface",
1616
+ "--badge-trait-text",
1617
+ "--badge-trait-text-font-family",
1618
+ "--badge-trait-text-font-size",
1619
+ "--badge-trait-text-font-weight",
1620
+ "--badge-trait-text-line-height",
1621
+ "--badge-trait-border",
1622
+ "--badge-trait-border-width",
1623
+ "--badge-trait-shadow",
1624
+ "--sectiondivider-title",
1625
+ "--sectiondivider-title-font-family",
1626
+ "--sectiondivider-title-font-size",
1627
+ "--sectiondivider-title-font-weight",
1628
+ "--sectiondivider-title-line-height",
1629
+ "--sectiondivider-title-border-width",
1630
+ "--sectiondivider-title-stroke-color",
1631
+ "--sectiondivider-description",
1632
+ "--sectiondivider-description-font-family",
1633
+ "--sectiondivider-description-font-size",
1634
+ "--sectiondivider-description-font-weight",
1635
+ "--sectiondivider-description-line-height",
1636
+ "--dialog-primary-default-surface",
1637
+ "--dialog-primary-default-text",
1638
+ "--dialog-primary-default-border",
1639
+ "--dialog-primary-default-border-width",
1640
+ "--dialog-primary-hover-surface",
1641
+ "--dialog-primary-hover-text",
1642
+ "--dialog-primary-hover-border",
1643
+ "--dialog-primary-hover-border-width",
1644
+ "--dialog-secondary-default-text",
1645
+ "--dialog-secondary-default-border",
1646
+ "--dialog-secondary-default-border-width",
1647
+ "--dialog-secondary-hover-surface",
1648
+ "--dialog-secondary-hover-text",
1649
+ "--dialog-secondary-hover-border",
1650
+ "--dialog-secondary-hover-border-width"
1651
+ ]);
1652
+ var colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys = {
1653
+ id: "2026-09-03-drop-legacy-component-keys",
1654
+ fromVersion: 7,
1655
+ toVersion: 8,
1656
+ appliesTo: "colors-and-type",
1657
+ apply(rawVars) {
1658
+ const out = {};
1659
+ for (const [key, value] of Object.entries(rawVars)) {
1660
+ if (DROPPED3.has(key)) continue;
1661
+ out[key] = value;
1662
+ }
1663
+ return out;
1664
+ }
1665
+ };
1666
+
1613
1667
  // src/editor/core/themes/migrations/index.ts
1614
1668
  var MIGRATIONS = [
1615
1669
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -1644,7 +1698,8 @@ var MIGRATIONS = [
1644
1698
  componentMigration_2026_09_01_tintRename,
1645
1699
  componentMigration_2026_09_01_tabbarActiveTint,
1646
1700
  componentMigration_2026_09_01_gateSuffixEnabled,
1647
- componentMigration_2026_09_02_sectiondividerDropTitleOutline
1701
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline,
1702
+ colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys
1648
1703
  ];
1649
1704
  function countFor(kind) {
1650
1705
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -3816,7 +3871,7 @@ ${lines.join("\n")}
3816
3871
  return "corrupt";
3817
3872
  }
3818
3873
  function notAThemeError(fileName) {
3819
- return `"${fileName}" is a colors-and-type file, not a theme. Before 0.48 those lived in themes/; move it to ${import_path4.default.basename(COLORS_AND_TYPE_DIR)}/ or delete it. To build a theme, use the theme generator skill "generate-theme".`;
3874
+ return `"${fileName}" is a colors-and-type file, not a theme. Before 0.48 those lived in themes/; move it to ${import_path4.default.basename(COLORS_AND_TYPE_DIR)}/ or delete it. To build a theme, use the theme skill "create-theme".`;
3820
3875
  }
3821
3876
  function respondUnreadableTheme(res, fileName, missingError) {
3822
3877
  switch (unreadableThemeReason(fileName)) {
@@ -4408,7 +4463,7 @@ ${lines.join("\n")}
4408
4463
  const { theme, filled } = read;
4409
4464
  if (!theme.colorsAndType) {
4410
4465
  jsonResponse(res, 422, {
4411
- error: 'This theme carries no colors and type. Build one with the theme generator skill "generate-theme".'
4466
+ error: 'This theme carries no colors and type. Build one with the theme skill "create-theme".'
4412
4467
  });
4413
4468
  return;
4414
4469
  }
@@ -1,3 +1,11 @@
1
+ import {
2
+ THEME_SCHEMA_VERSION,
3
+ detectLegacyLayout,
4
+ isColorsAndTypeShaped,
5
+ nextAvailableName,
6
+ normalizeTheme,
7
+ versionedFileResourceServer
8
+ } from "./chunk-7VRTBGJT.js";
1
9
  import {
2
10
  formatGradientValue,
3
11
  palettesToVars,
@@ -6,17 +14,9 @@ import {
6
14
  reconcilePalettesFromCssVars,
7
15
  sanitizeFileName
8
16
  } from "./chunk-O6GQ6GBH.js";
9
- import {
10
- THEME_SCHEMA_VERSION,
11
- detectLegacyLayout,
12
- isColorsAndTypeShaped,
13
- nextAvailableName,
14
- normalizeTheme,
15
- versionedFileResourceServer
16
- } from "./chunk-RIXO2E55.js";
17
17
  import {
18
18
  CURRENT_COMPONENT_SCHEMA_VERSION
19
- } from "./chunk-YLCOIGQC.js";
19
+ } from "./chunk-V3YF6CGT.js";
20
20
  import {
21
21
  TOKENS_CSS_MIGRATIONS,
22
22
  extractGlobalRootBody,
@@ -659,7 +659,7 @@ ${lines.join("\n")}
659
659
  return "corrupt";
660
660
  }
661
661
  function notAThemeError(fileName) {
662
- return `"${fileName}" is a colors-and-type file, not a theme. Before 0.48 those lived in themes/; move it to ${path.basename(COLORS_AND_TYPE_DIR)}/ or delete it. To build a theme, use the theme generator skill "generate-theme".`;
662
+ return `"${fileName}" is a colors-and-type file, not a theme. Before 0.48 those lived in themes/; move it to ${path.basename(COLORS_AND_TYPE_DIR)}/ or delete it. To build a theme, use the theme skill "create-theme".`;
663
663
  }
664
664
  function respondUnreadableTheme(res, fileName, missingError) {
665
665
  switch (unreadableThemeReason(fileName)) {
@@ -1251,7 +1251,7 @@ ${lines.join("\n")}
1251
1251
  const { theme, filled } = read;
1252
1252
  if (!theme.colorsAndType) {
1253
1253
  jsonResponse(res, 422, {
1254
- error: 'This theme carries no colors and type. Build one with the theme generator skill "generate-theme".'
1254
+ error: 'This theme carries no colors and type. Build one with the theme skill "create-theme".'
1255
1255
  });
1256
1256
  return;
1257
1257
  }
@@ -999,6 +999,60 @@ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
999
999
  }
1000
1000
  };
1001
1001
 
1002
+ // src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts
1003
+ var DROPPED3 = /* @__PURE__ */ new Set([
1004
+ "--badge-trait-surface",
1005
+ "--badge-trait-text",
1006
+ "--badge-trait-text-font-family",
1007
+ "--badge-trait-text-font-size",
1008
+ "--badge-trait-text-font-weight",
1009
+ "--badge-trait-text-line-height",
1010
+ "--badge-trait-border",
1011
+ "--badge-trait-border-width",
1012
+ "--badge-trait-shadow",
1013
+ "--sectiondivider-title",
1014
+ "--sectiondivider-title-font-family",
1015
+ "--sectiondivider-title-font-size",
1016
+ "--sectiondivider-title-font-weight",
1017
+ "--sectiondivider-title-line-height",
1018
+ "--sectiondivider-title-border-width",
1019
+ "--sectiondivider-title-stroke-color",
1020
+ "--sectiondivider-description",
1021
+ "--sectiondivider-description-font-family",
1022
+ "--sectiondivider-description-font-size",
1023
+ "--sectiondivider-description-font-weight",
1024
+ "--sectiondivider-description-line-height",
1025
+ "--dialog-primary-default-surface",
1026
+ "--dialog-primary-default-text",
1027
+ "--dialog-primary-default-border",
1028
+ "--dialog-primary-default-border-width",
1029
+ "--dialog-primary-hover-surface",
1030
+ "--dialog-primary-hover-text",
1031
+ "--dialog-primary-hover-border",
1032
+ "--dialog-primary-hover-border-width",
1033
+ "--dialog-secondary-default-text",
1034
+ "--dialog-secondary-default-border",
1035
+ "--dialog-secondary-default-border-width",
1036
+ "--dialog-secondary-hover-surface",
1037
+ "--dialog-secondary-hover-text",
1038
+ "--dialog-secondary-hover-border",
1039
+ "--dialog-secondary-hover-border-width"
1040
+ ]);
1041
+ var colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys = {
1042
+ id: "2026-09-03-drop-legacy-component-keys",
1043
+ fromVersion: 7,
1044
+ toVersion: 8,
1045
+ appliesTo: "colors-and-type",
1046
+ apply(rawVars) {
1047
+ const out = {};
1048
+ for (const [key, value] of Object.entries(rawVars)) {
1049
+ if (DROPPED3.has(key)) continue;
1050
+ out[key] = value;
1051
+ }
1052
+ return out;
1053
+ }
1054
+ };
1055
+
1002
1056
  // src/editor/core/themes/migrations/index.ts
1003
1057
  var MIGRATIONS = [
1004
1058
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -1033,7 +1087,8 @@ var MIGRATIONS = [
1033
1087
  componentMigration_2026_09_01_tintRename,
1034
1088
  componentMigration_2026_09_01_tabbarActiveTint,
1035
1089
  componentMigration_2026_09_01_gateSuffixEnabled,
1036
- componentMigration_2026_09_02_sectiondividerDropTitleOutline
1090
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline,
1091
+ colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys
1037
1092
  ];
1038
1093
  function countFor(kind) {
1039
1094
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -7,10 +7,10 @@ import {
7
7
  normalizeTheme,
8
8
  planLegacyRenames,
9
9
  versionedFileResourceServer
10
- } from "../chunk-RIXO2E55.js";
10
+ } from "../chunk-7VRTBGJT.js";
11
11
  import {
12
12
  CURRENT_COMPONENT_SCHEMA_VERSION
13
- } from "../chunk-YLCOIGQC.js";
13
+ } from "../chunk-V3YF6CGT.js";
14
14
  import {
15
15
  readLiveTokensConfig,
16
16
  resolveDataDirs