@motion-proto/live-tokens 0.50.0 → 0.53.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 (91) hide show
  1. package/.claude/skills/live-tokens-adjust-shape-space/SKILL.md +7 -1
  2. package/CHANGELOG.md +108 -0
  3. package/bin/adjust.mjs +16 -39
  4. package/bin/generate-theme.mjs +20 -6
  5. package/dist-plugin/adjust/index.cjs +781 -21
  6. package/dist-plugin/adjust/index.d.cts +2 -1
  7. package/dist-plugin/adjust/index.d.ts +2 -1
  8. package/dist-plugin/adjust/index.js +43 -21
  9. package/dist-plugin/{chunk-6OZFXIQI.js → chunk-232GZGQU.js} +207 -12
  10. package/dist-plugin/chunk-NE6N66EE.js +753 -0
  11. package/dist-plugin/{chunk-76TFDTJO.js → chunk-PB2JTK2H.js} +179 -128
  12. package/dist-plugin/{chunk-44RSTAII.js → chunk-TKZBVIW5.js} +33 -5
  13. package/dist-plugin/chunk-YR6GPXW2.js +129 -0
  14. package/dist-plugin/generateColorsAndType/index.cjs +135 -63
  15. package/dist-plugin/generateColorsAndType/index.d.cts +2 -1
  16. package/dist-plugin/generateColorsAndType/index.d.ts +2 -1
  17. package/dist-plugin/generateColorsAndType/index.js +28 -784
  18. package/dist-plugin/{themeTypes-DSwKq-bj.d.ts → index-DpTIRZ2H.d.cts} +67 -26
  19. package/dist-plugin/{themeTypes-DSwKq-bj.d.cts → index-DpTIRZ2H.d.ts} +67 -26
  20. package/dist-plugin/index.cjs +1254 -140
  21. package/dist-plugin/index.js +106 -82
  22. package/dist-plugin/migrateData/index.cjs +956 -14
  23. package/dist-plugin/migrateData/index.js +10 -3
  24. package/dist-plugin/tokensCssMigrations/index.cjs +71 -5
  25. package/dist-plugin/tokensCssMigrations/index.d.cts +20 -9
  26. package/dist-plugin/tokensCssMigrations/index.d.ts +20 -9
  27. package/dist-plugin/tokensCssMigrations/index.js +4 -1
  28. package/package.json +8 -4
  29. package/src/editor/component-editor/NotificationEditor.svelte +6 -0
  30. package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +9 -23
  31. package/src/editor/component-editor/scaffolding/LinkedBlock.svelte +8 -8
  32. package/src/editor/core/components/adjustAliases.ts +49 -22
  33. package/src/editor/core/components/aliasKinds.ts +7 -2
  34. package/src/editor/core/components/componentConfigService.ts +1 -1
  35. package/src/editor/core/palettes/oklch.ts +3 -137
  36. package/src/editor/core/palettes/paletteDerivation.ts +79 -37
  37. package/src/editor/core/store/editorStore.ts +7 -197
  38. package/src/editor/core/store/editorTypes.ts +9 -30
  39. package/src/editor/core/themes/generateColorsAndType.ts +18 -8
  40. package/src/editor/core/themes/lookSummary.ts +3 -25
  41. package/src/editor/core/themes/migrateComponentConfig.ts +205 -0
  42. package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +1 -1
  43. package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +1 -1
  44. package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +1 -1
  45. package/src/editor/core/themes/parsers/gradient.ts +211 -0
  46. package/src/editor/core/themes/slices/gradients.ts +5 -58
  47. package/src/editor/core/themes/themeService.ts +22 -9
  48. package/src/editor/core/themes/themeTypes.ts +89 -27
  49. package/src/editor/docs/content/editing-tokens.md +6 -2
  50. package/src/editor/docs/content/themes-workflow.md +9 -11
  51. package/src/editor/docs/content/where-themes-live.md +2 -2
  52. package/src/editor/docs/content.generated.ts +3 -3
  53. package/src/editor/index.ts +1 -0
  54. package/src/editor/styles/ui-editor.css +5 -2
  55. package/src/editor/ui/BezierCurveEditor.svelte +90 -67
  56. package/src/editor/ui/PaletteEditor.svelte +180 -59
  57. package/src/editor/ui/ThemePanel.svelte +24 -15
  58. package/src/editor/ui/Toggle.svelte +36 -24
  59. package/src/editor/ui/UIPillButton.svelte +1 -1
  60. package/src/editor/ui/UIReveal.svelte +47 -0
  61. package/src/editor/ui/UISquareButton.svelte +1 -1
  62. package/src/editor/ui/colors/ColorStory.svelte +12 -8
  63. package/src/editor/ui/colors/ColorsTab.svelte +4 -5
  64. package/src/editor/ui/curveEngine.ts +101 -21
  65. package/src/editor/ui/palette/OverridesPanel.svelte +23 -8
  66. package/src/editor/ui/palette/PaletteBase.svelte +17 -78
  67. package/src/editor/ui/palette/PaletteJumpButton.svelte +3 -3
  68. package/src/editor/ui/palette/ScaleCurveEditor.svelte +110 -20
  69. package/src/editor/ui/palette/curveSummary.ts +20 -0
  70. package/src/editor/ui/palette/dockMagnify.ts +5 -13
  71. package/src/editor/ui/palette/paletteMath.ts +7 -4
  72. package/src/live-tokens/data/colors-and-type/autumn.json +528 -528
  73. package/src/live-tokens/data/colors-and-type/default.json +247 -247
  74. package/src/live-tokens/data/colors-and-type/halloween.json +532 -532
  75. package/src/live-tokens/data/colors-and-type/midnight-study.json +538 -538
  76. package/src/live-tokens/data/colors-and-type/ocean.json +521 -521
  77. package/src/live-tokens/data/colors-and-type/royal-velvet.json +532 -532
  78. package/src/live-tokens/data/colors-and-type/spring-meadow.json +504 -504
  79. package/src/live-tokens/data/colors-and-type/sunset.json +531 -531
  80. package/src/live-tokens/data/themes/autumn.json +604 -568
  81. package/src/live-tokens/data/themes/halloween.json +584 -583
  82. package/src/live-tokens/data/themes/midnight-study.json +673 -605
  83. package/src/live-tokens/data/themes/ocean.json +597 -561
  84. package/src/live-tokens/data/themes/royal-velvet.json +574 -573
  85. package/src/live-tokens/data/themes/spring-meadow.json +590 -556
  86. package/src/live-tokens/data/themes/sunset.json +632 -571
  87. package/src/live-tokens/data/tokens.generated.css +282 -282
  88. package/src/system/components/FloatingTokenTags.css +0 -1
  89. package/src/system/internal/backgroundContrast.ts +7 -0
  90. package/src/system/internal/oklch.ts +189 -0
  91. package/src/system/styles/tokens.css +283 -283
