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