@tenphi/glaze 0.0.0-snapshot.d860537 → 0.0.0-snapshot.e7185f1

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 CHANGED
@@ -22,6 +22,7 @@ Glaze generates robust **light**, **dark**, and **high-contrast** color schemes
22
22
 
23
23
  - **OKHSL color space** — perceptually uniform hue and saturation
24
24
  - **WCAG 2 contrast solving** — automatic lightness adjustment to meet AA/AAA targets
25
+ - **Mix colors** — blend two colors with OKHSL or sRGB interpolation, opaque or transparent, with optional contrast solving
25
26
  - **Shadow colors** — OKHSL-native shadow computation with automatic alpha, fg/bg tinting, and per-scheme adaptation
26
27
  - **Light + Dark + High-Contrast** — all schemes from one definition
27
28
  - **Per-color hue override** — absolute or relative hue shifts within a theme
@@ -69,9 +70,9 @@ const danger = primary.extend({ hue: 23 });
69
70
  const success = primary.extend({ hue: 157 });
70
71
 
71
72
  // Compose into a palette and export
72
- const palette = glaze.palette({ primary, danger, success });
73
- const tokens = palette.tokens({ prefix: true });
74
- // → { light: { 'primary-surface': 'okhsl(...)', ... }, dark: { 'primary-surface': 'okhsl(...)', ... } }
73
+ const palette = glaze.palette({ primary, danger, success }, { primary: 'primary' });
74
+ const tokens = palette.tokens();
75
+ // → { light: { 'primary-surface': 'okhsl(...)', 'surface': 'okhsl(...)', ... }, dark: { ... } }
75
76
  ```
76
77
 
77
78
  ## Core Concepts
@@ -193,6 +194,8 @@ A single value applies to both modes. All control is local and explicit.
193
194
  'muted': { base: 'surface', lightness: ['-35', '-50'], contrast: ['AA-large', 'AA'] }
194
195
  ```
195
196
 
197
+ **Full lightness spectrum in HC mode:** In high-contrast variants, the `lightLightness` and `darkLightness` window constraints are bypassed entirely. Colors can reach the full 0–100 lightness range, maximizing perceivable contrast. Normal (non-HC) variants continue to use the configured windows.
198
+
196
199
  ## Theme Color Management
197
200
 
198
201
  ### Adding Colors
@@ -387,6 +390,7 @@ Available tuning parameters:
387
390
  | `minGapTarget` | 0.05 | Target minimum gap between pigment and bg lightness |
388
391
  | `alphaMax` | 0.6 | Asymptotic maximum alpha |
389
392
  | `bgHueBlend` | 0.2 | Blend weight pulling pigment hue toward bg hue |
393
+ | `darkShadowCurve` | 0.5 | Power curve for dark-scheme alpha (0-1). Lower = more dampening; 1 = no dampening |
390
394
 
391
395
  ### Standalone Shadow Computation
392
396
 
@@ -413,6 +417,139 @@ const css = glaze.format(v, 'oklch');
413
417
  }
