@motion-proto/live-tokens 0.55.1 → 0.57.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 (107) hide show
  1. package/.claude/skills/{live-tokens-adjust-shape-space → live-tokens-adjust-geometry}/SKILL.md +5 -5
  2. package/.claude/skills/live-tokens-build-page/SKILL.md +2 -0
  3. package/.claude/skills/live-tokens-create-component/SKILL.md +20 -357
  4. package/.claude/skills/live-tokens-create-component/references/fixed-overlays.md +3 -0
  5. package/.claude/skills/live-tokens-create-component/references/intrinsics.md +58 -0
  6. package/.claude/skills/live-tokens-create-component/references/linked-siblings.md +70 -0
  7. package/.claude/skills/live-tokens-generate-theme/SKILL.md +79 -98
  8. package/.claude/skills/live-tokens-generate-theme/references/named-themes.md +18 -0
  9. package/.claude/skills/live-tokens-pair-fonts/SKILL.md +88 -0
  10. package/.claude/skills/live-tokens-pick-component/SKILL.md +4 -1
  11. package/CHANGELOG.md +197 -0
  12. package/README.md +21 -8
  13. package/bin/cli.mjs +42 -3
  14. package/bin/set-fonts.mjs +280 -0
  15. package/dist-plugin/adjust/index.cjs +1 -0
  16. package/dist-plugin/adjust/index.d.cts +3 -3
  17. package/dist-plugin/adjust/index.d.ts +3 -3
  18. package/dist-plugin/adjust/index.js +1 -1
  19. package/dist-plugin/{chunk-TKZBVIW5.js → chunk-E5QYON4L.js} +59 -2
  20. package/dist-plugin/{chunk-PB2JTK2H.js → chunk-LW4SR7AZ.js} +39 -6
  21. package/dist-plugin/{chunk-YR6GPXW2.js → chunk-XWXIMTWZ.js} +0 -5
  22. package/dist-plugin/{chunk-D3ZVKOR4.js → chunk-Y5CNFSSV.js} +1 -0
  23. package/dist-plugin/{dataPaths-DBN0RPuT.d.cts → dataPaths-CRfD1LdA.d.cts} +3 -0
  24. package/dist-plugin/{dataPaths-DBN0RPuT.d.ts → dataPaths-CRfD1LdA.d.ts} +3 -0
  25. package/dist-plugin/fontPairing/index.cjs +413 -0
  26. package/dist-plugin/fontPairing/index.d.cts +109 -0
  27. package/dist-plugin/fontPairing/index.d.ts +109 -0
  28. package/dist-plugin/fontPairing/index.js +321 -0
  29. package/dist-plugin/generateColorsAndType/index.cjs +22 -9
  30. package/dist-plugin/generateColorsAndType/index.d.cts +3 -3
  31. package/dist-plugin/generateColorsAndType/index.d.ts +3 -3
  32. package/dist-plugin/generateColorsAndType/index.js +8 -5
  33. package/dist-plugin/index-4N-Orzzi.d.cts +3 -0
  34. package/dist-plugin/index-4N-Orzzi.d.ts +3 -0
  35. package/dist-plugin/index.cjs +158 -9
  36. package/dist-plugin/index.d.cts +1 -1
  37. package/dist-plugin/index.d.ts +1 -1
  38. package/dist-plugin/index.js +71 -4
  39. package/dist-plugin/migrateData/index.cjs +1 -0
  40. package/dist-plugin/migrateData/index.d.cts +1 -1
  41. package/dist-plugin/migrateData/index.d.ts +1 -1
  42. package/dist-plugin/migrateData/index.js +1 -1
  43. package/dist-plugin/{index-DpTIRZ2H.d.cts → themeTypes-DSV3Zisf.d.cts} +13 -4
  44. package/dist-plugin/{index-DpTIRZ2H.d.ts → themeTypes-DSV3Zisf.d.ts} +13 -4
  45. package/dist-plugin/tokensCssMigrations/index.cjs +58 -1
  46. package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
  47. package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
  48. package/dist-plugin/tokensCssMigrations/index.js +3 -3
  49. package/package.json +5 -2
  50. package/src/editor/core/fonts/applyFontPairing.ts +158 -0
  51. package/src/editor/core/fonts/fontLoader.ts +1 -0
  52. package/src/editor/core/fonts/fontMigration.ts +31 -1
  53. package/src/editor/core/fonts/fontPairing.ts +13 -6
  54. package/src/editor/core/fonts/googleFontsUrl.ts +123 -0
  55. package/src/editor/core/fonts/weightCoverage.ts +92 -0
  56. package/src/editor/core/palettes/paletteDerivation.ts +9 -2
  57. package/src/editor/core/sketch/maskField.ts +381 -0
  58. package/src/editor/core/sketch/sketchLayer.ts +1028 -0
  59. package/src/editor/core/sketch/sketchPresetService.ts +65 -0
  60. package/src/editor/core/sketch/sketchPresets.ts +328 -0
  61. package/src/editor/core/sketch/sketchStore.ts +190 -0
  62. package/src/editor/core/store/editorPersistence.ts +28 -12
  63. package/src/editor/core/store/editorTypes.ts +4 -1
  64. package/src/editor/core/store/editorViewStore.ts +2 -2
  65. package/src/editor/core/store/gradientSource.ts +15 -1
  66. package/src/editor/core/themes/parsers/gradient.ts +62 -4
  67. package/src/editor/core/themes/slices/gradients.ts +75 -14
  68. package/src/editor/core/themes/themeTypes.ts +6 -1
  69. package/src/editor/docs/Docs.svelte +4 -3
  70. package/src/editor/docs/chapters.ts +1 -0
  71. package/src/editor/docs/content/01-overview.md +2 -1
  72. package/src/editor/docs/content/editing-tokens.md +5 -1
  73. package/src/editor/docs/content/sketch-mode.md +89 -0
  74. package/src/editor/docs/content/themes-workflow.md +39 -0
  75. package/src/editor/docs/content.generated.ts +4 -3
  76. package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
  77. package/src/editor/pages/EditorShell.svelte +43 -0
  78. package/src/editor/ui/EditorViewSwitcher.svelte +15 -2
  79. package/src/editor/ui/FontStackEditor.svelte +3 -0
  80. package/src/editor/ui/GradientEditor.svelte +38 -1
  81. package/src/editor/ui/ProjectFontsSection.svelte +24 -36
  82. package/src/editor/ui/UIReveal.svelte +7 -1
  83. package/src/editor/ui/UISegmentedControl.svelte +4 -8
  84. package/src/editor/ui/sections/GradientsSection.svelte +47 -1
  85. package/src/editor/ui/sketch/SketchDial.svelte +124 -0
  86. package/src/editor/ui/sketch/SketchPreview.svelte +119 -0
  87. package/src/editor/ui/sketch/SketchRange.svelte +185 -0
  88. package/src/editor/ui/sketch/SketchTab.svelte +1263 -0
  89. package/src/live-tokens/data/colors-and-type/autumn.json +17 -0
  90. package/src/live-tokens/data/colors-and-type/default.json +17 -0
  91. package/src/live-tokens/data/colors-and-type/halloween.json +17 -0
  92. package/src/live-tokens/data/colors-and-type/midnight-study.json +17 -0
  93. package/src/live-tokens/data/colors-and-type/ocean.json +17 -0
  94. package/src/live-tokens/data/colors-and-type/royal-velvet.json +17 -0
  95. package/src/live-tokens/data/colors-and-type/sketches.json +2520 -0
  96. package/src/live-tokens/data/colors-and-type/spring-meadow.json +17 -0
  97. package/src/live-tokens/data/colors-and-type/sunset.json +17 -0
  98. package/src/live-tokens/data/themes/autumn.json +17 -0
  99. package/src/live-tokens/data/themes/halloween.json +17 -0
  100. package/src/live-tokens/data/themes/midnight-study.json +17 -0
  101. package/src/live-tokens/data/themes/ocean.json +17 -0
  102. package/src/live-tokens/data/themes/royal-velvet.json +17 -0
  103. package/src/live-tokens/data/themes/sketches.json +3984 -0
  104. package/src/live-tokens/data/themes/spring-meadow.json +17 -0
  105. package/src/live-tokens/data/themes/sunset.json +17 -0
  106. package/src/live-tokens/data/tokens.generated.css +1 -0
  107. package/src/system/styles/tokens.css +15 -2
