@tenphi/glaze 0.14.0 → 0.15.1
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/README.md +1 -1
- package/dist/index.cjs +206 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -28
- package/dist/index.d.mts +83 -28
- package/dist/index.mjs +206 -160
- package/dist/index.mjs.map +1 -1
- package/docs/api.md +38 -9
- package/docs/migration.md +1 -1
- package/docs/okhst.md +1 -9
- package/package.json +6 -2
package/dist/index.mjs
CHANGED
|
@@ -256,10 +256,48 @@ const getCs = (L, a, b, cusp) => {
|
|
|
256
256
|
cMax
|
|
257
257
|
];
|
|
258
258
|
};
|
|
259
|
+
const CYAN_A = Math.cos(199.8 * Math.PI / 180);
|
|
260
|
+
const CYAN_B = Math.sin(199.8 * Math.PI / 180);
|
|
261
|
+
const BLUE_A = Math.cos(267.4 * Math.PI / 180);
|
|
262
|
+
const BLUE_B = Math.sin(267.4 * Math.PI / 180);
|
|
263
|
+
let cyanCusp;
|
|
264
|
+
let blueCusp;
|
|
265
|
+
/**
|
|
266
|
+
* Computes the maximum safe OKLCH chroma that fits inside the sRGB gamut
|
|
267
|
+
* for all possible hues at a given OKLab lightness `L`.
|
|
268
|
+
*/
|
|
269
|
+
function computeSafeChromaOKLCH(L) {
|
|
270
|
+
if (!cyanCusp) cyanCusp = findCuspOKLCH(CYAN_A, CYAN_B);
|
|
271
|
+
if (!blueCusp) blueCusp = findCuspOKLCH(BLUE_A, BLUE_B);
|
|
272
|
+
const c1 = findGamutIntersectionOKLCH(CYAN_A, CYAN_B, L, 1, L, cyanCusp);
|
|
273
|
+
const c2 = findGamutIntersectionOKLCH(BLUE_A, BLUE_B, L, 1, L, blueCusp);
|
|
274
|
+
return Math.min(c1, c2);
|
|
275
|
+
}
|
|
276
|
+
/** Per-hue cusp-lightness cache. The cusp is mode-independent, so keying on
|
|
277
|
+
* a rounded hue is safe and keeps the cache small. */
|
|
278
|
+
const cuspLightnessCache = /* @__PURE__ */ new Map();
|
|
279
|
+
/**
|
|
280
|
+
* OKHSL lightness of the gamut cusp for a hue — the lightness where the
|
|
281
|
+
* realizable chroma peaks. Reuses the same `find_cusp` OKHSL already runs for
|
|
282
|
+
* its `s` normalization (no new color math); the OKLab cusp lightness is run
|
|
283
|
+
* through the OKHSL `toe` and clamped to `[0.001, 0.999]` so divisions that
|
|
284
|
+
* key off it stay safe. Cached per (rounded) hue.
|
|
285
|
+
*
|
|
286
|
+
* @param h Hue, 0–360.
|
|
287
|
+
*/
|
|
288
|
+
function cuspLightness(h) {
|
|
289
|
+
const key = Math.round(constrainAngle(h) * 100) / 100;
|
|
290
|
+
const cached = cuspLightnessCache.get(key);
|
|
291
|
+
if (cached !== void 0) return cached;
|
|
292
|
+
const hNorm = key / 360;
|
|
293
|
+
const lc = clampVal(toe(findCuspOKLCH(Math.cos(TAU * hNorm), Math.sin(TAU * hNorm))[0]), .001, .999);
|
|
294
|
+
cuspLightnessCache.set(key, lc);
|
|
295
|
+
return lc;
|
|
296
|
+
}
|
|
259
297
|
/**
|
|
260
298
|
* Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to OKLab [L, a, b].
|
|
261
299
|
*/
|
|
262
|
-
function okhslToOklab(h, s, l) {
|
|
300
|
+
function okhslToOklab(h, s, l, pastel = false) {
|
|
263
301
|
const L = toeInv(l);
|
|
264
302
|
let a = 0;
|
|
265
303
|
let b = 0;
|
|
@@ -267,24 +305,30 @@ function okhslToOklab(h, s, l) {
|
|
|
267
305
|
if (L !== 0 && L !== 1 && s !== 0) {
|
|
268
306
|
const a_ = Math.cos(TAU * hNorm);
|
|
269
307
|
const b_ = Math.sin(TAU * hNorm);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (s < mid) {
|
|
275
|
-
t = midInv * s;
|
|
276
|
-
k0 = 0;
|
|
277
|
-
k1 = mid * c0;
|
|
278
|
-
k2 = 1 - k1 / cMid;
|
|
308
|
+
if (pastel) {
|
|
309
|
+
const c = s * computeSafeChromaOKLCH(L);
|
|
310
|
+
a = c * a_;
|
|
311
|
+
b = c * b_;
|
|
279
312
|
} else {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
313
|
+
const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
|
|
314
|
+
const mid = .8;
|
|
315
|
+
const midInv = 1.25;
|
|
316
|
+
let t, k0, k1, k2;
|
|
317
|
+
if (s < mid) {
|
|
318
|
+
t = midInv * s;
|
|
319
|
+
k0 = 0;
|
|
320
|
+
k1 = mid * c0;
|
|
321
|
+
k2 = 1 - k1 / cMid;
|
|
322
|
+
} else {
|
|
323
|
+
t = 5 * (s - .8);
|
|
324
|
+
k0 = cMid;
|
|
325
|
+
k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
|
|
326
|
+
k2 = 1 - k1 / (cMax - cMid);
|
|
327
|
+
}
|
|
328
|
+
const c = k0 + t * k1 / (1 - k2 * t);
|
|
329
|
+
a = c * a_;
|
|
330
|
+
b = c * b_;
|
|
284
331
|
}
|
|
285
|
-
const c = k0 + t * k1 / (1 - k2 * t);
|
|
286
|
-
a = c * a_;
|
|
287
|
-
b = c * b_;
|
|
288
332
|
}
|
|
289
333
|
return [
|
|
290
334
|
L,
|
|
@@ -296,8 +340,8 @@ function okhslToOklab(h, s, l) {
|
|
|
296
340
|
* Convert OKHSL (h: 0–360, s: 0–1, l: 0–1) to linear sRGB.
|
|
297
341
|
* Channels may exceed [0, 1] near gamut boundaries — caller must clamp if needed.
|
|
298
342
|
*/
|
|
299
|
-
function okhslToLinearSrgb(h, s, l) {
|
|
300
|
-
return OKLabToLinearSRGB(okhslToOklab(h, s, l));
|
|
343
|
+
function okhslToLinearSrgb(h, s, l, pastel = false) {
|
|
344
|
+
return OKLabToLinearSRGB(okhslToOklab(h, s, l, pastel));
|
|
301
345
|
}
|
|
302
346
|
/**
|
|
303
347
|
* Compute relative luminance Y from linear sRGB channels.
|
|
@@ -327,8 +371,8 @@ const sRGBGammaToLinear = (val) => {
|
|
|
327
371
|
/**
|
|
328
372
|
* Convert OKHSL to gamma-encoded sRGB (clamped to 0–1).
|
|
329
373
|
*/
|
|
330
|
-
function okhslToSrgb(h, s, l) {
|
|
331
|
-
const lin = okhslToLinearSrgb(h, s, l);
|
|
374
|
+
function okhslToSrgb(h, s, l, pastel = false) {
|
|
375
|
+
const lin = okhslToLinearSrgb(h, s, l, pastel);
|
|
332
376
|
return [
|
|
333
377
|
Math.max(0, Math.min(1, sRGBLinearToGamma(lin[0]))),
|
|
334
378
|
Math.max(0, Math.min(1, sRGBLinearToGamma(lin[1]))),
|
|
@@ -370,7 +414,7 @@ const linearSrgbToOklab = (rgb) => {
|
|
|
370
414
|
* Input: [L, a, b] where L: 0–1, a/b: roughly -0.5 to 0.5.
|
|
371
415
|
* Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.
|
|
372
416
|
*/
|
|
373
|
-
const oklabToOkhsl = (lab) => {
|
|
417
|
+
const oklabToOkhsl = (lab, pastel = false) => {
|
|
374
418
|
const L = lab[0];
|
|
375
419
|
const a = lab[1];
|
|
376
420
|
const b = lab[2];
|
|
@@ -390,19 +434,22 @@ const oklabToOkhsl = (lab) => {
|
|
|
390
434
|
const b_ = b / C;
|
|
391
435
|
let h = Math.atan2(b, a) * (180 / Math.PI);
|
|
392
436
|
h = constrainAngle(h);
|
|
393
|
-
const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
|
|
394
|
-
const mid = .8;
|
|
395
|
-
const midInv = 1.25;
|
|
396
437
|
let s;
|
|
397
|
-
if (C
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
438
|
+
if (pastel) s = C / computeSafeChromaOKLCH(L);
|
|
439
|
+
else {
|
|
440
|
+
const [c0, cMid, cMax] = getCs(L, a_, b_, findCuspOKLCH(a_, b_));
|
|
441
|
+
const mid = .8;
|
|
442
|
+
const midInv = 1.25;
|
|
443
|
+
if (C < cMid) {
|
|
444
|
+
const k1 = mid * c0;
|
|
445
|
+
s = C / (k1 + C * (1 - k1 / cMid)) / midInv;
|
|
446
|
+
} else {
|
|
447
|
+
const k0 = cMid;
|
|
448
|
+
const k1 = .2 * cMid ** 2 * 1.25 ** 2 / c0;
|
|
449
|
+
const k2 = 1 - k1 / (cMax - cMid);
|
|
450
|
+
const cDiff = C - k0;
|
|
451
|
+
s = mid + cDiff / (k1 + cDiff * k2) / 5;
|
|
452
|
+
}
|
|
406
453
|
}
|
|
407
454
|
const l = toe(L);
|
|
408
455
|
return [
|
|
@@ -415,12 +462,12 @@ const oklabToOkhsl = (lab) => {
|
|
|
415
462
|
* Convert gamma-encoded sRGB (0–1 per channel) to OKHSL.
|
|
416
463
|
* Returns [h, s, l] where h: 0–360, s: 0–1, l: 0–1.
|
|
417
464
|
*/
|
|
418
|
-
function srgbToOkhsl(rgb) {
|
|
465
|
+
function srgbToOkhsl(rgb, pastel = false) {
|
|
419
466
|
return oklabToOkhsl(linearSrgbToOklab([
|
|
420
467
|
sRGBGammaToLinear(rgb[0]),
|
|
421
468
|
sRGBGammaToLinear(rgb[1]),
|
|
422
469
|
sRGBGammaToLinear(rgb[2])
|
|
423
|
-
]));
|
|
470
|
+
]), pastel);
|
|
424
471
|
}
|
|
425
472
|
/**
|
|
426
473
|
* Convert CSS HSL (sRGB-based) to gamma-encoded sRGB [r, g, b] in 0–1 range.
|
|
@@ -535,24 +582,26 @@ function fmt$1(value, decimals) {
|
|
|
535
582
|
* Format OKHSL values as a CSS `okhsl(H S% L%)` string.
|
|
536
583
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
537
584
|
*/
|
|
538
|
-
function formatOkhsl(h, s, l) {
|
|
539
|
-
|
|
585
|
+
function formatOkhsl(h, s, l, pastel = false) {
|
|
586
|
+
let outS = s;
|
|
587
|
+
if (pastel) outS = oklabToOkhsl(okhslToOklab(h, s / 100, l / 100, true), false)[1] * 100;
|
|
588
|
+
return `okhsl(${fmt$1(h, 2)} ${fmt$1(outS, 2)}% ${fmt$1(l, 2)}%)`;
|
|
540
589
|
}
|
|
541
590
|
/**
|
|
542
591
|
* Format OKHSL values as a CSS `rgb(R G B)` string.
|
|
543
592
|
* Uses 2 decimal places to avoid 8-bit quantization contrast loss.
|
|
544
593
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
545
594
|
*/
|
|
546
|
-
function formatRgb(h, s, l) {
|
|
547
|
-
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
|
|
595
|
+
function formatRgb(h, s, l, pastel = false) {
|
|
596
|
+
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);
|
|
548
597
|
return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;
|
|
549
598
|
}
|
|
550
599
|
/**
|
|
551
600
|
* Format OKHSL values as a CSS `hsl(H S% L%)` string.
|
|
552
601
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
553
602
|
*/
|
|
554
|
-
function formatHsl(h, s, l) {
|
|
555
|
-
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
|
|
603
|
+
function formatHsl(h, s, l, pastel = false) {
|
|
604
|
+
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100, pastel);
|
|
556
605
|
const max = Math.max(r, g, b);
|
|
557
606
|
const min = Math.min(r, g, b);
|
|
558
607
|
const delta = max - min;
|
|
@@ -571,8 +620,8 @@ function formatHsl(h, s, l) {
|
|
|
571
620
|
* Format OKHSL values as a CSS `oklch(L C H)` string.
|
|
572
621
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
573
622
|
*/
|
|
574
|
-
function formatOklch(h, s, l) {
|
|
575
|
-
const [L, a, b] = okhslToOklab(h, s / 100, l / 100);
|
|
623
|
+
function formatOklch(h, s, l, pastel = false) {
|
|
624
|
+
const [L, a, b] = okhslToOklab(h, s / 100, l / 100, pastel);
|
|
576
625
|
const C = Math.sqrt(a * a + b * b);
|
|
577
626
|
let hh = Math.atan2(b, a) * (180 / Math.PI);
|
|
578
627
|
hh = constrainAngle(hh);
|
|
@@ -598,7 +647,6 @@ function defaultConfig() {
|
|
|
598
647
|
eps: .05
|
|
599
648
|
},
|
|
600
649
|
darkDesaturation: .1,
|
|
601
|
-
saturationTaper: .15,
|
|
602
650
|
states: {
|
|
603
651
|
dark: "@dark",
|
|
604
652
|
highContrast: "@high-contrast"
|
|
@@ -607,7 +655,8 @@ function defaultConfig() {
|
|
|
607
655
|
dark: true,
|
|
608
656
|
highContrast: false
|
|
609
657
|
},
|
|
610
|
-
autoFlip: true
|
|
658
|
+
autoFlip: true,
|
|
659
|
+
pastel: false
|
|
611
660
|
};
|
|
612
661
|
}
|
|
613
662
|
let globalConfig = defaultConfig();
|
|
@@ -637,7 +686,6 @@ function configure(config) {
|
|
|
637
686
|
lightTone: config.lightTone ?? globalConfig.lightTone,
|
|
638
687
|
darkTone: config.darkTone ?? globalConfig.darkTone,
|
|
639
688
|
darkDesaturation: config.darkDesaturation ?? globalConfig.darkDesaturation,
|
|
640
|
-
saturationTaper: config.saturationTaper ?? globalConfig.saturationTaper,
|
|
641
689
|
states: {
|
|
642
690
|
dark: config.states?.dark ?? globalConfig.states.dark,
|
|
643
691
|
highContrast: config.states?.highContrast ?? globalConfig.states.highContrast
|
|
@@ -647,7 +695,8 @@ function configure(config) {
|
|
|
647
695
|
highContrast: config.modes?.highContrast ?? globalConfig.modes.highContrast
|
|
648
696
|
},
|
|
649
697
|
shadowTuning: config.shadowTuning ?? globalConfig.shadowTuning,
|
|
650
|
-
autoFlip: config.autoFlip ?? globalConfig.autoFlip
|
|
698
|
+
autoFlip: config.autoFlip ?? globalConfig.autoFlip,
|
|
699
|
+
pastel: config.pastel ?? globalConfig.pastel
|
|
651
700
|
};
|
|
652
701
|
}
|
|
653
702
|
function resetConfig() {
|
|
@@ -666,11 +715,11 @@ function mergeConfig(base, override) {
|
|
|
666
715
|
lightTone: override.lightTone !== void 0 ? override.lightTone : base.lightTone,
|
|
667
716
|
darkTone: override.darkTone !== void 0 ? override.darkTone : base.darkTone,
|
|
668
717
|
darkDesaturation: override.darkDesaturation ?? base.darkDesaturation,
|
|
669
|
-
saturationTaper: override.saturationTaper ?? base.saturationTaper,
|
|
670
718
|
states: base.states,
|
|
671
719
|
modes: base.modes,
|
|
672
720
|
shadowTuning: override.shadowTuning ?? base.shadowTuning,
|
|
673
|
-
autoFlip: override.autoFlip ?? base.autoFlip
|
|
721
|
+
autoFlip: override.autoFlip ?? base.autoFlip,
|
|
722
|
+
pastel: override.pastel ?? base.pastel
|
|
674
723
|
};
|
|
675
724
|
}
|
|
676
725
|
|
|
@@ -763,8 +812,8 @@ function isAbsoluteTone(tone) {
|
|
|
763
812
|
* - the `{ h, s, t }` <-> `{ h, s, l }` color-space converters,
|
|
764
813
|
* - the resolved-variant edge adapter (`variantToOkhsl`),
|
|
765
814
|
* - the per-scheme tone mapping that replaced the Möbius dark curve
|
|
766
|
-
* (`mapToneForScheme`), the
|
|
767
|
-
*
|
|
815
|
+
* (`mapToneForScheme`), the dark desaturation reducer, and the solver's scheme
|
|
816
|
+
* tone range.
|
|
768
817
|
*
|
|
769
818
|
* See `docs/okhst.md` for the full specification and the calibrated
|
|
770
819
|
* default constants.
|
|
@@ -907,33 +956,6 @@ function mapSaturationDark(s, mode, config) {
|
|
|
907
956
|
if (mode === "static") return s;
|
|
908
957
|
return s * (1 - config.darkDesaturation);
|
|
909
958
|
}
|
|
910
|
-
/** Smoothstep `0..1`. */
|
|
911
|
-
function smoothstep(x) {
|
|
912
|
-
const t = clamp(x, 0, 1);
|
|
913
|
-
return t * t * (3 - 2 * t);
|
|
914
|
-
}
|
|
915
|
-
/** Fraction of the tone range over which the taper ramps in, per end. */
|
|
916
|
-
const TAPER_REGION = .15;
|
|
917
|
-
/**
|
|
918
|
-
* Gently taper saturation toward the tone extremes, where in-gamut chroma
|
|
919
|
-
* collapses and high saturation reads as noise. `taper` is the *strength*
|
|
920
|
-
* (0–1): the maximum fraction of saturation removed at the very edges. The
|
|
921
|
-
* rolloff ramps in smoothly over the outer {@link TAPER_REGION} of tone on
|
|
922
|
-
* each end, so mid-tones are untouched and high-tone surfaces keep most of
|
|
923
|
-
* their color. `taper = 0` disables the effect.
|
|
924
|
-
*
|
|
925
|
-
* @param s Saturation (0–1).
|
|
926
|
-
* @param toneFinal Stored canonical tone (0–1).
|
|
927
|
-
* @param taper Strength (0–1); default config is a gentle 0.15.
|
|
928
|
-
*/
|
|
929
|
-
function saturationEnvelope(s, toneFinal, taper) {
|
|
930
|
-
if (taper <= 0) return s;
|
|
931
|
-
const t = clamp(toneFinal, 0, 1);
|
|
932
|
-
const strength = clamp(taper, 0, 1);
|
|
933
|
-
const edge = Math.min(t, 1 - t);
|
|
934
|
-
if (edge >= TAPER_REGION) return s;
|
|
935
|
-
return s * (1 - strength * (1 - smoothstep(edge / TAPER_REGION)));
|
|
936
|
-
}
|
|
937
959
|
/**
|
|
938
960
|
* Tone search range (0–1) for the contrast solver in a given scheme.
|
|
939
961
|
* `static` searches the full range; otherwise the scheme window's tone
|
|
@@ -1038,12 +1060,12 @@ const cacheOrder = [];
|
|
|
1038
1060
|
* the metric's luminance basis. The metric is part of the cache key because
|
|
1039
1061
|
* WCAG and APCA derive different luminances from the same color.
|
|
1040
1062
|
*/
|
|
1041
|
-
function cachedLuminance(metric, h, s, t) {
|
|
1063
|
+
function cachedLuminance(metric, h, s, t, pastel) {
|
|
1042
1064
|
const tRounded = Math.round(t * 1e4) / 1e4;
|
|
1043
|
-
const key = `${metric}|${h}|${s}|${tRounded}`;
|
|
1065
|
+
const key = `${metric}|${h}|${s}|${tRounded}|${pastel}`;
|
|
1044
1066
|
const cached = luminanceCache.get(key);
|
|
1045
1067
|
if (cached !== void 0) return cached;
|
|
1046
|
-
const y = metricLuminance(metric, okhslToLinearSrgb(h, s, fromTone(tRounded * 100, REF_EPS)));
|
|
1068
|
+
const y = metricLuminance(metric, okhslToLinearSrgb(h, s, fromTone(tRounded * 100, REF_EPS), pastel));
|
|
1047
1069
|
if (luminanceCache.size >= CACHE_SIZE) {
|
|
1048
1070
|
const evict = cacheOrder.shift();
|
|
1049
1071
|
luminanceCache.delete(evict);
|
|
@@ -1174,14 +1196,11 @@ function solveNearestContrast(opts) {
|
|
|
1174
1196
|
* staying as close to `preferredTone` as possible.
|
|
1175
1197
|
*/
|
|
1176
1198
|
function findToneForContrast(options) {
|
|
1177
|
-
const { hue, saturation, preferredTone, baseLinearRgb, contrast, toneRange = [0, 1], epsilon = 1e-4, maxIterations = 18 } = options;
|
|
1199
|
+
const { hue, saturation, preferredTone, baseLinearRgb, contrast, toneRange = [0, 1], epsilon = 1e-4, maxIterations = 18, pastel = false } = options;
|
|
1178
1200
|
const { metric, target } = contrast;
|
|
1179
1201
|
const searchTarget = metric === "wcag" ? target * 1.01 : target + .5;
|
|
1180
1202
|
const yBase = metricLuminance(metric, baseLinearRgb);
|
|
1181
|
-
const
|
|
1182
|
-
const lum = taper > 0 ? (t) => {
|
|
1183
|
-
return metricLuminance(metric, okhslToLinearSrgb(hue, saturationEnvelope(saturation, t, taper), fromTone(t * 100, REF_EPS)));
|
|
1184
|
-
} : (t) => cachedLuminance(metric, hue, saturation, t);
|
|
1203
|
+
const lum = (t) => cachedLuminance(metric, hue, saturation, t, pastel);
|
|
1185
1204
|
const scorePref = metricScore(metric, lum(preferredTone), yBase);
|
|
1186
1205
|
if (scorePref >= searchTarget) return {
|
|
1187
1206
|
tone: preferredTone,
|
|
@@ -1520,7 +1539,8 @@ function toOkhslVariant(v) {
|
|
|
1520
1539
|
h: c.h,
|
|
1521
1540
|
s: c.s,
|
|
1522
1541
|
l: c.l,
|
|
1523
|
-
alpha: v.alpha
|
|
1542
|
+
alpha: v.alpha,
|
|
1543
|
+
pastel: v.pastel
|
|
1524
1544
|
};
|
|
1525
1545
|
}
|
|
1526
1546
|
/** Edge adapter: OKHSL-lightness variant → resolved variant (`t`). */
|
|
@@ -1567,6 +1587,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
1567
1587
|
const mode = def.mode ?? "auto";
|
|
1568
1588
|
const satFactor = clamp(def.saturation ?? 1, 0, 1);
|
|
1569
1589
|
const flip = def.flip ?? ctx.config.autoFlip;
|
|
1590
|
+
const pastel = def.pastel ?? ctx.config.pastel;
|
|
1570
1591
|
const baseVariant = getSchemeVariant(baseResolved, isDark, isHighContrast);
|
|
1571
1592
|
const baseTone = baseVariant.t * 100;
|
|
1572
1593
|
let preferredTone;
|
|
@@ -1585,7 +1606,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
1585
1606
|
const resolvedContrast = resolveContrastSpec(rawContrast, isHighContrast);
|
|
1586
1607
|
const effectiveSat = isDark ? mapSaturationDark(satFactor * ctx.saturation / 100, mode, ctx.config) : satFactor * ctx.saturation / 100;
|
|
1587
1608
|
const baseOkhsl = toOkhslVariant(baseVariant);
|
|
1588
|
-
const baseLinearRgb = okhslToLinearSrgb(baseOkhsl.h, baseOkhsl.s, baseOkhsl.l);
|
|
1609
|
+
const baseLinearRgb = okhslToLinearSrgb(baseOkhsl.h, baseOkhsl.s, baseOkhsl.l, baseVariant.pastel ?? ctx.config.pastel);
|
|
1589
1610
|
const toneRange = schemeToneRange(isDark, mode, isHighContrast, ctx.config);
|
|
1590
1611
|
let initialDirection;
|
|
1591
1612
|
if (preferredTone < baseTone) initialDirection = "darker";
|
|
@@ -1599,7 +1620,7 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
1599
1620
|
toneRange: [0, 1],
|
|
1600
1621
|
initialDirection,
|
|
1601
1622
|
flip,
|
|
1602
|
-
|
|
1623
|
+
pastel
|
|
1603
1624
|
});
|
|
1604
1625
|
if (!result.met) warnContrastUnmet(name, isDark, isHighContrast, resolvedContrast, result.contrast);
|
|
1605
1626
|
return {
|
|
@@ -1619,6 +1640,7 @@ function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
|
|
|
1619
1640
|
const mode = regDef.mode ?? "auto";
|
|
1620
1641
|
const isRoot = isAbsoluteTone(regDef.tone) && !regDef.base;
|
|
1621
1642
|
const effectiveHue = resolveEffectiveHue(ctx.hue, regDef.hue);
|
|
1643
|
+
const pastel = regDef.pastel ?? ctx.config.pastel;
|
|
1622
1644
|
let finalTone;
|
|
1623
1645
|
let satFactor;
|
|
1624
1646
|
if (isRoot) {
|
|
@@ -1631,14 +1653,14 @@ function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
|
|
|
1631
1653
|
satFactor = dep.satFactor;
|
|
1632
1654
|
}
|
|
1633
1655
|
const baseSat = satFactor * ctx.saturation / 100;
|
|
1634
|
-
|
|
1656
|
+
const finalSat = isDark ? mapSaturationDark(baseSat, mode, ctx.config) : baseSat;
|
|
1635
1657
|
const toneFraction = clamp(finalTone / 100, 0, 1);
|
|
1636
|
-
finalSat = saturationEnvelope(finalSat, toneFraction, ctx.config.saturationTaper);
|
|
1637
1658
|
return {
|
|
1638
1659
|
h: effectiveHue,
|
|
1639
1660
|
s: clamp(finalSat, 0, 1),
|
|
1640
1661
|
t: toneFraction,
|
|
1641
|
-
alpha: regDef.opacity ?? 1
|
|
1662
|
+
alpha: regDef.opacity ?? 1,
|
|
1663
|
+
pastel
|
|
1642
1664
|
};
|
|
1643
1665
|
}
|
|
1644
1666
|
function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
|
|
@@ -1647,10 +1669,13 @@ function resolveShadowForScheme(def, ctx, isDark, isHighContrast) {
|
|
|
1647
1669
|
if (def.fg) fgVariant = toOkhslVariant(getSchemeVariant(ctx.resolved.get(def.fg), isDark, isHighContrast));
|
|
1648
1670
|
const intensity = isHighContrast ? pairHC(def.intensity) : pairNormal(def.intensity);
|
|
1649
1671
|
const tuning = resolveShadowTuning(def.tuning, ctx.config.shadowTuning);
|
|
1650
|
-
return
|
|
1672
|
+
return {
|
|
1673
|
+
...toToneVariant(computeShadow(bgVariant, fgVariant, intensity, tuning)),
|
|
1674
|
+
pastel: def.pastel ?? ctx.config.pastel
|
|
1675
|
+
};
|
|
1651
1676
|
}
|
|
1652
|
-
function okhslVariantToLinearRgb(v) {
|
|
1653
|
-
return okhslToLinearSrgb(v.h, v.s, v.l);
|
|
1677
|
+
function okhslVariantToLinearRgb(v, pastel) {
|
|
1678
|
+
return okhslToLinearSrgb(v.h, v.s, v.l, pastel);
|
|
1654
1679
|
}
|
|
1655
1680
|
/**
|
|
1656
1681
|
* Resolve hue for OKHSL mixing, handling achromatic colors.
|
|
@@ -1673,12 +1698,12 @@ function linearSrgbLerp(base, target, t) {
|
|
|
1673
1698
|
base[2] + (target[2] - base[2]) * t
|
|
1674
1699
|
];
|
|
1675
1700
|
}
|
|
1676
|
-
function linearRgbToToneVariant(rgb) {
|
|
1701
|
+
function linearRgbToToneVariant(rgb, pastel) {
|
|
1677
1702
|
const [h, s, l] = srgbToOkhsl([
|
|
1678
1703
|
Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[0]))),
|
|
1679
1704
|
Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[1]))),
|
|
1680
1705
|
Math.max(0, Math.min(1, sRGBLinearToGamma(rgb[2])))
|
|
1681
|
-
]);
|
|
1706
|
+
], pastel);
|
|
1682
1707
|
return toToneVariant({
|
|
1683
1708
|
h,
|
|
1684
1709
|
s,
|
|
@@ -1694,15 +1719,16 @@ function resolveMixForScheme(def, ctx, isDark, isHighContrast) {
|
|
|
1694
1719
|
let t = clamp(isHighContrast ? pairHC(def.value) : pairNormal(def.value), 0, 100) / 100;
|
|
1695
1720
|
const blend = def.blend ?? "opaque";
|
|
1696
1721
|
const space = def.space ?? "okhsl";
|
|
1697
|
-
const
|
|
1698
|
-
const
|
|
1722
|
+
const pastel = def.pastel ?? ctx.config.pastel;
|
|
1723
|
+
const baseLinear = okhslVariantToLinearRgb(baseVariant, baseVariant.pastel ?? ctx.config.pastel);
|
|
1724
|
+
const targetLinear = okhslVariantToLinearRgb(targetVariant, targetVariant.pastel ?? ctx.config.pastel);
|
|
1699
1725
|
if (def.contrast !== void 0) {
|
|
1700
1726
|
const resolvedContrast = resolveContrastSpec(def.contrast, isHighContrast);
|
|
1701
1727
|
const metric = resolvedContrast.metric;
|
|
1702
1728
|
let luminanceAt;
|
|
1703
1729
|
if (blend === "transparent" || space === "srgb") luminanceAt = (v) => metricLuminance(metric, linearSrgbLerp(baseLinear, targetLinear, v));
|
|
1704
1730
|
else luminanceAt = (v) => {
|
|
1705
|
-
return metricLuminance(metric, okhslToLinearSrgb(mixHue(baseVariant, targetVariant, v), baseVariant.s + (targetVariant.s - baseVariant.s) * v, baseVariant.l + (targetVariant.l - baseVariant.l) * v));
|
|
1731
|
+
return metricLuminance(metric, okhslToLinearSrgb(mixHue(baseVariant, targetVariant, v), baseVariant.s + (targetVariant.s - baseVariant.s) * v, baseVariant.l + (targetVariant.l - baseVariant.l) * v, pastel));
|
|
1706
1732
|
};
|
|
1707
1733
|
t = findValueForMixContrast({
|
|
1708
1734
|
preferredValue: t,
|
|
@@ -1713,19 +1739,28 @@ function resolveMixForScheme(def, ctx, isDark, isHighContrast) {
|
|
|
1713
1739
|
flip: ctx.config.autoFlip
|
|
1714
1740
|
}).value;
|
|
1715
1741
|
}
|
|
1716
|
-
if (blend === "transparent") return
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
}
|
|
1742
|
+
if (blend === "transparent") return {
|
|
1743
|
+
...toToneVariant({
|
|
1744
|
+
h: targetVariant.h,
|
|
1745
|
+
s: targetVariant.s,
|
|
1746
|
+
l: targetVariant.l,
|
|
1747
|
+
alpha: clamp(t, 0, 1)
|
|
1748
|
+
}),
|
|
1749
|
+
pastel
|
|
1750
|
+
};
|
|
1751
|
+
if (space === "srgb") return {
|
|
1752
|
+
...linearRgbToToneVariant(linearSrgbLerp(baseLinear, targetLinear, t), pastel),
|
|
1753
|
+
pastel
|
|
1754
|
+
};
|
|
1755
|
+
return {
|
|
1756
|
+
...toToneVariant({
|
|
1757
|
+
h: mixHue(baseVariant, targetVariant, t),
|
|
1758
|
+
s: clamp(baseVariant.s + (targetVariant.s - baseVariant.s) * t, 0, 1),
|
|
1759
|
+
l: clamp(baseVariant.l + (targetVariant.l - baseVariant.l) * t, 0, 1),
|
|
1760
|
+
alpha: 1
|
|
1761
|
+
}),
|
|
1762
|
+
pastel
|
|
1763
|
+
};
|
|
1729
1764
|
}
|
|
1730
1765
|
function defMode(def) {
|
|
1731
1766
|
if (isShadowDef(def) || isMixDef(def)) return void 0;
|
|
@@ -1776,7 +1811,7 @@ function seedField(order, ctx, field, source) {
|
|
|
1776
1811
|
* resolved with a `base` + `contrast` may land slightly under the contrast
|
|
1777
1812
|
* its tone implies because chromatic luminance drifts from the gray tone.
|
|
1778
1813
|
*/
|
|
1779
|
-
function verifyContrastDrift(order, defs, result) {
|
|
1814
|
+
function verifyContrastDrift(order, defs, result, config) {
|
|
1780
1815
|
for (const name of order) {
|
|
1781
1816
|
const def = defs[name];
|
|
1782
1817
|
if (isShadowDef(def) || isMixDef(def)) continue;
|
|
@@ -1812,8 +1847,10 @@ function verifyContrastDrift(order, defs, result) {
|
|
|
1812
1847
|
const bVariant = base[s.field];
|
|
1813
1848
|
const cOkhsl = toOkhslVariant(cVariant);
|
|
1814
1849
|
const bOkhsl = toOkhslVariant(bVariant);
|
|
1815
|
-
const
|
|
1816
|
-
const
|
|
1850
|
+
const cPastel = cVariant.pastel ?? config.pastel;
|
|
1851
|
+
const bPastel = bVariant.pastel ?? config.pastel;
|
|
1852
|
+
const yC = metricLuminance(spec.metric, okhslToLinearSrgb(cOkhsl.h, cOkhsl.s, cOkhsl.l, cPastel));
|
|
1853
|
+
const yB = metricLuminance(spec.metric, okhslToLinearSrgb(bOkhsl.h, bOkhsl.s, bOkhsl.l, bPastel));
|
|
1817
1854
|
warnContrastDrift(name, s.isDark, s.isHighContrast, spec, yC, yB);
|
|
1818
1855
|
}
|
|
1819
1856
|
}
|
|
@@ -1846,7 +1883,7 @@ function resolveAllColors(hue, saturation, defs, config, externalBases) {
|
|
|
1846
1883
|
darkContrast: darkHCMap.get(name),
|
|
1847
1884
|
mode: defMode(defs[name])
|
|
1848
1885
|
});
|
|
1849
|
-
verifyContrastDrift(order, defs, result);
|
|
1886
|
+
verifyContrastDrift(order, defs, result, config);
|
|
1850
1887
|
return result;
|
|
1851
1888
|
}
|
|
1852
1889
|
|
|
@@ -1871,9 +1908,10 @@ const formatters = {
|
|
|
1871
1908
|
function fmt(value, decimals) {
|
|
1872
1909
|
return parseFloat(value.toFixed(decimals)).toString();
|
|
1873
1910
|
}
|
|
1874
|
-
function formatVariant(v, format = "okhsl") {
|
|
1911
|
+
function formatVariant(v, format = "okhsl", pastel = false) {
|
|
1912
|
+
const effectivePastel = v.pastel ?? pastel;
|
|
1875
1913
|
const { l } = variantToOkhsl(v);
|
|
1876
|
-
const base = formatters[format](v.h, v.s * 100, l * 100);
|
|
1914
|
+
const base = formatters[format](v.h, v.s * 100, l * 100, effectivePastel);
|
|
1877
1915
|
if (v.alpha >= 1) return base;
|
|
1878
1916
|
const closing = base.lastIndexOf(")");
|
|
1879
1917
|
return `${base.slice(0, closing)} / ${fmt(v.alpha, 4)})`;
|
|
@@ -1885,44 +1923,44 @@ function resolveModes(override) {
|
|
|
1885
1923
|
highContrast: override?.highContrast ?? cfg.modes.highContrast
|
|
1886
1924
|
};
|
|
1887
1925
|
}
|
|
1888
|
-
function buildTokenMap(resolved, prefix, states, modes, format = "okhsl") {
|
|
1926
|
+
function buildTokenMap(resolved, prefix, states, modes, format = "okhsl", pastel = false) {
|
|
1889
1927
|
const tokens = {};
|
|
1890
1928
|
for (const [name, color] of resolved) {
|
|
1891
1929
|
const key = `#${prefix}${name}`;
|
|
1892
|
-
const entry = { "": formatVariant(color.light, format) };
|
|
1893
|
-
if (modes.dark) entry[states.dark] = formatVariant(color.dark, format);
|
|
1894
|
-
if (modes.highContrast) entry[states.highContrast] = formatVariant(color.lightContrast, format);
|
|
1895
|
-
if (modes.dark && modes.highContrast) entry[`${states.dark} & ${states.highContrast}`] = formatVariant(color.darkContrast, format);
|
|
1930
|
+
const entry = { "": formatVariant(color.light, format, pastel) };
|
|
1931
|
+
if (modes.dark) entry[states.dark] = formatVariant(color.dark, format, pastel);
|
|
1932
|
+
if (modes.highContrast) entry[states.highContrast] = formatVariant(color.lightContrast, format, pastel);
|
|
1933
|
+
if (modes.dark && modes.highContrast) entry[`${states.dark} & ${states.highContrast}`] = formatVariant(color.darkContrast, format, pastel);
|
|
1896
1934
|
tokens[key] = entry;
|
|
1897
1935
|
}
|
|
1898
1936
|
return tokens;
|
|
1899
1937
|
}
|
|
1900
|
-
function buildFlatTokenMap(resolved, prefix, modes, format = "okhsl") {
|
|
1938
|
+
function buildFlatTokenMap(resolved, prefix, modes, format = "okhsl", pastel = false) {
|
|
1901
1939
|
const result = { light: {} };
|
|
1902
1940
|
if (modes.dark) result.dark = {};
|
|
1903
1941
|
if (modes.highContrast) result.lightContrast = {};
|
|
1904
1942
|
if (modes.dark && modes.highContrast) result.darkContrast = {};
|
|
1905
1943
|
for (const [name, color] of resolved) {
|
|
1906
1944
|
const key = `${prefix}${name}`;
|
|
1907
|
-
result.light[key] = formatVariant(color.light, format);
|
|
1908
|
-
if (modes.dark) result.dark[key] = formatVariant(color.dark, format);
|
|
1909
|
-
if (modes.highContrast) result.lightContrast[key] = formatVariant(color.lightContrast, format);
|
|
1910
|
-
if (modes.dark && modes.highContrast) result.darkContrast[key] = formatVariant(color.darkContrast, format);
|
|
1945
|
+
result.light[key] = formatVariant(color.light, format, pastel);
|
|
1946
|
+
if (modes.dark) result.dark[key] = formatVariant(color.dark, format, pastel);
|
|
1947
|
+
if (modes.highContrast) result.lightContrast[key] = formatVariant(color.lightContrast, format, pastel);
|
|
1948
|
+
if (modes.dark && modes.highContrast) result.darkContrast[key] = formatVariant(color.darkContrast, format, pastel);
|
|
1911
1949
|
}
|
|
1912
1950
|
return result;
|
|
1913
1951
|
}
|
|
1914
|
-
function buildJsonMap(resolved, modes, format = "okhsl") {
|
|
1952
|
+
function buildJsonMap(resolved, modes, format = "okhsl", pastel = false) {
|
|
1915
1953
|
const result = {};
|
|
1916
1954
|
for (const [name, color] of resolved) {
|
|
1917
|
-
const entry = { light: formatVariant(color.light, format) };
|
|
1918
|
-
if (modes.dark) entry.dark = formatVariant(color.dark, format);
|
|
1919
|
-
if (modes.highContrast) entry.lightContrast = formatVariant(color.lightContrast, format);
|
|
1920
|
-
if (modes.dark && modes.highContrast) entry.darkContrast = formatVariant(color.darkContrast, format);
|
|
1955
|
+
const entry = { light: formatVariant(color.light, format, pastel) };
|
|
1956
|
+
if (modes.dark) entry.dark = formatVariant(color.dark, format, pastel);
|
|
1957
|
+
if (modes.highContrast) entry.lightContrast = formatVariant(color.lightContrast, format, pastel);
|
|
1958
|
+
if (modes.dark && modes.highContrast) entry.darkContrast = formatVariant(color.darkContrast, format, pastel);
|
|
1921
1959
|
result[name] = entry;
|
|
1922
1960
|
}
|
|
1923
1961
|
return result;
|
|
1924
1962
|
}
|
|
1925
|
-
function buildCssMap(resolved, prefix, suffix, format) {
|
|
1963
|
+
function buildCssMap(resolved, prefix, suffix, format, pastel = false) {
|
|
1926
1964
|
const lines = {
|
|
1927
1965
|
light: [],
|
|
1928
1966
|
dark: [],
|
|
@@ -1931,10 +1969,10 @@ function buildCssMap(resolved, prefix, suffix, format) {
|
|
|
1931
1969
|
};
|
|
1932
1970
|
for (const [name, color] of resolved) {
|
|
1933
1971
|
const prop = `--${prefix}${name}${suffix}`;
|
|
1934
|
-
lines.light.push(`${prop}: ${formatVariant(color.light, format)};`);
|
|
1935
|
-
lines.dark.push(`${prop}: ${formatVariant(color.dark, format)};`);
|
|
1936
|
-
lines.lightContrast.push(`${prop}: ${formatVariant(color.lightContrast, format)};`);
|
|
1937
|
-
lines.darkContrast.push(`${prop}: ${formatVariant(color.darkContrast, format)};`);
|
|
1972
|
+
lines.light.push(`${prop}: ${formatVariant(color.light, format, pastel)};`);
|
|
1973
|
+
lines.dark.push(`${prop}: ${formatVariant(color.dark, format, pastel)};`);
|
|
1974
|
+
lines.lightContrast.push(`${prop}: ${formatVariant(color.lightContrast, format, pastel)};`);
|
|
1975
|
+
lines.darkContrast.push(`${prop}: ${formatVariant(color.darkContrast, format, pastel)};`);
|
|
1938
1976
|
}
|
|
1939
1977
|
return {
|
|
1940
1978
|
light: lines.light.join("\n"),
|
|
@@ -1986,7 +2024,6 @@ function buildValueFormConfigOverride(userOverride) {
|
|
|
1986
2024
|
lightTone: userOverride?.lightTone !== void 0 ? userOverride.lightTone : false,
|
|
1987
2025
|
darkTone: userOverride?.darkTone !== void 0 ? userOverride.darkTone : cfg.darkTone,
|
|
1988
2026
|
darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,
|
|
1989
|
-
saturationTaper: userOverride?.saturationTaper ?? cfg.saturationTaper,
|
|
1990
2027
|
autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,
|
|
1991
2028
|
shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning
|
|
1992
2029
|
};
|
|
@@ -2003,7 +2040,6 @@ function buildStructuredConfigOverride(userOverride) {
|
|
|
2003
2040
|
lightTone: userOverride?.lightTone !== void 0 ? userOverride.lightTone : cfg.lightTone,
|
|
2004
2041
|
darkTone: userOverride?.darkTone !== void 0 ? userOverride.darkTone : cfg.darkTone,
|
|
2005
2042
|
darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,
|
|
2006
|
-
saturationTaper: userOverride?.saturationTaper ?? cfg.saturationTaper,
|
|
2007
2043
|
autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,
|
|
2008
2044
|
shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning
|
|
2009
2045
|
};
|
|
@@ -2288,6 +2324,7 @@ function buildStandaloneValueDefs(main, options) {
|
|
|
2288
2324
|
mode: options?.mode ?? "auto",
|
|
2289
2325
|
flip: options?.flip,
|
|
2290
2326
|
opacity: options?.opacity,
|
|
2327
|
+
pastel: options?.pastel,
|
|
2291
2328
|
base: hasExternalBase ? STANDALONE_BASE : needsSeedAnchor ? STANDALONE_SEED : void 0
|
|
2292
2329
|
};
|
|
2293
2330
|
const defs = { [primary]: valueDef };
|
|
@@ -2319,7 +2356,7 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
2319
2356
|
};
|
|
2320
2357
|
};
|
|
2321
2358
|
const tokenLike = (options) => {
|
|
2322
|
-
return buildTokenMap(resolveOnce(), "", resolveStates(options), resolveModes(options?.modes), options?.format)[`#${primary}`];
|
|
2359
|
+
return buildTokenMap(resolveOnce(), "", resolveStates(options), resolveModes(options?.modes), options?.format, effectiveConfig.pastel)[`#${primary}`];
|
|
2323
2360
|
};
|
|
2324
2361
|
return {
|
|
2325
2362
|
resolve() {
|
|
@@ -2328,10 +2365,10 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
2328
2365
|
token: tokenLike,
|
|
2329
2366
|
tasty: tokenLike,
|
|
2330
2367
|
json(options) {
|
|
2331
|
-
return buildJsonMap(resolveOnce(), resolveModes(options?.modes), options?.format)[primary];
|
|
2368
|
+
return buildJsonMap(resolveOnce(), resolveModes(options?.modes), options?.format, effectiveConfig.pastel)[primary];
|
|
2332
2369
|
},
|
|
2333
2370
|
css(options) {
|
|
2334
|
-
return buildCssMap(new Map([[options.name, resolveOnce().get(primary)]]), "", options.suffix ?? "-color", options.format ?? "rgb");
|
|
2371
|
+
return buildCssMap(new Map([[options.name, resolveOnce().get(primary)]]), "", options.suffix ?? "-color", options.format ?? "rgb", effectiveConfig.pastel);
|
|
2335
2372
|
},
|
|
2336
2373
|
export: exportData
|
|
2337
2374
|
};
|
|
@@ -2388,6 +2425,7 @@ function createColorToken(input, configOverride) {
|
|
|
2388
2425
|
flip: input.flip,
|
|
2389
2426
|
contrast: input.contrast,
|
|
2390
2427
|
opacity: input.opacity,
|
|
2428
|
+
pastel: input.pastel,
|
|
2391
2429
|
base: hasExternalBase ? STANDALONE_BASE : needsSeedAnchor ? STANDALONE_SEED : void 0
|
|
2392
2430
|
} };
|
|
2393
2431
|
if (needsSeedAnchor) {
|
|
@@ -2437,6 +2475,7 @@ function buildOverridesExport(options) {
|
|
|
2437
2475
|
if (options.contrast !== void 0) out.contrast = options.contrast;
|
|
2438
2476
|
if (options.opacity !== void 0) out.opacity = options.opacity;
|
|
2439
2477
|
if (options.name !== void 0) out.name = options.name;
|
|
2478
|
+
if (options.pastel !== void 0) out.pastel = options.pastel;
|
|
2440
2479
|
if (options.base !== void 0) out.base = isGlazeColorToken(options.base) ? options.base.export() : options.base;
|
|
2441
2480
|
return out;
|
|
2442
2481
|
}
|
|
@@ -2452,6 +2491,7 @@ function buildStructuredInputExport(input) {
|
|
|
2452
2491
|
if (input.opacity !== void 0) out.opacity = input.opacity;
|
|
2453
2492
|
if (input.contrast !== void 0) out.contrast = input.contrast;
|
|
2454
2493
|
if (input.name !== void 0) out.name = input.name;
|
|
2494
|
+
if (input.pastel !== void 0) out.pastel = input.pastel;
|
|
2455
2495
|
if (input.base !== void 0) out.base = isGlazeColorToken(input.base) ? input.base.export() : input.base;
|
|
2456
2496
|
return out;
|
|
2457
2497
|
}
|
|
@@ -2472,6 +2512,7 @@ function rehydrateOverrides(data) {
|
|
|
2472
2512
|
if (data.contrast !== void 0) out.contrast = data.contrast;
|
|
2473
2513
|
if (data.opacity !== void 0) out.opacity = data.opacity;
|
|
2474
2514
|
if (data.name !== void 0) out.name = data.name;
|
|
2515
|
+
if (data.pastel !== void 0) out.pastel = data.pastel;
|
|
2475
2516
|
if (data.base !== void 0) out.base = isExportedToken(data.base) ? colorFromExport(data.base) : data.base;
|
|
2476
2517
|
return out;
|
|
2477
2518
|
}
|
|
@@ -2487,6 +2528,7 @@ function rehydrateStructuredInput(data) {
|
|
|
2487
2528
|
if (data.opacity !== void 0) out.opacity = data.opacity;
|
|
2488
2529
|
if (data.contrast !== void 0) out.contrast = data.contrast;
|
|
2489
2530
|
if (data.name !== void 0) out.name = data.name;
|
|
2531
|
+
if (data.pastel !== void 0) out.pastel = data.pastel;
|
|
2490
2532
|
if (data.base !== void 0) out.base = isExportedToken(data.base) ? colorFromExport(data.base) : data.base;
|
|
2491
2533
|
return out;
|
|
2492
2534
|
}
|
|
@@ -2571,9 +2613,10 @@ function buildPaletteOutput(themes, paletteOptions, options, buildOne, merge, em
|
|
|
2571
2613
|
const seen = /* @__PURE__ */ new Map();
|
|
2572
2614
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
2573
2615
|
const resolved = theme.resolve();
|
|
2616
|
+
const pastel = theme.getConfig().pastel;
|
|
2574
2617
|
const prefix = resolvePrefix(options, themeName, true);
|
|
2575
|
-
merge(acc, buildOne(filterCollisions(resolved, prefix, seen, themeName), prefix));
|
|
2576
|
-
if (themeName === effectivePrimary) merge(acc, buildOne(filterCollisions(resolved, "", seen, themeName, true), ""));
|
|
2618
|
+
merge(acc, buildOne(filterCollisions(resolved, prefix, seen, themeName), prefix, pastel));
|
|
2619
|
+
if (themeName === effectivePrimary) merge(acc, buildOne(filterCollisions(resolved, "", seen, themeName, true), "", pastel));
|
|
2577
2620
|
}
|
|
2578
2621
|
return acc;
|
|
2579
2622
|
}
|
|
@@ -2582,7 +2625,7 @@ function createPalette(themes, paletteOptions) {
|
|
|
2582
2625
|
return {
|
|
2583
2626
|
tokens(options) {
|
|
2584
2627
|
const modes = resolveModes(options?.modes);
|
|
2585
|
-
return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix) => buildFlatTokenMap(filtered, prefix, modes, options?.format), (acc, part) => {
|
|
2628
|
+
return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix, pastel) => buildFlatTokenMap(filtered, prefix, modes, options?.format, pastel), (acc, part) => {
|
|
2586
2629
|
for (const variant of Object.keys(part)) {
|
|
2587
2630
|
if (!acc[variant]) acc[variant] = {};
|
|
2588
2631
|
Object.assign(acc[variant], part[variant]);
|
|
@@ -2596,18 +2639,18 @@ function createPalette(themes, paletteOptions) {
|
|
|
2596
2639
|
highContrast: options?.states?.highContrast ?? cfg.states.highContrast
|
|
2597
2640
|
};
|
|
2598
2641
|
const modes = resolveModes(options?.modes);
|
|
2599
|
-
return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix) => buildTokenMap(filtered, prefix, states, modes, options?.format), (acc, part) => Object.assign(acc, part), () => ({}));
|
|
2642
|
+
return buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix, pastel) => buildTokenMap(filtered, prefix, states, modes, options?.format, pastel), (acc, part) => Object.assign(acc, part), () => ({}));
|
|
2600
2643
|
},
|
|
2601
2644
|
json(options) {
|
|
2602
2645
|
const modes = resolveModes(options?.modes);
|
|
2603
2646
|
const result = {};
|
|
2604
|
-
for (const [themeName, theme] of Object.entries(themes)) result[themeName] = buildJsonMap(theme.resolve(), modes, options?.format);
|
|
2647
|
+
for (const [themeName, theme] of Object.entries(themes)) result[themeName] = buildJsonMap(theme.resolve(), modes, options?.format, theme.getConfig().pastel);
|
|
2605
2648
|
return result;
|
|
2606
2649
|
},
|
|
2607
2650
|
css(options) {
|
|
2608
2651
|
const suffix = options?.suffix ?? "-color";
|
|
2609
2652
|
const format = options?.format ?? "rgb";
|
|
2610
|
-
const lines = buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix) => buildCssMap(filtered, prefix, suffix, format), (acc, part) => {
|
|
2653
|
+
const lines = buildPaletteOutput(themes, paletteOptions, options, (filtered, prefix, pastel) => buildCssMap(filtered, prefix, suffix, format, pastel), (acc, part) => {
|
|
2611
2654
|
for (const key of [
|
|
2612
2655
|
"light",
|
|
2613
2656
|
"dark",
|
|
@@ -2674,6 +2717,9 @@ function createTheme(hue, saturation, initialColors, configOverride) {
|
|
|
2674
2717
|
get saturation() {
|
|
2675
2718
|
return saturation;
|
|
2676
2719
|
},
|
|
2720
|
+
getConfig() {
|
|
2721
|
+
return getEffectiveConfig();
|
|
2722
|
+
},
|
|
2677
2723
|
colors(defs) {
|
|
2678
2724
|
colorDefs = {
|
|
2679
2725
|
...colorDefs,
|
|
@@ -2728,7 +2774,7 @@ function createTheme(hue, saturation, initialColors, configOverride) {
|
|
|
2728
2774
|
},
|
|
2729
2775
|
tokens(options) {
|
|
2730
2776
|
const modes = resolveModes(options?.modes);
|
|
2731
|
-
return buildFlatTokenMap(resolveCached(), "", modes, options?.format);
|
|
2777
|
+
return buildFlatTokenMap(resolveCached(), "", modes, options?.format, getEffectiveConfig().pastel);
|
|
2732
2778
|
},
|
|
2733
2779
|
tasty(options) {
|
|
2734
2780
|
const cfg = getEffectiveConfig();
|
|
@@ -2737,14 +2783,14 @@ function createTheme(hue, saturation, initialColors, configOverride) {
|
|
|
2737
2783
|
highContrast: options?.states?.highContrast ?? cfg.states.highContrast
|
|
2738
2784
|
};
|
|
2739
2785
|
const modes = resolveModes(options?.modes);
|
|
2740
|
-
return buildTokenMap(resolveCached(), "", states, modes, options?.format);
|
|
2786
|
+
return buildTokenMap(resolveCached(), "", states, modes, options?.format, cfg.pastel);
|
|
2741
2787
|
},
|
|
2742
2788
|
json(options) {
|
|
2743
2789
|
const modes = resolveModes(options?.modes);
|
|
2744
|
-
return buildJsonMap(resolveCached(), modes, options?.format);
|
|
2790
|
+
return buildJsonMap(resolveCached(), modes, options?.format, getEffectiveConfig().pastel);
|
|
2745
2791
|
},
|
|
2746
2792
|
css(options) {
|
|
2747
|
-
return buildCssMap(resolveCached(), "", options?.suffix ?? "-color", options?.format ?? "rgb");
|
|
2793
|
+
return buildCssMap(resolveCached(), "", options?.suffix ?? "-color", options?.format ?? "rgb", getEffectiveConfig().pastel);
|
|
2748
2794
|
}
|
|
2749
2795
|
};
|
|
2750
2796
|
}
|
|
@@ -2767,7 +2813,7 @@ function createTheme(hue, saturation, initialColors, configOverride) {
|
|
|
2767
2813
|
* Create a single-hue glaze theme.
|
|
2768
2814
|
*
|
|
2769
2815
|
* An optional `config` override can be supplied to customize the resolve
|
|
2770
|
-
* behavior for this theme (tone windows,
|
|
2816
|
+
* behavior for this theme (tone windows, etc.). The
|
|
2771
2817
|
* override is **merged over the live global config at resolve time** —
|
|
2772
2818
|
* the theme still reacts to later `configure()` calls for fields it
|
|
2773
2819
|
* didn't override.
|
|
@@ -2827,7 +2873,7 @@ glaze.from = function from(data) {
|
|
|
2827
2873
|
*
|
|
2828
2874
|
* // Config override on any form
|
|
2829
2875
|
* glaze.color('#26fcb2', { darkTone: false, autoFlip: false })
|
|
2830
|
-
* glaze.color({ from: '#fff', base: bg }
|
|
2876
|
+
* glaze.color({ from: '#fff', base: bg })
|
|
2831
2877
|
* ```
|
|
2832
2878
|
*
|
|
2833
2879
|
* Defaults: every form defaults to `mode: 'auto'`. Value-shorthand forms
|
|
@@ -2881,8 +2927,8 @@ glaze.shadow = function shadow(input) {
|
|
|
2881
2927
|
};
|
|
2882
2928
|
};
|
|
2883
2929
|
/** Format a resolved color variant as a CSS string. */
|
|
2884
|
-
glaze.format = function format(variant, colorFormat) {
|
|
2885
|
-
return formatVariant(variant, colorFormat);
|
|
2930
|
+
glaze.format = function format(variant, colorFormat, pastel) {
|
|
2931
|
+
return formatVariant(variant, colorFormat, pastel);
|
|
2886
2932
|
};
|
|
2887
2933
|
/**
|
|
2888
2934
|
* Create a theme from a hex color string.
|
|
@@ -2936,5 +2982,5 @@ glaze.resetConfig = function resetConfig$1() {
|
|
|
2936
2982
|
};
|
|
2937
2983
|
|
|
2938
2984
|
//#endregion
|
|
2939
|
-
export { REF_EPS, apcaContrast, contrastRatioFromLuminance, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveContrastForMode, resolveMinContrast, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
|
|
2985
|
+
export { REF_EPS, apcaContrast, contrastRatioFromLuminance, cuspLightness, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveContrastForMode, resolveMinContrast, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
|
|
2940
2986
|
//# sourceMappingURL=index.mjs.map
|