414
418
  ```
415
419
 
420
+ ## Mix Colors
421
+
422
+ Mix colors blend two existing colors together. Use them for hover overlays, tints, shades, and any derived color that sits between two reference colors.
423
+
424
+ ### Opaque Mix
425
+
426
+ Produces a solid color by interpolating between `base` and `target`:
427
+
428
+ ```ts
429
+ theme.colors({
430
+ surface: { lightness: 95 },
431
+ accent: { lightness: 30 },
432
+
433
+ // 30% of the way from surface toward accent
434
+ tint: { type: 'mix', base: 'surface', target: 'accent', value: 30 },
435
+ });
436
+ ```
437
+
438
+ - `value` — mix ratio 0–100 (0 = pure base, 100 = pure target)
439
+ - The result is a fully opaque color (alpha = 1)
440
+ - Adapts to light/dark/HC schemes automatically via the resolved base and target
441
+
442
+ ### Transparent Mix
443
+
444
+ Produces the target color with a controlled opacity — useful for hover overlays:
445
+
446
+ ```ts
447
+ theme.colors({
448
+ surface: { lightness: 95 },
449
+ black: { lightness: 0, saturation: 0 },
450
+
451
+ hover: {
452
+ type: 'mix',
453
+ base: 'surface',
454
+ target: 'black',
455
+ value: 8,
456
+ blend: 'transparent',
457
+ },
458
+ });
459
+ // hover → target color (black) with alpha = 0.08
460
+ ```
461
+
462
+ The output color has `h`, `s`, `l` from the target and `alpha = value / 100`.
463
+
464
+ ### Blend Space
465
+
466
+ By default, opaque mixing interpolates in OKHSL (perceptually uniform, consistent with Glaze's model). Use `space: 'srgb'` for linear sRGB interpolation, which matches browser compositing:
467
+
468
+ ```ts
469
+ theme.colors({
470
+ surface: { lightness: 95 },
471
+ accent: { lightness: 30 },
472
+
473
+ // sRGB blend — matches what the browser would render
474
+ hover: { type: 'mix', base: 'surface', target: 'accent', value: 20, space: 'srgb' },
475
+ });
476
+ ```
477
+
478
+ | Space | Behavior | Best for |
479
+ |---|---|---|
480
+ | `'okhsl'` (default) | Perceptually uniform OKHSL interpolation | Design token derivation |
481
+ | `'srgb'` | Linear sRGB channel interpolation | Matching browser compositing |
482
+
483
+ The `space` option only affects opaque blending. Transparent blending always composites in linear sRGB (matching browser alpha compositing).
484
+
485
+ ### Contrast Solving
486
+
487
+ Mix colors support the same `contrast` prop as regular colors. The solver adjusts the mix ratio (opaque) or opacity (transparent) to meet the WCAG target:
488
+
489
+ ```ts
490
+ theme.colors({
491
+ surface: { lightness: 95 },
492
+ accent: { lightness: 30 },
493
+
494
+ // Ensure the mixed color has at least AA contrast against surface
495
+ tint: {
496
+ type: 'mix',
497
+ base: 'surface',
498
+ target: 'accent',
499
+ value: 10,
500
+ contrast: 'AA',
501
+ },
502
+
503
+ // Ensure the transparent overlay has at least 3:1 contrast
504
+ overlay: {
505
+ type: 'mix',
506
+ base: 'surface',
507
+ target: 'accent',
508
+ value: 5,
509
+ blend: 'transparent',
510
+ contrast: 3,
511
+ },
512
+ });
513
+ ```
514
+
515
+ ### High-Contrast Pairs
516
+
517
+ Both `value` and `contrast` support `[normal, highContrast]` pairs:
518
+
519
+ ```ts
520
+ theme.colors({
521
+ surface: { lightness: 95 },
522
+ accent: { lightness: 30 },
523
+
524
+ tint: {
525
+ type: 'mix',
526
+ base: 'surface',
527
+ target: 'accent',
528
+ value: [20, 40], // stronger mix in high-contrast mode
529
+ contrast: [3, 'AAA'], // stricter contrast in high-contrast mode
530
+ },
531
+ });
532
+ ```
533
+
534
+ ### Achromatic Colors
535
+
536
+ When mixing with achromatic colors (saturation near zero, e.g., white or black) in `okhsl` space, the hue comes from whichever color has saturation. This prevents meaningless hue artifacts and matches CSS `color-mix()` "missing component" behavior. For purely achromatic mixes, prefer `space: 'srgb'` where hue is irrelevant.
537
+
538
+ ### Mix Chaining
539
+
540
+ Mix colors can reference other mix colors, enabling multi-step derivations:
541
+
542
+ ```ts
543
+ theme.colors({
544
+ white: { lightness: 100, saturation: 0 },
545
+ black: { lightness: 0, saturation: 0 },
546
+ gray: { type: 'mix', base: 'white', target: 'black', value: 50, space: 'srgb' },
547
+ lightGray: { type: 'mix', base: 'white', target: 'gray', value: 50, space: 'srgb' },
548
+ });
549
+ ```
550
+
551
+ Mix colors cannot reference shadow colors (same restriction as regular dependent colors).
552
+
416
553
  ## Output Formats
417
554
 
418
555
  Control the color format in exports with the `format` option:
@@ -467,7 +604,7 @@ Modes control how colors adapt across schemes:
467
604
 
468
605
  ```ts
469
606
  // Light: surface L=97, text lightness='-52' → L=45 (dark text on light bg)
