@wow-two-beta/ui 0.0.64 → 0.0.65
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/dist/{chunk-NIFL35PJ.js → chunk-3BNEDKMS.js} +3 -3
- package/dist/{chunk-NIFL35PJ.js.map → chunk-3BNEDKMS.js.map} +1 -1
- package/dist/chunk-LS4EGKUK.js +1656 -0
- package/dist/chunk-LS4EGKUK.js.map +1 -0
- package/dist/forms/index.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -4
- package/dist/layout/index.js +3 -3
- package/dist/themes/Oklch.d.ts +42 -0
- package/dist/themes/Theme.d.ts +76 -0
- package/dist/themes/Tokens.d.ts +40 -0
- package/dist/themes/css.d.ts +20 -0
- package/dist/themes/generate.d.ts +6 -0
- package/dist/themes/index.d.ts +11 -0
- package/dist/themes/index.js +4 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/themes/pool.d.ts +3 -0
- package/dist/themes/registry.d.ts +16 -0
- package/dist/themes/validate.d.ts +25 -0
- package/dist/themes/validated.d.ts +3 -0
- package/dist/themes.css +15374 -0
- package/dist/themes.json +2898 -0
- package/package.json +9 -2
|
@@ -0,0 +1,1656 @@
|
|
|
1
|
+
import { __export } from './chunk-DCHYNTHI.js';
|
|
2
|
+
|
|
3
|
+
// src/themes/index.ts
|
|
4
|
+
var themes_exports = {};
|
|
5
|
+
__export(themes_exports, {
|
|
6
|
+
AA_TEXT: () => AA_TEXT,
|
|
7
|
+
AA_UI: () => AA_UI,
|
|
8
|
+
Oklch: () => Oklch,
|
|
9
|
+
SEMANTIC_TOKENS: () => SEMANTIC_TOKENS,
|
|
10
|
+
SURFACE_TOKENS: () => SURFACE_TOKENS,
|
|
11
|
+
THEMES: () => THEMES,
|
|
12
|
+
THEME_IDS: () => THEME_IDS,
|
|
13
|
+
THEME_SEEDS: () => THEME_SEEDS,
|
|
14
|
+
TONE_FAMILIES: () => TONE_FAMILIES,
|
|
15
|
+
ThemeStatus: () => ThemeStatus,
|
|
16
|
+
applyToneSlots: () => applyToneSlots,
|
|
17
|
+
candidateThemes: () => candidateThemes,
|
|
18
|
+
clampChromaToGamut: () => clampChromaToGamut,
|
|
19
|
+
contrastPairs: () => contrastPairs,
|
|
20
|
+
contrastRatio: () => contrastRatio,
|
|
21
|
+
contrastRatioCss: () => contrastRatioCss,
|
|
22
|
+
emitAllThemesCss: () => emitAllThemesCss,
|
|
23
|
+
emitThemesManifest: () => emitThemesManifest,
|
|
24
|
+
generateTheme: () => generateTheme,
|
|
25
|
+
getTheme: () => getTheme,
|
|
26
|
+
isInSrgbGamut: () => isInSrgbGamut,
|
|
27
|
+
normalizeHue: () => normalizeHue,
|
|
28
|
+
oklchToCss: () => oklchToCss,
|
|
29
|
+
oklchToHex: () => oklchToHex,
|
|
30
|
+
parseColor: () => parseColor,
|
|
31
|
+
relativeLuminance: () => relativeLuminance,
|
|
32
|
+
themeToCss: () => themeToCss,
|
|
33
|
+
validateTheme: () => validateTheme,
|
|
34
|
+
validatedThemes: () => validatedThemes
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// src/themes/Oklch.ts
|
|
38
|
+
var clamp01 = (x) => x < 0 ? 0 : x > 1 ? 1 : x;
|
|
39
|
+
function normalizeHue(h) {
|
|
40
|
+
const m = h % 360;
|
|
41
|
+
return m < 0 ? m + 360 : m;
|
|
42
|
+
}
|
|
43
|
+
function oklchToLinearRgb({ l, c, h }) {
|
|
44
|
+
const hr = normalizeHue(h) * Math.PI / 180;
|
|
45
|
+
const a = Math.cos(hr) * c;
|
|
46
|
+
const b = Math.sin(hr) * c;
|
|
47
|
+
const l_ = l + 0.3963377774 * a + 0.2158037573 * b;
|
|
48
|
+
const m_ = l - 0.1055613458 * a - 0.0638541728 * b;
|
|
49
|
+
const s_ = l - 0.0894841775 * a - 1.291485548 * b;
|
|
50
|
+
const l3 = l_ * l_ * l_;
|
|
51
|
+
const m3 = m_ * m_ * m_;
|
|
52
|
+
const s3 = s_ * s_ * s_;
|
|
53
|
+
return {
|
|
54
|
+
r: 4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3,
|
|
55
|
+
g: -1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3,
|
|
56
|
+
b: -0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function linearToSrgbChannel(x) {
|
|
60
|
+
const v = clamp01(x);
|
|
61
|
+
return v <= 31308e-7 ? 12.92 * v : 1.055 * Math.pow(v, 1 / 2.4) - 0.055;
|
|
62
|
+
}
|
|
63
|
+
function srgbToLinearChannel(x) {
|
|
64
|
+
return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
|
|
65
|
+
}
|
|
66
|
+
function linearRgbToSrgb(rgb) {
|
|
67
|
+
return {
|
|
68
|
+
r: linearToSrgbChannel(rgb.r),
|
|
69
|
+
g: linearToSrgbChannel(rgb.g),
|
|
70
|
+
b: linearToSrgbChannel(rgb.b)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function isInSrgbGamut(color) {
|
|
74
|
+
const { r, g, b } = oklchToLinearRgb(color);
|
|
75
|
+
const eps = 1e-4;
|
|
76
|
+
return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;
|
|
77
|
+
}
|
|
78
|
+
function clampChromaToGamut(color) {
|
|
79
|
+
if (isInSrgbGamut(color)) return color;
|
|
80
|
+
let lo = 0;
|
|
81
|
+
let hi = color.c;
|
|
82
|
+
for (let i = 0; i < 24; i++) {
|
|
83
|
+
const mid = (lo + hi) / 2;
|
|
84
|
+
if (isInSrgbGamut({ l: color.l, c: mid, h: color.h })) lo = mid;
|
|
85
|
+
else hi = mid;
|
|
86
|
+
}
|
|
87
|
+
return { l: color.l, c: lo, h: color.h };
|
|
88
|
+
}
|
|
89
|
+
function to2Hex(v) {
|
|
90
|
+
return Math.round(clamp01(v) * 255).toString(16).padStart(2, "0");
|
|
91
|
+
}
|
|
92
|
+
function oklchToHex(color) {
|
|
93
|
+
const safe = clampChromaToGamut(color);
|
|
94
|
+
const { r, g, b } = linearRgbToSrgb(oklchToLinearRgb(safe));
|
|
95
|
+
return `#${to2Hex(r)}${to2Hex(g)}${to2Hex(b)}`;
|
|
96
|
+
}
|
|
97
|
+
function oklchToCss(color) {
|
|
98
|
+
const safe = clampChromaToGamut(color);
|
|
99
|
+
const l = (clamp01(safe.l) * 100).toFixed(1);
|
|
100
|
+
const c = Math.max(0, safe.c).toFixed(4);
|
|
101
|
+
const h = normalizeHue(safe.h).toFixed(1);
|
|
102
|
+
return `oklch(${l}% ${c} ${h})`;
|
|
103
|
+
}
|
|
104
|
+
function parseHex(hex) {
|
|
105
|
+
let h = hex.trim().replace(/^#/, "");
|
|
106
|
+
if (h.length === 3) {
|
|
107
|
+
h = h.replace(/(.)/g, "$1$1");
|
|
108
|
+
}
|
|
109
|
+
if (h.length !== 6 || /[^0-9a-fA-F]/.test(h)) return null;
|
|
110
|
+
return {
|
|
111
|
+
r: parseInt(h.slice(0, 2), 16) / 255,
|
|
112
|
+
g: parseInt(h.slice(2, 4), 16) / 255,
|
|
113
|
+
b: parseInt(h.slice(4, 6), 16) / 255
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function relativeLuminanceFromSrgb({ r, g, b }) {
|
|
117
|
+
const R = srgbToLinearChannel(r);
|
|
118
|
+
const G = srgbToLinearChannel(g);
|
|
119
|
+
const B = srgbToLinearChannel(b);
|
|
120
|
+
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
|
121
|
+
}
|
|
122
|
+
function relativeLuminance(color) {
|
|
123
|
+
return relativeLuminanceFromSrgb(linearRgbToSrgb(oklchToLinearRgb(clampChromaToGamut(color))));
|
|
124
|
+
}
|
|
125
|
+
function contrastFromLuminances(l1, l2) {
|
|
126
|
+
const hi = Math.max(l1, l2);
|
|
127
|
+
const lo = Math.min(l1, l2);
|
|
128
|
+
return (hi + 0.05) / (lo + 0.05);
|
|
129
|
+
}
|
|
130
|
+
function contrastRatio(a, b) {
|
|
131
|
+
return contrastFromLuminances(relativeLuminance(a), relativeLuminance(b));
|
|
132
|
+
}
|
|
133
|
+
function contrastRatioCss(a, b) {
|
|
134
|
+
const ca = parseColor(a);
|
|
135
|
+
const cb = parseColor(b);
|
|
136
|
+
if (!ca || !cb) return 1;
|
|
137
|
+
return contrastRatio(ca, cb);
|
|
138
|
+
}
|
|
139
|
+
var OKLCH_RE = /^oklch\(\s*([\d.]+)%?\s+([\d.]+)\s+([\d.]+)\s*\)$/i;
|
|
140
|
+
function parseColor(value) {
|
|
141
|
+
const v = value.trim();
|
|
142
|
+
const m = OKLCH_RE.exec(v);
|
|
143
|
+
if (m && m[1] && m[2] && m[3]) {
|
|
144
|
+
const lRaw = parseFloat(m[1]);
|
|
145
|
+
const l = v.includes("%") ? lRaw / 100 : lRaw;
|
|
146
|
+
return { l, c: parseFloat(m[2]), h: parseFloat(m[3]) };
|
|
147
|
+
}
|
|
148
|
+
if (v.startsWith("#")) {
|
|
149
|
+
const srgb = parseHex(v);
|
|
150
|
+
if (!srgb) return null;
|
|
151
|
+
return srgbToOklch(srgb);
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
function srgbToOklch(srgb) {
|
|
156
|
+
const r = srgbToLinearChannel(srgb.r);
|
|
157
|
+
const g = srgbToLinearChannel(srgb.g);
|
|
158
|
+
const b = srgbToLinearChannel(srgb.b);
|
|
159
|
+
const l_ = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
160
|
+
const m_ = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
161
|
+
const s_ = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
162
|
+
const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
|
|
163
|
+
const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
|
|
164
|
+
const bb = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
|
|
165
|
+
const c = Math.hypot(a, bb);
|
|
166
|
+
const h = normalizeHue(Math.atan2(bb, a) * 180 / Math.PI);
|
|
167
|
+
return { l: L, c, h };
|
|
168
|
+
}
|
|
169
|
+
var Oklch = {
|
|
170
|
+
normalizeHue,
|
|
171
|
+
isInSrgbGamut,
|
|
172
|
+
clampChromaToGamut,
|
|
173
|
+
oklchToHex,
|
|
174
|
+
oklchToCss,
|
|
175
|
+
parseColor,
|
|
176
|
+
relativeLuminance,
|
|
177
|
+
contrastRatio,
|
|
178
|
+
contrastRatioCss
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// src/themes/Tokens.ts
|
|
182
|
+
var TONE_FAMILIES = [
|
|
183
|
+
"primary",
|
|
184
|
+
"accent",
|
|
185
|
+
"destructive",
|
|
186
|
+
"info",
|
|
187
|
+
"success",
|
|
188
|
+
"warning"
|
|
189
|
+
];
|
|
190
|
+
var SURFACE_TOKENS = [
|
|
191
|
+
"background",
|
|
192
|
+
"foreground",
|
|
193
|
+
"card",
|
|
194
|
+
"card-foreground",
|
|
195
|
+
"popover",
|
|
196
|
+
"popover-foreground",
|
|
197
|
+
"muted",
|
|
198
|
+
"muted-foreground",
|
|
199
|
+
"subtle-foreground",
|
|
200
|
+
"inverse",
|
|
201
|
+
"inverse-foreground",
|
|
202
|
+
"border",
|
|
203
|
+
"border-strong",
|
|
204
|
+
"input",
|
|
205
|
+
"ring"
|
|
206
|
+
];
|
|
207
|
+
var SEMANTIC_TOKENS = [
|
|
208
|
+
...SURFACE_TOKENS,
|
|
209
|
+
...TONE_FAMILIES.flatMap(
|
|
210
|
+
(f) => [f, `${f}-foreground`, `${f}-soft`, `${f}-soft-foreground`]
|
|
211
|
+
)
|
|
212
|
+
];
|
|
213
|
+
function applyToneSlots(target, family, slots) {
|
|
214
|
+
target[family] = slots.base;
|
|
215
|
+
target[`${family}-foreground`] = slots.foreground;
|
|
216
|
+
target[`${family}-soft`] = slots.soft;
|
|
217
|
+
target[`${family}-soft-foreground`] = slots.softForeground;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/themes/Theme.ts
|
|
221
|
+
var ThemeStatus = {
|
|
222
|
+
Validated: "validated",
|
|
223
|
+
Candidate: "candidate"
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// src/themes/validate.ts
|
|
227
|
+
var AA_TEXT = 4.5;
|
|
228
|
+
var AA_UI = 3;
|
|
229
|
+
function contrastPairs() {
|
|
230
|
+
const pairs = [
|
|
231
|
+
{ fg: "foreground", bg: "background", min: AA_TEXT },
|
|
232
|
+
{ fg: "card-foreground", bg: "card", min: AA_TEXT },
|
|
233
|
+
{ fg: "popover-foreground", bg: "popover", min: AA_TEXT },
|
|
234
|
+
{ fg: "muted-foreground", bg: "muted", min: AA_TEXT },
|
|
235
|
+
{ fg: "subtle-foreground", bg: "background", min: AA_UI },
|
|
236
|
+
{ fg: "inverse-foreground", bg: "inverse", min: AA_TEXT },
|
|
237
|
+
// Focus ring is a UI affordance against the page → AA_UI.
|
|
238
|
+
{ fg: "ring", bg: "background", min: AA_UI }
|
|
239
|
+
];
|
|
240
|
+
for (const f of TONE_FAMILIES) {
|
|
241
|
+
pairs.push({ fg: `${f}-foreground`, bg: f, min: AA_TEXT });
|
|
242
|
+
pairs.push({ fg: `${f}-soft-foreground`, bg: `${f}-soft`, min: AA_TEXT });
|
|
243
|
+
}
|
|
244
|
+
return pairs;
|
|
245
|
+
}
|
|
246
|
+
function checkMode(set, mode) {
|
|
247
|
+
const failures = [];
|
|
248
|
+
for (const { fg, bg, min } of contrastPairs()) {
|
|
249
|
+
const ratio = contrastRatioCss(set[fg], set[bg]);
|
|
250
|
+
if (ratio + 1e-3 < min) {
|
|
251
|
+
failures.push(
|
|
252
|
+
`${mode}: ${fg} on ${bg} = ${ratio.toFixed(2)} (need ${min.toFixed(1)})`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return failures;
|
|
257
|
+
}
|
|
258
|
+
function validateTheme(theme) {
|
|
259
|
+
const failures = [
|
|
260
|
+
...checkMode(theme.light, "light"),
|
|
261
|
+
...checkMode(theme.dark, "dark")
|
|
262
|
+
];
|
|
263
|
+
return failures.length === 0 ? { contrastAA: true } : { contrastAA: false, failures };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/themes/generate.ts
|
|
267
|
+
var NEUTRAL_TINT = {
|
|
268
|
+
cool: { hue: 250, chroma: 0.012 },
|
|
269
|
+
// bluish slate
|
|
270
|
+
neutral: { hue: 270, chroma: 3e-3 },
|
|
271
|
+
// near-achromatic
|
|
272
|
+
warm: { hue: 70, chroma: 0.012 }
|
|
273
|
+
// warm stone
|
|
274
|
+
};
|
|
275
|
+
var STATUS_HUE = {
|
|
276
|
+
success: 150,
|
|
277
|
+
warning: 80,
|
|
278
|
+
destructive: 27,
|
|
279
|
+
info: 230
|
|
280
|
+
};
|
|
281
|
+
var clampL = (l) => Math.min(0.985, Math.max(0.06, l));
|
|
282
|
+
function bestTextOn(bg, hue) {
|
|
283
|
+
const white = { l: 0.985, c: 4e-3, h: hue };
|
|
284
|
+
const black = { l: 0.18, c: 0.01, h: hue };
|
|
285
|
+
return contrastRatio(white, bg) >= contrastRatio(black, bg) ? white : black;
|
|
286
|
+
}
|
|
287
|
+
function nudgeForeground(fg, bg, min) {
|
|
288
|
+
let cur = { ...fg };
|
|
289
|
+
if (contrastRatio(cur, bg) >= min) return cur;
|
|
290
|
+
const goLighter = relativeLuminance(bg) < 0.4;
|
|
291
|
+
const step = goLighter ? 0.03 : -0.03;
|
|
292
|
+
for (let i = 0; i < 32; i++) {
|
|
293
|
+
cur = { ...cur, l: clampL(cur.l + step) };
|
|
294
|
+
if (contrastRatio(cur, bg) >= min) return cur;
|
|
295
|
+
if (cur.l <= 0.06 || cur.l >= 0.985) break;
|
|
296
|
+
}
|
|
297
|
+
return goLighter ? { l: 0.985, c: 0, h: fg.h } : { l: 0.1, c: 0, h: fg.h };
|
|
298
|
+
}
|
|
299
|
+
function resolveSolidPair(base, fg, min) {
|
|
300
|
+
let curFg = nudgeForeground(fg, base, min);
|
|
301
|
+
if (contrastRatio(curFg, base) >= min) return { base, foreground: curFg };
|
|
302
|
+
const fgIsLight = relativeLuminance(curFg) >= 0.5;
|
|
303
|
+
const step = fgIsLight ? -0.02 : 0.02;
|
|
304
|
+
let curBase = { ...base };
|
|
305
|
+
for (let i = 0; i < 32; i++) {
|
|
306
|
+
curBase = { ...curBase, l: clampL(curBase.l + step) };
|
|
307
|
+
curFg = nudgeForeground(curFg, curBase, min);
|
|
308
|
+
if (contrastRatio(curFg, curBase) >= min) break;
|
|
309
|
+
if (curBase.l <= 0.06 || curBase.l >= 0.985) break;
|
|
310
|
+
}
|
|
311
|
+
return { base: curBase, foreground: curFg };
|
|
312
|
+
}
|
|
313
|
+
function modeConfig(isDark, surface) {
|
|
314
|
+
const crisp = surface === "crisp";
|
|
315
|
+
if (isDark) {
|
|
316
|
+
return {
|
|
317
|
+
bgL: crisp ? 0.16 : 0.2,
|
|
318
|
+
surfStep: crisp ? 0.05 : 0.04,
|
|
319
|
+
fgL: 0.96,
|
|
320
|
+
toneL: 0.7,
|
|
321
|
+
toneC: 0.16,
|
|
322
|
+
softL: 0.3,
|
|
323
|
+
softC: 0.06,
|
|
324
|
+
isDark: true
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
bgL: 1,
|
|
329
|
+
surfStep: crisp ? -0.035 : -0.025,
|
|
330
|
+
fgL: 0.2,
|
|
331
|
+
toneL: 0.58,
|
|
332
|
+
toneC: 0.17,
|
|
333
|
+
softL: 0.95,
|
|
334
|
+
softC: 0.05,
|
|
335
|
+
isDark: false
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function buildMode(primaryHue, accentHue, neutralTemp, surface, isDark) {
|
|
339
|
+
const cfg = modeConfig(isDark, surface);
|
|
340
|
+
const tint = NEUTRAL_TINT[neutralTemp];
|
|
341
|
+
const nh = tint.hue;
|
|
342
|
+
const nc = tint.chroma;
|
|
343
|
+
const background = { l: clampL(cfg.bgL), c: nc, h: nh };
|
|
344
|
+
const card = { l: clampL(cfg.bgL + cfg.surfStep), c: nc, h: nh };
|
|
345
|
+
const popover = card;
|
|
346
|
+
const muted = { l: clampL(cfg.bgL + cfg.surfStep * 1.5), c: nc * 1.4, h: nh };
|
|
347
|
+
const border = { l: clampL(cfg.bgL + cfg.surfStep * 2.2), c: nc * 1.6, h: nh };
|
|
348
|
+
const borderStrong = {
|
|
349
|
+
l: clampL(cfg.bgL + cfg.surfStep * 3.4),
|
|
350
|
+
c: nc * 1.8,
|
|
351
|
+
h: nh
|
|
352
|
+
};
|
|
353
|
+
const input = borderStrong;
|
|
354
|
+
const foreground = nudgeForeground({ l: cfg.fgL, c: nc * 2, h: nh }, background, AA_TEXT);
|
|
355
|
+
const cardFg = nudgeForeground(foreground, card, AA_TEXT);
|
|
356
|
+
const popoverFg = nudgeForeground(foreground, popover, AA_TEXT);
|
|
357
|
+
const mutedFg = nudgeForeground(
|
|
358
|
+
{ l: isDark ? 0.72 : 0.5, c: nc * 2.5, h: nh },
|
|
359
|
+
muted,
|
|
360
|
+
AA_TEXT
|
|
361
|
+
);
|
|
362
|
+
const subtleFg = nudgeForeground(
|
|
363
|
+
{ l: isDark ? 0.55 : 0.62, c: nc * 2, h: nh },
|
|
364
|
+
background,
|
|
365
|
+
AA_UI
|
|
366
|
+
);
|
|
367
|
+
const inverse = isDark ? { l: 0.96, c: nc, h: nh } : { l: 0.2, c: nc * 2, h: nh };
|
|
368
|
+
const inverseFg = nudgeForeground(
|
|
369
|
+
{ l: isDark ? 0.18 : 0.97, c: nc, h: nh },
|
|
370
|
+
inverse,
|
|
371
|
+
AA_TEXT
|
|
372
|
+
);
|
|
373
|
+
const buildTone = (hue, chromaScale = 1) => {
|
|
374
|
+
const baseSeed = { l: cfg.toneL, c: cfg.toneC * chromaScale, h: hue };
|
|
375
|
+
const foregroundC = bestTextOn(baseSeed, hue);
|
|
376
|
+
const { base, foreground: fg } = resolveSolidPair(baseSeed, foregroundC, AA_TEXT);
|
|
377
|
+
const soft = { l: cfg.softL, c: cfg.softC * chromaScale, h: hue };
|
|
378
|
+
const softFgSeed = isDark ? { l: 0.85, c: cfg.softC * 1.4 * chromaScale, h: hue } : { l: 0.42, c: cfg.toneC * 0.9 * chromaScale, h: hue };
|
|
379
|
+
const softFg = nudgeForeground(softFgSeed, soft, AA_TEXT);
|
|
380
|
+
return {
|
|
381
|
+
base: oklchToCss(base),
|
|
382
|
+
foreground: oklchToCss(fg),
|
|
383
|
+
soft: oklchToCss(soft),
|
|
384
|
+
softForeground: oklchToCss(softFg)
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
const ring = nudgeForeground(
|
|
388
|
+
{ l: isDark ? 0.7 : 0.55, c: 0.16, h: primaryHue },
|
|
389
|
+
background,
|
|
390
|
+
AA_UI
|
|
391
|
+
);
|
|
392
|
+
const set = {
|
|
393
|
+
background: oklchToCss(background),
|
|
394
|
+
foreground: oklchToCss(foreground),
|
|
395
|
+
card: oklchToCss(card),
|
|
396
|
+
"card-foreground": oklchToCss(cardFg),
|
|
397
|
+
popover: oklchToCss(popover),
|
|
398
|
+
"popover-foreground": oklchToCss(popoverFg),
|
|
399
|
+
muted: oklchToCss(muted),
|
|
400
|
+
"muted-foreground": oklchToCss(mutedFg),
|
|
401
|
+
"subtle-foreground": oklchToCss(subtleFg),
|
|
402
|
+
inverse: oklchToCss(inverse),
|
|
403
|
+
"inverse-foreground": oklchToCss(inverseFg),
|
|
404
|
+
border: oklchToCss(border),
|
|
405
|
+
"border-strong": oklchToCss(borderStrong),
|
|
406
|
+
input: oklchToCss(input),
|
|
407
|
+
ring: oklchToCss(ring)
|
|
408
|
+
};
|
|
409
|
+
const tones = {
|
|
410
|
+
primary: primaryHue,
|
|
411
|
+
accent: accentHue,
|
|
412
|
+
destructive: STATUS_HUE.destructive,
|
|
413
|
+
info: STATUS_HUE.info,
|
|
414
|
+
success: STATUS_HUE.success,
|
|
415
|
+
warning: STATUS_HUE.warning
|
|
416
|
+
};
|
|
417
|
+
for (const [family, hue] of Object.entries(tones)) {
|
|
418
|
+
const chromaScale = family === "warning" ? 0.92 : 1;
|
|
419
|
+
applyToneSlots(set, family, buildTone(hue, chromaScale));
|
|
420
|
+
}
|
|
421
|
+
return set;
|
|
422
|
+
}
|
|
423
|
+
function accentHueFrom(primaryHue, mode) {
|
|
424
|
+
switch (mode) {
|
|
425
|
+
case "complementary":
|
|
426
|
+
return normalizeHue(primaryHue + 180);
|
|
427
|
+
case "analogous":
|
|
428
|
+
return normalizeHue(primaryHue + 40);
|
|
429
|
+
case "triadic":
|
|
430
|
+
return normalizeHue(primaryHue + 120);
|
|
431
|
+
case "mono":
|
|
432
|
+
return primaryHue;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
function defaultDescription(seed) {
|
|
436
|
+
const temp = seed.neutralTemp ?? "neutral";
|
|
437
|
+
const surf = seed.surface ?? "crisp";
|
|
438
|
+
return `Generated theme \xB7 hue ${Math.round(seed.primaryHue)}\xB0 \xB7 ${temp} neutrals \xB7 ${surf} surfaces.`;
|
|
439
|
+
}
|
|
440
|
+
function generateTheme(seed) {
|
|
441
|
+
const primaryHue = normalizeHue(seed.primaryHue);
|
|
442
|
+
const neutralTemp = seed.neutralTemp ?? "neutral";
|
|
443
|
+
const accentMode = seed.accentMode ?? "complementary";
|
|
444
|
+
const surface = seed.surface ?? "crisp";
|
|
445
|
+
const accentHue = accentHueFrom(primaryHue, accentMode);
|
|
446
|
+
const light = buildMode(primaryHue, accentHue, neutralTemp, surface, false);
|
|
447
|
+
const dark = buildMode(primaryHue, accentHue, neutralTemp, surface, true);
|
|
448
|
+
const meta = validateTheme({ light, dark });
|
|
449
|
+
const autoTags = [
|
|
450
|
+
neutralTemp,
|
|
451
|
+
accentMode,
|
|
452
|
+
surface,
|
|
453
|
+
meta.contrastAA ? "aa" : "aa-fail"
|
|
454
|
+
];
|
|
455
|
+
return {
|
|
456
|
+
id: seed.id,
|
|
457
|
+
name: seed.name,
|
|
458
|
+
description: seed.description ?? defaultDescription(seed),
|
|
459
|
+
tags: Array.from(/* @__PURE__ */ new Set([...seed.tags ?? [], ...autoTags])),
|
|
460
|
+
light,
|
|
461
|
+
dark,
|
|
462
|
+
radius: seed.radius,
|
|
463
|
+
// Generated/curated themes default to `candidate` — engine-proven, not yet
|
|
464
|
+
// validated against a real app surface.
|
|
465
|
+
status: ThemeStatus.Candidate,
|
|
466
|
+
meta
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/themes/css.ts
|
|
471
|
+
var RADIUS_SCALE = {
|
|
472
|
+
sm: { md: "0.375rem", lg: "0.5rem", xl: "0.75rem" },
|
|
473
|
+
md: { md: "0.5rem", lg: "0.75rem", xl: "1rem" },
|
|
474
|
+
lg: { md: "0.625rem", lg: "0.875rem", xl: "1.25rem" }
|
|
475
|
+
};
|
|
476
|
+
function declarations(set, indent = " ") {
|
|
477
|
+
return SEMANTIC_TOKENS.map((tok) => `${indent}--color-${tok}: ${set[tok]};`).join(
|
|
478
|
+
"\n"
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
function radiusDeclarations(theme, indent = " ") {
|
|
482
|
+
if (!theme.radius) return "";
|
|
483
|
+
const scale = RADIUS_SCALE[theme.radius];
|
|
484
|
+
return "\n" + Object.entries(scale).map(([k, v]) => `${indent}--radius-${k}: ${v};`).join("\n");
|
|
485
|
+
}
|
|
486
|
+
function themeToCss(theme) {
|
|
487
|
+
const radius = radiusDeclarations(theme);
|
|
488
|
+
const light = `.theme-${theme.id} {
|
|
489
|
+
${declarations(theme.light)}${radius}
|
|
490
|
+
}`;
|
|
491
|
+
const dark = `.dark.theme-${theme.id} {
|
|
492
|
+
${declarations(theme.dark)}
|
|
493
|
+
}`;
|
|
494
|
+
return `${light}
|
|
495
|
+
|
|
496
|
+
${dark}`;
|
|
497
|
+
}
|
|
498
|
+
function emitAllThemesCss(themes) {
|
|
499
|
+
const banner = "/* Generated by @wow-two-beta/ui theme engine \u2014 do not edit by hand.\n * Source: src/themes/registry.ts \u2192 regenerate via the package build. */\n";
|
|
500
|
+
const body = themes.map(themeToCss).join("\n\n");
|
|
501
|
+
return `${banner}
|
|
502
|
+
${body}
|
|
503
|
+
`;
|
|
504
|
+
}
|
|
505
|
+
function emitThemesManifest(themes) {
|
|
506
|
+
return themes.map((t) => ({
|
|
507
|
+
id: t.id,
|
|
508
|
+
name: t.name,
|
|
509
|
+
description: t.description,
|
|
510
|
+
tags: t.tags,
|
|
511
|
+
status: t.status,
|
|
512
|
+
contrastAA: t.meta.contrastAA
|
|
513
|
+
}));
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// src/themes/validated.ts
|
|
517
|
+
var LIB_DEFAULT_LIGHT = {
|
|
518
|
+
background: "#ffffff",
|
|
519
|
+
foreground: "#18181b",
|
|
520
|
+
card: "#ffffff",
|
|
521
|
+
"card-foreground": "#18181b",
|
|
522
|
+
popover: "#ffffff",
|
|
523
|
+
"popover-foreground": "#18181b",
|
|
524
|
+
muted: "#f4f4f5",
|
|
525
|
+
"muted-foreground": "#71717a",
|
|
526
|
+
"subtle-foreground": "#a1a1aa",
|
|
527
|
+
inverse: "#18181b",
|
|
528
|
+
"inverse-foreground": "#fafafa",
|
|
529
|
+
border: "#e4e4e7",
|
|
530
|
+
"border-strong": "#d4d4d8",
|
|
531
|
+
input: "#d4d4d8",
|
|
532
|
+
ring: "#3b82f6",
|
|
533
|
+
primary: "#2563eb",
|
|
534
|
+
"primary-foreground": "#ffffff",
|
|
535
|
+
"primary-soft": "#dbeafe",
|
|
536
|
+
"primary-soft-foreground": "#1d4ed8",
|
|
537
|
+
accent: "#0d9488",
|
|
538
|
+
"accent-foreground": "#ffffff",
|
|
539
|
+
"accent-soft": "#ccfbf1",
|
|
540
|
+
"accent-soft-foreground": "#115e59",
|
|
541
|
+
destructive: "#dc2626",
|
|
542
|
+
"destructive-foreground": "#ffffff",
|
|
543
|
+
"destructive-soft": "#fef2f2",
|
|
544
|
+
"destructive-soft-foreground": "#b91c1c",
|
|
545
|
+
info: "#0891b2",
|
|
546
|
+
"info-foreground": "#ffffff",
|
|
547
|
+
"info-soft": "#ecfeff",
|
|
548
|
+
"info-soft-foreground": "#0e7490",
|
|
549
|
+
success: "#16a34a",
|
|
550
|
+
"success-foreground": "#ffffff",
|
|
551
|
+
"success-soft": "#f0fdf4",
|
|
552
|
+
"success-soft-foreground": "#15803d",
|
|
553
|
+
warning: "#f59e0b",
|
|
554
|
+
"warning-foreground": "#78350f",
|
|
555
|
+
"warning-soft": "#fffbeb",
|
|
556
|
+
"warning-soft-foreground": "#b45309"
|
|
557
|
+
};
|
|
558
|
+
var LIB_DEFAULT_DARK = {
|
|
559
|
+
background: "#09090b",
|
|
560
|
+
foreground: "#fafafa",
|
|
561
|
+
card: "#18181b",
|
|
562
|
+
"card-foreground": "#fafafa",
|
|
563
|
+
popover: "#18181b",
|
|
564
|
+
"popover-foreground": "#fafafa",
|
|
565
|
+
muted: "#18181b",
|
|
566
|
+
"muted-foreground": "#a1a1aa",
|
|
567
|
+
"subtle-foreground": "#71717a",
|
|
568
|
+
inverse: "#fafafa",
|
|
569
|
+
"inverse-foreground": "#09090b",
|
|
570
|
+
border: "#27272a",
|
|
571
|
+
"border-strong": "#3f3f46",
|
|
572
|
+
input: "#3f3f46",
|
|
573
|
+
ring: "#60a5fa",
|
|
574
|
+
primary: "#3b82f6",
|
|
575
|
+
"primary-foreground": "#ffffff",
|
|
576
|
+
"primary-soft": "#1e3a8a",
|
|
577
|
+
"primary-soft-foreground": "#dbeafe",
|
|
578
|
+
accent: "#2dd4bf",
|
|
579
|
+
"accent-foreground": "#042f2e",
|
|
580
|
+
"accent-soft": "#134e4a",
|
|
581
|
+
"accent-soft-foreground": "#5eead4",
|
|
582
|
+
destructive: "#ef4444",
|
|
583
|
+
"destructive-foreground": "#ffffff",
|
|
584
|
+
"destructive-soft": "#7f1d1d",
|
|
585
|
+
"destructive-soft-foreground": "#fee2e2",
|
|
586
|
+
info: "#06b6d4",
|
|
587
|
+
"info-foreground": "#ffffff",
|
|
588
|
+
"info-soft": "#164e63",
|
|
589
|
+
"info-soft-foreground": "#cffafe",
|
|
590
|
+
success: "#22c55e",
|
|
591
|
+
"success-foreground": "#ffffff",
|
|
592
|
+
"success-soft": "#14532d",
|
|
593
|
+
"success-soft-foreground": "#dcfce7",
|
|
594
|
+
warning: "#f59e0b",
|
|
595
|
+
"warning-foreground": "#78350f",
|
|
596
|
+
"warning-soft": "#78350f",
|
|
597
|
+
"warning-soft-foreground": "#fef3c7"
|
|
598
|
+
};
|
|
599
|
+
var smartQrLight = {
|
|
600
|
+
...LIB_DEFAULT_LIGHT,
|
|
601
|
+
background: "#d9dde8",
|
|
602
|
+
card: "#ebeef4",
|
|
603
|
+
popover: "#ebeef4",
|
|
604
|
+
"popover-foreground": "#1c1d26",
|
|
605
|
+
muted: "#f1f2f8",
|
|
606
|
+
foreground: "#1c1d26",
|
|
607
|
+
"card-foreground": "#1c1d26",
|
|
608
|
+
// = foreground (app inherits foreground here)
|
|
609
|
+
"muted-foreground": "#6e7188",
|
|
610
|
+
"subtle-foreground": "#9b9fb5",
|
|
611
|
+
border: "#e4e6f0",
|
|
612
|
+
"border-strong": "#c7cad9",
|
|
613
|
+
input: "#e4e6f0",
|
|
614
|
+
ring: "#8b5cf6",
|
|
615
|
+
primary: "#7c3aed",
|
|
616
|
+
"primary-foreground": "#f5f3ff",
|
|
617
|
+
"primary-soft": "#ede9fe",
|
|
618
|
+
"primary-soft-foreground": "#5b21b6",
|
|
619
|
+
accent: "#0d9488",
|
|
620
|
+
"accent-foreground": "#ffffff",
|
|
621
|
+
"accent-soft": "#ccfbf1",
|
|
622
|
+
"accent-soft-foreground": "#115e59"
|
|
623
|
+
};
|
|
624
|
+
var smartQrDark = {
|
|
625
|
+
...LIB_DEFAULT_DARK,
|
|
626
|
+
background: "#121214",
|
|
627
|
+
card: "#1c1c1f",
|
|
628
|
+
popover: "#1c1c1f",
|
|
629
|
+
"popover-foreground": "#e7e7e9",
|
|
630
|
+
muted: "#18181b",
|
|
631
|
+
foreground: "#e7e7e9",
|
|
632
|
+
"card-foreground": "#e7e7e9",
|
|
633
|
+
// = foreground (app inherits foreground here)
|
|
634
|
+
"muted-foreground": "#a1a1aa",
|
|
635
|
+
"subtle-foreground": "#6e6e76",
|
|
636
|
+
border: "#2a2a2e",
|
|
637
|
+
"border-strong": "#3a3a40",
|
|
638
|
+
input: "#2a2a2e",
|
|
639
|
+
ring: "#8b5cf6",
|
|
640
|
+
primary: "#8b5cf6",
|
|
641
|
+
"primary-soft": "#2a2440",
|
|
642
|
+
"primary-soft-foreground": "#c4b5fd",
|
|
643
|
+
accent: "#2dd4bf",
|
|
644
|
+
"accent-soft": "#103a35",
|
|
645
|
+
"accent-soft-foreground": "#5eead4"
|
|
646
|
+
};
|
|
647
|
+
var smartQr = {
|
|
648
|
+
id: "smart-qr",
|
|
649
|
+
name: "Smart QR",
|
|
650
|
+
description: "Violet brand + teal accent on cool lavender-grey (light) / charcoal (dark) \u2014 the validated Smart QR product theme.",
|
|
651
|
+
tags: ["brand", "violet", "teal", "validated", "product"],
|
|
652
|
+
light: smartQrLight,
|
|
653
|
+
dark: smartQrDark,
|
|
654
|
+
status: ThemeStatus.Validated,
|
|
655
|
+
// Recorded for transparency. We do NOT auto-nudge any value — status stays
|
|
656
|
+
// `validated` even if a pair fails (the human validated it visually).
|
|
657
|
+
meta: validateTheme({ light: smartQrLight, dark: smartQrDark })
|
|
658
|
+
};
|
|
659
|
+
var VALIDATED_THEMES = [smartQr];
|
|
660
|
+
|
|
661
|
+
// src/themes/pool.ts
|
|
662
|
+
var NAMED_SEEDS = [
|
|
663
|
+
{
|
|
664
|
+
id: "catppuccin-latte",
|
|
665
|
+
name: "Catppuccin Latte",
|
|
666
|
+
description: "Soft mauve brand on warm latte neutrals \u2014 the light Catppuccin flavour.",
|
|
667
|
+
tags: ["editor", "catppuccin", "pastel", "warm", "soft"],
|
|
668
|
+
primaryHue: 290,
|
|
669
|
+
neutralTemp: "warm",
|
|
670
|
+
accentMode: "analogous",
|
|
671
|
+
surface: "soft"
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
id: "catppuccin-frappe",
|
|
675
|
+
name: "Catppuccin Frapp\xE9",
|
|
676
|
+
description: "Muted mauve brand on cool slate \u2014 the mid Catppuccin flavour.",
|
|
677
|
+
tags: ["editor", "catppuccin", "pastel", "cool", "muted"],
|
|
678
|
+
primaryHue: 287,
|
|
679
|
+
neutralTemp: "cool",
|
|
680
|
+
accentMode: "analogous",
|
|
681
|
+
surface: "soft"
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
id: "catppuccin-macchiato",
|
|
685
|
+
name: "Catppuccin Macchiato",
|
|
686
|
+
description: "Lavender-mauve brand on deep cool neutrals \u2014 the darker Catppuccin flavour.",
|
|
687
|
+
tags: ["editor", "catppuccin", "pastel", "cool", "soft"],
|
|
688
|
+
primaryHue: 280,
|
|
689
|
+
neutralTemp: "cool",
|
|
690
|
+
accentMode: "triadic",
|
|
691
|
+
surface: "soft"
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
id: "catppuccin-mocha",
|
|
695
|
+
name: "Catppuccin Mocha",
|
|
696
|
+
description: "Pastel mauve brand on the darkest Catppuccin slate \u2014 cozy and dim.",
|
|
697
|
+
tags: ["editor", "catppuccin", "pastel", "cool", "soft"],
|
|
698
|
+
primaryHue: 283,
|
|
699
|
+
neutralTemp: "cool",
|
|
700
|
+
accentMode: "analogous",
|
|
701
|
+
surface: "soft"
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
id: "tokyo-night",
|
|
705
|
+
name: "Tokyo Night",
|
|
706
|
+
description: "Indigo-blue brand on deep cool navy \u2014 neon-city night editor palette.",
|
|
707
|
+
tags: ["editor", "tokyo-night", "cool", "calm"],
|
|
708
|
+
primaryHue: 252,
|
|
709
|
+
neutralTemp: "cool",
|
|
710
|
+
accentMode: "analogous",
|
|
711
|
+
surface: "soft"
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
id: "tokyo-night-storm",
|
|
715
|
+
name: "Tokyo Night Storm",
|
|
716
|
+
description: "Soft blue brand on stormy blue-grey \u2014 the lighter-ground Tokyo Night variant.",
|
|
717
|
+
tags: ["editor", "tokyo-night", "cool", "muted"],
|
|
718
|
+
primaryHue: 246,
|
|
719
|
+
neutralTemp: "cool",
|
|
720
|
+
accentMode: "triadic",
|
|
721
|
+
surface: "soft"
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
id: "tokyo-night-light",
|
|
725
|
+
name: "Tokyo Night Light",
|
|
726
|
+
description: "Indigo brand on crisp cool paper \u2014 the daytime Tokyo Night.",
|
|
727
|
+
tags: ["editor", "tokyo-night", "cool", "light"],
|
|
728
|
+
primaryHue: 250,
|
|
729
|
+
neutralTemp: "cool",
|
|
730
|
+
accentMode: "analogous",
|
|
731
|
+
surface: "crisp"
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
id: "rose-pine",
|
|
735
|
+
name: "Ros\xE9 Pine",
|
|
736
|
+
description: "Dusky rose brand on muted plum-grey \u2014 the cozy Ros\xE9 Pine vibe.",
|
|
737
|
+
tags: ["editor", "rose-pine", "muted", "soft", "cool"],
|
|
738
|
+
primaryHue: 350,
|
|
739
|
+
neutralTemp: "cool",
|
|
740
|
+
accentMode: "triadic",
|
|
741
|
+
surface: "soft"
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
id: "rose-pine-moon",
|
|
745
|
+
name: "Ros\xE9 Pine Moon",
|
|
746
|
+
description: "Soft rose brand on a lighter moonlit plum ground \u2014 Ros\xE9 Pine Moon.",
|
|
747
|
+
tags: ["editor", "rose-pine", "muted", "soft", "cool"],
|
|
748
|
+
primaryHue: 345,
|
|
749
|
+
neutralTemp: "cool",
|
|
750
|
+
accentMode: "analogous",
|
|
751
|
+
surface: "soft"
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
id: "rose-pine-dawn",
|
|
755
|
+
name: "Ros\xE9 Pine Dawn",
|
|
756
|
+
description: "Rose brand on warm parchment \u2014 the light Ros\xE9 Pine Dawn.",
|
|
757
|
+
tags: ["editor", "rose-pine", "warm", "soft", "light"],
|
|
758
|
+
primaryHue: 352,
|
|
759
|
+
neutralTemp: "warm",
|
|
760
|
+
accentMode: "analogous",
|
|
761
|
+
surface: "soft"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
id: "one-dark",
|
|
765
|
+
name: "One Dark",
|
|
766
|
+
description: "Hyperlink-blue brand on cool gunmetal \u2014 the Atom/One Dark classic.",
|
|
767
|
+
tags: ["editor", "one-dark", "cool", "calm"],
|
|
768
|
+
primaryHue: 240,
|
|
769
|
+
neutralTemp: "cool",
|
|
770
|
+
accentMode: "complementary",
|
|
771
|
+
surface: "crisp"
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
id: "one-light",
|
|
775
|
+
name: "One Light",
|
|
776
|
+
description: "Blue brand on crisp neutral paper \u2014 the One Light editor theme.",
|
|
777
|
+
tags: ["editor", "one-light", "neutral", "light"],
|
|
778
|
+
primaryHue: 240,
|
|
779
|
+
neutralTemp: "neutral",
|
|
780
|
+
accentMode: "complementary",
|
|
781
|
+
surface: "crisp"
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
id: "ayu-dark",
|
|
785
|
+
name: "Ayu Dark",
|
|
786
|
+
description: "Warm amber brand on near-black ink \u2014 Ayu Dark\u2019s signature glow.",
|
|
787
|
+
tags: ["editor", "ayu", "warm", "vibrant"],
|
|
788
|
+
primaryHue: 60,
|
|
789
|
+
neutralTemp: "warm",
|
|
790
|
+
accentMode: "analogous",
|
|
791
|
+
surface: "crisp"
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
id: "ayu-mirage",
|
|
795
|
+
name: "Ayu Mirage",
|
|
796
|
+
description: "Amber-gold brand on muted blue-grey \u2014 the mid Ayu Mirage tone.",
|
|
797
|
+
tags: ["editor", "ayu", "warm", "muted"],
|
|
798
|
+
primaryHue: 55,
|
|
799
|
+
neutralTemp: "cool",
|
|
800
|
+
accentMode: "triadic",
|
|
801
|
+
surface: "soft"
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
id: "ayu-light",
|
|
805
|
+
name: "Ayu Light",
|
|
806
|
+
description: "Warm orange brand on bright paper \u2014 the daytime Ayu Light.",
|
|
807
|
+
tags: ["editor", "ayu", "warm", "light"],
|
|
808
|
+
primaryHue: 48,
|
|
809
|
+
neutralTemp: "warm",
|
|
810
|
+
accentMode: "analogous",
|
|
811
|
+
surface: "crisp"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
id: "everforest",
|
|
815
|
+
name: "Everforest",
|
|
816
|
+
description: "Soft moss-green brand on warm forest-grey \u2014 the gentle Everforest palette.",
|
|
817
|
+
tags: ["editor", "everforest", "nature", "warm", "muted"],
|
|
818
|
+
primaryHue: 135,
|
|
819
|
+
neutralTemp: "warm",
|
|
820
|
+
accentMode: "analogous",
|
|
821
|
+
surface: "soft"
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
id: "everforest-light",
|
|
825
|
+
name: "Everforest Light",
|
|
826
|
+
description: "Moss green brand on warm cream \u2014 the light Everforest.",
|
|
827
|
+
tags: ["editor", "everforest", "nature", "warm", "light"],
|
|
828
|
+
primaryHue: 130,
|
|
829
|
+
neutralTemp: "warm",
|
|
830
|
+
accentMode: "analogous",
|
|
831
|
+
surface: "soft"
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
id: "kanagawa",
|
|
835
|
+
name: "Kanagawa",
|
|
836
|
+
description: "Wave-blue brand on warm sumi-ink grey \u2014 inspired by Hokusai\u2019s Great Wave.",
|
|
837
|
+
tags: ["editor", "kanagawa", "cool", "muted", "warm"],
|
|
838
|
+
primaryHue: 220,
|
|
839
|
+
neutralTemp: "warm",
|
|
840
|
+
accentMode: "triadic",
|
|
841
|
+
surface: "soft"
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
id: "kanagawa-lotus",
|
|
845
|
+
name: "Kanagawa Lotus",
|
|
846
|
+
description: "Indigo brand on warm parchment \u2014 the light Kanagawa Lotus.",
|
|
847
|
+
tags: ["editor", "kanagawa", "warm", "light", "muted"],
|
|
848
|
+
primaryHue: 235,
|
|
849
|
+
neutralTemp: "warm",
|
|
850
|
+
accentMode: "analogous",
|
|
851
|
+
surface: "soft"
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
id: "night-owl",
|
|
855
|
+
name: "Night Owl",
|
|
856
|
+
description: "Cyan-teal brand on deep midnight blue \u2014 a palette tuned for late-night coding.",
|
|
857
|
+
tags: ["editor", "night-owl", "cool", "vibrant"],
|
|
858
|
+
primaryHue: 195,
|
|
859
|
+
neutralTemp: "cool",
|
|
860
|
+
accentMode: "triadic",
|
|
861
|
+
surface: "soft"
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
id: "light-owl",
|
|
865
|
+
name: "Light Owl",
|
|
866
|
+
description: "Teal brand on crisp cool paper \u2014 the daytime Light Owl.",
|
|
867
|
+
tags: ["editor", "night-owl", "cool", "light"],
|
|
868
|
+
primaryHue: 198,
|
|
869
|
+
neutralTemp: "cool",
|
|
870
|
+
accentMode: "complementary",
|
|
871
|
+
surface: "crisp"
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
id: "synthwave",
|
|
875
|
+
name: "Synthwave",
|
|
876
|
+
description: "Hot-magenta brand with a cyan accent on deep purple-black \u2014 retro 80s neon.",
|
|
877
|
+
tags: ["editor", "synthwave", "retro", "vibrant", "neon"],
|
|
878
|
+
primaryHue: 320,
|
|
879
|
+
neutralTemp: "cool",
|
|
880
|
+
accentMode: "triadic",
|
|
881
|
+
surface: "crisp"
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
id: "outrun",
|
|
885
|
+
name: "Outrun",
|
|
886
|
+
description: "Sunset-orange brand with a violet accent on dark indigo \u2014 neon sunset drive.",
|
|
887
|
+
tags: ["retro", "synthwave", "vibrant", "warm", "neon"],
|
|
888
|
+
primaryHue: 32,
|
|
889
|
+
neutralTemp: "cool",
|
|
890
|
+
accentMode: "triadic",
|
|
891
|
+
surface: "crisp"
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
id: "material",
|
|
895
|
+
name: "Material",
|
|
896
|
+
description: "Indigo brand with a teal accent on neutral greys \u2014 the Material Design baseline.",
|
|
897
|
+
tags: ["brand", "material", "neutral", "classic"],
|
|
898
|
+
primaryHue: 255,
|
|
899
|
+
neutralTemp: "neutral",
|
|
900
|
+
accentMode: "complementary",
|
|
901
|
+
surface: "crisp"
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
id: "material-ocean",
|
|
905
|
+
name: "Material Ocean",
|
|
906
|
+
description: "Bright blue brand on deep ocean-navy \u2014 the Material Theme Ocean variant.",
|
|
907
|
+
tags: ["editor", "material", "cool", "calm"],
|
|
908
|
+
primaryHue: 225,
|
|
909
|
+
neutralTemp: "cool",
|
|
910
|
+
accentMode: "analogous",
|
|
911
|
+
surface: "soft"
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
id: "palenight",
|
|
915
|
+
name: "Palenight",
|
|
916
|
+
description: "Soft violet brand on dim blue-grey \u2014 the mellow Material Palenight.",
|
|
917
|
+
tags: ["editor", "material", "cool", "muted", "soft"],
|
|
918
|
+
primaryHue: 270,
|
|
919
|
+
neutralTemp: "cool",
|
|
920
|
+
accentMode: "analogous",
|
|
921
|
+
surface: "soft"
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
id: "oceanic-next",
|
|
925
|
+
name: "Oceanic Next",
|
|
926
|
+
description: "Teal-blue brand on slate navy \u2014 the Oceanic Next editor palette.",
|
|
927
|
+
tags: ["editor", "oceanic", "cool", "calm"],
|
|
928
|
+
primaryHue: 200,
|
|
929
|
+
neutralTemp: "cool",
|
|
930
|
+
accentMode: "analogous",
|
|
931
|
+
surface: "soft"
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
id: "horizon",
|
|
935
|
+
name: "Horizon",
|
|
936
|
+
description: "Coral-rose brand with a cyan accent on warm plum-charcoal \u2014 the warm Horizon palette.",
|
|
937
|
+
tags: ["editor", "horizon", "warm", "vibrant"],
|
|
938
|
+
primaryHue: 5,
|
|
939
|
+
neutralTemp: "warm",
|
|
940
|
+
accentMode: "triadic",
|
|
941
|
+
surface: "soft"
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
id: "github-dark",
|
|
945
|
+
name: "GitHub Dark",
|
|
946
|
+
description: "GitHub-blue brand on cool slate \u2014 the dark GitHub interface palette.",
|
|
947
|
+
tags: ["brand", "github", "cool", "professional"],
|
|
948
|
+
primaryHue: 235,
|
|
949
|
+
neutralTemp: "cool",
|
|
950
|
+
accentMode: "complementary",
|
|
951
|
+
surface: "crisp"
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
id: "github-light",
|
|
955
|
+
name: "GitHub Light",
|
|
956
|
+
description: "GitHub-blue brand on crisp neutral white \u2014 the light GitHub interface.",
|
|
957
|
+
tags: ["brand", "github", "neutral", "professional", "light"],
|
|
958
|
+
primaryHue: 235,
|
|
959
|
+
neutralTemp: "neutral",
|
|
960
|
+
accentMode: "complementary",
|
|
961
|
+
surface: "crisp"
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
id: "github-dimmed",
|
|
965
|
+
name: "GitHub Dimmed",
|
|
966
|
+
description: "GitHub-blue brand on softened slate \u2014 the low-glare GitHub Dimmed mode.",
|
|
967
|
+
tags: ["brand", "github", "cool", "muted"],
|
|
968
|
+
primaryHue: 233,
|
|
969
|
+
neutralTemp: "cool",
|
|
970
|
+
accentMode: "complementary",
|
|
971
|
+
surface: "soft"
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
id: "cobalt2",
|
|
975
|
+
name: "Cobalt2",
|
|
976
|
+
description: "Electric cobalt brand with an amber accent on deep navy \u2014 Wes Bos\u2019 Cobalt2.",
|
|
977
|
+
tags: ["editor", "cobalt", "cool", "vibrant"],
|
|
978
|
+
primaryHue: 228,
|
|
979
|
+
neutralTemp: "cool",
|
|
980
|
+
accentMode: "complementary",
|
|
981
|
+
surface: "crisp"
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
id: "panda",
|
|
985
|
+
name: "Panda",
|
|
986
|
+
description: "Pink-magenta brand with a cyan accent on near-black grey \u2014 the friendly Panda Syntax.",
|
|
987
|
+
tags: ["editor", "panda", "vibrant", "neutral"],
|
|
988
|
+
primaryHue: 335,
|
|
989
|
+
neutralTemp: "neutral",
|
|
990
|
+
accentMode: "triadic",
|
|
991
|
+
surface: "crisp"
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
id: "monokai-pro",
|
|
995
|
+
name: "Monokai Pro",
|
|
996
|
+
description: "Warm yellow-amber brand with a magenta accent on warm charcoal \u2014 Monokai Pro.",
|
|
997
|
+
tags: ["editor", "monokai", "warm", "vibrant"],
|
|
998
|
+
primaryHue: 70,
|
|
999
|
+
neutralTemp: "warm",
|
|
1000
|
+
accentMode: "complementary",
|
|
1001
|
+
surface: "crisp"
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
id: "solarized-dark",
|
|
1005
|
+
name: "Solarized Dark",
|
|
1006
|
+
description: "Cyan-blue brand on the deep teal-grey Solarized base \u2014 the dark Solarized.",
|
|
1007
|
+
tags: ["editor", "solarized", "cool", "muted"],
|
|
1008
|
+
primaryHue: 205,
|
|
1009
|
+
neutralTemp: "cool",
|
|
1010
|
+
accentMode: "complementary",
|
|
1011
|
+
surface: "soft"
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
id: "gruvbox-light",
|
|
1015
|
+
name: "Gruvbox Light",
|
|
1016
|
+
description: "Warm orange brand on retro cream \u2014 the light Gruvbox.",
|
|
1017
|
+
tags: ["editor", "gruvbox", "warm", "retro", "light"],
|
|
1018
|
+
primaryHue: 45,
|
|
1019
|
+
neutralTemp: "warm",
|
|
1020
|
+
accentMode: "analogous",
|
|
1021
|
+
surface: "soft"
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
id: "gruvbox-material",
|
|
1025
|
+
name: "Gruvbox Material",
|
|
1026
|
+
description: "Softened amber brand on muted warm grey \u2014 the gentler Gruvbox Material.",
|
|
1027
|
+
tags: ["editor", "gruvbox", "warm", "retro", "muted"],
|
|
1028
|
+
primaryHue: 52,
|
|
1029
|
+
neutralTemp: "warm",
|
|
1030
|
+
accentMode: "triadic",
|
|
1031
|
+
surface: "soft"
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
id: "nord-light",
|
|
1035
|
+
name: "Nord Light",
|
|
1036
|
+
description: "Frost-blue brand on bright arctic snow \u2014 the light counterpart to Nord.",
|
|
1037
|
+
tags: ["editor", "nord", "cool", "muted", "light"],
|
|
1038
|
+
primaryHue: 213,
|
|
1039
|
+
neutralTemp: "cool",
|
|
1040
|
+
accentMode: "analogous",
|
|
1041
|
+
surface: "soft"
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
id: "aurora",
|
|
1045
|
+
name: "Aurora",
|
|
1046
|
+
description: "Frost-green brand with a violet accent on cool slate \u2014 Nord\u2019s Aurora highlights.",
|
|
1047
|
+
tags: ["editor", "nord", "cool", "nature"],
|
|
1048
|
+
primaryHue: 150,
|
|
1049
|
+
neutralTemp: "cool",
|
|
1050
|
+
accentMode: "triadic",
|
|
1051
|
+
surface: "soft"
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
id: "dracula-pro",
|
|
1055
|
+
name: "Dracula Pro",
|
|
1056
|
+
description: "Refined purple brand with a pink accent on warm-tinted charcoal \u2014 Dracula Pro.",
|
|
1057
|
+
tags: ["editor", "dracula", "vibrant", "cool"],
|
|
1058
|
+
primaryHue: 268,
|
|
1059
|
+
neutralTemp: "cool",
|
|
1060
|
+
accentMode: "analogous",
|
|
1061
|
+
surface: "crisp"
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
id: "shades-of-purple",
|
|
1065
|
+
name: "Shades of Purple",
|
|
1066
|
+
description: "Royal violet brand with a gold accent on deep indigo \u2014 the bold SoP palette.",
|
|
1067
|
+
tags: ["editor", "purple", "vibrant", "cool"],
|
|
1068
|
+
primaryHue: 275,
|
|
1069
|
+
neutralTemp: "cool",
|
|
1070
|
+
accentMode: "complementary",
|
|
1071
|
+
surface: "crisp"
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
id: "winter-is-coming",
|
|
1075
|
+
name: "Winter is Coming",
|
|
1076
|
+
description: "Cool blue brand on icy slate \u2014 the crisp Winter-is-Coming editor theme.",
|
|
1077
|
+
tags: ["editor", "cool", "calm", "muted"],
|
|
1078
|
+
primaryHue: 218,
|
|
1079
|
+
neutralTemp: "cool",
|
|
1080
|
+
accentMode: "analogous",
|
|
1081
|
+
surface: "crisp"
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
id: "cyberpunk",
|
|
1085
|
+
name: "Cyberpunk",
|
|
1086
|
+
description: "Electric cyan brand with a hot-pink accent on black \u2014 high-voltage neon.",
|
|
1087
|
+
tags: ["retro", "neon", "vibrant", "cool"],
|
|
1088
|
+
primaryHue: 192,
|
|
1089
|
+
neutralTemp: "cool",
|
|
1090
|
+
accentMode: "triadic",
|
|
1091
|
+
surface: "crisp"
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
id: "spacegray",
|
|
1095
|
+
name: "Spacegray",
|
|
1096
|
+
description: "Muted blue brand on understated cool grey \u2014 the calm Spacegray UI.",
|
|
1097
|
+
tags: ["editor", "cool", "muted", "minimal"],
|
|
1098
|
+
primaryHue: 210,
|
|
1099
|
+
neutralTemp: "cool",
|
|
1100
|
+
accentMode: "analogous",
|
|
1101
|
+
surface: "soft"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
id: "github-copilot",
|
|
1105
|
+
name: "Copilot",
|
|
1106
|
+
description: "Teal-cyan brand on neutral slate \u2014 a calm assistant-inspired palette.",
|
|
1107
|
+
tags: ["brand", "cool", "fresh", "professional"],
|
|
1108
|
+
primaryHue: 185,
|
|
1109
|
+
neutralTemp: "neutral",
|
|
1110
|
+
accentMode: "complementary",
|
|
1111
|
+
surface: "crisp"
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
id: "vercel",
|
|
1115
|
+
name: "Vercel",
|
|
1116
|
+
description: "Pure achromatic brand on stark neutral greys \u2014 the high-contrast Vercel look.",
|
|
1117
|
+
tags: ["brand", "neutral", "minimal", "grayscale"],
|
|
1118
|
+
primaryHue: 0,
|
|
1119
|
+
neutralTemp: "neutral",
|
|
1120
|
+
accentMode: "mono",
|
|
1121
|
+
surface: "crisp"
|
|
1122
|
+
},
|
|
1123
|
+
{
|
|
1124
|
+
id: "stripe",
|
|
1125
|
+
name: "Stripe",
|
|
1126
|
+
description: "Indigo-violet brand with an analogous accent on cool neutrals \u2014 the Stripe brand feel.",
|
|
1127
|
+
tags: ["brand", "cool", "professional", "vibrant"],
|
|
1128
|
+
primaryHue: 258,
|
|
1129
|
+
neutralTemp: "cool",
|
|
1130
|
+
accentMode: "analogous",
|
|
1131
|
+
surface: "crisp"
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
id: "spotify",
|
|
1135
|
+
name: "Spotify",
|
|
1136
|
+
description: "Vivid green brand on near-black neutral \u2014 the energetic streaming-app palette.",
|
|
1137
|
+
tags: ["brand", "nature", "vibrant", "neutral"],
|
|
1138
|
+
primaryHue: 145,
|
|
1139
|
+
neutralTemp: "neutral",
|
|
1140
|
+
accentMode: "analogous",
|
|
1141
|
+
surface: "crisp"
|
|
1142
|
+
},
|
|
1143
|
+
{
|
|
1144
|
+
id: "firewatch",
|
|
1145
|
+
name: "Firewatch",
|
|
1146
|
+
description: "Sunset-orange brand with a teal accent on dusky blue \u2014 inspired by the game\u2019s vistas.",
|
|
1147
|
+
tags: ["nature", "warm", "vibrant", "cool"],
|
|
1148
|
+
primaryHue: 28,
|
|
1149
|
+
neutralTemp: "cool",
|
|
1150
|
+
accentMode: "complementary",
|
|
1151
|
+
surface: "soft"
|
|
1152
|
+
},
|
|
1153
|
+
{
|
|
1154
|
+
id: "andromeda",
|
|
1155
|
+
name: "Andromeda",
|
|
1156
|
+
description: "Magenta-pink brand with a green accent on deep space-blue \u2014 the vivid Andromeda palette.",
|
|
1157
|
+
tags: ["editor", "vibrant", "cool", "neon"],
|
|
1158
|
+
primaryHue: 330,
|
|
1159
|
+
neutralTemp: "cool",
|
|
1160
|
+
accentMode: "complementary",
|
|
1161
|
+
surface: "crisp"
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
id: "bluloco-light",
|
|
1165
|
+
name: "Bluloco Light",
|
|
1166
|
+
description: "Saturated blue brand on crisp paper \u2014 the punchy Bluloco Light.",
|
|
1167
|
+
tags: ["editor", "cool", "vibrant", "light"],
|
|
1168
|
+
primaryHue: 230,
|
|
1169
|
+
neutralTemp: "neutral",
|
|
1170
|
+
accentMode: "complementary",
|
|
1171
|
+
surface: "crisp"
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
id: "noctis",
|
|
1175
|
+
name: "Noctis",
|
|
1176
|
+
description: "Teal brand on deep blue-green ink \u2014 the legible Noctis editor palette.",
|
|
1177
|
+
tags: ["editor", "cool", "fresh", "muted"],
|
|
1178
|
+
primaryHue: 180,
|
|
1179
|
+
neutralTemp: "cool",
|
|
1180
|
+
accentMode: "analogous",
|
|
1181
|
+
surface: "soft"
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
id: "min-dark",
|
|
1185
|
+
name: "Min Dark",
|
|
1186
|
+
description: "Restrained cyan brand on pure dark neutral \u2014 the minimal Miniml/Min theme.",
|
|
1187
|
+
tags: ["editor", "minimal", "cool", "neutral"],
|
|
1188
|
+
primaryHue: 190,
|
|
1189
|
+
neutralTemp: "neutral",
|
|
1190
|
+
accentMode: "mono",
|
|
1191
|
+
surface: "crisp"
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
id: "poimandres",
|
|
1195
|
+
name: "Poimandres",
|
|
1196
|
+
description: "Teal-cyan brand on deep blue-grey \u2014 the muted, modern Poimandres palette.",
|
|
1197
|
+
tags: ["editor", "cool", "muted", "calm"],
|
|
1198
|
+
primaryHue: 188,
|
|
1199
|
+
neutralTemp: "cool",
|
|
1200
|
+
accentMode: "analogous",
|
|
1201
|
+
surface: "soft"
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
id: "flexoki",
|
|
1205
|
+
name: "Flexoki",
|
|
1206
|
+
description: "Warm red-brown brand on inky warm paper \u2014 the analog Flexoki palette.",
|
|
1207
|
+
tags: ["editor", "warm", "muted", "paper"],
|
|
1208
|
+
primaryHue: 25,
|
|
1209
|
+
neutralTemp: "warm",
|
|
1210
|
+
accentMode: "analogous",
|
|
1211
|
+
surface: "soft"
|
|
1212
|
+
},
|
|
1213
|
+
{
|
|
1214
|
+
id: "zenburn",
|
|
1215
|
+
name: "Zenburn",
|
|
1216
|
+
description: "Muted olive-tan brand on low-contrast warm grey \u2014 the classic low-glare Zenburn.",
|
|
1217
|
+
tags: ["editor", "warm", "muted", "low-contrast"],
|
|
1218
|
+
primaryHue: 95,
|
|
1219
|
+
neutralTemp: "warm",
|
|
1220
|
+
accentMode: "analogous",
|
|
1221
|
+
surface: "soft"
|
|
1222
|
+
},
|
|
1223
|
+
{
|
|
1224
|
+
id: "oxocarbon",
|
|
1225
|
+
name: "Oxocarbon",
|
|
1226
|
+
description: "Magenta-violet brand with a cyan accent on pure carbon grey \u2014 IBM-inspired Oxocarbon.",
|
|
1227
|
+
tags: ["editor", "vibrant", "neutral", "cool"],
|
|
1228
|
+
primaryHue: 300,
|
|
1229
|
+
neutralTemp: "neutral",
|
|
1230
|
+
accentMode: "triadic",
|
|
1231
|
+
surface: "crisp"
|
|
1232
|
+
},
|
|
1233
|
+
{
|
|
1234
|
+
id: "iceberg",
|
|
1235
|
+
name: "Iceberg",
|
|
1236
|
+
description: "Cool periwinkle-blue brand on icy blue-grey \u2014 the restrained Iceberg palette.",
|
|
1237
|
+
tags: ["editor", "cool", "muted", "calm"],
|
|
1238
|
+
primaryHue: 245,
|
|
1239
|
+
neutralTemp: "cool",
|
|
1240
|
+
accentMode: "analogous",
|
|
1241
|
+
surface: "soft"
|
|
1242
|
+
},
|
|
1243
|
+
{
|
|
1244
|
+
id: "apprentice",
|
|
1245
|
+
name: "Apprentice",
|
|
1246
|
+
description: "Muted khaki-green brand on warm dark grey \u2014 the low-key Apprentice terminal palette.",
|
|
1247
|
+
tags: ["editor", "warm", "muted", "low-contrast"],
|
|
1248
|
+
primaryHue: 100,
|
|
1249
|
+
neutralTemp: "warm",
|
|
1250
|
+
accentMode: "analogous",
|
|
1251
|
+
surface: "soft"
|
|
1252
|
+
},
|
|
1253
|
+
{
|
|
1254
|
+
id: "tomorrow-night",
|
|
1255
|
+
name: "Tomorrow Night",
|
|
1256
|
+
description: "Calm blue brand on neutral charcoal \u2014 the balanced Tomorrow Night classic.",
|
|
1257
|
+
tags: ["editor", "cool", "calm", "neutral"],
|
|
1258
|
+
primaryHue: 222,
|
|
1259
|
+
neutralTemp: "neutral",
|
|
1260
|
+
accentMode: "complementary",
|
|
1261
|
+
surface: "crisp"
|
|
1262
|
+
},
|
|
1263
|
+
{
|
|
1264
|
+
id: "embark",
|
|
1265
|
+
name: "Embark",
|
|
1266
|
+
description: "Violet brand with a teal accent on deep blue-purple \u2014 the vivid Embark palette.",
|
|
1267
|
+
tags: ["editor", "vibrant", "cool"],
|
|
1268
|
+
primaryHue: 278,
|
|
1269
|
+
neutralTemp: "cool",
|
|
1270
|
+
accentMode: "triadic",
|
|
1271
|
+
surface: "soft"
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
id: "moonlight",
|
|
1275
|
+
name: "Moonlight",
|
|
1276
|
+
description: "Periwinkle-violet brand on deep blue night \u2014 the dreamy Moonlight II palette.",
|
|
1277
|
+
tags: ["editor", "cool", "calm", "soft"],
|
|
1278
|
+
primaryHue: 262,
|
|
1279
|
+
neutralTemp: "cool",
|
|
1280
|
+
accentMode: "analogous",
|
|
1281
|
+
surface: "soft"
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
id: "bearded",
|
|
1285
|
+
name: "Bearded",
|
|
1286
|
+
description: "Magenta brand with a green accent on cool charcoal \u2014 a bold Bearded-style palette.",
|
|
1287
|
+
tags: ["editor", "vibrant", "cool"],
|
|
1288
|
+
primaryHue: 315,
|
|
1289
|
+
neutralTemp: "cool",
|
|
1290
|
+
accentMode: "complementary",
|
|
1291
|
+
surface: "crisp"
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
id: "city-lights",
|
|
1295
|
+
name: "City Lights",
|
|
1296
|
+
description: "Steel-blue brand on deep blue-grey \u2014 the muted, urban City Lights palette.",
|
|
1297
|
+
tags: ["editor", "cool", "muted", "calm"],
|
|
1298
|
+
primaryHue: 205,
|
|
1299
|
+
neutralTemp: "cool",
|
|
1300
|
+
accentMode: "analogous",
|
|
1301
|
+
surface: "soft"
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
id: "snazzy",
|
|
1305
|
+
name: "Snazzy",
|
|
1306
|
+
description: "Bright cyan brand with a magenta accent on near-black \u2014 the punchy Hyper Snazzy.",
|
|
1307
|
+
tags: ["terminal", "vibrant", "cool", "neon"],
|
|
1308
|
+
primaryHue: 188,
|
|
1309
|
+
neutralTemp: "cool",
|
|
1310
|
+
accentMode: "triadic",
|
|
1311
|
+
surface: "crisp"
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
id: "tomorrow-light",
|
|
1315
|
+
name: "Tomorrow",
|
|
1316
|
+
description: "Soft blue brand on clean neutral paper \u2014 the original light Tomorrow.",
|
|
1317
|
+
tags: ["editor", "neutral", "calm", "light"],
|
|
1318
|
+
primaryHue: 222,
|
|
1319
|
+
neutralTemp: "neutral",
|
|
1320
|
+
accentMode: "complementary",
|
|
1321
|
+
surface: "crisp"
|
|
1322
|
+
},
|
|
1323
|
+
{
|
|
1324
|
+
id: "paper-color",
|
|
1325
|
+
name: "PaperColor",
|
|
1326
|
+
description: "Crisp blue brand on bright paper-white \u2014 the print-like PaperColor light theme.",
|
|
1327
|
+
tags: ["editor", "neutral", "paper", "light"],
|
|
1328
|
+
primaryHue: 228,
|
|
1329
|
+
neutralTemp: "neutral",
|
|
1330
|
+
accentMode: "complementary",
|
|
1331
|
+
surface: "crisp"
|
|
1332
|
+
},
|
|
1333
|
+
{
|
|
1334
|
+
id: "quietlight",
|
|
1335
|
+
name: "Quiet Light",
|
|
1336
|
+
description: "Olive-green brand on warm cream \u2014 the soft, low-contrast Quiet Light.",
|
|
1337
|
+
tags: ["editor", "warm", "soft", "light"],
|
|
1338
|
+
primaryHue: 110,
|
|
1339
|
+
neutralTemp: "warm",
|
|
1340
|
+
accentMode: "analogous",
|
|
1341
|
+
surface: "soft"
|
|
1342
|
+
}
|
|
1343
|
+
];
|
|
1344
|
+
var HUE_STOPS = [
|
|
1345
|
+
{ hue: 0, family: "Scarlet", word: "Ember" },
|
|
1346
|
+
{ hue: 24, family: "Coral", word: "Flare" },
|
|
1347
|
+
{ hue: 48, family: "Marigold", word: "Glow" },
|
|
1348
|
+
{ hue: 72, family: "Citron", word: "Zest" },
|
|
1349
|
+
{ hue: 96, family: "Chartreuse", word: "Sprout" },
|
|
1350
|
+
{ hue: 120, family: "Clover", word: "Meadow" },
|
|
1351
|
+
{ hue: 144, family: "Jade", word: "Grove" },
|
|
1352
|
+
{ hue: 168, family: "Spruce", word: "Tide" },
|
|
1353
|
+
{ hue: 192, family: "Lagoon", word: "Reef" },
|
|
1354
|
+
{ hue: 216, family: "Cerulean", word: "Drift" },
|
|
1355
|
+
{ hue: 240, family: "Sapphire", word: "Dusk" },
|
|
1356
|
+
{ hue: 264, family: "Iris", word: "Nocturne" },
|
|
1357
|
+
{ hue: 288, family: "Orchid", word: "Bloom" },
|
|
1358
|
+
{ hue: 312, family: "Fuchsia", word: "Pulse" },
|
|
1359
|
+
{ hue: 336, family: "Magenta", word: "Blush" }
|
|
1360
|
+
];
|
|
1361
|
+
var ACCENT_VARIANTS = [
|
|
1362
|
+
{ mode: "complementary", init: "x", word: "complementary" },
|
|
1363
|
+
{ mode: "analogous", init: "a", word: "analogous" },
|
|
1364
|
+
{ mode: "triadic", init: "t", word: "triadic" }
|
|
1365
|
+
];
|
|
1366
|
+
var TEMP_VARIANTS = [
|
|
1367
|
+
{ temp: "cool", init: "c" },
|
|
1368
|
+
{ temp: "warm", init: "w" }
|
|
1369
|
+
];
|
|
1370
|
+
function buildSpectrumSeeds() {
|
|
1371
|
+
const seeds = [];
|
|
1372
|
+
for (const stop of HUE_STOPS) {
|
|
1373
|
+
let i = 0;
|
|
1374
|
+
for (const accent of ACCENT_VARIANTS) {
|
|
1375
|
+
for (const temp of TEMP_VARIANTS) {
|
|
1376
|
+
const surface = i % 2 === 0 ? "crisp" : "soft";
|
|
1377
|
+
const tempWord = temp.temp === "cool" ? "cool" : "warm";
|
|
1378
|
+
seeds.push({
|
|
1379
|
+
id: `spectrum-${stop.hue}-${accent.init}${temp.init}`,
|
|
1380
|
+
name: `${stop.family} ${stop.word}`,
|
|
1381
|
+
description: `${stop.family} brand at hue ${stop.hue}\xB0 \u2014 ${accent.word} accent on ${tempWord} neutrals (${surface} surfaces).`,
|
|
1382
|
+
tags: ["spectrum", "sweep", stop.family.toLowerCase(), tempWord, accent.word],
|
|
1383
|
+
primaryHue: stop.hue,
|
|
1384
|
+
neutralTemp: temp.temp,
|
|
1385
|
+
accentMode: accent.mode,
|
|
1386
|
+
surface
|
|
1387
|
+
});
|
|
1388
|
+
i++;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return seeds;
|
|
1393
|
+
}
|
|
1394
|
+
var SPECTRUM_SEEDS = buildSpectrumSeeds();
|
|
1395
|
+
var POOL_SEEDS = [...NAMED_SEEDS, ...SPECTRUM_SEEDS];
|
|
1396
|
+
|
|
1397
|
+
// src/themes/registry.ts
|
|
1398
|
+
var THEME_SEEDS = [
|
|
1399
|
+
{
|
|
1400
|
+
id: "wow",
|
|
1401
|
+
name: "WoW",
|
|
1402
|
+
description: "House blue \u2014 the @wow-two-beta/ui default vibe, regenerated in OKLCH.",
|
|
1403
|
+
tags: ["brand", "default"],
|
|
1404
|
+
primaryHue: 264,
|
|
1405
|
+
neutralTemp: "cool",
|
|
1406
|
+
accentMode: "analogous",
|
|
1407
|
+
surface: "crisp"
|
|
1408
|
+
},
|
|
1409
|
+
{
|
|
1410
|
+
id: "midnight",
|
|
1411
|
+
name: "Midnight",
|
|
1412
|
+
description: "Deep indigo on cool slate \u2014 calm, focused, low-glare.",
|
|
1413
|
+
tags: ["cool", "calm"],
|
|
1414
|
+
primaryHue: 268,
|
|
1415
|
+
neutralTemp: "cool",
|
|
1416
|
+
accentMode: "triadic",
|
|
1417
|
+
surface: "soft"
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
id: "slate",
|
|
1421
|
+
name: "Slate",
|
|
1422
|
+
description: "Neutral steel-blue brand on balanced greys \u2014 quiet and professional.",
|
|
1423
|
+
tags: ["neutral", "professional"],
|
|
1424
|
+
primaryHue: 235,
|
|
1425
|
+
neutralTemp: "cool",
|
|
1426
|
+
accentMode: "complementary",
|
|
1427
|
+
surface: "crisp"
|
|
1428
|
+
},
|
|
1429
|
+
{
|
|
1430
|
+
id: "ocean",
|
|
1431
|
+
name: "Ocean",
|
|
1432
|
+
description: "Azure brand with a teal accent over cool neutrals.",
|
|
1433
|
+
tags: ["cool", "fresh"],
|
|
1434
|
+
primaryHue: 222,
|
|
1435
|
+
neutralTemp: "cool",
|
|
1436
|
+
accentMode: "analogous",
|
|
1437
|
+
surface: "crisp"
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
id: "forest",
|
|
1441
|
+
name: "Forest",
|
|
1442
|
+
description: "Pine green brand, warm-leaning neutrals, earthy accent.",
|
|
1443
|
+
tags: ["nature", "warm"],
|
|
1444
|
+
primaryHue: 150,
|
|
1445
|
+
neutralTemp: "warm",
|
|
1446
|
+
accentMode: "analogous",
|
|
1447
|
+
surface: "soft"
|
|
1448
|
+
},
|
|
1449
|
+
{
|
|
1450
|
+
id: "emerald",
|
|
1451
|
+
name: "Emerald",
|
|
1452
|
+
description: "Vivid green-teal brand on crisp cool greys.",
|
|
1453
|
+
tags: ["nature", "cool"],
|
|
1454
|
+
primaryHue: 165,
|
|
1455
|
+
neutralTemp: "cool",
|
|
1456
|
+
accentMode: "complementary",
|
|
1457
|
+
surface: "crisp"
|
|
1458
|
+
},
|
|
1459
|
+
{
|
|
1460
|
+
id: "sunset",
|
|
1461
|
+
name: "Sunset",
|
|
1462
|
+
description: "Warm orange brand with a violet accent \u2014 energetic dusk palette.",
|
|
1463
|
+
tags: ["warm", "vibrant"],
|
|
1464
|
+
primaryHue: 42,
|
|
1465
|
+
neutralTemp: "warm",
|
|
1466
|
+
accentMode: "complementary",
|
|
1467
|
+
surface: "crisp"
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
id: "amber",
|
|
1471
|
+
name: "Amber",
|
|
1472
|
+
description: "Golden brand on warm stone \u2014 cozy and grounded.",
|
|
1473
|
+
tags: ["warm", "cozy"],
|
|
1474
|
+
primaryHue: 75,
|
|
1475
|
+
neutralTemp: "warm",
|
|
1476
|
+
accentMode: "triadic",
|
|
1477
|
+
surface: "soft"
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
id: "rose",
|
|
1481
|
+
name: "Rose",
|
|
1482
|
+
description: "Soft crimson-pink brand with a warm neutral ground.",
|
|
1483
|
+
tags: ["warm", "soft"],
|
|
1484
|
+
primaryHue: 12,
|
|
1485
|
+
neutralTemp: "warm",
|
|
1486
|
+
accentMode: "analogous",
|
|
1487
|
+
surface: "soft"
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
id: "crimson",
|
|
1491
|
+
name: "Crimson",
|
|
1492
|
+
description: "Bold red brand on neutral greys \u2014 high-impact and direct.",
|
|
1493
|
+
tags: ["warm", "bold"],
|
|
1494
|
+
primaryHue: 25,
|
|
1495
|
+
neutralTemp: "neutral",
|
|
1496
|
+
accentMode: "complementary",
|
|
1497
|
+
surface: "crisp"
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
id: "plum",
|
|
1501
|
+
name: "Plum",
|
|
1502
|
+
description: "Rich magenta-purple brand with a green accent.",
|
|
1503
|
+
tags: ["vibrant", "cool"],
|
|
1504
|
+
primaryHue: 330,
|
|
1505
|
+
neutralTemp: "cool",
|
|
1506
|
+
accentMode: "complementary",
|
|
1507
|
+
surface: "crisp"
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
id: "grape",
|
|
1511
|
+
name: "Grape",
|
|
1512
|
+
description: "Royal violet brand over cool neutrals, analogous accent.",
|
|
1513
|
+
tags: ["cool", "vibrant"],
|
|
1514
|
+
primaryHue: 295,
|
|
1515
|
+
neutralTemp: "cool",
|
|
1516
|
+
accentMode: "analogous",
|
|
1517
|
+
surface: "soft"
|
|
1518
|
+
},
|
|
1519
|
+
{
|
|
1520
|
+
id: "lavender",
|
|
1521
|
+
name: "Lavender",
|
|
1522
|
+
description: "Gentle violet brand, soft surfaces, low-glare.",
|
|
1523
|
+
tags: ["cool", "soft"],
|
|
1524
|
+
primaryHue: 285,
|
|
1525
|
+
neutralTemp: "cool",
|
|
1526
|
+
accentMode: "triadic",
|
|
1527
|
+
surface: "soft"
|
|
1528
|
+
},
|
|
1529
|
+
{
|
|
1530
|
+
id: "teal",
|
|
1531
|
+
name: "Teal",
|
|
1532
|
+
description: "Balanced teal brand with a coral accent on neutral greys.",
|
|
1533
|
+
tags: ["cool", "fresh"],
|
|
1534
|
+
primaryHue: 195,
|
|
1535
|
+
neutralTemp: "neutral",
|
|
1536
|
+
accentMode: "complementary",
|
|
1537
|
+
surface: "crisp"
|
|
1538
|
+
},
|
|
1539
|
+
{
|
|
1540
|
+
id: "cyan",
|
|
1541
|
+
name: "Cyan",
|
|
1542
|
+
description: "Bright cyan brand, cool neutrals, electric feel.",
|
|
1543
|
+
tags: ["cool", "vibrant"],
|
|
1544
|
+
primaryHue: 210,
|
|
1545
|
+
neutralTemp: "cool",
|
|
1546
|
+
accentMode: "analogous",
|
|
1547
|
+
surface: "crisp"
|
|
1548
|
+
},
|
|
1549
|
+
{
|
|
1550
|
+
id: "mint",
|
|
1551
|
+
name: "Mint",
|
|
1552
|
+
description: "Light spring-green brand on soft cool greys.",
|
|
1553
|
+
tags: ["nature", "soft"],
|
|
1554
|
+
primaryHue: 158,
|
|
1555
|
+
neutralTemp: "neutral",
|
|
1556
|
+
accentMode: "analogous",
|
|
1557
|
+
surface: "soft"
|
|
1558
|
+
},
|
|
1559
|
+
{
|
|
1560
|
+
id: "nord",
|
|
1561
|
+
name: "Nord",
|
|
1562
|
+
description: "Arctic blue brand on desaturated cool slate \u2014 Nord-inspired.",
|
|
1563
|
+
tags: ["cool", "calm", "muted"],
|
|
1564
|
+
primaryHue: 213,
|
|
1565
|
+
neutralTemp: "cool",
|
|
1566
|
+
accentMode: "analogous",
|
|
1567
|
+
surface: "soft"
|
|
1568
|
+
},
|
|
1569
|
+
{
|
|
1570
|
+
id: "solarized",
|
|
1571
|
+
name: "Solarized",
|
|
1572
|
+
description: "Cyan-blue brand on warm tan neutrals \u2014 Solarized-inspired balance.",
|
|
1573
|
+
tags: ["warm", "muted"],
|
|
1574
|
+
primaryHue: 205,
|
|
1575
|
+
neutralTemp: "warm",
|
|
1576
|
+
accentMode: "complementary",
|
|
1577
|
+
surface: "soft"
|
|
1578
|
+
},
|
|
1579
|
+
{
|
|
1580
|
+
id: "dracula",
|
|
1581
|
+
name: "Dracula",
|
|
1582
|
+
description: "Purple brand with a pink-magenta accent on cool neutrals \u2014 Dracula-inspired.",
|
|
1583
|
+
tags: ["cool", "vibrant"],
|
|
1584
|
+
primaryHue: 265,
|
|
1585
|
+
neutralTemp: "cool",
|
|
1586
|
+
accentMode: "triadic",
|
|
1587
|
+
surface: "crisp"
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
id: "gruvbox",
|
|
1591
|
+
name: "Gruvbox",
|
|
1592
|
+
description: "Warm orange-amber brand on retro warm neutrals \u2014 Gruvbox-inspired.",
|
|
1593
|
+
tags: ["warm", "retro", "muted"],
|
|
1594
|
+
primaryHue: 50,
|
|
1595
|
+
neutralTemp: "warm",
|
|
1596
|
+
accentMode: "analogous",
|
|
1597
|
+
surface: "soft"
|
|
1598
|
+
},
|
|
1599
|
+
{
|
|
1600
|
+
id: "monokai",
|
|
1601
|
+
name: "Monokai",
|
|
1602
|
+
description: "Lime-green brand with a magenta accent on neutral greys \u2014 Monokai-inspired.",
|
|
1603
|
+
tags: ["vibrant", "neutral"],
|
|
1604
|
+
primaryHue: 130,
|
|
1605
|
+
neutralTemp: "neutral",
|
|
1606
|
+
accentMode: "complementary",
|
|
1607
|
+
surface: "crisp"
|
|
1608
|
+
},
|
|
1609
|
+
{
|
|
1610
|
+
id: "mono",
|
|
1611
|
+
name: "Mono",
|
|
1612
|
+
description: "Achromatic \u2014 black/white brand on pure neutral greys. Minimal, content-first.",
|
|
1613
|
+
tags: ["neutral", "minimal", "grayscale"],
|
|
1614
|
+
primaryHue: 270,
|
|
1615
|
+
neutralTemp: "neutral",
|
|
1616
|
+
accentMode: "mono",
|
|
1617
|
+
surface: "crisp"
|
|
1618
|
+
},
|
|
1619
|
+
{
|
|
1620
|
+
id: "graphite",
|
|
1621
|
+
name: "Graphite",
|
|
1622
|
+
description: "Near-mono with a faint cool-blue brand \u2014 understated and dense.",
|
|
1623
|
+
tags: ["neutral", "minimal"],
|
|
1624
|
+
primaryHue: 240,
|
|
1625
|
+
neutralTemp: "cool",
|
|
1626
|
+
accentMode: "mono",
|
|
1627
|
+
surface: "crisp"
|
|
1628
|
+
},
|
|
1629
|
+
{
|
|
1630
|
+
id: "sand",
|
|
1631
|
+
name: "Sand",
|
|
1632
|
+
description: "Warm taupe brand on soft sandy neutrals \u2014 paper-like and gentle.",
|
|
1633
|
+
tags: ["warm", "soft", "minimal"],
|
|
1634
|
+
primaryHue: 60,
|
|
1635
|
+
neutralTemp: "warm",
|
|
1636
|
+
accentMode: "mono",
|
|
1637
|
+
surface: "soft"
|
|
1638
|
+
}
|
|
1639
|
+
];
|
|
1640
|
+
var CANDIDATE_SEEDS = [...THEME_SEEDS, ...POOL_SEEDS];
|
|
1641
|
+
var CANDIDATE_THEMES = CANDIDATE_SEEDS.map(generateTheme);
|
|
1642
|
+
var THEMES = [...VALIDATED_THEMES, ...CANDIDATE_THEMES];
|
|
1643
|
+
function getTheme(id) {
|
|
1644
|
+
return THEMES.find((t) => t.id === id);
|
|
1645
|
+
}
|
|
1646
|
+
function validatedThemes() {
|
|
1647
|
+
return THEMES.filter((t) => t.status === ThemeStatus.Validated);
|
|
1648
|
+
}
|
|
1649
|
+
function candidateThemes() {
|
|
1650
|
+
return THEMES.filter((t) => t.status === ThemeStatus.Candidate);
|
|
1651
|
+
}
|
|
1652
|
+
var THEME_IDS = THEMES.map((t) => t.id);
|
|
1653
|
+
|
|
1654
|
+
export { AA_TEXT, AA_UI, Oklch, SEMANTIC_TOKENS, SURFACE_TOKENS, THEMES, THEME_IDS, THEME_SEEDS, TONE_FAMILIES, ThemeStatus, applyToneSlots, candidateThemes, clampChromaToGamut, contrastPairs, contrastRatio, contrastRatioCss, emitAllThemesCss, emitThemesManifest, generateTheme, getTheme, isInSrgbGamut, normalizeHue, oklchToCss, oklchToHex, parseColor, relativeLuminance, themeToCss, themes_exports, validateTheme, validatedThemes };
|
|
1655
|
+
//# sourceMappingURL=chunk-LS4EGKUK.js.map
|
|
1656
|
+
//# sourceMappingURL=chunk-LS4EGKUK.js.map
|