@@ -0,0 +1,321 @@
1
+ import {
2
+ readLiveTokensConfig,
3
+ resolveDataDirs
4
+ } from "../chunk-Y5CNFSSV.js";
5
+
6
+ // src/editor/core/fonts/fontParse.ts
7
+ function parseGoogleFontsUrl(url2) {
8
+ let u;
9
+ try {
10
+ u = new URL(url2);
11
+ } catch {
12
+ return null;
13
+ }
14
+ if (!u.hostname.includes("fonts.googleapis.com")) return null;
15
+ const familyParams = u.searchParams.getAll("family");
16
+ if (familyParams.length === 0) return null;
17
+ return familyParams.map((raw) => {
18
+ const [rawName, spec] = raw.split(":");
19
+ const name = decodeURIComponent(rawName).replace(/\+/g, " ");
20
+ const parsed = { name };
21
+ if (spec) {
22
+ const axisMatch = spec.match(/(?:ital,)?wght@([^&]+)/);
23
+ const italics = spec.startsWith("ital,");
24
+ if (italics) parsed.italics = true;
25
+ if (axisMatch) {
26
+ const tokens = axisMatch[1].split(";");
27
+ const weights = /* @__PURE__ */ new Set();
28
+ for (const tok of tokens) {
29
+ const parts = tok.split(",");
30
+ const wghtStr = parts.length === 2 ? parts[1] : parts[0];
31
+ if (wghtStr.includes("..")) {
32
+ const [lo, hi] = wghtStr.split("..").map((n) => parseInt(n, 10));
33
+ if (!isNaN(lo) && !isNaN(hi)) {
34
+ for (let w = lo; w <= hi; w += 100) weights.add(w);
35
+ }
36
+ } else {
37
+ const w = parseInt(wghtStr, 10);
38
+ if (!isNaN(w)) weights.add(w);
39
+ }
40
+ }
41
+ if (weights.size > 0) parsed.weights = [...weights].sort((a, b) => a - b);
42
+ }
43
+ }
44
+ return parsed;
45
+ });
46
+ }
47
+ function parseFontFaceText(css) {
48
+ const rules = [...css.matchAll(/@font-face\s*\{([^}]*)\}/g)];
49
+ const byName = /* @__PURE__ */ new Map();
50
+ for (const [, body] of rules) {
51
+ const nameMatch = body.match(/font-family\s*:\s*([^;]+);/i);
52
+ if (!nameMatch) continue;
53
+ const name = nameMatch[1].trim().replace(/^['"]|['"]$/g, "");
54
+ const weightMatch = body.match(/font-weight\s*:\s*([^;]+);/i);
55
+ const styleMatch = body.match(/font-style\s*:\s*([^;]+);/i);
56
+ const entry = byName.get(name) ?? { weights: /* @__PURE__ */ new Set(), italics: false };
57
+ if (weightMatch) {
58
+ const val = weightMatch[1].trim();
59
+ const rangeParts = val.split(/\s+/).map((s) => parseInt(s, 10)).filter((n) => !isNaN(n));
60
+ if (rangeParts.length === 2) {
61
+ const [lo, hi] = rangeParts;
62
+ for (let w = lo; w <= hi; w += 100) entry.weights.add(w);
63
+ } else if (rangeParts.length === 1) {
64
+ entry.weights.add(rangeParts[0]);
65
+ }
66
+ }
67
+ if (styleMatch && /italic|oblique/i.test(styleMatch[1])) entry.italics = true;
68
+ byName.set(name, entry);
69
+ }
70
+ return [...byName.entries()].map(([name, e]) => ({
71
+ name,
72
+ ...e.weights.size > 0 ? { weights: [...e.weights].sort((a, b) => a - b) } : {},
73
+ ...e.italics ? { italics: true } : {}
74
+ }));
75
+ }
76
+
77
+ // src/editor/core/fonts/fontPairing.ts
78
+ var PAIRING = ["--font-display", "--font-sans"];
79
+ function familyIndex(sources) {
80
+ const familyById = /* @__PURE__ */ new Map();
81
+ for (const source of sources) {
82
+ for (const family of source.families) familyById.set(family.id, family);
83
+ }
84
+ return familyById;
85
+ }
86
+ function resolvedFaceName(stack, familyById) {
87
+ for (const slot of stack?.slots ?? []) {
88
+ if (slot.kind === "project") {
89
+ const family = familyById.get(slot.familyId);
90
+ if (family) return family.name;
91
+ continue;
92
+ }
93
+ if (slot.kind === "system") return "System";
94
+ return slot.value;
95
+ }
96
+ return null;
97
+ }
98
+ function fontPairingLabel(stacks, sources) {
99
+ const familyById = familyIndex(sources);
100
+ return PAIRING.map((variable) => resolvedFaceName(stacks.find((s) => s.variable === variable), familyById)).filter((label) => label !== null).join(" / ");
101
+ }
102
+
103
+ // src/editor/core/fonts/applyFontPairing.ts
104
+ var SLOT_ORDER = ["display", "body", "serif", "mono", "editorial"];
105
+ var SLOT_VARIABLES = {
106
+ display: "--font-display",
107
+ body: "--font-sans",
108
+ serif: "--font-serif",
109
+ mono: "--font-mono",
110
+ editorial: "--font-editorial"
111
+ };
112
+ function slugifyFamily(name) {
113
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
114
+ }
115
+ function weightsFor(face) {
116
+ if (face.weights) {
117
+ return { weights: face.weights, ...face.italics ? { italics: true } : {} };
118
+ }
119
+ const parsed = parseGoogleFontsUrl(face.url)?.[0];
120
+ return {
121
+ ...parsed?.weights ? { weights: parsed.weights } : {},
122
+ ...face.italics || parsed?.italics ? { italics: true } : {}
123
+ };
124
+ }
125
+ function sourceFor(face, idPrefix) {
126
+ const id = `${idPrefix}${slugifyFamily(face.name)}`;
127
+ return {
128
+ id,
129
+ kind: "google",
130
+ url: face.url,
131
+ label: "Google Fonts",
132
+ families: [
133
+ {
134
+ id: `${id}:${slugifyFamily(face.name)}`,
135
+ name: face.name,
136
+ cssName: `"${face.name}"`,
137
+ ...weightsFor(face)
138
+ }
139
+ ]
140
+ };
141
+ }
142
+ function rewriteStack(stacks, variable, familyId) {
143
+ const stack = stacks.find((s) => s.variable === variable);
144
+ if (!stack) throw new Error(`colors and type have no ${variable} stack to rewrite`);
145
+ return stacks.map(
146
+ (s) => s === stack ? { ...s, slots: [{ kind: "project", familyId }, ...s.slots.filter((slot) => slot.kind !== "project")] } : s
147
+ );
148
+ }
149
+ function applyFontPairing(colorsAndType, pairing, { idPrefix = "src_google_" } = {}) {
150
+ const slots = SLOT_ORDER.filter((slot) => pairing[slot]);
151
+ if (slots.length === 0) throw new Error("pairing names no slot to change");
152
+ const before = colorsAndType.fontStacks ?? [];
153
+ const beforeSources = colorsAndType.fontSources ?? [];
154
+ const beforeIndex = familyIndex(beforeSources);
155
+ const stamped = slots.map((slot) => ({ slot, source: sourceFor(pairing[slot], idPrefix) }));
156
+ const stampedIds = new Set(stamped.map((s) => s.source.id));
157
+ let stacks = before;
158
+ const changes = [];
159
+ for (const { slot, source } of stamped) {
160
+ const variable = SLOT_VARIABLES[slot];
161
+ const from = resolvedFaceName(before.find((s) => s.variable === variable), beforeIndex);
162
+ stacks = rewriteStack(stacks, variable, source.families[0].id);
163
+ changes.push({ slot, variable, from, to: source.families[0].name });
164
+ }
165
+ const referenced = new Set(
166
+ stacks.flatMap((s) => s.slots).filter((s) => s.kind === "project").map((s) => s.familyId)
167
+ );
168
+ const kept = [...beforeSources.filter((s) => !stampedIds.has(s.id)), ...stamped.map((s) => s.source)];
169
+ const sources = kept.filter((s) => s.families.some((f) => referenced.has(f.id)));
170
+ const dropped = kept.filter((s) => !sources.includes(s)).map((s) => ({ id: s.id, names: s.families.map((f) => f.name) }));
171
+ const next = { ...colorsAndType, fontSources: sources, fontStacks: stacks };
172
+ const changed = JSON.stringify([beforeSources, before]) !== JSON.stringify([sources, stacks]);
173
+ return {
174
+ colorsAndType: next,
175
+ report: { changes: changes.filter((c) => c.from !== c.to), dropped, changed }
176
+ };
177
+ }
178
+
179
+ // src/editor/core/fonts/googleFontsUrl.ts
180
+ var LADDER = [100, 200, 300, 400, 500, 600, 700, 800, 900];
181
+ function familyParam(name) {
182
+ return name.trim().replace(/\s+/g, "+");
183
+ }
184
+ function url(name, spec) {
185
+ const family = spec ? `${familyParam(name)}:${spec}` : familyParam(name);
186
+ return `https://fonts.googleapis.com/css2?family=${family}&display=swap`;
187
+ }
188
+ function discoveryUrl(name) {
189
+ const pairs = [
190
+ ...LADDER.map((w) => `0,${w}`),
191
+ ...LADDER.map((w) => `1,${w}`)
192
+ ];
193
+ return url(name, `ital,wght@${pairs.join(";")}`);
194
+ }
195
+ function isContiguous(weights) {
196
+ return weights.length > 1 && weights.every((w, i) => i === 0 || w - weights[i - 1] === 100);
197
+ }
198
+ function persistUrlFor(name, weights, italics) {
199
+ if (weights.length === 0 || weights.length === 1 && weights[0] === 400 && !italics) {
200
+ return url(name);
201
+ }
202
+ if (isContiguous(weights)) {
203
+ const range = `${weights[0]}..${weights[weights.length - 1]}`;
204
+ return url(name, italics ? `ital,wght@0,${range};1,${range}` : `wght@${range}`);
205
+ }
206
+ const spec = italics ? `ital,wght@${[...weights.map((w) => `0,${w}`), ...weights.map((w) => `1,${w}`)].join(";")}` : `wght@${weights.join(";")}`;
207
+ return url(name, spec);
208
+ }
209
+ function censusFrom(css, requested) {
210
+ const families = parseFontFaceText(css);
211
+ if (families.length === 0) {
212
+ throw new Error(`Google Fonts returned no @font-face rules for "${requested}".`);
213
+ }
214
+ const family = families[0];
215
+ return {
216
+ name: family.name,
217
+ weights: family.weights ?? [],
218
+ italics: family.italics === true
219
+ };
220
+ }
221
+ async function resolveGoogleFont(name, fetcher) {
222
+ const probeUrl = discoveryUrl(name);
223
+ const probe = await fetcher(probeUrl);
224
+ if (!probe.ok) {
225
+ throw new Error(
226
+ `"${name}" is not on Google Fonts (the API answered ${probe.status}). Check the spelling against fonts.google.com.`
227
+ );
228
+ }
229
+ const census = censusFrom(await probe.text(), name);
230
+ const candidates = [persistUrlFor(census.name, census.weights, census.italics)];
231
+ const enumerated = census.weights.length > 0 ? url(
232
+ census.name,
233
+ census.italics ? `ital,wght@${[...census.weights.map((w) => `0,${w}`), ...census.weights.map((w) => `1,${w}`)].join(";")}` : `wght@${census.weights.join(";")}`
234
+ ) : null;
235
+ if (enumerated && !candidates.includes(enumerated)) candidates.push(enumerated);
236
+ const bare = url(census.name);
237
+ if (!candidates.includes(bare)) candidates.push(bare);
238
+ for (const candidate of candidates) {
239
+ const res = await fetcher(candidate);
240
+ if (!res.ok) continue;
241
+ const served = censusFrom(await res.text(), census.name);
242
+ return {
243
+ name: census.name,
244
+ url: candidate,
245
+ weights: served.weights,
246
+ italics: served.italics,
247
+ probeUrl
248
+ };
249
+ }
250
+ throw new Error(`Could not build a working Google Fonts URL for "${census.name}".`);
251
+ }
252
+
253
+ // src/editor/core/fonts/fontWeightAvailability.ts
254
+ function inferFontFamilyVariable(weightVariable) {
255
+ return weightVariable.endsWith("-font-weight") ? `${weightVariable.slice(0, -"-font-weight".length)}-font-family` : null;
256
+ }
257
+
258
+ // src/editor/core/fonts/weightCoverage.ts
259
+ var STACK_REF = /var\(\s*(--font-(?:display|sans|serif|mono))\s*\)/;
260
+ var VAR_REF = /var\(\s*(--[a-z0-9-]+)/i;
261
+ function declarations(css) {
262
+ const decls = /* @__PURE__ */ new Map();
263
+ for (const [, name, value] of css.matchAll(/(--[a-z0-9-]+)\s*:\s*([^;{}]+);/gi)) {
264
+ decls.set(name, value.trim());
265
+ }
266
+ return decls;
267
+ }
268
+ function requiredWeights(tokensCss, overrides = {}) {
269
+ const decls = declarations(tokensCss);
270
+ for (const [name, value] of Object.entries(overrides)) decls.set(name, String(value).trim());
271
+ const scale = /* @__PURE__ */ new Map();
272
+ for (const [name, value] of decls) {
273
+ if (name.startsWith("--font-weight-") && /^\d+$/.test(value)) scale.set(name, Number(value));
274
+ }
275
+ const seen = /* @__PURE__ */ new Set();
276
+ const out = [];
277
+ for (const [name, value] of decls) {
278
+ const familyVariable = inferFontFamilyVariable(name);
279
+ if (!familyVariable) continue;
280
+ const stack = decls.get(familyVariable)?.match(STACK_REF)?.[1];
281
+ if (!stack) continue;
282
+ const weight = /^\d+$/.test(value) ? Number(value) : scale.get(value.match(VAR_REF)?.[1] ?? "");
283
+ if (weight === void 0) continue;
284
+ const key = `${stack}:${weight}`;
285
+ if (seen.has(key)) continue;
286
+ seen.add(key);
287
+ out.push({ variable: name, stack, weight });
288
+ }
289
+ return out;
290
+ }
291
+ function weightCoverage(requirements, faces) {
292
+ const out = [];
293
+ for (const [stack, face] of Object.entries(faces)) {
294
+ const required = [...new Set(requirements.filter((r) => r.stack === stack).map((r) => r.weight))].sort(
295
+ (a, b) => a - b
296
+ );
297
+ out.push({
298
+ stack,
299
+ family: face.name,
300
+ required,
301
+ available: face.weights,
302
+ missing: required.filter((w) => !face.weights.includes(w)),
303
+ italics: face.italics
304
+ });
305
+ }
306
+ return out;
307
+ }
308
+ export {
309
+ SLOT_ORDER,
310
+ SLOT_VARIABLES,
311
+ applyFontPairing,
312
+ discoveryUrl,
313
+ fontPairingLabel,
314
+ persistUrlFor,
315
+ readLiveTokensConfig,
316
+ requiredWeights,
317
+ resolveDataDirs,
318
+ resolveGoogleFont,
319
+ slugifyFamily,
320
+ weightCoverage
321
+ };
@@ -139,10 +139,6 @@ function oklchToCss(l, c, h) {
139
139
  const cs = trim(c, 4);
140
140
  return `oklch(${trim(l, 4)} ${cs} ${cs === "0" ? "0" : trim(h, 2)})`;
141
141
  }
142
- function oklchToCssClamped(l, c, h) {
143
- const g = gamutClamp(l, c, h);
144
- return oklchToCss(g.l, g.c, g.h);
145
- }
146
142
  var OKLCH_RE = /^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)(%?)\s+([\d.]+)(?:deg)?\s*\)$/i;