470
- // Dark: surface inverts to L≈14, sign flips → L=14+52=66
607
+ // Dark: surface inverts to L≈20 (Möbius curve), sign flips → L=20+52=72
471
608
  // contrast solver may push further (light text on dark bg)
472
609
  ```
473
610
 
@@ -484,14 +621,14 @@ Modes control how colors adapt across schemes:
484
621
 
485
622
  ### Lightness
486
623
 
487
- Root color lightness is mapped linearly within the configured `lightLightness` window:
624
+ Absolute lightness values (both root colors and dependent colors with absolute lightness) are mapped linearly within the configured `lightLightness` window:
488
625
 
489
626
  ```ts
490
627
  const [lo, hi] = lightLightness; // default: [10, 100]
491
628
  const mappedL = (lightness * (hi - lo)) / 100 + lo;
492
629
  ```
493
630
 
494
- Both `auto` and `fixed` modes use the same linear formula. `static` mode bypasses the mapping entirely.
631
+ Both `auto` and `fixed` modes use the same linear formula. `static` mode and high-contrast variants bypass the mapping entirely (identity: `mappedL = l`).
495
632
 
496
633
  | Color | Raw L | Mapped L (default [10, 100]) |
497
634
  |---|---|---|
@@ -503,24 +640,29 @@ Both `auto` and `fixed` modes use the same linear formula. `static` mode bypasse
503
640
 
504
641
  ### Lightness
505
642
 
506
- **`auto`** — inverted within the configured window:
643
+ **`auto`** — inverted with a Möbius transformation within the configured window:
507
644
 
508
645
  ```ts
509
646
  const [lo, hi] = darkLightness; // default: [15, 95]
510
- const invertedL = ((100 - lightness) * (hi - lo)) / 100 + lo;
647
+ const t = (100 - lightness) / 100;
648
+ const invertedL = lo + (hi - lo) * t / (t + darkCurve * (1 - t)); // darkCurve default: 0.5
511
649
  ```
512
650
 
513
- **`fixed`** mapped without inversion:
651
+ The `darkCurve` parameter (default `0.5`, range 0–1) controls how much the dark-mode inversion expands lightness deltas. Lower values produce stronger expansion; `1` gives linear (legacy) behavior. Accepts a `[normal, highContrast]` pair for separate HC tuning (e.g. `darkCurve: [0.5, 0.3]`); a single number applies to both. Unlike a power curve, the Möbius transformation provides **proportional expansion** — small and large deltas are scaled by similar ratios, preserving the visual hierarchy of the light theme.
652
+
653
+ **`fixed`** — mapped without inversion (not affected by `darkCurve`):
514
654
 
515
655
  ```ts
516
656
  const mappedL = (lightness * (hi - lo)) / 100 + lo;
517
657
  ```
518
658
 
519
- | Color | Light L | Auto (inverted) | Fixed (mapped) |
520
- |---|---|---|---|
521
- | surface (L=97) | 97 | 17.4 | 92.6 |
522
- | accent-fill (L=52) | 52 | 53.4 | 56.6 |
523
- | accent-text (L=100) | 100 | 15 | 95 |
659
+ | Color | Light L | Auto (curve=0.5) | Auto (curve=1, linear) | Fixed (mapped) |
660
+ |---|---|---|---|---|
661
+ | surface (L=97) | 97 | 19.7 | 17.4 | 92.6 |
662
+ | accent-fill (L=52) | 52 | 66.9 | 53.4 | 56.6 |
663
+ | accent-text (L=100) | 100 | 15 | 15 | 95 |
664
+
665
+ In high-contrast variants, the `darkLightness` window is bypassed — auto uses the Möbius curve over the full [0, 100] range, and fixed uses identity (`L`). To use a different curve shape for HC, pass a `[normal, hc]` pair to `darkCurve` (e.g. `darkCurve: [0.5, 0.3]`).
524
666
 
525
667
  ### Saturation
526
668
 
@@ -560,12 +702,21 @@ Combine multiple themes into a single palette:
560
702
  const palette = glaze.palette({ primary, danger, success, warning });
561
703
  ```
562
704
 
563
- ### Token Export
705
+ Optionally designate a primary theme at creation time:
706
+
707
+ ```ts
708
+ const palette = glaze.palette(
709
+ { primary, danger, success, warning },
710
+ { primary: 'primary' },
711
+ );
712
+ ```
713
+
714
+ ### Prefix Behavior
564
715
 
