@motion-proto/live-tokens 0.72.1 → 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 (81) hide show
  1. package/.claude/skills/live-tokens-build-page/SKILL.md +37 -2
  2. package/.claude/skills/live-tokens-build-page/references/layout-sources.md +48 -0
  3. package/.claude/skills/live-tokens-check-compliance/SKILL.md +2 -2
  4. package/.claude/skills/live-tokens-create-component/SKILL.md +4 -4
  5. package/.claude/skills/live-tokens-create-theme/SKILL.md +80 -0
  6. package/.claude/skills/live-tokens-create-theme/references/design-directions.md +94 -0
  7. package/.claude/skills/live-tokens-pick-component/SKILL.md +1 -1
  8. package/.claude/skills/live-tokens-set-colors/SKILL.md +140 -0
  9. package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +80 -0
  10. package/.claude/skills/{live-tokens-adjust-geometry → live-tokens-set-geometry}/SKILL.md +12 -7
  11. package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +61 -0
  12. package/.claude/skills/{live-tokens-pair-fonts → live-tokens-set-type}/SKILL.md +18 -15
  13. package/.claude/skills/live-tokens-set-type/references/type-anchors.md +60 -0
  14. package/CHANGELOG.md +141 -0
  15. package/README.md +24 -15
  16. package/bin/check-page.mjs +3 -3
  17. package/bin/cli.mjs +92 -55
  18. package/bin/lib/liveState.mjs +110 -0
  19. package/bin/save-theme.mjs +177 -0
  20. package/bin/set-colors.mjs +191 -0
  21. package/bin/{adjust.mjs → set-geometry.mjs} +18 -50
  22. package/bin/{set-fonts.mjs → set-type.mjs} +21 -55
  23. package/dist-plugin/{chunk-RIXO2E55.js → chunk-7VRTBGJT.js} +1 -1
  24. package/dist-plugin/{chunk-YLCOIGQC.js → chunk-V3YF6CGT.js} +56 -2
  25. package/dist-plugin/index.cjs +58 -3
  26. package/dist-plugin/index.js +11 -11
  27. package/dist-plugin/migrateData/index.cjs +56 -1
  28. package/dist-plugin/migrateData/index.js +2 -2
  29. package/dist-plugin/{generateColorsAndType → setColors}/index.cjs +1109 -1071
  30. package/dist-plugin/{generateColorsAndType → setColors}/index.d.cts +33 -24
  31. package/dist-plugin/{generateColorsAndType → setColors}/index.d.ts +33 -24
  32. package/dist-plugin/{generateColorsAndType → setColors}/index.js +45 -63
  33. package/dist-plugin/{adjust → setGeometry}/index.cjs +60 -5
  34. package/dist-plugin/{adjust → setGeometry}/index.d.cts +1 -1
  35. package/dist-plugin/{adjust → setGeometry}/index.d.ts +1 -1
  36. package/dist-plugin/{adjust → setGeometry}/index.js +1 -1
  37. package/dist-plugin/{fontPairing → setType}/index.cjs +4 -4
  38. package/dist-plugin/{fontPairing → setType}/index.d.cts +1 -1
  39. package/dist-plugin/{fontPairing → setType}/index.d.ts +1 -1
  40. package/dist-plugin/{themeTypes-DSV3Zisf.d.cts → themeTypes-BxRtuN5V.d.cts} +1 -1
  41. package/dist-plugin/{themeTypes-DSV3Zisf.d.ts → themeTypes-BxRtuN5V.d.ts} +1 -1
  42. package/package.json +10 -2
  43. package/src/editor/core/themes/{generateColorsAndType.ts → buildColors.ts} +82 -96
  44. package/src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts +62 -0
  45. package/src/editor/core/themes/migrations/index.ts +2 -0
  46. package/src/editor/docs/content/creating-components.md +13 -0
  47. package/src/editor/docs/content/themes-workflow.md +2 -2
  48. package/src/editor/docs/content.generated.ts +2 -2
  49. package/src/editor/overlay/LiveEditorOverlay.svelte +519 -28
  50. package/src/editor/skill-atlas/SkillAtlas.svelte +836 -0
  51. package/src/editor/skill-atlas/SkillAtlas.svelte.d.ts +4 -0
  52. package/src/editor/skill-atlas/SourcePane.svelte +364 -0
  53. package/src/editor/skill-atlas/TreeNodeCard.svelte +206 -0
  54. package/src/editor/skill-atlas/skillSources.generated.ts +45 -0
  55. package/src/editor/skill-atlas/skillSources.ts +1 -0
  56. package/src/editor/skill-atlas/skillTrees.ts +3844 -0
  57. package/src/editor/skill-atlas/types.ts +65 -0
  58. package/src/live-tokens/data/colors-and-type/autumn.json +1 -37
  59. package/src/live-tokens/data/colors-and-type/default.json +1 -37
  60. package/src/live-tokens/data/colors-and-type/halloween.json +1 -37
  61. package/src/live-tokens/data/colors-and-type/midnight-study.json +1 -37
  62. package/src/live-tokens/data/colors-and-type/ocean.json +1 -37
  63. package/src/live-tokens/data/colors-and-type/royal-velvet.json +1 -37
  64. package/src/live-tokens/data/colors-and-type/sketchy.json +1 -37
  65. package/src/live-tokens/data/colors-and-type/spring-meadow.json +1 -37
  66. package/src/live-tokens/data/colors-and-type/sunset.json +1 -37
  67. package/src/live-tokens/data/themes/autumn.json +1 -37
  68. package/src/live-tokens/data/themes/halloween.json +1 -37
  69. package/src/live-tokens/data/themes/midnight-study.json +1 -37
  70. package/src/live-tokens/data/themes/ocean.json +1 -37
  71. package/src/live-tokens/data/themes/royal-velvet.json +1 -37
  72. package/src/live-tokens/data/themes/sketchy.json +1 -37
  73. package/src/live-tokens/data/themes/spring-meadow.json +1 -37
  74. package/src/live-tokens/data/themes/sunset.json +1 -37
  75. package/src/live-tokens/data/tokens.generated.css +0 -36
  76. package/.claude/skills/live-tokens-generate-theme/SKILL.md +0 -156
  77. package/.claude/skills/live-tokens-generate-theme/references/mood-vocabulary.md +0 -43
  78. package/.claude/skills/live-tokens-generate-theme/references/named-themes.md +0 -18
  79. package/.claude/skills/live-tokens-generate-theme/references/style-vocabulary.md +0 -35
  80. package/bin/generate-theme.mjs +0 -260
  81. /package/dist-plugin/{fontPairing → setType}/index.js +0 -0