147
143
  var HEX6_RE = /^#[0-9a-f]{6}$/i;
148
144
  function parseOklchCss(value) {
@@ -336,7 +332,7 @@ function scaleStepToX(step, scale) {
336
332
  return scale.steps.length > 1 ? idx / (scale.steps.length - 1) * 100 : 50;
337
333
  }
338
334
  function serializeDerivedValue(value) {
339
- return value.kind === "raw" ? value.css : oklchToCssClamped(value.l, value.c, value.h);
335
+ return value.kind === "raw" ? value.css : oklchToCss(value.l, value.c, value.h);
340
336
  }
341
337
  function computePaletteOklch(index, base, lightnessCurve, saturationCurve, curveOffset, hueCurve) {
342
338
  const { c: baseC } = base;
@@ -609,6 +605,16 @@ function formatColorOpacity(name, opacity) {
609
605
  }
610
606
 
611
607
  // src/editor/core/themes/parsers/gradient.ts
608
+ var DIRECTION_ANGLES = {
609
+ "to top": 0,
610
+ "to top right": 45,
611
+ "to right": 90,
612
+ "to bottom right": 135,
613
+ "to bottom": 180,
614
+ "to bottom left": 225,
615
+ "to left": 270,
616
+ "to top left": 315
617
+ };
612
618
  var RADIAL_BASE_PX = 100;
613
619
  function formatStopColor(s) {
614
620
  const opacity = s.opacity ?? 100;
@@ -636,11 +642,15 @@ function formatGradientValue(v) {
636
642
  return first ? formatStopColor(first) : "transparent";
637
643
  }
638
644
  const stops = formatGradientStops(v.stops);
639
- if (v.type === "linear") return `linear-gradient(${v.angle}deg, ${stops})`;
645
+ if (v.type === "linear") {
646
+ return `linear-gradient(${v.direction ?? `${v.angle}deg`}, ${stops})`;
647
+ }
640
648
  return `radial-gradient(${formatRadialShape(v)} at ${v.centerX ?? 50}% 50%, ${stops})`;
641
649
  }
642
650
  var NUM = String.raw`-?\d+(?:\.\d+)?`;
643
- var LINEAR_RE = new RegExp(String.raw`^linear-gradient\(\s*(${NUM})deg\s*,\s*(.+)\)$`, "i");
651
+ var HEADING = String.raw`${NUM}deg|to\s+\w+(?:\s+\w+)?`;
652
+ var LINEAR_RE = new RegExp(String.raw`^linear-gradient\(\s*(${HEADING})\s*,\s*(.+)\)$`, "i");
653
+ var DEG_RE = new RegExp(String.raw`^(${NUM})deg$`, "i");
644
654
  var RADIAL_RE = new RegExp(
645
655
  String.raw`^radial-gradient\(\s*(circle|circle\s+${NUM}px|ellipse\s+${NUM}px\s+${NUM}px)\s+at\s+(${NUM})%\s+50%\s*,\s*(.+)\)$`,
646
656
  "i"
@@ -655,7 +665,8 @@ function makeDefaultGradients() {
655
665
  {
656
666
  variable: "--gradient-1",
657
667
  type: "linear",
658
- angle: 90,
668
+ angle: DIRECTION_ANGLES["to right"],
669
+ direction: "to right",
659
670
  stops: [
660
671
  { position: 0, color: "--color-brand-500" },
661
672
  { position: 100, color: "--color-accent-500" }
@@ -673,7 +684,8 @@ function makeDefaultGradients() {
673
684
  {
674
685
  variable: "--gradient-3",
675
686
  type: "linear",
676
- angle: 90,
687
+ angle: DIRECTION_ANGLES["to right"],
688
+ direction: "to right",
677
689
  stops: [
678
690
  { position: 0, color: "--color-success-500" },
679
691
  { position: 100, color: "--color-info-500" }
@@ -1914,6 +1926,7 @@ function resolveDataDirs(opts = {}) {
1914
1926
  colorsAndTypeDir: opts.colorsAndTypeDir ? import_path.default.resolve(opts.colorsAndTypeDir) : fileConfig.colorsAndTypeDir ? import_path.default.resolve(fileConfig.colorsAndTypeDir) : sub("colors-and-type"),
1915
1927
  componentConfigsDir: opts.componentConfigsDir ? import_path.default.resolve(opts.componentConfigsDir) : fileConfig.componentConfigsDir ? import_path.default.resolve(fileConfig.componentConfigsDir) : sub("component-configs"),
1916
1928
  themesDir: opts.themesDir ? import_path.default.resolve(opts.themesDir) : fileConfig.themesDir ? import_path.default.resolve(fileConfig.themesDir) : sub("themes"),
1929
+ sketchPresetsDir: sub("sketch-presets"),
1917
1930
  legacyManifestsDir: fileConfig.manifestsDir ? import_path.default.resolve(fileConfig.manifestsDir) : void 0
1918
1931
  };
1919
1932
  }
@@ -1,6 +1,6 @@
1
- import { F as FontSource, c as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, a as ColorsAndType } from '../index-DpTIRZ2H.cjs';
2
- export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-DpTIRZ2H.cjs';
3
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-DBN0RPuT.cjs';
1
+ import { F as FontSource, b as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, C as ColorsAndType } from '../themeTypes-DSV3Zisf.cjs';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-CRfD1LdA.cjs';
3
+ export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.cjs';
4
4
 
5
5
  /**
6
6
  * Pure palette → CSS-variable derivation.
@@ -1,6 +1,6 @@
1
- import { F as FontSource, c as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, a as ColorsAndType } from '../index-DpTIRZ2H.js';
2
- export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-DpTIRZ2H.js';
3
- export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-DBN0RPuT.js';
1
+ import { F as FontSource, b as FontStack, G as GradientDiskToken, O as Oklch, H as HarmonyMode, C as ColorsAndType } from '../themeTypes-DSV3Zisf.js';
2
+ export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-CRfD1LdA.js';
3
+ export { C as CURRENT_COMPONENT_SCHEMA_VERSION } from '../index-4N-Orzzi.js';
4
4
 
5
5
  /**
6
6
  * Pure palette → CSS-variable derivation.
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  DEFAULT_PALETTE_LIGHTNESS,
3
3
  DEFAULT_PALETTE_SATURATION,
4
+ DIRECTION_ANGLES,
4
5
  PALETTE_SPECS,
5
6
  PALETTE_STEPS,
6
7
  SCALES,
@@ -14,7 +15,7 @@ import {
14
15
  scaleToCssVar,
15
16
  setCurveAnchor,
16
17
  syncBaseAnchor
17
- } from "../chunk-PB2JTK2H.js";
18
+ } from "../chunk-LW4SR7AZ.js";
18
19
  import {
19
20
  CURRENT_COLORS_AND_TYPE_SCHEMA_VERSION,
20
21
  CURRENT_COMPONENT_SCHEMA_VERSION
@@ -25,11 +26,11 @@ import {
25
26
  hexToOklch,
26
27
  oklchToHex,
27
28
  oklchToHexClamped
28
- } from "../chunk-YR6GPXW2.js";
29
+ } from "../chunk-XWXIMTWZ.js";
29
30
  import {
30
31
  readLiveTokensConfig,
31
32
  resolveDataDirs
32
- } from "../chunk-D3ZVKOR4.js";
33
+ } from "../chunk-Y5CNFSSV.js";
33
34
 
34
35
  // src/editor/core/store/editorCore.ts
35
36
  import { writable, derived, get } from "svelte/store";
@@ -50,7 +51,8 @@ function makeDefaultGradients() {
50
51
  {
51
52
  variable: "--gradient-1",
52
53
  type: "linear",
53
- angle: 90,
54
+ angle: DIRECTION_ANGLES["to right"],
55
+ direction: "to right",
54
56
  stops: [
55
57
  { position: 0, color: "--color-brand-500" },
56
58
  { position: 100, color: "--color-accent-500" }
@@ -68,7 +70,8 @@ function makeDefaultGradients() {
68
70
  {
69
71
  variable: "--gradient-3",
70
72
  type: "linear",
71
- angle: 90,
73
+ angle: DIRECTION_ANGLES["to right"],
74
+ direction: "to right",
72
75
  stops: [
73
76
  { position: 0, color: "--color-success-500" },
74
77
  { position: 100, color: "--color-info-500" }
@@ -0,0 +1,3 @@
1
+ declare const CURRENT_COMPONENT_SCHEMA_VERSION: number;
2
+
3
+ export { CURRENT_COMPONENT_SCHEMA_VERSION as C };
@@ -0,0 +1,3 @@
1
+ declare const CURRENT_COMPONENT_SCHEMA_VERSION: number;
2
+
3
+ export { CURRENT_COMPONENT_SCHEMA_VERSION as C };