565
- Tokens are grouped by scheme variant, with plain color names as keys:
716
+ Palette export methods (`tokens()`, `tasty()`, `css()`) default to `prefix: true` — all tokens are automatically prefixed with the theme name to avoid collisions:
566
717
 
567
718
  ```ts
568
- const tokens = palette.tokens({ prefix: true });
719
+ const tokens = palette.tokens();
569
720
  // → {
570
721
  // light: { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' },
571
722
  // dark: { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' },
@@ -578,15 +729,68 @@ Custom prefix mapping:
578
729
  palette.tokens({ prefix: { primary: 'brand-', danger: 'error-' } });
579
730
  ```
580
731
 
732
+ To disable prefixing entirely, pass `prefix: false` explicitly.
733
+
734
+ ### Collision Detection
735
+
736
+ When two themes produce the same output key (via `prefix: false`, custom prefix maps, or primary unprefixed aliases), the first-written value wins and a `console.warn` is emitted:
737
+
738
+ ```ts
739
+ const palette = glaze.palette({ a, b });
740
+ palette.tokens({ prefix: false });
741
+ // ⚠ glaze: token "surface" from theme "b" collides with theme "a" — skipping.
742
+ ```
743
+
744
+ ### Primary Theme
745
+
746
+ The primary theme's tokens are duplicated without prefix, providing convenient short aliases alongside the prefixed versions. Set at palette creation to apply to all exports automatically:
747
+
748
+ ```ts
749
+ const palette = glaze.palette(
750
+ { primary, danger, success },
751
+ { primary: 'primary' },
752
+ );
753
+ const tokens = palette.tokens();
754
+ // → {
755
+ // light: {
756
+ // 'primary-surface': 'okhsl(...)', // prefixed (all themes)
757
+ // 'danger-surface': 'okhsl(...)',
758
+ // 'success-surface': 'okhsl(...)',
759
+ // 'surface': 'okhsl(...)', // unprefixed alias (primary only)
760
+ // },
761
+ // }
762
+ ```
763
+
764
+ Override or disable per-export:
765
+
766
+ ```ts
767
+ palette.tokens({ primary: 'danger' }); // use danger as primary for this call
768
+ palette.tokens({ primary: false }); // no primary for this call
769
+ ```
770
+
771
+ The `primary` option works on `tokens()`, `tasty()`, and `css()`. It combines with any prefix mode — when using a custom prefix map, primary tokens are still duplicated without prefix:
772
+
773
+ ```ts
774
+ palette.tokens({ prefix: { primary: 'p-', danger: 'd-' } });
775
+ // → 'p-surface' + 'surface' (alias from palette-level primary) + 'd-surface'
776
+ ```
777
+
778
+ An error is thrown if the primary name doesn't match any theme in the palette.
779
+
581
780
  ### Tasty Export (for [Tasty](https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs) style system)
582
781
 
583
782
  The `tasty()` method exports tokens in the [Tasty](https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs) style-to-state binding format — `#name` color token keys with state aliases (`''`, `@dark`, etc.):
584
783
 
585
784
  ```ts
586
- const tastyTokens = palette.tasty({ prefix: true });
785
+ const palette = glaze.palette(
786
+ { primary, danger, success },
787
+ { primary: 'primary' },
788
+ );
789
+ const tastyTokens = palette.tasty();
587
790
  // → {
588
791
  // '#primary-surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
589
792
  // '#danger-surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
793
+ // '#surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' }, // alias
590
794
  // }
591
795
  ```
592
796
 
@@ -653,8 +857,10 @@ palette.tasty({ states: { dark: '@dark', highContrast: '@hc' } });
653
857
 
654
858
  ### JSON Export (Framework-Agnostic)
655
859
 
860
+ JSON export groups by theme name (no prefix needed):
861
+
656
862
  ```ts
657
- const data = palette.json({ prefix: true });
863
+ const data = palette.json();
658
864
  // → {
659
865
  // primary: { surface: { light: 'okhsl(...)', dark: 'okhsl(...)' } },
660
866
  // danger: { surface: { light: 'okhsl(...)', dark: 'okhsl(...)' } },
@@ -676,7 +882,11 @@ const css = theme.css();
676
882
  Use in a stylesheet:
677
883
 
678
884
  ```ts