@@ -1,4 +1,4 @@
1
- import { F as FontSource, b as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, C as ColorsAndType } from '../themeTypes-DSV3Zisf.cjs';
1
+ import { P as PaletteConfig, H as HarmonyAxis, G as GradientDiskToken, O as Oklch, d as HarmonyMode } from '../themeTypes-BxRtuN5V.cjs';
2
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
 
@@ -20,33 +20,35 @@ export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.cjs';
20
20
  type SchemeDirection = 'light' | 'dark';
21
21
 
22
22
  /**
23
- * Brief → generator: a full ColorsAndType from 10 OKLCH seeds + a scheme, with
24
- * AA floors enforced on derived text tokens. Seed *selection* lives in the
25
- * live-tokens-generate-theme skill; the CLI reaches this via
26
- * `dist-plugin/generateColorsAndType`, so keep this module Node-safe (no DOM).
23
+ * Base colors → the theme's color state: ten OKLCH base colors + a scheme give
24
+ * the palettes, the harmony axes, the swatch gradients, and the override bag,
25
+ * with AA floors enforced on derived text tokens. Choosing the base colors
26
+ * lives in the live-tokens-set-colors skill; the CLI reaches this via
27
+ * `dist-plugin/setColors`, so keep this module Node-safe (no DOM).
28
+ *
29
+ * This is one dimension of a theme, not a theme: the caller merges the result
30
+ * into the live colors and type, and `save-theme` composes the document.
27
31
  */
28
32
 
