@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.cjs
CHANGED
|
@@ -135,6 +135,10 @@ function isInGamut(r, g, b) {
|
|
|
135
135
|
const eps = 1e-4;
|
|
136
136
|
return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;
|
|
137
137
|
}
|
|
138
|
+
function oklchToHexClamped(l, c, h) {
|
|
139
|
+
const g = gamutClamp(l, c, h);
|
|
140
|
+
return oklchToHex(g.l, g.c, g.h);
|
|
141
|
+
}
|
|
138
142
|
function gamutClamp(l, c, h) {
|
|
139
143
|
if (l <= 0) return { l: 0, c: 0, h };
|
|
140
144
|
if (l >= 1) return { l: 1, c: 0, h };
|
|
@@ -192,16 +196,16 @@ function sampleCurve(anchors, xPos) {
|
|
|
192
196
|
|
|
193
197
|
// src/editor/core/palettes/paletteDerivation.ts
|
|
194
198
|
var PALETTE_SPECS = [
|
|
195
|
-
{ label: "
|
|
196
|
-
{ label: "
|
|
197
|
-
{ label: "Background", cssNamespace: "canvas", emptySelector: true, initialColor:
|
|
198
|
-
{ label: "
|
|
199
|
-
{ label: "
|
|
200
|
-
{ label: "Special", cssNamespace: "special", initialColor:
|
|
201
|
-
{ label: "Info", cssNamespace: "info", initialColor:
|
|
202
|
-
{ label: "Success", cssNamespace: "success", initialColor:
|
|
203
|
-
{ label: "Warning", cssNamespace: "warning", initialColor:
|
|
204
|
-
{ label: "Danger", cssNamespace: "danger", initialColor:
|
|
199
|
+
{ label: "Brand", cssNamespace: "brand", initialColor: { l: 0.5573, c: 0.1841, h: 25.49 } },
|
|
200
|
+
{ label: "Accent", cssNamespace: "accent", initialColor: { l: 0.7674, c: 0.164, h: 70.44 } },
|
|
201
|
+
{ label: "Background", cssNamespace: "canvas", emptySelector: true, initialColor: { l: 0.2284, c: 0.0384, h: 282.93 } },
|
|
202
|
+
{ label: "Neutral", cssNamespace: "neutral", neutral: true, initialColor: { l: 0.5679, c: 0.0134, h: 240.07 } },
|
|
203
|
+
{ label: "Alternate", cssNamespace: "alternate", neutral: true, displayLabel: "Alternate (neutral)", initialColor: { l: 0.5873, c: 87e-4, h: 48.57 } },
|
|
204
|
+
{ label: "Special", cssNamespace: "special", initialColor: { l: 0.6056, c: 0.2189, h: 292.72 } },
|
|
205
|
+
{ label: "Info", cssNamespace: "info", initialColor: { l: 0.5871, c: 0.1855, h: 259.56 } },
|
|
206
|
+
{ label: "Success", cssNamespace: "success", initialColor: { l: 0.7198, c: 0.1918, h: 149.52 } },
|
|
207
|
+
{ label: "Warning", cssNamespace: "warning", initialColor: { l: 0.6704, c: 0.1716, h: 48.75 } },
|
|
208
|
+
{ label: "Danger", cssNamespace: "danger", initialColor: { l: 0.6103, c: 0.2165, h: 18.1 } }
|
|
205
209
|
];
|
|
206
210
|
var PALETTE_STEPS = [
|
|
207
211
|
{ label: "100" },
|
|
@@ -253,50 +257,123 @@ var SCALES = [
|
|
|
253
257
|
]
|
|
254
258
|
}
|
|
255
259
|
];
|
|
260
|
+
var BW_GUARD_MIN_L = 0.17;
|
|
261
|
+
var BW_GUARD_MAX_L = 0.93;
|
|
256
262
|
var DEFAULT_PALETTE_LIGHTNESS = () => [makeAnchor(0, 95, 5), makeAnchor(100, 8, 5)];
|
|
257
263
|
var DEFAULT_PALETTE_SATURATION = () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)];
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
264
|
+
function scaleCurveDefaults(scheme = "dark") {
|
|
265
|
+
if (scheme === "light") {
|
|
266
|
+
return {
|
|
267
|
+
Surfaces: {
|
|
268
|
+
lightness: () => [makeAnchor(0, 98, 5), makeAnchor(100, 82, 5)],
|
|
269
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
270
|
+
},
|
|
271
|
+
Borders: {
|
|
272
|
+
lightness: () => [makeAnchor(0, 92, 5), makeAnchor(100, 45, 5)],
|
|
273
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
274
|
+
},
|
|
275
|
+
Text: {
|
|
276
|
+
lightness: () => [makeAnchor(0, 30, 30), makeAnchor(100, 120, 30)],
|
|
277
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 15, 30)]
|
|
278
|
+
}
|
|
279
|
+
};
|
|
270
280
|
}
|
|
271
|
-
|
|
281
|
+
return {
|
|
282
|
+
Surfaces: {
|
|
283
|
+
lightness: () => [makeAnchor(0, 15, 5), makeAnchor(100, 47, 5)],
|
|
284
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
285
|
+
},
|
|
286
|
+
Borders: {
|
|
287
|
+
lightness: () => [makeAnchor(0, 25, 5), makeAnchor(100, 80, 5)],
|
|
288
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 100, 30)]
|
|
289
|
+
},
|
|
290
|
+
Text: {
|
|
291
|
+
lightness: () => [makeAnchor(0, 120, 30), makeAnchor(100, 55, 30)],
|
|
292
|
+
saturation: () => [makeAnchor(0, 100, 30), makeAnchor(100, 15, 30)]
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
var defaultScaleCurves = scaleCurveDefaults("dark");
|
|
272
297
|
function paletteStepKey(label) {
|
|
273
298
|
return `Palette-${label}`;
|
|
274
299
|
}
|
|
275
300
|
function stepKey(scaleTitle, stepName) {
|
|
276
301
|
return `${scaleTitle}-${stepName}`;
|
|
277
302
|
}
|
|
278
|
-
function stepIndexToX(index
|
|
279
|
-
return
|
|
303
|
+
function stepIndexToX(index) {
|
|
304
|
+
return index / (PALETTE_STEPS.length - 1) * 100;
|
|
305
|
+
}
|
|
306
|
+
function scaleStepToX(step, scale) {
|
|
307
|
+
const idx = scale.steps.indexOf(step);
|
|
308
|
+
return scale.steps.length > 1 ? idx / (scale.steps.length - 1) * 100 : 50;
|
|
309
|
+
}
|
|
310
|
+
function serializeDerivedValue(value) {
|
|
311
|
+
return value.kind === "raw" ? value.css : oklchToHexClamped(value.l, value.c, value.h);
|
|
280
312
|
}
|
|
281
|
-
function
|
|
282
|
-
const { c: baseC, h } =
|
|
283
|
-
const xPos = stepIndexToX(index
|
|
313
|
+
function computePaletteOklch(index, base, lightnessCurve, saturationCurve, curveOffset) {
|
|
314
|
+
const { c: baseC, h } = base;
|
|
315
|
+
const xPos = stepIndexToX(index);
|
|
284
316
|
const targetL = Math.max(0, Math.min(100, sampleCurve(lightnessCurve, xPos) + (curveOffset.lightness ?? 0))) / 100;
|
|
285
317
|
const satMul = Math.max(0, Math.min(2, (sampleCurve(saturationCurve, xPos) + (curveOffset.saturation ?? 0)) / 100));
|
|
286
318
|
const targetC = baseC * satMul;
|
|
287
|
-
|
|
288
|
-
|
|
319
|
+
return gamutClamp(targetL, targetC, h);
|
|
320
|
+
}
|
|
321
|
+
function nearestPaletteStep(lightnessCurve, baseL) {
|
|
322
|
+
let best = 0;
|
|
323
|
+
let bestD = Infinity;
|
|
324
|
+
for (let i = 0; i < PALETTE_STEPS.length; i++) {
|
|
325
|
+
const d = Math.abs(sampleCurve(lightnessCurve, stepIndexToX(i)) - baseL * 100);
|
|
326
|
+
if (d < bestD) {
|
|
327
|
+
bestD = d;
|
|
328
|
+
best = i;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return best;
|
|
332
|
+
}
|
|
333
|
+
function setCurveAnchor(curve, x, y) {
|
|
334
|
+
const existing = curve.findIndex((a) => Math.abs(a.x - x) < 0.5);
|
|
335
|
+
if (existing >= 0) {
|
|
336
|
+
const displacedY = curve[existing].y;
|
|
337
|
+
return { curve: curve.map((a, i) => i === existing ? { ...a, x, y } : a), displacedY };
|
|
338
|
+
}
|
|
339
|
+
let insertAt = curve.findIndex((a) => a.x > x);
|
|
340
|
+
if (insertAt < 0) insertAt = curve.length;
|
|
341
|
+
return { curve: [...curve.slice(0, insertAt), makeAnchor(x, y, 15), ...curve.slice(insertAt)] };
|
|
289
342
|
}
|
|
290
|
-
function
|
|
343
|
+
function liftCurveAnchor(curve, x, displacedY) {
|
|
344
|
+
const idx = curve.findIndex((a) => Math.abs(a.x - x) < 0.5);
|
|
345
|
+
if (idx < 0) return curve;
|
|
346
|
+
if (displacedY !== void 0) return curve.map((a, i) => i === idx ? { ...a, y: displacedY } : a);
|
|
347
|
+
if (idx === 0 || idx === curve.length - 1) return curve;
|
|
348
|
+
return curve.filter((_, i) => i !== idx);
|
|
349
|
+
}
|
|
350
|
+
function syncBaseAnchor(cfg) {
|
|
351
|
+
if (cfg.anchorToBase === false) return;
|
|
352
|
+
const prev = cfg.anchorPlacement;
|
|
353
|
+
let lCurve = cfg.lightnessCurve;
|
|
354
|
+
let sCurve = cfg.saturationCurve;
|
|
355
|
+
if (prev) {
|
|
356
|
+
const prevX = stepIndexToX(prev.step);
|
|
357
|
+
lCurve = liftCurveAnchor(lCurve, prevX, prev.displacedL);
|
|
358
|
+
sCurve = liftCurveAnchor(sCurve, prevX, prev.displacedS);
|
|
359
|
+
}
|
|
360
|
+
const step = nearestPaletteStep(lCurve, cfg.baseColor.l);
|
|
361
|
+
const x = stepIndexToX(step);
|
|
362
|
+
const l = setCurveAnchor(lCurve, x, cfg.baseColor.l * 100);
|
|
363
|
+
const s = setCurveAnchor(sCurve, x, 100);
|
|
364
|
+
cfg.lightnessCurve = l.curve;
|
|
365
|
+
cfg.saturationCurve = s.curve;
|
|
366
|
+
cfg.anchorPlacement = { step, displacedL: l.displacedY, displacedS: s.displacedY };
|
|
367
|
+
}
|
|
368
|
+
function computeDerivedOklch(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
291
369
|
const scale = SCALES.find((s) => s.title === scaleTitle);
|
|
292
|
-
const
|
|
293
|
-
const xPos = stepIndexToX(idx, scale.steps.length);
|
|
370
|
+
const xPos = scaleStepToX(step, scale);
|
|
294
371
|
const defs = defaultScaleCurves[scaleTitle];
|
|
295
372
|
const lCurve = scaleCurves[scaleTitle]?.lightness ?? defs.lightness();
|
|
296
373
|
const sCurve = scaleCurves[scaleTitle]?.saturation ?? defs.saturation();
|
|
297
374
|
const lOff = curveOffset[`${scaleTitle}-lightness`] ?? 0;
|
|
298
375
|
const sOff = curveOffset[`${scaleTitle}-saturation`] ?? 0;
|
|
299
|
-
const { l: baseL, c: baseC, h: baseH } =
|
|
376
|
+
const { l: baseL, c: baseC, h: baseH } = base;
|
|
300
377
|
let targetL;
|
|
301
378
|
if (scale.isText) {
|
|
302
379
|
const lMul = Math.max(0, Math.min(2, (sampleCurve(lCurve, xPos) + lOff) / 100));
|
|
@@ -306,8 +383,7 @@ function computeDerivedColor(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
|
306
383
|
}
|
|
307
384
|
const satMul = Math.max(0, Math.min(2, (sampleCurve(sCurve, xPos) + sOff) / 100));
|
|
308
385
|
const targetC = baseC * satMul;
|
|
309
|
-
|
|
310
|
-
return oklchToHex(clamped.l, clamped.c, clamped.h);
|
|
386
|
+
return gamutClamp(targetL, targetC, baseH);
|
|
311
387
|
}
|
|
312
388
|
function scaleToCssVar(scaleTitle, stepName, cssNamespace) {
|
|
313
389
|
if (cssNamespace === null) return null;
|
|
@@ -325,7 +401,7 @@ function scaleToCssVar(scaleTitle, stepName, cssNamespace) {
|
|
|
325
401
|
}
|
|
326
402
|
return null;
|
|
327
403
|
}
|
|
328
|
-
function
|
|
404
|
+
function derivePaletteValues(spec, config) {
|
|
329
405
|
const out = {};
|
|
330
406
|
if (!config) return out;
|
|
331
407
|
const baseColor = config.baseColor ?? spec.initialColor;
|
|
@@ -336,21 +412,24 @@ function derivePaletteVars(spec, config) {
|
|
|
336
412
|
const saturationCurve = config.saturationCurve ?? DEFAULT_PALETTE_SATURATION();
|
|
337
413
|
PALETTE_STEPS.forEach((ps, index) => {
|
|
338
414
|
const k = paletteStepKey(ps.label);
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
out[`--color-${spec.cssNamespace}-${ps.label}`] = effective;
|
|
415
|
+
const value = k in overrides ? { kind: "color", ...overrides[k] } : { kind: "color", ...computePaletteOklch(index, baseColor, lightnessCurve, saturationCurve, curveOffset) };
|
|
416
|
+
out[`--color-${spec.cssNamespace}-${ps.label}`] = value;
|
|
342
417
|
});
|
|
343
418
|
for (const scale of SCALES) {
|
|
344
419
|
for (const step of scale.steps) {
|
|
345
420
|
const k = stepKey(scale.title, step.name);
|
|
346
|
-
const
|
|
421
|
+
const value = k in overrides ? { kind: "color", ...overrides[k] } : { kind: "color", ...computeDerivedOklch(step, baseColor, scale.title, scaleCurves, curveOffset) };
|
|
347
422
|
const varName = scaleToCssVar(scale.title, step.name, spec.cssNamespace);
|
|
348
|
-
if (varName) out[varName] =
|
|
423
|
+
if (varName) out[varName] = value;
|
|
349
424
|
}
|
|
350
425
|
}
|
|
426
|
+
const textPrimary = out["--text-primary"];
|
|
427
|
+
if (textPrimary?.kind === "color") {
|
|
428
|
+
const mirroredL = Math.max(BW_GUARD_MIN_L, Math.min(BW_GUARD_MAX_L, 1 - textPrimary.l));
|
|
429
|
+
out["--text-inverted"] = { kind: "color", ...gamutClamp(mirroredL, textPrimary.c, textPrimary.h) };
|
|
430
|
+
}
|
|
351
431
|
if (spec.emptySelector) {
|
|
352
432
|
const emptyMode = config.emptyMode ?? "solid";
|
|
353
|
-
const emptyStep = config.emptyStep ?? "850";
|
|
354
433
|
const gradientStyle = config.gradientStyle ?? "linear";
|
|
355
434
|
const gradientAngle = config.gradientAngle ?? 180;
|
|
356
435
|
const gradientReverse = config.gradientReverse ?? false;
|
|
@@ -360,14 +439,17 @@ function derivePaletteVars(spec, config) {
|
|
|
360
439
|
{ position: 100, paletteLabel: "950" }
|
|
361
440
|
];
|
|
362
441
|
if (emptyMode === "solid") {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
out["--page-bg-attachment"] = "scroll";
|
|
442
|
+
out["--page-bg"] = { kind: "color", ...baseColor };
|
|
443
|
+
out["--page-bg-attachment"] = { kind: "raw", css: "scroll" };
|
|
366
444
|
} else {
|
|
367
445
|
const sortedStops = [...gradientStops].sort(
|
|
368
446
|
(a, b) => gradientReverse ? b.position - a.position : a.position - b.position
|
|
369
447
|
);
|
|
370
|
-
const stopsCss = sortedStops.map((s) =>
|
|
448
|
+
const stopsCss = sortedStops.map((s) => {
|
|
449
|
+
const stopValue = out[`--color-${spec.cssNamespace}-${s.paletteLabel}`];
|
|
450
|
+
const hex = stopValue ? serializeDerivedValue(stopValue) : "#000000";
|
|
451
|
+
return `${hex} ${s.position}%`;
|
|
452
|
+
}).join(", ");
|
|
371
453
|
let gradient;
|
|
372
454
|
switch (gradientStyle) {
|
|
373
455
|
case "radial":
|
|
@@ -379,16 +461,30 @@ function derivePaletteVars(spec, config) {
|
|
|
379
461
|
default:
|
|
380
462
|
gradient = `linear-gradient(${gradientAngle}deg, ${stopsCss})`;
|
|
381
463
|
}
|
|
382
|
-
out["--page-bg"] = gradient;
|
|
383
|
-
out["--page-bg-attachment"] = gradientSize === "window" ? "fixed" : "scroll";
|
|
464
|
+
out["--page-bg"] = { kind: "raw", css: gradient };
|
|
465
|
+
out["--page-bg-attachment"] = { kind: "raw", css: gradientSize === "window" ? "fixed" : "scroll" };
|
|
384
466
|
}
|
|
385
467
|
}
|
|
386
468
|
return out;
|
|
387
469
|
}
|
|
388
|
-
function
|
|
470
|
+
function derivePaletteVars(spec, config) {
|
|
471
|
+
const out = {};
|
|
472
|
+
for (const [k, v] of Object.entries(derivePaletteValues(spec, config))) {
|
|
473
|
+
out[k] = serializeDerivedValue(v);
|
|
474
|
+
}
|
|
475
|
+
return out;
|
|
476
|
+
}
|
|
477
|
+
function palettesToValues(palettes) {
|
|
389
478
|
const out = {};
|
|
390
479
|
for (const spec of PALETTE_SPECS) {
|
|
391
|
-
Object.assign(out,
|
|
480
|
+
Object.assign(out, derivePaletteValues(spec, palettes[spec.label]));
|
|
481
|
+
}
|
|
482
|
+
return out;
|
|
483
|
+
}
|
|
484
|
+
function palettesToVars(palettes) {
|
|
485
|
+
const out = {};
|
|
486
|
+
for (const [k, v] of Object.entries(palettesToValues(palettes))) {
|
|
487
|
+
out[k] = serializeDerivedValue(v);
|
|
392
488
|
}
|
|
393
489
|
return out;
|
|
394
490
|
}
|
|
@@ -403,8 +499,8 @@ function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
|
403
499
|
if (current._imported === true) {
|
|
404
500
|
const anchorHex = cssVars[`--color-${spec.cssNamespace}-500`];
|
|
405
501
|
if (anchorHex && HEX_RE.test(anchorHex.trim())) {
|
|
406
|
-
|
|
407
|
-
next[spec.label]
|
|
502
|
+
next[spec.label] = { ...current, baseColor: hexToOklch(anchorHex.trim()), _imported: false };
|
|
503
|
+
syncBaseAnchor(next[spec.label]);
|
|
408
504
|
snapped.add(spec.label);
|
|
409
505
|
} else {
|
|
410
506
|
next[spec.label] = { ...current, _imported: false };
|
|
@@ -417,6 +513,26 @@ function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
|
417
513
|
return { palettes: next, consumed, snapped };
|
|
418
514
|
}
|
|
419
515
|
|
|
516
|
+
// src/editor/core/themes/migrations/2026-07-21-palette-oklch-basis.ts
|
|
517
|
+
var round = (v, dp) => {
|
|
518
|
+
const f = 10 ** dp;
|
|
519
|
+
return Math.round(v * f) / f;
|
|
520
|
+
};
|
|
521
|
+
function toStoredOklch(value) {
|
|
522
|
+
if (typeof value !== "string") return value;
|
|
523
|
+
const { l, c, h } = hexToOklch(value);
|
|
524
|
+
return { l: round(l, 4), c: round(c, 4), h: round(h, 2) };
|
|
525
|
+
}
|
|
526
|
+
function migratePaletteColorsToOklch(editorConfigs) {
|
|
527
|
+
const out = {};
|
|
528
|
+
for (const [label, cfg] of Object.entries(editorConfigs)) {
|
|
529
|
+
const overrides = {};
|
|
530
|
+
for (const [k, v] of Object.entries(cfg.overrides ?? {})) overrides[k] = toStoredOklch(v);
|
|
531
|
+
out[label] = { ...cfg, baseColor: toStoredOklch(cfg.baseColor), overrides };
|
|
532
|
+
}
|
|
533
|
+
return out;
|
|
534
|
+
}
|
|
535
|
+
|
|
420
536
|
// vite-plugin/files/versionedFileResourceServer.ts
|
|
421
537
|
var import_fs = __toESM(require("fs"), 1);
|
|
422
538
|
var import_path = __toESM(require("path"), 1);
|
|
@@ -622,6 +738,19 @@ function ensureScale(css, opts) {
|
|
|
622
738
|
lines.splice(insertAfter + 1, 0, ...block);
|
|
623
739
|
return lines.join("\n");
|
|
624
740
|
}
|
|
741
|
+
function renameToken(css, oldName, newName) {
|
|
742
|
+
const defined = collectDefinedTokens(css);
|
|
743
|
+
if (!defined.has(oldName) || defined.has(newName)) return css;
|
|
744
|
+
const re = new RegExp(escapeRe(oldName) + "(?![a-z0-9-])", "gi");
|
|
745
|
+
return css.replace(re, newName);
|
|
746
|
+
}
|
|
747
|
+
function removeToken(css, name) {
|
|
748
|
+
const lines = css.split("\n");
|
|
749
|
+
const declRe = new RegExp("(^|[\\s;{])" + escapeRe(name) + "\\s*:");
|
|
750
|
+
const kept = lines.filter((line) => !declRe.test(line));
|
|
751
|
+
if (kept.length === lines.length) return css;
|
|
752
|
+
return kept.join("\n");
|
|
753
|
+
}
|
|
625
754
|
function removeTokensMatching(css, predicate) {
|
|
626
755
|
const lines = css.split("\n");
|
|
627
756
|
const declRe = /^\s*(--[a-z0-9-]+)\s*:/;
|
|
@@ -674,25 +803,17 @@ function findTopLevelRoot(lines) {
|
|
|
674
803
|
}
|
|
675
804
|
return null;
|
|
676
805
|
}
|
|
806
|
+
function escapeRe(s) {
|
|
807
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
808
|
+
}
|
|
677
809
|
|
|
678
810
|
// vite-plugin/tokensCssMigrations/migrations/2026-05-29-typography-scale-additions.ts
|
|
679
811
|
var tokensCssMigration_2026_05_29_typographyScaleAdditions = {
|
|
680
812
|
id: "2026-05-29-typography-scale-additions",
|
|
681
813
|
kind: "additive",
|
|
682
|
-
description: "Add --
|
|
814
|
+
description: "Add --letter-spacing-* and --ease-out-quart scales",
|
|
683
815
|
apply(css) {
|
|
684
816
|
let out = css;
|
|
685
|
-
out = ensureScale(out, {
|
|
686
|
-
sectionComment: "Line height (t-shirt scale)",
|
|
687
|
-
anchorPrefixes: ["--line-height-", "--font-size-", "--font-weight-", "--font-"],
|
|
688
|
-
entries: [
|
|
689
|
-
{ name: "--line-height-xs", value: "1" },
|
|
690
|
-
{ name: "--line-height-sm", value: "1.25" },
|
|
691
|
-
{ name: "--line-height-md", value: "1.5" },
|
|
692
|
-
{ name: "--line-height-lg", value: "1.75" },
|
|
693
|
-
{ name: "--line-height-xl", value: "2" }
|
|
694
|
-
]
|
|
695
|
-
});
|
|
696
817
|
out = ensureScale(out, {
|
|
697
818
|
sectionComment: "Letter spacing",
|
|
698
819
|
anchorPrefixes: ["--letter-spacing-", "--line-height-", "--font-size-", "--font-"],
|
|
@@ -835,13 +956,113 @@ var tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions = {
|
|
|
835
956
|
}
|
|
836
957
|
};
|
|
837
958
|
|
|
959
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-07-20-line-height-rename.ts
|
|
960
|
+
var RENAMES = [
|
|
961
|
+
["--line-height-xs", "--line-height-none"],
|
|
962
|
+
["--line-height-sm", "--line-height-tighter"],
|
|
963
|
+
["--line-height-md", "--line-height-normal"],
|
|
964
|
+
["--line-height-lg", "--line-height-relaxed"]
|
|
965
|
+
];
|
|
966
|
+
var SCALE = [
|
|
967
|
+
{ name: "--line-height-none", value: "1" },
|
|
968
|
+
{ name: "--line-height-tightest", value: "1.1" },
|
|
969
|
+
{ name: "--line-height-tighter", value: "1.25" },
|
|
970
|
+
{ name: "--line-height-tight", value: "1.35" },
|
|
971
|
+
{ name: "--line-height-normal", value: "1.5" },
|
|
972
|
+
{ name: "--line-height-relaxed", value: "1.75" }
|
|
973
|
+
];
|
|
974
|
+
var tokensCssMigration_2026_07_20_lineHeightRename = {
|
|
975
|
+
id: "2026-07-20-line-height-rename",
|
|
976
|
+
kind: "breaking",
|
|
977
|
+
description: "Reshape --line-height-{xs..xl} to leading vocabulary (none/tightest/tighter/tight/normal/relaxed); retire the 2.0 slot",
|
|
978
|
+
apply(css) {
|
|
979
|
+
let out = css;
|
|
980
|
+
for (const [oldName, newName] of RENAMES) out = renameToken(out, oldName, newName);
|
|
981
|
+
out = removeToken(out, "--line-height-xl");
|
|
982
|
+
out = ensureScale(out, {
|
|
983
|
+
anchorPrefixes: ["--line-height-", "--font-size-", "--font-weight-", "--font-"],
|
|
984
|
+
entries: SCALE
|
|
985
|
+
});
|
|
986
|
+
return out;
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-07-20-semantic-text-styles.ts
|
|
991
|
+
var BUNDLE = [
|
|
992
|
+
{ name: "--heading-xl-font-family", value: "var(--font-display)" },
|
|
993
|
+
{ name: "--heading-xl-font-size", value: "var(--font-size-4xl)" },
|
|
994
|
+
{ name: "--heading-xl-font-weight", value: "var(--font-weight-semibold)" },
|
|
995
|
+
{ name: "--heading-xl-line-height", value: "var(--line-height-tightest)" },
|
|
996
|
+
{ name: "--heading-xl-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
997
|
+
{ name: "--heading-lg-font-family", value: "var(--font-display)" },
|
|
998
|
+
{ name: "--heading-lg-font-size", value: "var(--font-size-2xl)" },
|
|
999
|
+
{ name: "--heading-lg-font-weight", value: "var(--font-weight-semibold)" },
|
|
1000
|
+
{ name: "--heading-lg-line-height", value: "var(--line-height-tightest)" },
|
|
1001
|
+
{ name: "--heading-lg-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1002
|
+
{ name: "--heading-md-font-family", value: "var(--font-display)" },
|
|
1003
|
+
{ name: "--heading-md-font-size", value: "var(--font-size-xl)" },
|
|
1004
|
+
{ name: "--heading-md-font-weight", value: "var(--font-weight-semibold)" },
|
|
1005
|
+
{ name: "--heading-md-line-height", value: "var(--line-height-tighter)" },
|
|
1006
|
+
{ name: "--heading-md-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1007
|
+
{ name: "--heading-sm-font-family", value: "var(--font-sans)" },
|
|
1008
|
+
{ name: "--heading-sm-font-size", value: "var(--font-size-lg)" },
|
|
1009
|
+
{ name: "--heading-sm-font-weight", value: "var(--font-weight-semibold)" },
|
|
1010
|
+
{ name: "--heading-sm-line-height", value: "var(--line-height-tighter)" },
|
|
1011
|
+
{ name: "--heading-sm-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1012
|
+
{ name: "--body-md-font-family", value: "var(--font-sans)" },
|
|
1013
|
+
{ name: "--body-md-font-size", value: "var(--font-size-md)" },
|
|
1014
|
+
{ name: "--body-md-font-weight", value: "var(--font-weight-normal)" },
|
|
1015
|
+
{ name: "--body-md-line-height", value: "var(--line-height-normal)" },
|
|
1016
|
+
{ name: "--body-md-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1017
|
+
{ name: "--body-sm-font-family", value: "var(--font-sans)" },
|
|
1018
|
+
{ name: "--body-sm-font-size", value: "var(--font-size-sm)" },
|
|
1019
|
+
{ name: "--body-sm-font-weight", value: "var(--font-weight-normal)" },
|
|
1020
|
+
{ name: "--body-sm-line-height", value: "var(--line-height-tight)" },
|
|
1021
|
+
{ name: "--body-sm-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1022
|
+
{ name: "--code-font-family", value: "var(--font-mono)" },
|
|
1023
|
+
{ name: "--code-font-size", value: "var(--font-size-sm)" },
|
|
1024
|
+
{ name: "--code-font-weight", value: "var(--font-weight-normal)" },
|
|
1025
|
+
{ name: "--code-line-height", value: "var(--line-height-normal)" },
|
|
1026
|
+
{ name: "--code-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1027
|
+
{ name: "--eyebrow-font-family", value: "var(--font-sans)" },
|
|
1028
|
+
{ name: "--eyebrow-font-size", value: "var(--font-size-sm)" },
|
|
1029
|
+
{ name: "--eyebrow-font-weight", value: "var(--font-weight-normal)" },
|
|
1030
|
+
{ name: "--eyebrow-line-height", value: "var(--line-height-normal)" },
|
|
1031
|
+
{ name: "--eyebrow-letter-spacing", value: "var(--letter-spacing-normal)" },
|
|
1032
|
+
{ name: "--eyebrow-text-transform", value: "none" }
|
|
1033
|
+
];
|
|
1034
|
+
var tokensCssMigration_2026_07_20_semanticTextStyles = {
|
|
1035
|
+
id: "2026-07-20-semantic-text-styles",
|
|
1036
|
+
kind: "additive",
|
|
1037
|
+
description: "Add the semantic text-style bundles (--heading-*/--body-*/--code-*/--eyebrow-*)",
|
|
1038
|
+
apply(css) {
|
|
1039
|
+
return ensureScale(css, {
|
|
1040
|
+
sectionComment: "Text styles \u2014 semantic typography roles",
|
|
1041
|
+
anchorPrefixes: [
|
|
1042
|
+
"--eyebrow-",
|
|
1043
|
+
"--code-",
|
|
1044
|
+
"--body-",
|
|
1045
|
+
"--heading-",
|
|
1046
|
+
"--letter-spacing-",
|
|
1047
|
+
"--line-height-",
|
|
1048
|
+
"--font-weight-",
|
|
1049
|
+
"--font-size-",
|
|
1050
|
+
"--font-"
|
|
1051
|
+
],
|
|
1052
|
+
entries: BUNDLE
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
|
|
838
1057
|
// vite-plugin/tokensCssMigrations/index.ts
|
|
839
1058
|
var TOKENS_CSS_MIGRATIONS = [
|
|
840
1059
|
tokensCssMigration_2026_05_29_typographyScaleAdditions,
|
|
841
1060
|
tokensCssMigration_2026_05_29_sectiondividerLegacyAxisCleanup,
|
|
842
1061
|
tokensCssMigration_2026_06_03_transformScaleAdditions,
|
|
843
1062
|
tokensCssMigration_2026_06_04_removeDeadSizeIconScale,
|
|
844
|
-
tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions
|
|
1063
|
+
tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions,
|
|
1064
|
+
tokensCssMigration_2026_07_20_lineHeightRename,
|
|
1065
|
+
tokensCssMigration_2026_07_20_semanticTextStyles
|
|
845
1066
|
];
|
|
846
1067
|
function runTokensCssMigrations(css) {
|
|
847
1068
|
return foldMigrations(css, () => true);
|
|
@@ -1032,7 +1253,7 @@ function themeFileApi(opts) {
|
|
|
1032
1253
|
let themeVarCount = 0;
|
|
1033
1254
|
if (themeData) {
|
|
1034
1255
|
const cssVars = { ...themeData.cssVariables || {} };
|
|
1035
|
-
Object.assign(cssVars, palettesToVars(themeData.editorConfigs ?? {}));
|
|
1256
|
+
Object.assign(cssVars, palettesToVars(migratePaletteColorsToOklch(themeData.editorConfigs ?? {})));
|
|
1036
1257
|
const resolvedFontVars = resolveFontStacks(themeData);
|
|
1037
1258
|
for (const [name, value] of Object.entries(resolvedFontVars)) {
|
|
1038
1259
|
cssVars[name] = value;
|