679
- const css = palette.css({ prefix: true });
885
+ const palette = glaze.palette(
886
+ { primary, danger, success },
887
+ { primary: 'primary' },
888
+ );
889
+ const css = palette.css();
680
890
 
681
891
  const stylesheet = `
682
892
  :root { ${css.light} }
@@ -692,7 +902,8 @@ Options:
692
902
  |---|---|---|
693
903
  | `format` | `'rgb'` | Color format (`'rgb'`, `'hsl'`, `'okhsl'`, `'oklch'`) |
694
904
  | `suffix` | `'-color'` | Suffix appended to each CSS property name |
695
- | `prefix` | | (palette only) Same prefix behavior as `tokens()` |
905
+ | `prefix` | `true` (palette) | (palette only) `true` uses `"<themeName>-"`, or provide a custom map |
906
+ | `primary` | inherited | (palette only) Override or disable (`false`) the palette-level primary for this call |
696
907
 
697
908
  ```ts
698
909
  // Custom suffix
@@ -703,9 +914,9 @@ theme.css({ suffix: '' });
703
914
  theme.css({ format: 'hsl' });
704
915
  // → "--surface-color: hsl(...);"
705
916
 
706
- // Palette with prefix
707
- palette.css({ prefix: true });
708
- // → "--primary-surface-color: rgb(...);\n--danger-surface-color: rgb(...);"
917
+ // Palette with primary (inherited from palette creation)
918
+ palette.css();
919
+ // → "--primary-surface-color: rgb(...);\n--surface-color: rgb(...);\n--danger-surface-color: rgb(...);"
709
920
  ```
710
921
 
711
922
  ## Output Modes
@@ -738,9 +949,10 @@ Resolution priority (highest first):
738
949
 
739
950
  ```ts