@@ -1,31 +1,40 @@
1
1
  <script lang="ts">
2
2
  import BezierCurveEditor from '../BezierCurveEditor.svelte';
3
- import type { CurveAnchor, CurveConfig } from '../curveEngine';
3
+ import UIReveal from '../UIReveal.svelte';
4
+ import { isAutoSmoothCurve, type CurveAnchor, type CurveConfig } from '../curveEngine';
5
+ import { curveSummary } from './curveSummary';
4
6
 
5
-
6
-
7
- interface Props {
8
- /**
7
+ /**
9
8
  * Single-channel curve editor — one Bezier curve for one channel
10
- * (lightness or saturation) of one scale (palette / gray-palette /
9
+ * (lightness, saturation, or hue) of one scale (palette / gray-palette /
11
10
  * Surfaces / Borders / Text). Instantiated 6+ times across PaletteEditor:
12
11
  * the parent's chromatic-palette + gray-palette curves and the four
13
12
  * derived-scale curve groups inside OverridesPanel.
14
13
  *
15
- * Pure presentational wrapper: it forwards props to BezierCurveEditor
16
- * and adapts the offset key into a single `onOffsetChange(value)` so the
14
+ * Pure presentational wrapper: it forwards props to BezierCurveEditor and
15
+ * adapts the offset key into a single `onOffsetChange(value)` so the
17
16
  * parent only needs to know how to wire `(key, value)` once (via a
18
- * closure passed in).
17
+ * closure passed in). It also owns the collapsible disclosure chrome
18
+ * around that editor; the open/closed flag itself is parent state
19
+ * (session-scoped, never written to theme JSON).
19
20
  */
21
+ interface Props {
20
22
  curveKey: string;
21
23
  anchors: CurveAnchor[];
22
24
  cfg: CurveConfig;
23
25
  stepCount: number;
24
26
  defaults: CurveAnchor[];
25
27
  offset?: number;
28
+ /** Undefined for a curve saved before the flag existed, or one never toggled;
29
+ * its shape answers for it. Only an explicit switch-off needs recording, since
30
+ * switching on is self-evident from the shape it produces. */
31
+ autoSmooth?: boolean;
26
32
  lockedAnchorIndex?: number | null;
33
+ open: boolean;
34
+ onToggleOpen: () => void;
27
35
  onAnchorsChange: (anchors: CurveAnchor[]) => void;
28
36
  onOffsetChange: (key: string, value: number) => void;
37
+ onAutoSmoothChange: (key: string, value: boolean) => void;
29
38
  onLockedAnchorUnlock?: (() => void) | null;
30
39
  }
31
40
 
@@ -36,21 +45,102 @@
36
45
  stepCount,
37
46
  defaults,
38
47
  offset = 0,
48
+ autoSmooth = undefined,
39
49
  lockedAnchorIndex = null,
50
+ open,
51
+ onToggleOpen,
40
52
  onAnchorsChange,
41
53
  onOffsetChange,
54
+ onAutoSmoothChange,
42
55
  onLockedAnchorUnlock = null
43
56
  }: Props = $props();