29
- interface ColorsAndTypeBrief {
30
- name: string;
33
+ interface ColorsInput {
31
34
  scheme: SchemeDirection;
32
- /** One seed per palette label (all 10 required); hex string or numeric OKLCH. */
33
- seeds: Record<string, Oklch | string>;
34
- /** Advisory record of the harmony reasoning; seeds stay ground truth. */
35
+ /** The one color each palette's ramp derives from (all 10 required); hex string or numeric OKLCH. */
36
+ baseColors: Record<string, Oklch | string>;
37
+ /** Advisory record of the harmony reasoning; the base colors stay ground truth. */
35
38
  harmony?: {
36
39
  mode: HarmonyMode;
37
40
  };
38
41
  /** Page-background sky. Off by default; the skill turns it on only when the
39
- * mood brief evokes atmosphere. The engine derives the stops itself, on the
42
+ * request evokes atmosphere. The engine derives the stops itself, on the
40
43
  * scheme's safe side of the Canvas anchor. */
41
44
  canvasGradient?: boolean;
42
45
  }
43
- /** Non-color content carried forward from the currently active colors and type
44
- * so gradients, shadow geometry, component aliases, and fonts survive
45
- * regeneration. Shadow opacity is derived, not carried — see `shadowVars`. */
46
+ /** The live colors and type this pass reads before it replaces the color
47
+ * state: the override bag, so every name no palette owns rides through, and
48
+ * the swatch gradients, so user-tuned ones survive. Shadow opacity is
49
+ * derived, not carried — see `shadowVars`. */
46
50
  interface CarryForward {
47
51
  cssVariables?: Record<string, string>;
48
- fontSources?: FontSource[];
49
- fontStacks?: FontStack[];
50
52
  gradients?: GradientDiskToken[];
51
53
  }
52
54
  interface ContrastCheck {
@@ -58,28 +60,35 @@ interface ContrastCheck {
58
60
  pass: boolean;
59
61
  corrected: boolean;
60
62
  }
61
- interface GenerateColorsAndTypeReport {
63
+ interface BuildColorsReport {
62
64
  scheme: SchemeDirection;
63
65
  checks: ContrastCheck[];
64
66
  failures: string[];
65
67
  /** 'recipes' when the engine replaced absent/stock swatch gradients with the
66
68
  * family-relative recipes; 'carried' when user-tuned ones rode through. */
67
69
  gradients: 'recipes' | 'carried';
68
- /** Present when the brief opted into the page-background sky: either
70
+ /** Present when the input opted into the page-background sky: either
69
71
  * 'on, <sky> → <anchor>' or a 'skipped — …' explanation when the Canvas
70
72
  * anchors at the ramp edge and leaves no room. */
71
73
  canvasGradient?: string;
72
74
  /** The derived shadow opacity and the canvas lightness it came from. */
73
75
  shadows: string;
74
76
  }
75
- interface GenerateColorsAndTypeResult {
76
- colorsAndType: ColorsAndType;
77
- slug: string;
78
- report: GenerateColorsAndTypeReport;
77
+ /** The color dimension of a colors-and-type document. Every other key —
78
+ * name, timestamps, fonts, schema version — belongs to the caller. */
79
+ interface ColorsState {
80
+ editorConfigs: Record<string, PaletteConfig>;
81
+ harmonyAxes: HarmonyAxis[];
82
+ gradients: GradientDiskToken[];
83
+ cssVariables: Record<string, string>;
84
+ }
85
+ interface BuildColorsResult {
86
+ colors: ColorsState;
87
+ report: BuildColorsReport;
79
88
  }
80
- declare function buildColorsAndTypeFromSeeds(brief: ColorsAndTypeBrief, carry?: CarryForward, now?: string): GenerateColorsAndTypeResult;
89
+ declare function buildColors(input: ColorsInput, carry?: CarryForward): BuildColorsResult;
81
90
 
82
91
  /** Sanitize a display name to a safe file name. Pure — no DOM, no fs. */
83
92
  declare function sanitizeFileName(name: string): string;
84
93
 
85
- export { type CarryForward, type ColorsAndTypeBrief, type ContrastCheck, type GenerateColorsAndTypeReport, type GenerateColorsAndTypeResult, buildColorsAndTypeFromSeeds, sanitizeFileName };
94
+ export { type BuildColorsReport, type BuildColorsResult, type CarryForward, type ColorsInput, type ColorsState, type ContrastCheck, buildColors, sanitizeFileName };
@@ -1,4 +1,4 @@
1
- import { F as FontSource, b as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, C as ColorsAndType } from '../themeTypes-DSV3Zisf.js';
1
+ import { P as PaletteConfig, H as HarmonyAxis, G as GradientDiskToken, O as Oklch, d as HarmonyMode } from '../themeTypes-BxRtuN5V.js';
2
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
 
@@ -20,33 +20,35 @@ export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.js';
20
20
  type SchemeDirection = 'light' | 'dark';
21
21
 
22
22
  /**
23
- * Brief → generator: a full ColorsAndType from 10 OKLCH seeds + a scheme, with
24
- * AA floors enforced on derived text tokens. Seed *selection* lives in the
25
- * live-tokens-generate-theme skill; the CLI reaches this via
26
- * `dist-plugin/generateColorsAndType`, so keep this module Node-safe (no DOM).
23
+ * Base colors → the theme's color state: ten OKLCH base colors + a scheme give
24
+ * the palettes, the harmony axes, the swatch gradients, and the override bag,
25
+ * with AA floors enforced on derived text tokens. Choosing the base colors
26
+ * lives in the live-tokens-set-colors skill; the CLI reaches this via
27
+ * `dist-plugin/setColors`, so keep this module Node-safe (no DOM).
28
+ *
29
+ * This is one dimension of a theme, not a theme: the caller merges the result
30
+ * into the live colors and type, and `save-theme` composes the document.
27
31
  */
28
32
 
29
- interface ColorsAndTypeBrief {
30
- name: string;
33
+ interface ColorsInput {
31
34
  scheme: SchemeDirection;
32
- /** One seed per palette label (all 10 required); hex string or numeric OKLCH. */
33
- seeds: Record<string, Oklch | string>;
34
- /** Advisory record of the harmony reasoning; seeds stay ground truth. */
35
+ /** The one color each palette's ramp derives from (all 10 required); hex string or numeric OKLCH. */
36
+ baseColors: Record<string, Oklch | string>;
37
+ /** Advisory record of the harmony reasoning; the base colors stay ground truth. */
35
38
  harmony?: {
36
39
  mode: HarmonyMode;
37
40
  };
38
41
  /** Page-background sky. Off by default; the skill turns it on only when the
39
- * mood brief evokes atmosphere. The engine derives the stops itself, on the
42
+ * request evokes atmosphere. The engine derives the stops itself, on the
40
43
  * scheme's safe side of the Canvas anchor. */
41
44
  canvasGradient?: boolean;
42
45
  }
43
- /** Non-color content carried forward from the currently active colors and type
44
- * so gradients, shadow geometry, component aliases, and fonts survive
45
- * regeneration. Shadow opacity is derived, not carried — see `shadowVars`. */
46
+ /** The live colors and type this pass reads before it replaces the color
47
+ * state: the override bag, so every name no palette owns rides through, and
48
+ * the swatch gradients, so user-tuned ones survive. Shadow opacity is
49
+ * derived, not carried — see `shadowVars`. */
46
50
  interface CarryForward {
47
51
  cssVariables?: Record<string, string>;
48
- fontSources?: FontSource[];
49
- fontStacks?: FontStack[];
50
52
  gradients?: GradientDiskToken[];
51
53
  }
52
54
  interface ContrastCheck {
@@ -58,28 +60,35 @@ interface ContrastCheck {
58
60
  pass: boolean;
59
61
  corrected: boolean;
60
62
  }
61
- interface GenerateColorsAndTypeReport {
63
+ interface BuildColorsReport {
62
64
  scheme: SchemeDirection;
63
65
  checks: ContrastCheck[];
64
66
  failures: string[];
65
67
  /** 'recipes' when the engine replaced absent/stock swatch gradients with the
66
68
  * family-relative recipes; 'carried' when user-tuned ones rode through. */
67
69
  gradients: 'recipes' | 'carried';
68
- /** Present when the brief opted into the page-background sky: either
70
+ /** Present when the input opted into the page-background sky: either
69
71
  * 'on, <sky> → <anchor>' or a 'skipped — …' explanation when the Canvas
70
72
  * anchors at the ramp edge and leaves no room. */
71
73
  canvasGradient?: string;
72
74
  /** The derived shadow opacity and the canvas lightness it came from. */
73
75
  shadows: string;
74
76
  }
75
- interface GenerateColorsAndTypeResult {
76
- colorsAndType: ColorsAndType;
77
- slug: string;
78
- report: GenerateColorsAndTypeReport;
77
+ /** The color dimension of a colors-and-type document. Every other key —
78
+ * name, timestamps, fonts, schema version — belongs to the caller. */
79
+ interface ColorsState {
80
+ editorConfigs: Record<string, PaletteConfig>;
81
+ harmonyAxes: HarmonyAxis[];
82
+ gradients: GradientDiskToken[];
83
+ cssVariables: Record<string, string>;
84
+ }
85
+ interface BuildColorsResult {
86
+ colors: ColorsState;
87
+ report: BuildColorsReport;
79
88
  }
80
- declare function buildColorsAndTypeFromSeeds(brief: ColorsAndTypeBrief, carry?: CarryForward, now?: string): GenerateColorsAndTypeResult;
89
+ declare function buildColors(input: ColorsInput, carry?: CarryForward): BuildColorsResult;
81
90
 
82
91
  /** Sanitize a display name to a safe file name. Pure — no DOM, no fs. */
83
92
  declare function sanitizeFileName(name: string): string;
84
93
 
85
- export { type CarryForward, type ColorsAndTypeBrief, type ContrastCheck, type GenerateColorsAndTypeReport, type GenerateColorsAndTypeResult, buildColorsAndTypeFromSeeds, sanitizeFileName };
94
+ export { type BuildColorsReport, type BuildColorsResult, type CarryForward, type ColorsInput, type ColorsState, type ContrastCheck, buildColors, sanitizeFileName };
@@ -17,9 +17,8 @@ import {
17
17
  syncBaseAnchor
18
18
  } from "../chunk-O6GQ6GBH.js";
19
19
  import {
20
- CURRENT_COLORS_AND_TYPE_SCHEMA_VERSION,
21
20
  CURRENT_COMPONENT_SCHEMA_VERSION
22
- } from "../chunk-YLCOIGQC.js";
21
+ } from "../chunk-V3YF6CGT.js";
23
22
  import {
24
23
  cssColorToOklch,
25
24
  gamutClamp,
@@ -227,7 +226,7 @@ function defaultScaleCurvesObject(scheme = "dark") {
227
226
  };
228
227
  }
229
228
 
230
- // src/editor/core/themes/generateColorsAndType.ts
229
+ // src/editor/core/themes/buildColors.ts
231
230
  var HEX_RE = /^#[0-9a-f]{6}$/i;
232
231
  var HARMONY_MODES = [
233
232
  "complementary",
@@ -250,7 +249,7 @@ var NEUTRAL_TEXT_FLOORS = [
250
249
  var FUNCTIONAL_TEXT_TARGET = 3.5;
251
250
  var FUNCTIONAL_TEXT_LABELS = PALETTE_SPECS.filter((s) => s.label !== "Neutral" && s.label !== "Canvas").map((s) => s.label);
252
251
  var norm = (h) => h >= 0 && h < 360 ? h : (h % 360 + 360) % 360;
253
- function parseSeed(label, raw, problems) {
252
+ function parseBaseColor(label, raw, problems) {
254
253
  if (typeof raw === "string") {
255
254
  if (!HEX_RE.test(raw.trim())) {
256
255
  problems.push(`${label}: "${raw}" is not a #rrggbb hex color`);
@@ -265,40 +264,36 @@ function parseSeed(label, raw, problems) {
265
264
  if (problems.length > 0) return null;
266
265
  return { l, c, h: norm(h) };
267
266
  }
268
- function validateBrief(brief) {
267
+ function validateInput(input) {
269
268
  const problems = [];
270
- const name = typeof brief.name === "string" ? brief.name.trim() : "";
271
- if (!name) problems.push("name: required");
272
- const slug = sanitizeFileName(name || "unnamed");
273
- if (slug === "default") problems.push('name: "default" is the protected package theme; pick another name');
274
- if (brief.scheme !== "light" && brief.scheme !== "dark") {
275
- problems.push(`scheme: must be "light" or "dark", got ${JSON.stringify(brief.scheme)}`);
269
+ if (input.scheme !== "light" && input.scheme !== "dark") {
270
+ problems.push(`scheme: must be "light" or "dark", got ${JSON.stringify(input.scheme)}`);
276
271
  }
277
- if (brief.harmony && !HARMONY_MODES.includes(brief.harmony.mode)) {
278
- problems.push(`harmony.mode: unknown mode ${JSON.stringify(brief.harmony.mode)}`);
272
+ if (input.harmony && !HARMONY_MODES.includes(input.harmony.mode)) {
273
+ problems.push(`harmony.mode: unknown mode ${JSON.stringify(input.harmony.mode)}`);
279
274
  }
280
- if (brief.canvasGradient !== void 0 && typeof brief.canvasGradient !== "boolean") {
281
- problems.push(`canvasGradient: must be a boolean, got ${JSON.stringify(brief.canvasGradient)}`);
275
+ if (input.canvasGradient !== void 0 && typeof input.canvasGradient !== "boolean") {
276
+ problems.push(`canvasGradient: must be a boolean, got ${JSON.stringify(input.canvasGradient)}`);
282
277
  }
283
- const seeds = {};
284
- const given = brief.seeds ?? {};
278
+ const baseColors = {};
279
+ const given = input.baseColors ?? {};
285
280
  for (const spec of PALETTE_SPECS) {
286
281
  if (!(spec.label in given)) {
287
- problems.push(`seeds.${spec.label}: missing`);
282
+ problems.push(`baseColors.${spec.label}: missing`);
288
283
  continue;
289
284
  }
290
- const parsed = parseSeed(spec.label, given[spec.label], problems);
291
- if (parsed) seeds[spec.label] = parsed;
285
+ const parsed = parseBaseColor(spec.label, given[spec.label], problems);
286
+ if (parsed) baseColors[spec.label] = parsed;
292
287
  }
293
288
  const known = new Set(PALETTE_SPECS.map((s) => s.label));
294
289
  for (const label of Object.keys(given)) {
295
- if (!known.has(label)) problems.push(`seeds.${label}: unknown palette (expected ${[...known].join(", ")})`);
290
+ if (!known.has(label)) problems.push(`baseColors.${label}: unknown palette (expected ${[...known].join(", ")})`);
296
291
  }
297
292
  if (problems.length > 0) {
298
- throw new Error(`Invalid theme brief:
293
+ throw new Error(`Invalid base color file:
299
294
  ${problems.join("\n ")}`);
300
295
  }
301
- return { seeds, slug };
296
+ return baseColors;
302
297
  }
303
298
  function checkDefs() {
304
299
  const defs = [];
@@ -350,11 +345,11 @@ function worstSurface(textHex, vars) {
350
345
  }
351
346
  function pinTextStep(cfg, step, solved) {
352
347
  const x = scaleStepToX(step, TEXT_SCALE);
353
- const seed = cfg.baseColor;
354
- const yL = Math.max(0, Math.min(200, solved.l / seed.l * 100));
348
+ const base = cfg.baseColor;
349
+ const yL = Math.max(0, Math.min(200, solved.l / base.l * 100));
355
350
  cfg.scaleCurves.Text.lightness = setCurveAnchor(cfg.scaleCurves.Text.lightness, x, yL).curve;
356
- if (seed.c > 0) {
357
- const yC = Math.max(0, Math.min(200, solved.c / seed.c * 100));
351
+ if (base.c > 0) {
352
+ const yC = Math.max(0, Math.min(200, solved.c / base.c * 100));
358
353
  cfg.scaleCurves.Text.saturation = setCurveAnchor(cfg.scaleCurves.Text.saturation, x, yC).curve;
359
354
  }
360
355
  }
@@ -373,14 +368,14 @@ function runContrastGate(configs, scheme) {
373
368
  const worst = worstSurface(textHex, vars);
374
369
  if (worst.ratio >= def.floor) continue;
375
370
  const cfg = configs[def.paletteLabel];
376
- const seed = cfg.baseColor;
371
+ const base = cfg.baseColor;
377
372
  const solved = findLForContrast({
378
373
  against: varToHex(vars[worst.against]) ?? "#000000",
379
374
  ratio: def.target,
380
375
  direction,
381
376
  c: text.c,
382
- h: seed.h,
383
- lMax: Math.min(1, 2 * seed.l)
377
+ h: base.h,
378
+ lMax: Math.min(1, 2 * base.l)
384
379
  });
385
380
  pinTextStep(cfg, def.step, solved);
386
381
  corrected.add(def.textVar);
@@ -402,7 +397,7 @@ function runContrastGate(configs, scheme) {
402
397
  });
403
398
  const failures = checks.filter((c) => !c.pass).map((c) => {
404
399
  const label = defs.find((d) => d.textVar === c.textVar).paletteLabel;
405
- const hint = scheme === "dark" ? `raise the ${label} seed lightness (derived text tops out at 2\xD7 seed L)` : `raise the ${label} seed lightness or reduce its chroma`;
400
+ const hint = scheme === "dark" ? `raise the ${label} base color lightness (derived text tops out at 2\xD7 its L)` : `raise the ${label} base color lightness or reduce its chroma`;
406
401
  return `${c.textVar} reaches ${c.ratio.toFixed(2)}:1 vs ${c.against} (floor ${c.floor}:1) \u2014 ${hint}`;
407
402
  });
408
403
  return { scheme, checks, failures };
@@ -418,11 +413,11 @@ var linear = (variable, angle, from, to) => ({
418
413
  angle,
419
414
  stops: [{ position: 0, color: from }, { position: 100, color: to }]
420
415
  });
421
- function recipeGradients(seeds, scheme) {
416
+ function recipeGradients(baseColors, scheme) {
422
417
  return [
423
418
  linear("--gradient-1", 90, "--color-brand-400", "--color-brand-700"),
424
- hueDist(seeds.Special.h, seeds.Brand.h) <= ADJACENT_HUE_MAX ? linear("--gradient-2", 135, "--color-special-500", "--color-brand-500") : linear("--gradient-2", 135, "--color-special-400", "--color-special-700"),
425
- hueDist(seeds.Brand.h, seeds.Accent.h) <= ADJACENT_HUE_MAX ? linear("--gradient-3", 90, "--color-brand-500", "--color-accent-500") : linear("--gradient-3", 90, "--color-accent-400", "--color-accent-700"),
419
+ hueDist(baseColors.Special.h, baseColors.Brand.h) <= ADJACENT_HUE_MAX ? linear("--gradient-2", 135, "--color-special-500", "--color-brand-500") : linear("--gradient-2", 135, "--color-special-400", "--color-special-700"),
420
+ hueDist(baseColors.Brand.h, baseColors.Accent.h) <= ADJACENT_HUE_MAX ? linear("--gradient-3", 90, "--color-brand-500", "--color-accent-500") : linear("--gradient-3", 90, "--color-accent-400", "--color-accent-700"),
426
421
  scheme === "dark" ? linear("--gradient-4", 180, "--color-canvas-600", "--color-canvas-900") : linear("--gradient-4", 180, "--color-canvas-200", "--color-canvas-500")
427
422
  ];
428
423
  }
@@ -434,7 +429,7 @@ function applyCanvasGradient(canvas, scheme) {
434
429
  const anchor = canvas.anchorPlacement.step;
435
430
  const sky = scheme === "dark" ? Math.min(anchor + 2, labels.length - 1) : Math.max(anchor - 2, 0);
436
431
  if (sky === anchor) {
437
- return `skipped \u2014 the Canvas seed anchors at the ramp edge (${labels[anchor]}), leaving no room for a sky; commit the canvas further from ${scheme === "dark" ? "black" : "white"}`;
432
+ return `skipped \u2014 the Canvas base color anchors at the ramp edge (${labels[anchor]}), leaving no room for a sky; commit the canvas further from ${scheme === "dark" ? "black" : "white"}`;
438
433
  }
439
434
  canvas.emptyMode = "gradient";
440
435
  canvas.gradientStyle = "linear";
@@ -475,57 +470,44 @@ function shadowVars(carried, canvas) {
475
470
  }
476
471
  return out;
477
472
  }
478
- function buildColorsAndTypeFromSeeds(brief, carry = {}, now = (/* @__PURE__ */ new Date()).toISOString()) {
479
- const { seeds, slug } = validateBrief(brief);
473
+ function buildColors(input, carry = {}) {
474
+ const baseColors = validateInput(input);
480
475
  const configs = {};
481
476
  for (const spec of PALETTE_SPECS) {
482
477
  configs[spec.label] = defaultPaletteConfig({
483
- baseColor: seeds[spec.label],
478
+ baseColor: baseColors[spec.label],
484
479
  neutral: spec.neutral,
485
- scheme: brief.scheme
480
+ scheme: input.scheme
486
481
  });
487
482
  }
488
- const report = runContrastGate(configs, brief.scheme);
489
- const canvasGradient = brief.canvasGradient ? applyCanvasGradient(configs.Canvas, brief.scheme) : void 0;
490
- const gradients = isStockGradients(carry.gradients) ? recipeGradients(seeds, brief.scheme) : carry.gradients;
483
+ const report = runContrastGate(configs, input.scheme);
484
+ const canvasGradient = input.canvasGradient ? applyCanvasGradient(configs.Canvas, input.scheme) : void 0;
485
+ const gradients = isStockGradients(carry.gradients) ? recipeGradients(baseColors, input.scheme) : carry.gradients;
491
486
  const harmonyAxes = [
492
- { hue: norm(seeds.Brand.h), family: "Brand" },
493
- { hue: norm(seeds.Accent.h), family: "Accent" },
494
- { hue: norm(seeds.Canvas.h), family: "Canvas" },
495
- { hue: norm(seeds.Brand.h + 270), family: null }
487
+ { hue: norm(baseColors.Brand.h), family: "Brand" },
488
+ { hue: norm(baseColors.Accent.h), family: "Accent" },
489
+ { hue: norm(baseColors.Canvas.h), family: "Canvas" },
490
+ { hue: norm(baseColors.Brand.h + 270), family: null }
496
491
  ];
497
492
  const owned = new Set(Object.keys(palettesToVars(configs)));
498
493
  const cssVariables = Object.fromEntries(
499
494
  Object.entries(carry.cssVariables ?? {}).filter(([k]) => !owned.has(k))
500
495
  );
501
496
  for (const t of gradients) cssVariables[t.variable] = formatGradientValue(t);
502
- Object.assign(cssVariables, shadowVars(carry.cssVariables ?? {}, seeds.Canvas));
503
- const colorsAndType = {
504
- name: brief.name.trim(),
505
- createdAt: now,
506
- updatedAt: now,
507
- editorConfigs: configs,
508
- cssVariables,
509
- fontSources: carry.fontSources ?? [],
510
- fontStacks: carry.fontStacks ?? [],
511
- gradients,
512
- harmonyAxes,
513
- schemaVersion: CURRENT_COLORS_AND_TYPE_SCHEMA_VERSION
514
- };
497
+ Object.assign(cssVariables, shadowVars(carry.cssVariables ?? {}, baseColors.Canvas));
515
498
  return {
516
- colorsAndType,
517
- slug,
499
+ colors: { editorConfigs: configs, harmonyAxes, gradients, cssVariables },
518
500
  report: {
519
501
  ...report,
520
502
  gradients: gradients === carry.gradients ? "carried" : "recipes",
521
- shadows: `opacity ${shadowOpacityForCanvas(seeds.Canvas.l)} for a canvas at L ${seeds.Canvas.l.toFixed(2)}`,
503
+ shadows: `opacity ${shadowOpacityForCanvas(baseColors.Canvas.l)} for a canvas at L ${baseColors.Canvas.l.toFixed(2)}`,
522
504
  ...canvasGradient ? { canvasGradient } : {}
523
505
  }
524
506
  };
525
507
  }
526
508
  export {
527
509
  CURRENT_COMPONENT_SCHEMA_VERSION,
528
- buildColorsAndTypeFromSeeds,
510
+ buildColors,
529
511
  readLiveTokensConfig,
530
512
  resolveDataDirs,
531
513
  sanitizeFileName
@@ -27,16 +27,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // vite-plugin/adjust/index.ts
31
- var adjust_exports = {};
32
- __export(adjust_exports, {
30
+ // vite-plugin/setGeometry/index.ts
31
+ var setGeometry_exports = {};
32
+ __export(setGeometry_exports, {
33
33
  CURRENT_COMPONENT_SCHEMA_VERSION: () => CURRENT_COMPONENT_SCHEMA_VERSION,
34
34
  adjustAliases: () => adjustAliases,
35
35
  matchesKind: () => matchesKind,
36
36
  readLiveTokensConfig: () => readLiveTokensConfig,
37
37
  resolveDataDirs: () => resolveDataDirs
38
38
  });
39
- module.exports = __toCommonJS(adjust_exports);
39
+ module.exports = __toCommonJS(setGeometry_exports);
40
40
 
41
41
  // src/editor/core/components/aliasKinds.ts
42
42
  var KIND_RULES = [
@@ -1151,6 +1151,60 @@ var componentMigration_2026_09_02_sectiondividerDropTitleOutline = {
1151
1151
  }
1152
1152
  };
1153
1153
 
1154
+ // src/editor/core/themes/migrations/2026-09-03-drop-legacy-component-keys.ts
1155
+ var DROPPED3 = /* @__PURE__ */ new Set([
1156
+ "--badge-trait-surface",
1157
+ "--badge-trait-text",
1158
+ "--badge-trait-text-font-family",
1159
+ "--badge-trait-text-font-size",
1160
+ "--badge-trait-text-font-weight",
1161
+ "--badge-trait-text-line-height",
1162
+ "--badge-trait-border",
1163
+ "--badge-trait-border-width",
1164
+ "--badge-trait-shadow",
1165
+ "--sectiondivider-title",
1166
+ "--sectiondivider-title-font-family",
1167
+ "--sectiondivider-title-font-size",
1168
+ "--sectiondivider-title-font-weight",
1169
+ "--sectiondivider-title-line-height",
1170
+ "--sectiondivider-title-border-width",
1171
+ "--sectiondivider-title-stroke-color",
1172
+ "--sectiondivider-description",
1173
+ "--sectiondivider-description-font-family",
1174
+ "--sectiondivider-description-font-size",
1175
+ "--sectiondivider-description-font-weight",
1176
+ "--sectiondivider-description-line-height",
1177
+ "--dialog-primary-default-surface",
1178
+ "--dialog-primary-default-text",
1179
+ "--dialog-primary-default-border",
1180
+ "--dialog-primary-default-border-width",
1181
+ "--dialog-primary-hover-surface",
1182
+ "--dialog-primary-hover-text",
1183
+ "--dialog-primary-hover-border",
1184
+ "--dialog-primary-hover-border-width",
1185
+ "--dialog-secondary-default-text",
1186
+ "--dialog-secondary-default-border",
1187
+ "--dialog-secondary-default-border-width",
1188
+ "--dialog-secondary-hover-surface",
1189
+ "--dialog-secondary-hover-text",
1190
+ "--dialog-secondary-hover-border",
1191
+ "--dialog-secondary-hover-border-width"
1192
+ ]);
1193
+ var colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys = {
1194
+ id: "2026-09-03-drop-legacy-component-keys",
1195
+ fromVersion: 7,
1196
+ toVersion: 8,
1197
+ appliesTo: "colors-and-type",
1198
+ apply(rawVars) {
1199
+ const out = {};
1200
+ for (const [key, value] of Object.entries(rawVars)) {
1201
+ if (DROPPED3.has(key)) continue;
1202
+ out[key] = value;
1203
+ }
1204
+ return out;
1205
+ }
1206
+ };
1207
+
1154
1208
  // src/editor/core/themes/migrations/index.ts
1155
1209
  var MIGRATIONS = [
1156
1210
  colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
@@ -1185,7 +1239,8 @@ var MIGRATIONS = [
1185
1239
  componentMigration_2026_09_01_tintRename,
1186
1240
  componentMigration_2026_09_01_tabbarActiveTint,
1187
1241
  componentMigration_2026_09_01_gateSuffixEnabled,
1188
- componentMigration_2026_09_02_sectiondividerDropTitleOutline
1242
+ componentMigration_2026_09_02_sectiondividerDropTitleOutline,
1243
+ colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys
1189
1244
  ];
1190
1245
  function countFor(kind) {
1191
1246
  return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
@@ -1,4 +1,4 @@
1
- import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-DSV3Zisf.cjs';
1
+ import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-BxRtuN5V.cjs';
2
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
 
@@ -1,4 +1,4 @@
1
- import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-DSV3Zisf.js';
1
+ import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-BxRtuN5V.js';
2
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
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CURRENT_COMPONENT_SCHEMA_VERSION
3
- } from "../chunk-YLCOIGQC.js";
3
+ } from "../chunk-V3YF6CGT.js";
4
4
  import {
5
5
  readLiveTokensConfig,
6
6
  resolveDataDirs
@@ -27,9 +27,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
- // vite-plugin/fontPairing/index.ts
31
- var fontPairing_exports = {};
32
- __export(fontPairing_exports, {
30
+ // vite-plugin/setType/index.ts
31
+ var setType_exports = {};
32
+ __export(setType_exports, {
33
33
  SLOT_ORDER: () => SLOT_ORDER,
34
34
  SLOT_VARIABLES: () => SLOT_VARIABLES,
35
35
  applyFontPairing: () => applyFontPairing,
@@ -43,7 +43,7 @@ __export(fontPairing_exports, {
43
43
  slugifyFamily: () => slugifyFamily,
44
44
  weightCoverage: () => weightCoverage
45
45
  });
46
- module.exports = __toCommonJS(fontPairing_exports);
46
+ module.exports = __toCommonJS(setType_exports);
47
47
 
48
48
  // src/editor/core/fonts/fontParse.ts
49
49
  function parseGoogleFontsUrl(url2) {
@@ -1,4 +1,4 @@
1
- import { c as FontStackVariable, C as ColorsAndType, b as FontStack, F as FontSource } from '../themeTypes-DSV3Zisf.cjs';
1
+ import { c as FontStackVariable, C as ColorsAndType, b as FontStack, F as FontSource } from '../themeTypes-BxRtuN5V.cjs';
2
2
  export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.cjs';
3
3
 
4
4
  type PairingSlot = 'display' | 'body' | 'serif' | 'mono' | 'editorial';
@@ -1,4 +1,4 @@
1
- import { c as FontStackVariable, C as ColorsAndType, b as FontStack, F as FontSource } from '../themeTypes-DSV3Zisf.js';
1
+ import { c as FontStackVariable, C as ColorsAndType, b as FontStack, F as FontSource } from '../themeTypes-BxRtuN5V.js';
2
2
  export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-BhWzd5cL.js';
3
3
 
4
4
  type PairingSlot = 'display' | 'body' | 'serif' | 'mono' | 'editorial';
@@ -257,4 +257,4 @@ interface ComponentConfig {
257
257
  schemaVersion?: number;
258
258
  }
259
259
 
260
- export type { AliasDiskValue as A, ColorsAndType as C, FontSource as F, GradientDiskToken as G, HarmonyMode as H, Oklch as O, ComponentConfig as a, FontStack as b, FontStackVariable as c };
260
+ export type { AliasDiskValue as A, ColorsAndType as C, FontSource as F, GradientDiskToken as G, HarmonyAxis as H, Oklch as O, PaletteConfig as P, ComponentConfig as a, FontStack as b, FontStackVariable as c, HarmonyMode as d };
@@ -257,4 +257,4 @@ interface ComponentConfig {
257
257
  schemaVersion?: number;
258
258
  }
259
259
 
260
- export type { AliasDiskValue as A, ColorsAndType as C, FontSource as F, GradientDiskToken as G, HarmonyMode as H, Oklch as O, ComponentConfig as a, FontStack as b, FontStackVariable as c };
260
+ export type { AliasDiskValue as A, ColorsAndType as C, FontSource as F, GradientDiskToken as G, HarmonyAxis as H, Oklch as O, PaletteConfig as P, ComponentConfig as a, FontStack as b, FontStackVariable as c, HarmonyMode as d };