740
951
  glaze.configure({
741
- lightLightness: [10, 100], // Light scheme lightness window [lo, hi]
742
- darkLightness: [15, 95], // Dark scheme lightness window [lo, hi]
952
+ lightLightness: [10, 100], // Light scheme lightness window [lo, hi] (bypassed in HC)
953
+ darkLightness: [15, 95], // Dark scheme lightness window [lo, hi] (bypassed in HC)
743
954
  darkDesaturation: 0.1, // Saturation reduction in dark scheme (0–1)
955
+ darkCurve: 0.5, // Möbius beta for dark auto-inversion (0–1); or [normal, hc] pair
744
956
  states: {
745
957
  dark: '@dark', // State alias for dark mode tokens
746
958
  highContrast: '@high-contrast',
@@ -752,16 +964,17 @@ glaze.configure({
752
964
  shadowTuning: { // Default tuning for all shadow colors
753
965
  alphaMax: 0.6,
754
966
  bgHueBlend: 0.2,
967
+ darkShadowCurve: 0.5, // Power curve for dark-scheme alpha dampening (0-1)
755
968
  },
756
969
  });
757
970
  ```
758
971
 
759
972
  ## Color Definition Shape
760
973
 
761
- `ColorDef` is a discriminated union of regular colors and shadow colors:
974
+ `ColorDef` is a discriminated union of regular colors, shadow colors, and mix colors:
762
975
 
763
976
  ```ts
764
- type ColorDef = RegularColorDef | ShadowColorDef;
977
+ type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
765
978
 
766
979
  interface RegularColorDef {
767
980
  lightness?: HCPair<number | RelativeValue>;
@@ -780,9 +993,19 @@ interface ShadowColorDef {
780
993
  intensity: HCPair<number>; // 0–100
781
994
  tuning?: ShadowTuning;
782
995
  }
996
+
997
+ interface MixColorDef {
998
+ type: 'mix';
999
+ base: string; // "from" color name
1000
+ target: string; // "to" color name
1001
+ value: HCPair<number>; // 0–100 (mix ratio or opacity)
1002
+ blend?: 'opaque' | 'transparent'; // default: 'opaque'
1003
+ space?: 'okhsl' | 'srgb'; // default: 'okhsl'
1004
+ contrast?: HCPair<MinContrast>;
1005
+ }
783
1006
  ```
784
1007
 
785
- A root color must have absolute `lightness` (a number). A dependent color must have `base`. Relative `lightness` (a string) requires `base`. Shadow colors use `type: 'shadow'` and must reference a non-shadow `bg` color.
1008
+ A root color must have absolute `lightness` (a number). A dependent color must have `base`. Relative `lightness` (a string) requires `base`. Shadow colors use `type: 'shadow'` and must reference a non-shadow `bg` color. Mix colors use `type: 'mix'` and must reference two non-shadow colors.
786
1009
 
787
1010
  ## Validation
788
1011
 
@@ -801,6 +1024,12 @@ A root color must have absolute `lightness` (a number). A dependent color must h
801
1024
  | Regular color `base` references a shadow color | Validation error |
802
1025
  | Shadow `intensity` outside 0–100 | Clamp silently |
803
1026
  | `contrast` + `opacity` combined | Warning |
1027
+ | Mix `base` references non-existent color | Validation error |
1028
+ | Mix `target` references non-existent color | Validation error |
1029
+ | Mix `base` references a shadow color | Validation error |
1030
+ | Mix `target` references a shadow color | Validation error |
1031
+ | Mix `value` outside 0–100 | Clamp silently |
1032
+ | Circular references involving mix colors | Validation error |
804
1033
 
805
1034
  ## Advanced: Color Math Utilities
806
1035
 
@@ -846,6 +1075,10 @@ primary.colors({
846
1075
  'shadow-md': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 10 },
847
1076
  'shadow-lg': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 20 },
848
1077
 
1078
+ // Mix colors — hover overlays and tints
1079
+ 'hover': { type: 'mix', base: 'surface', target: 'accent-fill', value: 8, blend: 'transparent' },
1080
+ 'tint': { type: 'mix', base: 'surface', target: 'accent-fill', value: 20 },
1081
+
849
1082
  // Fixed-alpha overlay
850
1083
  overlay: { lightness: 0, opacity: 0.5 },
851
1084
  });
@@ -855,18 +1088,21 @@ const success = primary.extend({ hue: 157 });
855
1088
  const warning = primary.extend({ hue: 84 });
856
1089
  const note = primary.extend({ hue: 302 });
857
1090
 
858
- const palette = glaze.palette({ primary, danger, success, warning, note });
1091
+ const palette = glaze.palette(
1092
+ { primary, danger, success, warning, note },
1093
+ { primary: 'primary' },
1094
+ );
859
1095
 
860
- // Export as flat token map grouped by variant
861
- const tokens = palette.tokens({ prefix: true });
862
- // tokens.light → { 'primary-surface': 'okhsl(...)', 'primary-shadow-md': 'okhsl(... / 0.1)' }
1096
+ // Export as flat token map grouped by variant (prefix defaults to true)
1097
+ const tokens = palette.tokens();
1098
+ // tokens.light → { 'primary-surface': '...', 'surface': '...', 'danger-surface': '...' }
863
1099
 
864
1100
  // Export as tasty style-to-state bindings (for Tasty style system)
865
- const tastyTokens = palette.tasty({ prefix: true });
1101
+ const tastyTokens = palette.tasty();
866
1102
 
867
1103
  // Export as CSS custom properties (rgb format by default)
868
- const css = palette.css({ prefix: true });
869
- // css.light → "--primary-surface-color: rgb(...);\n--primary-shadow-md-color: rgb(... / 0.1);"
1104
+ const css = palette.css();
1105
+ // css.light → "--primary-surface-color: rgb(...);\n--surface-color: rgb(...);\n--danger-surface-color: rgb(...);"
870
1106
 
871
1107
  // Standalone shadow computation
872
1108
  const v = glaze.shadow({ bg: '#f0eef5', fg: '#1a1a2e', intensity: 10 });
@@ -921,7 +1157,7 @@ brand.colors({ surface: { lightness: 97 }, text: { base: 'surface', lightness: '
921
1157
  | Method | Description |
922
1158
  |---|---|
923
1159
  | `glaze.configure(config)` | Set global configuration |
924
- | `glaze.palette(themes)` | Compose themes into a palette |
1160
+ | `glaze.palette(themes, options?)` | Compose themes into a palette (options: `{ primary? }`) |
925
1161
  | `glaze.getConfig()` | Get current global config |
926
1162
  | `glaze.resetConfig()` | Reset to defaults |
927
1163