@motion-proto/live-tokens 0.40.0 → 0.41.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.
- package/CHANGELOG.md +115 -0
- package/dist-plugin/{chunk-D77VD4Z6.js → chunk-H4TRUINI.js} +102 -13
- package/dist-plugin/index.cjs +288 -67
- package/dist-plugin/index.js +171 -55
- package/dist-plugin/tokensCssMigrations/index.cjs +102 -13
- package/dist-plugin/tokensCssMigrations/index.js +1 -1
- package/package.json +3 -2
- package/src/app/site.css +97 -20
- package/src/editor/core/palettes/colorHarmony.ts +228 -0
- package/src/editor/core/palettes/contrast.ts +128 -0
- package/src/editor/core/palettes/oklch.ts +8 -0
- package/src/editor/core/palettes/paletteDerivation.ts +267 -72
- package/src/editor/core/palettes/recommendText.ts +216 -0
- package/src/editor/core/palettes/solveTextContrast.ts +251 -0
- package/src/editor/core/store/editorCore.ts +2 -1
- package/src/editor/core/store/editorPersistence.ts +18 -1
- package/src/editor/core/store/editorStore.ts +20 -1
- package/src/editor/core/store/editorTypes.ts +4 -0
- package/src/editor/core/store/editorViewStore.ts +7 -3
- package/src/editor/core/themes/migrations/2026-06-05-palette-unification.ts +11 -9
- package/src/editor/core/themes/migrations/2026-07-21-palette-oklch-basis.ts +51 -0
- package/src/editor/core/themes/migrations/2026-07-24-base-anchor-placement.ts +37 -0
- package/src/editor/core/themes/migrations/2026-07-25-background-spot-to-base.ts +40 -0
- package/src/editor/core/themes/themeTypes.ts +23 -3
- package/src/editor/docs/CodeBlock.svelte +1 -1
- package/src/editor/docs/Docs.svelte +30 -13
- package/src/editor/pages/EditorShell.svelte +31 -3
- package/src/editor/ui/ColorEditPanel.svelte +22 -16
- package/src/editor/ui/EditorViewSwitcher.svelte +43 -9
- package/src/editor/ui/FontStackEditor.svelte +0 -1
- package/src/editor/ui/PaletteEditor.svelte +117 -155
- package/src/editor/ui/ProjectFontsSection.svelte +0 -3
- package/src/editor/ui/TextStylesSection.svelte +173 -0
- package/src/editor/ui/UILineHeightSelector.svelte +6 -5
- package/src/editor/ui/UIPaletteSelector.svelte +6 -1
- package/src/editor/ui/UITextTransformSelector.svelte +106 -0
- package/src/editor/ui/VariablesTab.svelte +23 -10
- package/src/editor/ui/colors/ColorReadouts.svelte +123 -0
- package/src/editor/ui/colors/ColorStory.svelte +375 -0
- package/src/editor/ui/colors/ColorWheel.svelte +740 -0
- package/src/editor/ui/colors/ColorsTab.svelte +508 -0
- package/src/editor/ui/colors/HarmonyAxesList.svelte +320 -0
- package/src/editor/ui/colors/LightnessBar.svelte +261 -0
- package/src/editor/ui/colors/PaletteStepStrip.svelte +142 -0
- package/src/editor/ui/colors/colorWheelMath.ts +9 -0
- package/src/editor/ui/colors/harmony-icons/analogous.svg +13 -0
- package/src/editor/ui/colors/harmony-icons/complementary.svg +10 -0
- package/src/editor/ui/colors/harmony-icons/compound.svg +15 -0
- package/src/editor/ui/colors/harmony-icons/custom.svg +10 -0
- package/src/editor/ui/colors/harmony-icons/monochromatic.svg +11 -0
- package/src/editor/ui/colors/harmony-icons/shades.svg +9 -0
- package/src/editor/ui/colors/harmony-icons/split-complementary.svg +13 -0
- package/src/editor/ui/colors/harmony-icons/square.svg +13 -0
- package/src/editor/ui/colors/harmony-icons/tetradic.svg +15 -0
- package/src/editor/ui/colors/harmony-icons/triadic.svg +13 -0
- package/src/editor/ui/colors/harmonyModeIcons.ts +23 -0
- package/src/editor/ui/colors/paletteBaseColor.ts +214 -0
- package/src/editor/ui/index.ts +0 -1
- package/src/editor/ui/palette/OverridesPanel.svelte +6 -3
- package/src/editor/ui/palette/PaletteBase.svelte +16 -8
- package/src/editor/ui/palette/dockMagnify.ts +22 -0
- package/src/editor/ui/palette/paletteEditorState.ts +5 -4
- package/src/editor/ui/palette/paletteMath.ts +93 -181
- package/src/editor/ui/sections/textStyles.ts +82 -0
- package/src/editor/ui/sections/tokenScales.ts +3 -3
- package/src/live-tokens/data/themes/default.json +3 -3
- package/src/live-tokens/data/tokens.generated.css +96 -95
- package/src/system/components/Badge.svelte +11 -11
- package/src/system/components/Button.svelte +7 -7
- package/src/system/components/Callout.svelte +8 -8
- package/src/system/components/Card.svelte +2 -2
- package/src/system/components/CodeSnippet.svelte +1 -1
- package/src/system/components/CollapsibleSection.svelte +7 -7
- package/src/system/components/CornerBadge.svelte +1 -1
- package/src/system/components/Dialog.svelte +2 -2
- package/src/system/components/FloatingTokenTags.css +6 -5
- package/src/system/components/Input.svelte +6 -6
- package/src/system/components/MenuSelect.svelte +4 -4
- package/src/system/components/Notification.svelte +8 -8
- package/src/system/components/ProgressBar.svelte +2 -2
- package/src/system/components/RadioButton.svelte +4 -4
- package/src/system/components/SectionDivider.svelte +6 -6
- package/src/system/components/SegmentedControl.svelte +5 -5
- package/src/system/components/SideNavigation.svelte +12 -12
- package/src/system/components/TabBar.svelte +4 -4
- package/src/system/components/Table.svelte +2 -2
- package/src/system/components/Tooltip.svelte +1 -1
- package/src/system/styles/tokens.css +59 -6
- package/src/editor/ui/TextTab.svelte +0 -203
package/dist-plugin/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
runAdditiveTokensCssMigrations,
|
|
6
6
|
runTokensCssMigrations,
|
|
7
7
|
validateTokensCss
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-H4TRUINI.js";
|
|
9
9
|
|
|
10
10
|
// vite-plugin/themeFileApi.ts
|
|
11
11
|
import fs2 from "fs";
|
|
@@ -94,6 +94,10 @@ function isInGamut(r, g, b) {
|
|
|
94
94
|
const eps = 1e-4;
|
|
95
95
|
return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;
|
|
96
96
|
}
|
|
97
|
+
function oklchToHexClamped(l, c, h) {
|
|
98
|
+
const g = gamutClamp(l, c, h);
|
|
99
|
+
return oklchToHex(g.l, g.c, g.h);
|
|
100
|
+
}
|
|
97
101
|
function gamutClamp(l, c, h) {
|
|
98
102
|
if (l <= 0) return { l: 0, c: 0, h };
|
|
99
103
|
if (l >= 1) return { l: 1, c: 0, h };
|
|
@@ -151,16 +155,16 @@ function sampleCurve(anchors, xPos) {
|
|
|
151
155
|
|
|
152
156
|
// src/editor/core/palettes/paletteDerivation.ts
|
|
153
157
|
var PALETTE_SPECS = [
|
|
154
|
-
{ label: "
|
|
155
|
-
{ label: "
|
|
156
|
-
{ label: "Background", cssNamespace: "canvas", emptySelector: true, initialColor:
|
|
157
|
-
{ label: "
|
|
158
|
-
{ label: "
|
|
159
|
-
{ label: "Special", cssNamespace: "special", initialColor:
|
|
160
|
-
{ label: "Info", cssNamespace: "info", initialColor:
|
|
161
|
-
{ label: "Success", cssNamespace: "success", initialColor:
|
|
162
|
-
{ label: "Warning", cssNamespace: "warning", initialColor:
|
|
163
|
-
{ label: "Danger", cssNamespace: "danger", initialColor:
|
|
158
|
+
{ label: "Brand", cssNamespace: "brand", initialColor: { l: 0.5573, c: 0.1841, h: 25.49 } },
|
|
159
|
+
{ label: "Accent", cssNamespace: "accent", initialColor: { l: 0.7674, c: 0.164, h: 70.44 } },
|
|
160
|
+
{ label: "Background", cssNamespace: "canvas", emptySelector: true, initialColor: { l: 0.2284, c: 0.0384, h: 282.93 } },
|
|
161
|
+
{ label: "Neutral", cssNamespace: "neutral", neutral: true, initialColor: { l: 0.5679, c: 0.0134, h: 240.07 } },
|
|
162
|
+
{ label: "Alternate", cssNamespace: "alternate", neutral: true, displayLabel: "Alternate (neutral)", initialColor: { l: 0.5873, c: 87e-4, h: 48.57 } },
|
|
163
|
+
{ label: "Special", cssNamespace: "special", initialColor: { l: 0.6056, c: 0.2189, h: 292.72 } },
|
|
164
|
+
{ label: "Info", cssNamespace: "info", initialColor: { l: 0.5871, c: 0.1855, h: 259.56 } },
|
|
165
|
+
{ label: "Success", cssNamespace: "success", initialColor: { l: 0.7198, c: 0.1918, h: 149.52 } },
|
|
166
|
+
{ label: "Warning", cssNamespace: "warning", initialColor: { l: 0.6704, c: 0.1716, h: 48.75 } },
|
|
167
|
+
{ label: "Danger", cssNamespace: "danger", initialColor: { l: 0.6103, c: 0.2165, h: 18.1 } }
|
|
164
168
|
];
|
|
165
169
|
var PALETTE_STEPS = [
|
|
166
170
|
{ label: "100" },
|
|
@@ -212,50 +216,123 @@ var SCALES = [
|
|
|
212
216
|
]
|
|
213
217
|
}
|
|
214
218
|
];
|
|
219
|
+
var BW_GUARD_MIN_L = 0.17;
|
|
220
|
+
var BW_GUARD_MAX_L = 0.93;
|
|
215
221
|
var DEFAULT_PALETTE_LIGHTNESS = () => [makeAnchor(0, 95, 5), makeAnchor(100, 8, 5)];
|
|
216
222
|
var DEFAULT_PALETTE_SATURATION = () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)];
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
223
|
+
function scaleCurveDefaults(scheme = "dark") {
|
|
224
|
+
if (scheme === "light") {
|
|
225
|
+
return {
|
|
226
|
+
Surfaces: {
|
|
227
|
+
lightness: () => [makeAnchor(0, 98, 5), makeAnchor(100, 82, 5)],
|
|
228
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
229
|
+
},
|
|
230
|
+
Borders: {
|
|
231
|
+
lightness: () => [makeAnchor(0, 92, 5), makeAnchor(100, 45, 5)],
|
|
232
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
233
|
+
},
|
|
234
|
+
Text: {
|
|
235
|
+
lightness: () => [makeAnchor(0, 30, 30), makeAnchor(100, 120, 30)],
|
|
236
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 15, 30)]
|
|
237
|
+
}
|
|
238
|
+
};
|
|
229
239
|
}
|
|
230
|
-
|
|
240
|
+
return {
|
|
241
|
+
Surfaces: {
|
|
242
|
+
lightness: () => [makeAnchor(0, 15, 5), makeAnchor(100, 47, 5)],
|
|
243
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
244
|
+
},
|
|
245
|
+
Borders: {
|
|
246
|
+
lightness: () => [makeAnchor(0, 25, 5), makeAnchor(100, 80, 5)],
|
|
247
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
248
|
+
},
|
|
249
|
+
Text: {
|
|
250
|
+
lightness: () => [makeAnchor(0, 120, 30), makeAnchor(100, 55, 30)],
|
|
251
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 15, 30)]
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
var defaultScaleCurves = scaleCurveDefaults("dark");
|
|
231
256
|
function paletteStepKey(label) {
|
|
232
257
|
return `Palette-${label}`;
|
|
233
258
|
}
|
|
234
259
|
function stepKey(scaleTitle, stepName) {
|
|
235
260
|
return `${scaleTitle}-${stepName}`;
|
|
236
261
|
}
|
|
237
|
-
function stepIndexToX(index
|
|
238
|
-
return
|
|
262
|
+
function stepIndexToX(index) {
|
|
263
|
+
return index / (PALETTE_STEPS.length - 1) * 100;
|
|
264
|
+
}
|
|
265
|
+
function scaleStepToX(step, scale) {
|
|
266
|
+
const idx = scale.steps.indexOf(step);
|
|
267
|
+
return scale.steps.length > 1 ? idx / (scale.steps.length - 1) * 100 : 50;
|
|
239
268
|
}
|
|
240
|
-
function
|
|
241
|
-
|
|
242
|
-
|
|
269
|
+
function serializeDerivedValue(value) {
|
|
270
|
+
return value.kind === "raw" ? value.css : oklchToHexClamped(value.l, value.c, value.h);
|
|
271
|
+
}
|
|
272
|
+
function computePaletteOklch(index, base, lightnessCurve, saturationCurve, curveOffset) {
|
|
273
|
+
const { c: baseC, h } = base;
|
|
274
|
+
const xPos = stepIndexToX(index);
|
|
243
275
|
const targetL = Math.max(0, Math.min(100, sampleCurve(lightnessCurve, xPos) + (curveOffset.lightness ?? 0))) / 100;
|
|
244
276
|
const satMul = Math.max(0, Math.min(2, (sampleCurve(saturationCurve, xPos) + (curveOffset.saturation ?? 0)) / 100));
|
|
245
277
|
const targetC = baseC * satMul;
|
|
246
|
-
|
|
247
|
-
|
|
278
|
+
return gamutClamp(targetL, targetC, h);
|
|
279
|
+
}
|
|
280
|
+
function nearestPaletteStep(lightnessCurve, baseL) {
|
|
281
|
+
let best = 0;
|
|
282
|
+
let bestD = Infinity;
|
|
283
|
+
for (let i = 0; i < PALETTE_STEPS.length; i++) {
|
|
284
|
+
const d = Math.abs(sampleCurve(lightnessCurve, stepIndexToX(i)) - baseL * 100);
|
|
285
|
+
if (d < bestD) {
|
|
286
|
+
bestD = d;
|
|
287
|
+
best = i;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return best;
|
|
291
|
+
}
|
|
292
|
+
function setCurveAnchor(curve, x, y) {
|
|
293
|
+
const existing = curve.findIndex((a) => Math.abs(a.x - x) < 0.5);
|
|
294
|
+
if (existing >= 0) {
|
|
295
|
+
const displacedY = curve[existing].y;
|
|
296
|
+
return { curve: curve.map((a, i) => i === existing ? { ...a, x, y } : a), displacedY };
|
|
297
|
+
}
|
|
298
|
+
let insertAt = curve.findIndex((a) => a.x > x);
|
|
299
|
+
if (insertAt < 0) insertAt = curve.length;
|
|
300
|
+
return { curve: [...curve.slice(0, insertAt), makeAnchor(x, y, 15), ...curve.slice(insertAt)] };
|
|
301
|
+
}
|
|
302
|
+
function liftCurveAnchor(curve, x, displacedY) {
|
|
303
|
+
const idx = curve.findIndex((a) => Math.abs(a.x - x) < 0.5);
|
|
304
|
+
if (idx < 0) return curve;
|
|
305
|
+
if (displacedY !== void 0) return curve.map((a, i) => i === idx ? { ...a, y: displacedY } : a);
|
|
306
|
+
if (idx === 0 || idx === curve.length - 1) return curve;
|
|
307
|
+
return curve.filter((_, i) => i !== idx);
|
|
308
|
+
}
|
|
309
|
+
function syncBaseAnchor(cfg) {
|
|
310
|
+
if (cfg.anchorToBase === false) return;
|
|
311
|
+
const prev = cfg.anchorPlacement;
|
|
312
|
+
let lCurve = cfg.lightnessCurve;
|
|
313
|
+
let sCurve = cfg.saturationCurve;
|
|
314
|
+
if (prev) {
|
|
315
|
+
const prevX = stepIndexToX(prev.step);
|
|
316
|
+
lCurve = liftCurveAnchor(lCurve, prevX, prev.displacedL);
|
|
317
|
+
sCurve = liftCurveAnchor(sCurve, prevX, prev.displacedS);
|
|
318
|
+
}
|
|
319
|
+
const step = nearestPaletteStep(lCurve, cfg.baseColor.l);
|
|
320
|
+
const x = stepIndexToX(step);
|
|
321
|
+
const l = setCurveAnchor(lCurve, x, cfg.baseColor.l * 100);
|
|
322
|
+
const s = setCurveAnchor(sCurve, x, 100);
|
|
323
|
+
cfg.lightnessCurve = l.curve;
|
|
324
|
+
cfg.saturationCurve = s.curve;
|
|
325
|
+
cfg.anchorPlacement = { step, displacedL: l.displacedY, displacedS: s.displacedY };
|
|
248
326
|
}
|
|
249
|
-
function
|
|
327
|
+
function computeDerivedOklch(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
250
328
|
const scale = SCALES.find((s) => s.title === scaleTitle);
|
|
251
|
-
const
|
|
252
|
-
const xPos = stepIndexToX(idx, scale.steps.length);
|
|
329
|
+
const xPos = scaleStepToX(step, scale);
|
|
253
330
|
const defs = defaultScaleCurves[scaleTitle];
|
|
254
331
|
const lCurve = scaleCurves[scaleTitle]?.lightness ?? defs.lightness();
|
|
255
332
|
const sCurve = scaleCurves[scaleTitle]?.saturation ?? defs.saturation();
|
|
256
333
|
const lOff = curveOffset[`${scaleTitle}-lightness`] ?? 0;
|
|
257
334
|
const sOff = curveOffset[`${scaleTitle}-saturation`] ?? 0;
|
|
258
|
-
const { l: baseL, c: baseC, h: baseH } =
|
|
335
|
+
const { l: baseL, c: baseC, h: baseH } = base;
|
|
259
336
|
let targetL;
|
|
260
337
|
if (scale.isText) {
|
|
261
338
|
const lMul = Math.max(0, Math.min(2, (sampleCurve(lCurve, xPos) + lOff) / 100));
|
|
@@ -265,8 +342,7 @@ function computeDerivedColor(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
|
265
342
|
}
|
|
266
343
|
const satMul = Math.max(0, Math.min(2, (sampleCurve(sCurve, xPos) + sOff) / 100));
|
|
267
344
|
const targetC = baseC * satMul;
|
|
268
|
-
|
|
269
|
-
return oklchToHex(clamped.l, clamped.c, clamped.h);
|
|
345
|
+
return gamutClamp(targetL, targetC, baseH);
|
|
270
346
|
}
|
|
271
347
|
function scaleToCssVar(scaleTitle, stepName, cssNamespace) {
|
|
272
348
|
if (cssNamespace === null) return null;
|
|
@@ -284,7 +360,7 @@ function scaleToCssVar(scaleTitle, stepName, cssNamespace) {
|
|
|
284
360
|
}
|
|
285
361
|
return null;
|
|
286
362
|
}
|
|
287
|
-
function
|
|
363
|
+
function derivePaletteValues(spec, config) {
|
|
288
364
|
const out = {};
|
|
289
365
|
if (!config) return out;
|
|
290
366
|
const baseColor = config.baseColor ?? spec.initialColor;
|
|
@@ -295,21 +371,24 @@ function derivePaletteVars(spec, config) {
|
|
|
295
371
|
const saturationCurve = config.saturationCurve ?? DEFAULT_PALETTE_SATURATION();
|
|
296
372
|
PALETTE_STEPS.forEach((ps, index) => {
|
|
297
373
|
const k = paletteStepKey(ps.label);
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
out[`--color-${spec.cssNamespace}-${ps.label}`] = effective;
|
|
374
|
+
const value = k in overrides ? { kind: "color", ...overrides[k] } : { kind: "color", ...computePaletteOklch(index, baseColor, lightnessCurve, saturationCurve, curveOffset) };
|
|
375
|
+
out[`--color-${spec.cssNamespace}-${ps.label}`] = value;
|
|
301
376
|
});
|
|
302
377
|
for (const scale of SCALES) {
|
|
303
378
|
for (const step of scale.steps) {
|
|
304
379
|
const k = stepKey(scale.title, step.name);
|
|
305
|
-
const
|
|
380
|
+
const value = k in overrides ? { kind: "color", ...overrides[k] } : { kind: "color", ...computeDerivedOklch(step, baseColor, scale.title, scaleCurves, curveOffset) };
|
|
306
381
|
const varName = scaleToCssVar(scale.title, step.name, spec.cssNamespace);
|
|
307
|
-
if (varName) out[varName] =
|
|
382
|
+
if (varName) out[varName] = value;
|
|
308
383
|
}
|
|
309
384
|
}
|
|
385
|
+
const textPrimary = out["--text-primary"];
|
|
386
|
+
if (textPrimary?.kind === "color") {
|
|
387
|
+
const mirroredL = Math.max(BW_GUARD_MIN_L, Math.min(BW_GUARD_MAX_L, 1 - textPrimary.l));
|
|
388
|
+
out["--text-inverted"] = { kind: "color", ...gamutClamp(mirroredL, textPrimary.c, textPrimary.h) };
|
|
389
|
+
}
|
|
310
390
|
if (spec.emptySelector) {
|
|
311
391
|
const emptyMode = config.emptyMode ?? "solid";
|
|
312
|
-
const emptyStep = config.emptyStep ?? "850";
|
|
313
392
|
const gradientStyle = config.gradientStyle ?? "linear";
|
|
314
393
|
const gradientAngle = config.gradientAngle ?? 180;
|
|
315
394
|
const gradientReverse = config.gradientReverse ?? false;
|
|
@@ -319,14 +398,17 @@ function derivePaletteVars(spec, config) {
|
|
|
319
398
|
{ position: 100, paletteLabel: "950" }
|
|
320
399
|
];
|
|
321
400
|
if (emptyMode === "solid") {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
out["--page-bg-attachment"] = "scroll";
|
|
401
|
+
out["--page-bg"] = { kind: "color", ...baseColor };
|
|
402
|
+
out["--page-bg-attachment"] = { kind: "raw", css: "scroll" };
|
|
325
403
|
} else {
|
|
326
404
|
const sortedStops = [...gradientStops].sort(
|
|
327
405
|
(a, b) => gradientReverse ? b.position - a.position : a.position - b.position
|
|
328
406
|
);
|
|
329
|
-
const stopsCss = sortedStops.map((s) =>
|
|
407
|
+
const stopsCss = sortedStops.map((s) => {
|
|
408
|
+
const stopValue = out[`--color-${spec.cssNamespace}-${s.paletteLabel}`];
|
|
409
|
+
const hex = stopValue ? serializeDerivedValue(stopValue) : "#000000";
|
|
410
|
+
return `${hex} ${s.position}%`;
|
|
411
|
+
}).join(", ");
|
|
330
412
|
let gradient;
|
|
331
413
|
switch (gradientStyle) {
|
|
332
414
|
case "radial":
|
|
@@ -338,16 +420,30 @@ function derivePaletteVars(spec, config) {
|
|
|
338
420
|
default:
|
|
339
421
|
gradient = `linear-gradient(${gradientAngle}deg, ${stopsCss})`;
|
|
340
422
|
}
|
|
341
|
-
out["--page-bg"] = gradient;
|
|
342
|
-
out["--page-bg-attachment"] = gradientSize === "window" ? "fixed" : "scroll";
|
|
423
|
+
out["--page-bg"] = { kind: "raw", css: gradient };
|
|
424
|
+
out["--page-bg-attachment"] = { kind: "raw", css: gradientSize === "window" ? "fixed" : "scroll" };
|
|
343
425
|
}
|
|
344
426
|
}
|
|
345
427
|
return out;
|
|
346
428
|
}
|
|
347
|
-
function
|
|
429
|
+
function derivePaletteVars(spec, config) {
|
|
430
|
+
const out = {};
|
|
431
|
+
for (const [k, v] of Object.entries(derivePaletteValues(spec, config))) {
|
|
432
|
+
out[k] = serializeDerivedValue(v);
|
|
433
|
+
}
|
|
434
|
+
return out;
|
|
435
|
+
}
|
|
436
|
+
function palettesToValues(palettes) {
|
|
348
437
|
const out = {};
|
|
349
438
|
for (const spec of PALETTE_SPECS) {
|
|
350
|
-
Object.assign(out,
|
|
439
|
+
Object.assign(out, derivePaletteValues(spec, palettes[spec.label]));
|
|
440
|
+
}
|
|
441
|
+
return out;
|
|
442
|
+
}
|
|
443
|
+
function palettesToVars(palettes) {
|
|
444
|
+
const out = {};
|
|
445
|
+
for (const [k, v] of Object.entries(palettesToValues(palettes))) {
|
|
446
|
+
out[k] = serializeDerivedValue(v);
|
|
351
447
|
}
|
|
352
448
|
return out;
|
|
353
449
|
}
|
|
@@ -362,8 +458,8 @@ function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
|
362
458
|
if (current._imported === true) {
|
|
363
459
|
const anchorHex = cssVars[`--color-${spec.cssNamespace}-500`];
|
|
364
460
|
if (anchorHex && HEX_RE.test(anchorHex.trim())) {
|
|
365
|
-
|
|
366
|
-
next[spec.label]
|
|
461
|
+
next[spec.label] = { ...current, baseColor: hexToOklch(anchorHex.trim()), _imported: false };
|
|
462
|
+
syncBaseAnchor(next[spec.label]);
|
|
367
463
|
snapped.add(spec.label);
|
|
368
464
|
} else {
|
|
369
465
|
next[spec.label] = { ...current, _imported: false };
|
|
@@ -376,6 +472,26 @@ function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
|
376
472
|
return { palettes: next, consumed, snapped };
|
|
377
473
|
}
|
|
378
474
|
|
|
475
|
+
// src/editor/core/themes/migrations/2026-07-21-palette-oklch-basis.ts
|
|
476
|
+
var round = (v, dp) => {
|
|
477
|
+
const f = 10 ** dp;
|
|
478
|
+
return Math.round(v * f) / f;
|
|
479
|
+
};
|
|
480
|
+
function toStoredOklch(value) {
|
|
481
|
+
if (typeof value !== "string") return value;
|
|
482
|
+
const { l, c, h } = hexToOklch(value);
|
|
483
|
+
return { l: round(l, 4), c: round(c, 4), h: round(h, 2) };
|
|
484
|
+
}
|
|
485
|
+
function migratePaletteColorsToOklch(editorConfigs) {
|
|
486
|
+
const out = {};
|
|
487
|
+
for (const [label, cfg] of Object.entries(editorConfigs)) {
|
|
488
|
+
const overrides = {};
|
|
489
|
+
for (const [k, v] of Object.entries(cfg.overrides ?? {})) overrides[k] = toStoredOklch(v);
|
|
490
|
+
out[label] = { ...cfg, baseColor: toStoredOklch(cfg.baseColor), overrides };
|
|
491
|
+
}
|
|
492
|
+
return out;
|
|
493
|
+
}
|
|
494
|
+
|
|
379
495
|
// vite-plugin/files/versionedFileResourceServer.ts
|
|
380
496
|
import fs from "fs";
|
|
381
497
|
import path from "path";
|
|
@@ -654,7 +770,7 @@ function themeFileApi(opts) {
|
|
|
654
770
|
let themeVarCount = 0;
|
|
655
771
|
if (themeData) {
|
|
656
772
|
const cssVars = { ...themeData.cssVariables || {} };
|
|
657
|
-
Object.assign(cssVars, palettesToVars(themeData.editorConfigs ?? {}));
|
|
773
|
+
Object.assign(cssVars, palettesToVars(migratePaletteColorsToOklch(themeData.editorConfigs ?? {})));
|
|
658
774
|
const resolvedFontVars = resolveFontStacks(themeData);
|
|
659
775
|
for (const [name, value] of Object.entries(resolvedFontVars)) {
|
|
660
776
|
cssVars[name] = value;
|
|
@@ -156,20 +156,9 @@ function escapeRe(s) {
|
|
|
156
156
|
var tokensCssMigration_2026_05_29_typographyScaleAdditions = {
|
|
157
157
|
id: "2026-05-29-typography-scale-additions",
|
|
158
158
|
kind: "additive",
|
|
159
|
-
description: "Add --
|
|
159
|
+
description: "Add --letter-spacing-* and --ease-out-quart scales",
|
|
160
160
|
apply(css) {
|
|
161
161
|
let out = css;
|
|
162
|
-
out = ensureScale(out, {
|
|
163
|
-
sectionComment: "Line height (t-shirt scale)",
|
|
164
|
-
anchorPrefixes: ["--line-height-", "--font-size-", "--font-weight-", "--font-"],
|
|
165
|
-
entries: [
|
|
166
|
-
{ name: "--line-height-xs", value: "1" },
|
|
167
|
-
{ name: "--line-height-sm", value: "1.25" },
|
|
168
|
-
{ name: "--line-height-md", value: "1.5" },
|
|
169
|
-
{ name: "--line-height-lg", value: "1.75" },
|
|
170
|
-
{ name: "--line-height-xl", value: "2" }
|
|
171
|
-
]
|
|
172
|
-
});
|
|
173
162
|
out = ensureScale(out, {
|
|
174
163
|
sectionComment: "Letter spacing",
|
|
175
164
|
anchorPrefixes: ["--letter-spacing-", "--line-height-", "--font-size-", "--font-"],
|
|
@@ -312,6 +301,104 @@ var tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions = {
|
|
|
312
301
|
}
|
|
313
302
|
};
|
|
314
303
|
|
|
304
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-07-20-line-height-rename.ts
|
|
305
|
+
var RENAMES = [
|
|
306
|
+
["--line-height-xs", "--line-height-none"],
|
|
307
|
+
["--line-height-sm", "--line-height-tighter"],
|
|
308
|
+
["--line-height-md", "--line-height-normal"],
|
|
309
|
+
["--line-height-lg", "--line-height-relaxed"]
|
|
310
|
+
];
|
|
311
|
+
var SCALE = [
|
|
312
|
+
{ name: "--line-height-none", value: "1" },
|
|
313
|
+
{ name: "--line-height-tightest", value: "1.1" },
|
|
314
|
+
{ name: "--line-height-tighter", value: "1.25" },
|
|
315
|
+
{ name: "--line-height-tight", value: "1.35" },
|
|
316
|
+
{ name: "--line-height-normal", value: "1.5" },
|
|
317
|
+
{ name: "--line-height-relaxed", value: "1.75" }
|
|
318
|
+
];
|
|
319
|
+
var tokensCssMigration_2026_07_20_lineHeightRename = {
|
|
320
|
+
id: "2026-07-20-line-height-rename",
|
|
321
|
+
kind: "breaking",
|
|
322
|
+
description: "Reshape --line-height-{xs..xl} to leading vocabulary (none/tightest/tighter/tight/normal/relaxed); retire the 2.0 slot",
|
|
323
|
+
apply(css) {
|
|
324
|
+
let out = css;
|
|
325
|
+
for (const [oldName, newName] of RENAMES) out = renameToken(out, oldName, newName);
|
|
326
|
+
out = removeToken(out, "--line-height-xl");
|
|
327
|
+
out = ensureScale(out, {
|
|
328
|
+
anchorPrefixes: ["--line-height-", "--font-size-", "--font-weight-", "--font-"],
|
|
329
|
+
entries: SCALE
|
|
330
|
+
});
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-07-20-semantic-text-styles.ts
|
|
336
|
+
var BUNDLE = [
|
|
337
|
+
{ name: "--heading-xl-font-family", value: "var(--font-display)" },
|
|
338
|
+
{ name: "--heading-xl-font-size", value: "var(--font-size-4xl)" },
|
|
339
|
+
{ name: "--heading-xl-font-weight", value: "var(--font-weight-semibold)" },
|
|
340
|
+
{ name: "--heading-xl-line-height", value: "var(--line-height-tightest)" },
|
|
341
|
+
{ name: "--heading-xl-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
342
|
+
{ name: "--heading-lg-font-family", value: "var(--font-display)" },
|
|
343
|
+
{ name: "--heading-lg-font-size", value: "var(--font-size-2xl)" },
|
|
344
|
+
{ name: "--heading-lg-font-weight", value: "var(--font-weight-semibold)" },
|
|
345
|
+
{ name: "--heading-lg-line-height", value: "var(--line-height-tightest)" },
|
|
346
|
+
{ name: "--heading-lg-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
347
|
+
{ name: "--heading-md-font-family", value: "var(--font-display)" },
|
|
348
|
+
{ name: "--heading-md-font-size", value: "var(--font-size-xl)" },
|
|
349
|
+
{ name: "--heading-md-font-weight", value: "var(--font-weight-semibold)" },
|
|
350
|
+
{ name: "--heading-md-line-height", value: "var(--line-height-tighter)" },
|
|
351
|
+
{ name: "--heading-md-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
352
|
+
{ name: "--heading-sm-font-family", value: "var(--font-sans)" },
|
|
353
|
+
{ name: "--heading-sm-font-size", value: "var(--font-size-lg)" },
|
|
354
|
+
{ name: "--heading-sm-font-weight", value: "var(--font-weight-semibold)" },
|
|
355
|
+
{ name: "--heading-sm-line-height", value: "var(--line-height-tighter)" },
|
|
356
|
+
{ name: "--heading-sm-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
357
|
+
{ name: "--body-md-font-family", value: "var(--font-sans)" },
|
|
358
|
+
{ name: "--body-md-font-size", value: "var(--font-size-md)" },
|
|
359
|
+
{ name: "--body-md-font-weight", value: "var(--font-weight-normal)" },
|
|
360
|
+
{ name: "--body-md-line-height", value: "var(--line-height-normal)" },
|
|
361
|
+
{ name: "--body-md-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
362
|
+
{ name: "--body-sm-font-family", value: "var(--font-sans)" },
|
|
363
|
+
{ name: "--body-sm-font-size", value: "var(--font-size-sm)" },
|
|
364
|
+
{ name: "--body-sm-font-weight", value: "var(--font-weight-normal)" },
|
|
365
|
+
{ name: "--body-sm-line-height", value: "var(--line-height-tight)" },
|
|
366
|
+
{ name: "--body-sm-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
367
|
+
{ name: "--code-font-family", value: "var(--font-mono)" },
|
|
368
|
+
{ name: "--code-font-size", value: "var(--font-size-sm)" },
|
|
369
|
+
{ name: "--code-font-weight", value: "var(--font-weight-normal)" },
|
|
370
|
+
{ name: "--code-line-height", value: "var(--line-height-normal)" },
|
|
371
|
+
{ name: "--code-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
372
|
+
{ name: "--eyebrow-font-family", value: "var(--font-sans)" },
|
|
373
|
+
{ name: "--eyebrow-font-size", value: "var(--font-size-sm)" },
|
|
374
|
+
{ name: "--eyebrow-font-weight", value: "var(--font-weight-normal)" },
|
|
375
|
+
{ name: "--eyebrow-line-height", value: "var(--line-height-normal)" },
|
|
376
|
+
{ name: "--eyebrow-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
377
|
+
{ name: "--eyebrow-text-transform", value: "none" }
|
|
378
|
+
];
|
|
379
|
+
var tokensCssMigration_2026_07_20_semanticTextStyles = {
|
|
380
|
+
id: "2026-07-20-semantic-text-styles",
|
|
381
|
+
kind: "additive",
|
|
382
|
+
description: "Add the semantic text-style bundles (--heading-*/--body-*/--code-*/--eyebrow-*)",
|
|
383
|
+
apply(css) {
|
|
384
|
+
return ensureScale(css, {
|
|
385
|
+
sectionComment: "Text styles \u2014 semantic typography roles",
|
|
386
|
+
anchorPrefixes: [
|
|
387
|
+
"--eyebrow-",
|
|
388
|
+
"--code-",
|
|
389
|
+
"--body-",
|
|
390
|
+
"--heading-",
|
|
391
|
+
"--letter-spacing-",
|
|
392
|
+
"--line-height-",
|
|
393
|
+
"--font-weight-",
|
|
394
|
+
"--font-size-",
|
|
395
|
+
"--font-"
|
|
396
|
+
],
|
|
397
|
+
entries: BUNDLE
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
|
|
315
402
|
// vite-plugin/files/dataPaths.ts
|
|
316
403
|
var import_fs = __toESM(require("fs"), 1);
|
|
317
404
|
var import_path = __toESM(require("path"), 1);
|
|
@@ -351,7 +438,9 @@ var TOKENS_CSS_MIGRATIONS = [
|
|
|
351
438
|
tokensCssMigration_2026_05_29_sectiondividerLegacyAxisCleanup,
|
|
352
439
|
tokensCssMigration_2026_06_03_transformScaleAdditions,
|
|
353
440
|
tokensCssMigration_2026_06_04_removeDeadSizeIconScale,
|
|
354
|
-
tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions
|
|
441
|
+
tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions,
|
|
442
|
+
tokensCssMigration_2026_07_20_lineHeightRename,
|
|
443
|
+
tokensCssMigration_2026_07_20_semanticTextStyles
|
|
355
444
|
];
|
|
356
445
|
function runTokensCssMigrations(css) {
|
|
357
446
|
return foldMigrations(css, () => true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motion-proto/live-tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Design token editor with live CSS variable editing. Svelte 5 + Vite 8.",
|
|
6
6
|
"keywords": [
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"template",
|
|
33
33
|
"!**/*.test.ts",
|
|
34
34
|
"!**/*.spec.ts",
|
|
35
|
-
"!**/__tests__/**"
|
|
35
|
+
"!**/__tests__/**",
|
|
36
|
+
"!**/__snapshots__/**"
|
|
36
37
|
],
|
|
37
38
|
"bin": {
|
|
38
39
|
"live-tokens": "./bin/cli.mjs"
|