57
+
58
+ let summary = $derived(curveSummary(anchors, defaults, offset, cfg.unit ?? ''));
59
+ let autoSmoothResolved = $derived(autoSmooth ?? isAutoSmoothCurve(anchors));
44
60
  </script>
45
61
 
46
- <BezierCurveEditor
47
- {anchors}
48
- {cfg}
49
- {stepCount}
50
- defaultAnchors={defaults}
51
- {offset}
52
- {lockedAnchorIndex}
53
- {onLockedAnchorUnlock}
54
- {onAnchorsChange}
55
- onOffsetChange={(v) => onOffsetChange(curveKey, v)}
56
- />
62
+ <div class="curve-section">
63
+ <button
64
+ class="curve-section-toggle"
65
+ type="button"
66
+ aria-expanded={open}
67
+ onclick={onToggleOpen}
68
+ >
69
+ <i class="fas" class:fa-chevron-right={!open} class:fa-chevron-down={open} aria-hidden="true"></i>
70
+ <span class="curve-section-label">{cfg.label}</span>
71
+ <span class="curve-section-summary">
72
+ {#if summary !== 'default'}<span class="curve-section-dot" aria-hidden="true"></span>{/if}
73
+ {summary}
74
+ </span>
75
+ </button>
76
+ <UIReveal {open}>
77
+ <BezierCurveEditor
78
+ {anchors}
79
+ {cfg}
80
+ {stepCount}
81
+ defaultAnchors={defaults}
82
+ {offset}
83
+ autoSmooth={autoSmoothResolved}
84
+ {lockedAnchorIndex}
85
+ {onLockedAnchorUnlock}
86
+ {onAnchorsChange}
87
+ onOffsetChange={(v) => onOffsetChange(curveKey, v)}
88
+ onAutoSmoothChange={(v) => onAutoSmoothChange(curveKey, v)}
89
+ />
90
+ </UIReveal>
91
+ </div>
92
+
93
+ <style>
94
+ .curve-section {
95
+ display: flex;
96
+ flex-direction: column;
97
+ gap: var(--ui-space-4);
98
+ }
99
+
100
+ .curve-section-toggle {
101
+ display: flex;
102
+ align-items: center;
103
+ gap: var(--ui-space-8);
104
+ width: 100%;
105
+ padding: var(--ui-space-4) var(--ui-space-2);
106
+ background: none;
107
+ border: none;
108
+ color: var(--ui-text-tertiary);
109
+ cursor: pointer;
110
+ text-align: left;
111
+ transition: color var(--ui-transition-fast);
112
+ }
113
+
114
+ .curve-section-toggle:hover {
115
+ color: var(--ui-text-primary);
116
+ }
117
+
118
+ .curve-section-toggle i {
119
+ font-size: var(--ui-font-size-xs);
120
+ width: 0.75rem;
121
+ text-align: center;
122
+ }
123
+
124
+ .curve-section-label {
125
+ font-size: var(--ui-font-size-md);
126
+ font-weight: var(--ui-font-weight-semibold);
127
+ }
128
+
129
+ .curve-section-summary {
130
+ display: flex;
131
+ align-items: center;
132
+ gap: var(--ui-space-4);
133
+ margin-left: auto;
134
+ font-size: var(--ui-font-size-sm);
135
+ font-weight: var(--ui-font-weight-normal);
136
+ color: var(--ui-text-muted);
137
+ }
138
+
139
+ .curve-section-dot {
140
+ width: 0.375rem;
141
+ height: 0.375rem;
142
+ border-radius: var(--ui-radius-full);
143
+ background: var(--ui-text-primary);
144
+ flex-shrink: 0;
145
+ }
146
+ </style>
@@ -0,0 +1,20 @@
1
+ import type { CurveAnchor } from '../curveEngine';
2
+
3
+ const ANCHOR_KEYS = ['x', 'y', 'inDx', 'inDy', 'outDx', 'outDy'] as const;
4
+
5
+ function anchorsEqual(a: CurveAnchor[], b: CurveAnchor[]): boolean {
6
+ return a.length === b.length && a.every((anchor, i) => ANCHOR_KEYS.every((k) => anchor[k] === b[i][k]));
7
+ }
8
+
9
+ /**
10
+ * Collapsed-row readout for a curve section. Range rather than first-to-last:
11
+ * a peak's endpoints can match the defaults' while the middle diverges, and
12
+ * first-to-last would misstate the peak's range as flat.
13
+ */
14
+ export function curveSummary(anchors: CurveAnchor[], defaults: CurveAnchor[], offset: number, unit = ''): string {
15
+ if (offset === 0 && anchorsEqual(anchors, defaults)) return 'default';
16
+ const ys = anchors.map((a) => a.y);
17
+ const range = `${Math.round(Math.min(...ys))} to ${Math.round(Math.max(...ys))}${unit}`;
18
+ const offsetPart = offset !== 0 ? ` offset ${offset > 0 ? '+' : ''}${offset}${unit}` : '';
19
+ return `${range}${offsetPart}`;
20
+ }
@@ -1,22 +1,14 @@
1
- /**
2
- * macOS-dock magnification policy for palette ramps, shared by the palette
3
- * editor's swatch grid and the Colors view's step strips so the falloff tunes
4
- * in one place. Layout stays native to each surface (grid tracks vs
5
- * flex-grow); only the size policy is shared.
6
- */
1
+ /** macOS-dock magnification for the Colors view's step strips. The palette
2
+ * editor's own grid stays even, because its curve editors plot one step per
3
+ * column. */
7
4
 
8
5
  const ANCHORED_GROW = 1.7;
9
6
  const NEIGHBOUR_GROW = 1.2;
10
7
 
11
- /** Size share for a ramp cell: anchored opens widest, immediate neighbours
12
- * get a smaller boost, everything else stays 1. Doubles as a flex-grow. */
8
+ /** Flex-grow for a ramp cell: anchored opens widest, immediate neighbours get a
9
+ * smaller boost, everything else stays 1. */
13
10
  export function dockGrow(index: number, anchored: number | null): number {
14
11
  if (anchored === null) return 1;
15
12
  const d = Math.abs(index - anchored);
16
13
  return d === 0 ? ANCHORED_GROW : d === 1 ? NEIGHBOUR_GROW : 1;
17
14
  }
18
-
19
- /** Grid track list (`minmax(0, Nfr)` per column) for a `cols`-column ramp. */
20
- export function dockTrackTemplate(cols: number, anchored: number | null): string {
21
- return Array.from({ length: cols }, (_, i) => `minmax(0, ${dockGrow(i, anchored)}fr)`).join(' ');
22
- }
@@ -1,5 +1,5 @@
1
1
  import type { Oklch } from '../../core/palettes/oklch';
2
- import { type CurveAnchor, makeAnchor } from '../curveEngine';
2
+ import { type CurveAnchor, makeAnchor, resmoothAutoCurve } from '../curveEngine';
3
3
  import type { PaletteConfig } from '../../core/themes/themeTypes';
4
4
  import {
5
5
  type Step,
@@ -9,6 +9,7 @@ import {
9
9
  PALETTE_STEPS,
10
10
  DEFAULT_PALETTE_LIGHTNESS,
11
11
  DEFAULT_PALETTE_SATURATION,
12
+ DEFAULT_PALETTE_HUE,
12
13
  defaultScaleCurves,
13
14
  scaleCurveDefaults,
14
15
  computePaletteOklch,
@@ -33,6 +34,7 @@ export {
33
34
  PALETTE_STEPS,
34
35
  DEFAULT_PALETTE_LIGHTNESS,
35
36
  DEFAULT_PALETTE_SATURATION,
37
+ DEFAULT_PALETTE_HUE,
36
38
  defaultScaleCurves,
37
39
  scaleCurveDefaults,
38
40
  computePaletteOklch,
@@ -54,11 +56,12 @@ export interface PaletteStepDef {
54
56
  }
55
57
 
56
58
  export type CurveOffset = Record<string, number>;
57
- export type ScaleCurves = Record<string, { lightness: CurveAnchor[]; saturation: CurveAnchor[] }>;
59
+ export type ScaleCurves = Record<string, { lightness: CurveAnchor[]; saturation: CurveAnchor[]; hue?: CurveAnchor[] }>;
58
60
 
59
61
  // Neutrals seed a calmer, wider lightness ramp than accents; the saturation
60
62
  // curve is the same flat 100 (chroma comes from a low-chroma base, not a cap).
61
- export const DEFAULT_NEUTRAL_LIGHTNESS = (): CurveAnchor[] => [makeAnchor(0, 92, 5), makeAnchor(100, 3, 5)];
63
+ export const DEFAULT_NEUTRAL_LIGHTNESS = (): CurveAnchor[] =>
64
+ resmoothAutoCurve([makeAnchor(0, 92), makeAnchor(100, 3)]);
62
65
 
63
66
  /**
64
67
  * Seed config for a palette. The derivation path is unified; the only
@@ -103,7 +106,7 @@ export const paletteStepLightness: PaletteStepDef[] = [
103
106
  { label: '950', lightness: 8 },
104
107
  ];
105
108
 
106
- export const scaleCurveKey = (scaleTitle: string, channel: 'lightness' | 'saturation') => `${scaleTitle}-${channel}`;
109
+ export const scaleCurveKey = (scaleTitle: string, channel: 'lightness' | 'saturation' | 'hue') => `${scaleTitle}-${channel}`;
107
110
 
108
111
  interface PaletteComputed {
109
112
  oklch: Oklch;