@weasel-js/theme 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,195 +39,6 @@ interface RawToken {
39
39
  * prefix). Still unresolved — see `ResolvedTokenMap` for the output side. */
40
40
  type FlatTokens = Record<string, RawToken>;
41
41
 
42
- /**
43
- * A theme ready to resolve: its axes and its tokens, each plain or varying by
44
- * axis, references intact. A `by` that leaves a value out contributes nothing
45
- * for that selection, so the theme it extends supplies it.
46
- */
47
- interface Theme {
48
- readonly name: string;
49
- readonly extends: Theme | null;
50
- readonly axes: AxisDefs;
51
- readonly tokens: Readonly<Record<string, Varying<RawToken>>>;
52
- /** Ramp name → step names in order, for the ramps this theme declares itself. */
53
- readonly ramps?: Readonly<Record<string, readonly string[]>>;
54
- /** The colors a `tone` index picks from. Absent: the nearest theme it extends that has one. */
55
- readonly tones?: SerializableColorList;
56
- }
57
- /** What `defineTheme` accepts: a definition whose `extends` is a `Theme`, holding pins and components only. */
58
- type ThemeInput = Omit<ThemeDefinition, 'extends'> & {
59
- readonly extends?: Theme | null;
60
- };
61
- /** The built-in theme, from the baked output of themes/weasel.json. */
62
- declare const weaselTheme: Theme;
63
- /**
64
- * Build a theme from pins. Unless `extends` says otherwise the result layers
65
- * onto `weaselTheme`, so a theme only names what it changes. A definition with
66
- * seeds, ramps, scales or semantics needs deriving first.
67
- */
68
- declare function defineTheme(input: ThemeInput): Theme;
69
-
70
- /** The output of `resolveTheme`: every token of a theme, for one selection, keyed
71
- * by CSS custom-property name and flattened to a final CSS value. */
72
- type ResolvedTheme = Readonly<Record<TokenName, string>>;
73
- /** Every axis the chain declares. An axis declared more than once keeps every value; a descendant's value entries and default win. */
74
- declare function themeAxes(theme: Theme): AxisDefs;
75
- /**
76
- * Merge the extends chain at a selection, resolve every alias, and key the
77
- * result by CSS custom-property name. A missing or unknown axis value takes the
78
- * axis default.
79
- *
80
- * Pure — no DOM. An unresolvable reference throws rather than falling back.
81
- */
82
- declare function resolveTheme(theme: Theme, selection?: Selection): ResolvedTheme;
83
-
84
- /** The categorical generator the swatch ramp uses, asked for `count` colors. */
85
- interface GeneratedColors {
86
- readonly generate: {
87
- readonly count: number;
88
- readonly gates?: CategoricalRampDef['gates'];
89
- };
90
- }
91
- /** A ramp of the active theme, by name — `{ ramp: 'swatch' }` walks its steps in order. */
92
- interface RampColors {
93
- readonly ramp: string;
94
- }
95
- /** The forms a theme definition can hold: everything but a function. */
96
- type SerializableColorList = readonly string[] | GeneratedColors | RampColors;
97
- /**
98
- * Several colors, read by index with `colorAt`, wrapping. Literals; the swatch
99
- * ramp's generator; a ramp of the active theme, which follows the mode; or a
100
- * function of the index.
101
- */
102
- type ColorList = SerializableColorList | ((i: number) => string);
103
- /** What a `ColorList` resolves against. `useTheme()`'s value is one. */
104
- interface ColorContext {
105
- readonly theme: Theme;
106
- readonly resolved: ResolvedTheme;
107
- }
108
- /** A ramp's step names, from the nearest theme in the chain that declares it. */
109
- declare function rampSteps(theme: Theme, ramp: string): readonly string[];
110
- /** The tone list a theme declares, from the nearest theme in its chain that has one. */
111
- declare function themeTones(theme: Theme): ColorList;
112
- /** The `i`th color of `list`, wrapping. A ramp list reads the resolved theme, so the answer follows its mode. */
113
- declare function colorAt(list: ColorList, i: number, ctx?: ColorContext): string;
114
- /**
115
- * As `colorAt`, but a ramp list answers with its custom property —
116
- * `var(--wzl-swatch-sky)` — so a color written into CSS follows a mode change
117
- * without re-rendering, provider or not.
118
- */
119
- declare function colorCssAt(list: ColorList, i: number, ctx?: ColorContext): string;
120
- /** How many distinct colors `list` holds before it wraps; `undefined` for a function, which never does. */
121
- declare function colorCount(list: ColorList, ctx?: ColorContext): number | undefined;
122
-
123
- /** A number, or `{seeds.name}`. */
124
- type NumberParam = Varying<number | string>;
125
- interface PinObject {
126
- readonly value: TokenValue;
127
- readonly type?: string;
128
- readonly description?: string;
129
- readonly alpha?: number;
130
- }
131
- /** A bare value or `{ value, type?, description?, alpha? }`. The value may be a `{token}` reference. */
132
- type PinValue = TokenValue | PinObject;
133
- interface LightnessRampDef {
134
- readonly kind: 'lightness';
135
- readonly steps: Varying<readonly string[]>;
136
- /** First and last step's OKLCH lightness. */
137
- readonly lightness: Varying<readonly [NumberParam, NumberParam]>;
138
- /** 0 walks evenly; 1 follows a smoothstep S. */
139
- readonly curve?: NumberParam;
140
- /** Degrees. Ignored when an anchor is given. */
141
- readonly hue?: NumberParam;
142
- readonly chroma?: Varying<{
143
- readonly peak: NumberParam;
144
- readonly lightBias?: NumberParam;
145
- readonly darkBias?: NumberParam;
146
- }>;
147
- /**
148
- * Step name → exact hex (or `{seeds.name}`). An anchor's hue and chroma replace `hue` and `chroma.peak`; with several,
149
- * both blend by step between consecutive anchors, and steps outside them take the nearest anchor's.
150
- */
151
- readonly anchor?: Varying<Readonly<Record<string, Varying<string>>>>;
152
- readonly description?: string;
153
- readonly describe?: Readonly<Record<string, string>>;
154
- }
155
- interface CategoricalRampDef {
156
- readonly kind: 'categorical';
157
- readonly steps: Varying<readonly string[]>;
158
- /** Any of the palette generator's `Constraints` except `count` and `anchors`. */
159
- readonly gates?: Varying<Readonly<Record<string, Varying<number | string>>>>;
160
- readonly anchors?: readonly {
161
- readonly name: string;
162
- readonly hue: number;
163
- readonly lightness: number;
164
- readonly chroma?: number;
165
- }[];
166
- readonly description?: string;
167
- readonly describe?: Readonly<Record<string, string>>;
168
- }
169
- type RampDef = LightnessRampDef | CategoricalRampDef;
170
- interface ScaleDef {
171
- readonly steps: Varying<readonly string[]>;
172
- readonly base: NumberParam;
173
- /** Linear: `base + step × i`. */
174
- readonly step?: NumberParam;
175
- /** Geometric: `base × ratio^i`. */
176
- readonly ratio?: NumberParam;
177
- /** Explicit: `base × factors[i]`, one per step. For a ramp no single rule fits. */
178
- readonly factors?: Varying<readonly NumberParam[]>;
179
- readonly description?: string;
180
- readonly describe?: Readonly<Record<string, string>>;
181
- }
182
- interface SemanticCommon {
183
- readonly type?: string;
184
- readonly description?: string;
185
- /** Audited, never applied. */
186
- readonly check?: {
187
- readonly contrast: number;
188
- readonly against: readonly string[];
189
- };
190
- }
191
- type StepRule = SemanticCommon & {
192
- readonly ramp: string;
193
- readonly step: Varying<string>;
194
- };
195
- type OffsetRule = SemanticCommon & {
196
- readonly from: string;
197
- readonly offset: number;
198
- readonly dir: 'lighter' | 'darker' | 'away';
199
- };
200
- type ContrastRule = SemanticCommon & {
201
- readonly ramp: string;
202
- readonly contrast: {
203
- readonly min: number;
204
- readonly against: readonly string[];
205
- };
206
- };
207
- type RefRule = SemanticCommon & {
208
- readonly ref: string;
209
- readonly alpha?: number;
210
- };
211
- type LiteralRule = SemanticCommon & {
212
- readonly value: TokenValue;
213
- };
214
- type SemanticRule = StepRule | OffsetRule | ContrastRule | RefRule | LiteralRule;
215
- interface ThemeDefinition {
216
- readonly name: string;
217
- /** Another definition's name. Absent or null: extends nothing. */
218
- readonly extends?: string | null;
219
- readonly description?: string;
220
- readonly axes?: AxisDefs;
221
- readonly seeds?: Readonly<Record<string, Varying<number | string>>>;
222
- readonly ramps?: Readonly<Record<string, RampDef>>;
223
- readonly scales?: Readonly<Record<string, ScaleDef>>;
224
- readonly semantics?: Readonly<Record<string, Varying<SemanticRule>>>;
225
- readonly components?: Readonly<Record<string, Varying<PinValue>>>;
226
- readonly pins?: Readonly<Record<string, Varying<PinValue>>>;
227
- /** The colors a `tone` index picks from. Absent: the nearest theme it extends that has one, else the swatch ramp. */
228
- readonly tones?: SerializableColorList;
229
- }
230
-
231
42
  type Lookup = (name: string) => ThemeDefinition | undefined;
232
43
  /** The definition with its whole `extends` chain folded in, child entries winning. */
233
44
  declare function mergeChain(def: ThemeDefinition, lookup?: Lookup, seen?: ReadonlySet<string>): ThemeDefinition;
@@ -302,9 +113,9 @@ declare const THEMES: {
302
113
  readonly '--wzl-gray-700': "#25272c";
303
114
  readonly '--wzl-gray-800': "#181a1e";
304
115
  readonly '--wzl-gray-900': "#0e0f12";
305
- readonly '--wzl-accent-soft': "#1d1454";
306
- readonly '--wzl-accent-base': "#2e1f7a";
307
- readonly '--wzl-accent-strong': "#5841b8";
116
+ readonly '--wzl-accent-soft': "#262a66";
117
+ readonly '--wzl-accent-base': "#5b63c9";
118
+ readonly '--wzl-accent-strong': "#8c94ee";
308
119
  readonly '--wzl-secondary-soft': "#704e09";
309
120
  readonly '--wzl-secondary-base': "#dc9d15";
310
121
  readonly '--wzl-secondary-strong': "#f1cb8d";
@@ -340,7 +151,7 @@ declare const THEMES: {
340
151
  readonly '--wzl-fg-subtle': "#6f737b";
341
152
  readonly '--wzl-border': "#25272c";
342
153
  readonly '--wzl-border-strong': "#6f737b";
343
- readonly '--wzl-accent-fg': "#5841b8";
154
+ readonly '--wzl-accent-fg': "#8c94ee";
344
155
  readonly '--wzl-secondary-fg': "#dc9d15";
345
156
  readonly '--wzl-fg-inverse': "#0e0f12";
346
157
  readonly '--wzl-shadow': "rgba(0, 0, 0, 0.6)";
@@ -383,11 +194,11 @@ declare const THEMES: {
383
194
  readonly '--wzl-stance-danger-tone': "#d94a3f";
384
195
  readonly '--wzl-stance-danger-border-color': "#d94a3f";
385
196
  readonly '--wzl-stance-danger-title-color': "#d94a3f";
386
- readonly '--wzl-accent': "#2e1f7a";
387
- readonly '--wzl-stance-notice-tone': "#2e1f7a";
197
+ readonly '--wzl-accent': "#5b63c9";
198
+ readonly '--wzl-stance-notice-tone': "#5b63c9";
388
199
  readonly '--wzl-stance-notice-tone-mix': "8%";
389
- readonly '--wzl-stance-important-border-color': "#5841b8";
390
- readonly '--wzl-stance-important-title-color': "#5841b8";
200
+ readonly '--wzl-stance-important-border-color': "#8c94ee";
201
+ readonly '--wzl-stance-important-title-color': "#8c94ee";
391
202
  readonly '--wzl-stance-preview-pad': "0";
392
203
  readonly '--wzl-stance-preview-title-size': "8px";
393
204
  readonly '--wzl-stance-preview-title-case': "none";
@@ -397,13 +208,13 @@ declare const THEMES: {
397
208
  readonly '--wzl-fg-on-accent': "#f5f5f6";
398
209
  readonly '--wzl-line': "rgba(230, 231, 233, 0.2)";
399
210
  readonly '--wzl-line-strong': "rgba(230, 231, 233, 0.4)";
400
- readonly '--wzl-curve-color': "#5841b8";
401
- readonly '--wzl-accent-hover': "#5841b8";
211
+ readonly '--wzl-curve-color': "#8c94ee";
212
+ readonly '--wzl-accent-hover': "#8c94ee";
402
213
  readonly '--wzl-secondary': "#dc9d15";
403
214
  readonly '--wzl-warning': "#d99a3f";
404
215
  readonly '--wzl-success': "#2ec27e";
405
- readonly '--wzl-focus-ring': "#5841b8";
406
- readonly '--wzl-glass-tint': "#2e1f7a";
216
+ readonly '--wzl-focus-ring': "#8c94ee";
217
+ readonly '--wzl-glass-tint': "#5b63c9";
407
218
  readonly '--wzl-surface-hover': "rgba(230, 231, 233, 0.1)";
408
219
  readonly '--wzl-surface-pressed': "rgba(230, 231, 233, 0.18)";
409
220
  readonly '--wzl-radius-sm': "3px";
@@ -468,9 +279,9 @@ declare const THEMES: {
468
279
  readonly '--wzl-gray-700': "#25272c";
469
280
  readonly '--wzl-gray-800': "#181a1e";
470
281
  readonly '--wzl-gray-900': "#0e0f12";
471
- readonly '--wzl-accent-soft': "#1d1454";
472
- readonly '--wzl-accent-base': "#2e1f7a";
473
- readonly '--wzl-accent-strong': "#5841b8";
282
+ readonly '--wzl-accent-soft': "#262a66";
283
+ readonly '--wzl-accent-base': "#5b63c9";
284
+ readonly '--wzl-accent-strong': "#8c94ee";
474
285
  readonly '--wzl-secondary-soft': "#704e09";
475
286
  readonly '--wzl-secondary-base': "#dc9d15";
476
287
  readonly '--wzl-secondary-strong': "#f1cb8d";
@@ -506,7 +317,7 @@ declare const THEMES: {
506
317
  readonly '--wzl-fg-subtle': "#6f737b";
507
318
  readonly '--wzl-border': "#25272c";
508
319
  readonly '--wzl-border-strong': "#6f737b";
509
- readonly '--wzl-accent-fg': "#5841b8";
320
+ readonly '--wzl-accent-fg': "#8c94ee";
510
321
  readonly '--wzl-secondary-fg': "#dc9d15";
511
322
  readonly '--wzl-fg-inverse': "#0e0f12";
512
323
  readonly '--wzl-shadow': "rgba(0, 0, 0, 0.6)";
@@ -549,11 +360,11 @@ declare const THEMES: {
549
360
  readonly '--wzl-stance-danger-tone': "#d94a3f";
550
361
  readonly '--wzl-stance-danger-border-color': "#d94a3f";
551
362
  readonly '--wzl-stance-danger-title-color': "#d94a3f";
552
- readonly '--wzl-accent': "#2e1f7a";
553
- readonly '--wzl-stance-notice-tone': "#2e1f7a";
363
+ readonly '--wzl-accent': "#5b63c9";
364
+ readonly '--wzl-stance-notice-tone': "#5b63c9";
554
365
  readonly '--wzl-stance-notice-tone-mix': "8%";
555
- readonly '--wzl-stance-important-border-color': "#5841b8";
556
- readonly '--wzl-stance-important-title-color': "#5841b8";
366
+ readonly '--wzl-stance-important-border-color': "#8c94ee";
367
+ readonly '--wzl-stance-important-title-color': "#8c94ee";
557
368
  readonly '--wzl-stance-preview-pad': "0";
558
369
  readonly '--wzl-stance-preview-title-size': "10px";
559
370
  readonly '--wzl-stance-preview-title-case': "none";
@@ -563,13 +374,13 @@ declare const THEMES: {
563
374
  readonly '--wzl-fg-on-accent': "#f5f5f6";
564
375
  readonly '--wzl-line': "rgba(230, 231, 233, 0.2)";
565
376
  readonly '--wzl-line-strong': "rgba(230, 231, 233, 0.4)";
566
- readonly '--wzl-curve-color': "#5841b8";
567
- readonly '--wzl-accent-hover': "#5841b8";
377
+ readonly '--wzl-curve-color': "#8c94ee";
378
+ readonly '--wzl-accent-hover': "#8c94ee";
568
379
  readonly '--wzl-secondary': "#dc9d15";
569
380
  readonly '--wzl-warning': "#d99a3f";
570
381
  readonly '--wzl-success': "#2ec27e";
571
- readonly '--wzl-focus-ring': "#5841b8";
572
- readonly '--wzl-glass-tint': "#2e1f7a";
382
+ readonly '--wzl-focus-ring': "#8c94ee";
383
+ readonly '--wzl-glass-tint': "#5b63c9";
573
384
  readonly '--wzl-surface-hover': "rgba(230, 231, 233, 0.1)";
574
385
  readonly '--wzl-surface-pressed': "rgba(230, 231, 233, 0.18)";
575
386
  readonly '--wzl-radius-sm': "3px";
@@ -634,9 +445,9 @@ declare const THEMES: {
634
445
  readonly '--wzl-gray-700': "#25272c";
635
446
  readonly '--wzl-gray-800': "#181a1e";
636
447
  readonly '--wzl-gray-900': "#0e0f12";
637
- readonly '--wzl-accent-soft': "#1d1454";
638
- readonly '--wzl-accent-base': "#2e1f7a";
639
- readonly '--wzl-accent-strong': "#5841b8";
448
+ readonly '--wzl-accent-soft': "#262a66";
449
+ readonly '--wzl-accent-base': "#5b63c9";
450
+ readonly '--wzl-accent-strong': "#8c94ee";
640
451
  readonly '--wzl-secondary-soft': "#704e09";
641
452
  readonly '--wzl-secondary-base': "#dc9d15";
642
453
  readonly '--wzl-secondary-strong': "#f1cb8d";
@@ -672,7 +483,7 @@ declare const THEMES: {
672
483
  readonly '--wzl-fg-subtle': "#6f737b";
673
484
  readonly '--wzl-border': "#25272c";
674
485
  readonly '--wzl-border-strong': "#6f737b";
675
- readonly '--wzl-accent-fg': "#5841b8";
486
+ readonly '--wzl-accent-fg': "#8c94ee";
676
487
  readonly '--wzl-secondary-fg': "#dc9d15";
677
488
  readonly '--wzl-fg-inverse': "#0e0f12";
678
489
  readonly '--wzl-shadow': "rgba(0, 0, 0, 0.6)";
@@ -715,11 +526,11 @@ declare const THEMES: {
715
526
  readonly '--wzl-stance-danger-tone': "#d94a3f";
716
527
  readonly '--wzl-stance-danger-border-color': "#d94a3f";
717
528
  readonly '--wzl-stance-danger-title-color': "#d94a3f";
718
- readonly '--wzl-accent': "#2e1f7a";
719
- readonly '--wzl-stance-notice-tone': "#2e1f7a";
529
+ readonly '--wzl-accent': "#5b63c9";
530
+ readonly '--wzl-stance-notice-tone': "#5b63c9";
720
531
  readonly '--wzl-stance-notice-tone-mix': "8%";
721
- readonly '--wzl-stance-important-border-color': "#5841b8";
722
- readonly '--wzl-stance-important-title-color': "#5841b8";
532
+ readonly '--wzl-stance-important-border-color': "#8c94ee";
533
+ readonly '--wzl-stance-important-title-color': "#8c94ee";
723
534
  readonly '--wzl-stance-preview-pad': "0";
724
535
  readonly '--wzl-stance-preview-title-size': "12px";
725
536
  readonly '--wzl-stance-preview-title-case': "none";
@@ -729,13 +540,13 @@ declare const THEMES: {
729
540
  readonly '--wzl-fg-on-accent': "#f5f5f6";
730
541
  readonly '--wzl-line': "rgba(230, 231, 233, 0.2)";
731
542
  readonly '--wzl-line-strong': "rgba(230, 231, 233, 0.4)";
732
- readonly '--wzl-curve-color': "#5841b8";
733
- readonly '--wzl-accent-hover': "#5841b8";
543
+ readonly '--wzl-curve-color': "#8c94ee";
544
+ readonly '--wzl-accent-hover': "#8c94ee";
734
545
  readonly '--wzl-secondary': "#dc9d15";
735
546
  readonly '--wzl-warning': "#d99a3f";
736
547
  readonly '--wzl-success': "#2ec27e";
737
- readonly '--wzl-focus-ring': "#5841b8";
738
- readonly '--wzl-glass-tint': "#2e1f7a";
548
+ readonly '--wzl-focus-ring': "#8c94ee";
549
+ readonly '--wzl-glass-tint': "#5b63c9";
739
550
  readonly '--wzl-surface-hover': "rgba(230, 231, 233, 0.1)";
740
551
  readonly '--wzl-surface-pressed': "rgba(230, 231, 233, 0.18)";
741
552
  readonly '--wzl-radius-sm': "3px";
@@ -800,9 +611,9 @@ declare const THEMES: {
800
611
  readonly '--wzl-gray-700': "#25272c";
801
612
  readonly '--wzl-gray-800': "#181a1e";
802
613
  readonly '--wzl-gray-900': "#0e0f12";
803
- readonly '--wzl-accent-soft': "#1d1454";
804
- readonly '--wzl-accent-base': "#2e1f7a";
805
- readonly '--wzl-accent-strong': "#5841b8";
614
+ readonly '--wzl-accent-soft': "#312e81";
615
+ readonly '--wzl-accent-base': "#4338ca";
616
+ readonly '--wzl-accent-strong': "#6366f1";
806
617
  readonly '--wzl-secondary-soft': "#016458";
807
618
  readonly '--wzl-secondary-base': "#3ee1cb";
808
619
  readonly '--wzl-secondary-strong': "#94e3d5";
@@ -838,7 +649,7 @@ declare const THEMES: {
838
649
  readonly '--wzl-fg-subtle': "#4d5058";
839
650
  readonly '--wzl-border': "#c9cbcf";
840
651
  readonly '--wzl-border-strong': "#4d5058";
841
- readonly '--wzl-accent-fg': "#2e1f7a";
652
+ readonly '--wzl-accent-fg': "#4338ca";
842
653
  readonly '--wzl-secondary-fg': "#016458";
843
654
  readonly '--wzl-fg-inverse': "#f5f5f6";
844
655
  readonly '--wzl-shadow': "rgba(0, 0, 0, 0.18)";
@@ -881,11 +692,11 @@ declare const THEMES: {
881
692
  readonly '--wzl-stance-danger-tone': "#d94a3f";
882
693
  readonly '--wzl-stance-danger-border-color': "#d94a3f";
883
694
  readonly '--wzl-stance-danger-title-color': "#d94a3f";
884
- readonly '--wzl-accent': "#2e1f7a";
885
- readonly '--wzl-stance-notice-tone': "#2e1f7a";
695
+ readonly '--wzl-accent': "#4338ca";
696
+ readonly '--wzl-stance-notice-tone': "#4338ca";
886
697
  readonly '--wzl-stance-notice-tone-mix': "8%";
887
- readonly '--wzl-stance-important-border-color': "#2e1f7a";
888
- readonly '--wzl-stance-important-title-color': "#2e1f7a";
698
+ readonly '--wzl-stance-important-border-color': "#4338ca";
699
+ readonly '--wzl-stance-important-title-color': "#4338ca";
889
700
  readonly '--wzl-stance-preview-pad': "0";
890
701
  readonly '--wzl-stance-preview-title-size': "8px";
891
702
  readonly '--wzl-stance-preview-title-case': "none";
@@ -895,13 +706,13 @@ declare const THEMES: {
895
706
  readonly '--wzl-fg-on-accent': "#f5f5f6";
896
707
  readonly '--wzl-line': "rgba(14, 15, 18, 0.2)";
897
708
  readonly '--wzl-line-strong': "rgba(14, 15, 18, 0.4)";
898
- readonly '--wzl-curve-color': "#5841b8";
899
- readonly '--wzl-accent-hover': "#5841b8";
709
+ readonly '--wzl-curve-color': "#6366f1";
710
+ readonly '--wzl-accent-hover': "#6366f1";
900
711
  readonly '--wzl-secondary': "#3ee1cb";
901
712
  readonly '--wzl-warning': "#d99a3f";
902
713
  readonly '--wzl-success': "#2ec27e";
903
- readonly '--wzl-focus-ring': "#5841b8";
904
- readonly '--wzl-glass-tint': "#2e1f7a";
714
+ readonly '--wzl-focus-ring': "#6366f1";
715
+ readonly '--wzl-glass-tint': "#4338ca";
905
716
  readonly '--wzl-surface-hover': "rgba(14, 15, 18, 0.1)";
906
717
  readonly '--wzl-surface-pressed': "rgba(14, 15, 18, 0.18)";
907
718
  readonly '--wzl-radius-sm': "3px";
@@ -966,9 +777,9 @@ declare const THEMES: {
966
777
  readonly '--wzl-gray-700': "#25272c";
967
778
  readonly '--wzl-gray-800': "#181a1e";
968
779
  readonly '--wzl-gray-900': "#0e0f12";
969
- readonly '--wzl-accent-soft': "#1d1454";
970
- readonly '--wzl-accent-base': "#2e1f7a";
971
- readonly '--wzl-accent-strong': "#5841b8";
780
+ readonly '--wzl-accent-soft': "#312e81";
781
+ readonly '--wzl-accent-base': "#4338ca";
782
+ readonly '--wzl-accent-strong': "#6366f1";
972
783
  readonly '--wzl-secondary-soft': "#016458";
973
784
  readonly '--wzl-secondary-base': "#3ee1cb";
974
785
  readonly '--wzl-secondary-strong': "#94e3d5";
@@ -1004,7 +815,7 @@ declare const THEMES: {
1004
815
  readonly '--wzl-fg-subtle': "#4d5058";
1005
816
  readonly '--wzl-border': "#c9cbcf";
1006
817
  readonly '--wzl-border-strong': "#4d5058";
1007
- readonly '--wzl-accent-fg': "#2e1f7a";
818
+ readonly '--wzl-accent-fg': "#4338ca";
1008
819
  readonly '--wzl-secondary-fg': "#016458";
1009
820
  readonly '--wzl-fg-inverse': "#f5f5f6";
1010
821
  readonly '--wzl-shadow': "rgba(0, 0, 0, 0.18)";
@@ -1047,11 +858,11 @@ declare const THEMES: {
1047
858
  readonly '--wzl-stance-danger-tone': "#d94a3f";
1048
859
  readonly '--wzl-stance-danger-border-color': "#d94a3f";
1049
860
  readonly '--wzl-stance-danger-title-color': "#d94a3f";
1050
- readonly '--wzl-accent': "#2e1f7a";
1051
- readonly '--wzl-stance-notice-tone': "#2e1f7a";
861
+ readonly '--wzl-accent': "#4338ca";
862
+ readonly '--wzl-stance-notice-tone': "#4338ca";
1052
863
  readonly '--wzl-stance-notice-tone-mix': "8%";
1053
- readonly '--wzl-stance-important-border-color': "#2e1f7a";
1054
- readonly '--wzl-stance-important-title-color': "#2e1f7a";
864
+ readonly '--wzl-stance-important-border-color': "#4338ca";
865
+ readonly '--wzl-stance-important-title-color': "#4338ca";
1055
866
  readonly '--wzl-stance-preview-pad': "0";
1056
867
  readonly '--wzl-stance-preview-title-size': "10px";
1057
868
  readonly '--wzl-stance-preview-title-case': "none";
@@ -1061,13 +872,13 @@ declare const THEMES: {
1061
872
  readonly '--wzl-fg-on-accent': "#f5f5f6";
1062
873
  readonly '--wzl-line': "rgba(14, 15, 18, 0.2)";
1063
874
  readonly '--wzl-line-strong': "rgba(14, 15, 18, 0.4)";
1064
- readonly '--wzl-curve-color': "#5841b8";
1065
- readonly '--wzl-accent-hover': "#5841b8";
875
+ readonly '--wzl-curve-color': "#6366f1";
876
+ readonly '--wzl-accent-hover': "#6366f1";
1066
877
  readonly '--wzl-secondary': "#3ee1cb";
1067
878
  readonly '--wzl-warning': "#d99a3f";
1068
879
  readonly '--wzl-success': "#2ec27e";
1069
- readonly '--wzl-focus-ring': "#5841b8";
1070
- readonly '--wzl-glass-tint': "#2e1f7a";
880
+ readonly '--wzl-focus-ring': "#6366f1";
881
+ readonly '--wzl-glass-tint': "#4338ca";
1071
882
  readonly '--wzl-surface-hover': "rgba(14, 15, 18, 0.1)";
1072
883
  readonly '--wzl-surface-pressed': "rgba(14, 15, 18, 0.18)";
1073
884
  readonly '--wzl-radius-sm': "3px";
@@ -1132,9 +943,9 @@ declare const THEMES: {
1132
943
  readonly '--wzl-gray-700': "#25272c";
1133
944
  readonly '--wzl-gray-800': "#181a1e";
1134
945
  readonly '--wzl-gray-900': "#0e0f12";
1135
- readonly '--wzl-accent-soft': "#1d1454";
1136
- readonly '--wzl-accent-base': "#2e1f7a";
1137
- readonly '--wzl-accent-strong': "#5841b8";
946
+ readonly '--wzl-accent-soft': "#312e81";
947
+ readonly '--wzl-accent-base': "#4338ca";
948
+ readonly '--wzl-accent-strong': "#6366f1";
1138
949
  readonly '--wzl-secondary-soft': "#016458";
1139
950
  readonly '--wzl-secondary-base': "#3ee1cb";
1140
951
  readonly '--wzl-secondary-strong': "#94e3d5";
@@ -1170,7 +981,7 @@ declare const THEMES: {
1170
981
  readonly '--wzl-fg-subtle': "#4d5058";
1171
982
  readonly '--wzl-border': "#c9cbcf";
1172
983
  readonly '--wzl-border-strong': "#4d5058";
1173
- readonly '--wzl-accent-fg': "#2e1f7a";
984
+ readonly '--wzl-accent-fg': "#4338ca";
1174
985
  readonly '--wzl-secondary-fg': "#016458";
1175
986
  readonly '--wzl-fg-inverse': "#f5f5f6";
1176
987
  readonly '--wzl-shadow': "rgba(0, 0, 0, 0.18)";
@@ -1213,11 +1024,11 @@ declare const THEMES: {
1213
1024
  readonly '--wzl-stance-danger-tone': "#d94a3f";
1214
1025
  readonly '--wzl-stance-danger-border-color': "#d94a3f";
1215
1026
  readonly '--wzl-stance-danger-title-color': "#d94a3f";
1216
- readonly '--wzl-accent': "#2e1f7a";
1217
- readonly '--wzl-stance-notice-tone': "#2e1f7a";
1027
+ readonly '--wzl-accent': "#4338ca";
1028
+ readonly '--wzl-stance-notice-tone': "#4338ca";
1218
1029
  readonly '--wzl-stance-notice-tone-mix': "8%";
1219
- readonly '--wzl-stance-important-border-color': "#2e1f7a";
1220
- readonly '--wzl-stance-important-title-color': "#2e1f7a";
1030
+ readonly '--wzl-stance-important-border-color': "#4338ca";
1031
+ readonly '--wzl-stance-important-title-color': "#4338ca";
1221
1032
  readonly '--wzl-stance-preview-pad': "0";
1222
1033
  readonly '--wzl-stance-preview-title-size': "12px";
1223
1034
  readonly '--wzl-stance-preview-title-case': "none";
@@ -1227,13 +1038,13 @@ declare const THEMES: {
1227
1038
  readonly '--wzl-fg-on-accent': "#f5f5f6";
1228
1039
  readonly '--wzl-line': "rgba(14, 15, 18, 0.2)";
1229
1040
  readonly '--wzl-line-strong': "rgba(14, 15, 18, 0.4)";
1230
- readonly '--wzl-curve-color': "#5841b8";
1231
- readonly '--wzl-accent-hover': "#5841b8";
1041
+ readonly '--wzl-curve-color': "#6366f1";
1042
+ readonly '--wzl-accent-hover': "#6366f1";
1232
1043
  readonly '--wzl-secondary': "#3ee1cb";
1233
1044
  readonly '--wzl-warning': "#d99a3f";
1234
1045
  readonly '--wzl-success': "#2ec27e";
1235
- readonly '--wzl-focus-ring': "#5841b8";
1236
- readonly '--wzl-glass-tint': "#2e1f7a";
1046
+ readonly '--wzl-focus-ring': "#6366f1";
1047
+ readonly '--wzl-glass-tint': "#4338ca";
1237
1048
  readonly '--wzl-surface-hover': "rgba(14, 15, 18, 0.1)";
1238
1049
  readonly '--wzl-surface-pressed': "rgba(14, 15, 18, 0.18)";
1239
1050
  readonly '--wzl-radius-sm': "3px";
@@ -1296,4 +1107,193 @@ declare const THEME_SOURCES: Readonly<Record<string, ThemeDefinition>>;
1296
1107
  * what `weaselTheme` is built from, so the runtime entry bundles no generator. */
1297
1108
  declare const BAKED_THEMES: Readonly<Record<string, BakedTheme>>;
1298
1109
 
1299
- export { mergeChain as $, type AxisDef as A, BAKED_THEMES as B, type ColorContext as C, themeAxes as D, themeTones as E, type FlatTokens as F, type GeneratedColors as G, weaselTheme as H, type CategoricalRampDef as I, type ContrastRule as J, type LightnessRampDef as K, type Lookup as L, type LiteralRule as M, type NumberParam as N, type OffsetRule as O, type PinObject as P, type RampDef as Q, type ResolvedTheme as R, type Selection as S, type TokenName as T, type RefRule as U, type Varying as V, type ScaleDef as W, type SemanticRule as X, type StepRule as Y, bake as Z, bakeChain as _, type Theme as a, type TokenValue as b, type AxisDefs as c, type AxisValue as d, type BakedTheme as e, type ByAxis as f, type ColorList as g, type GeneratedTheme as h, type PinValue as i, type RampColors as j, type RawToken as k, type SerializableColorList as l, THEMES as m, THEME_SOURCES as n, type ThemeDefinition as o, type ThemeInput as p, colorAt as q, colorCount as r, colorCssAt as s, defineTheme as t, enumerateSelections as u, fullSelection as v, isByAxis as w, rampSteps as x, resolveTheme as y, selectionKey as z };
1110
+ /**
1111
+ * A theme ready to resolve: its axes and its tokens, each plain or varying by
1112
+ * axis, references intact. A `by` that leaves a value out contributes nothing
1113
+ * for that selection, so the theme it extends supplies it.
1114
+ */
1115
+ interface Theme {
1116
+ readonly name: string;
1117
+ readonly extends: Theme | null;
1118
+ readonly axes: AxisDefs;
1119
+ readonly tokens: Readonly<Record<string, Varying<RawToken>>>;
1120
+ /** Ramp name → step names in order, for the ramps this theme declares itself. */
1121
+ readonly ramps?: Readonly<Record<string, readonly string[]>>;
1122
+ /** The colors a `tone` index picks from. Absent: the nearest theme it extends that has one. */
1123
+ readonly tones?: SerializableColorList;
1124
+ }
1125
+ /** What `defineTheme` accepts: a definition whose `extends` is a `Theme`, holding pins and components only. */
1126
+ type ThemeInput = Omit<ThemeDefinition, 'extends'> & {
1127
+ readonly extends?: Theme | null;
1128
+ };
1129
+ /** The built-in theme, from the baked output of themes/weasel.json. */
1130
+ declare const weaselTheme: Theme;
1131
+ /**
1132
+ * Build a theme from pins. Unless `extends` says otherwise the result layers
1133
+ * onto `weaselTheme`, so a theme only names what it changes. A definition with
1134
+ * seeds, ramps, scales or semantics needs deriving first.
1135
+ */
1136
+ declare function defineTheme(input: ThemeInput): Theme;
1137
+
1138
+ /** The output of `resolveTheme`: every token of a theme, for one selection, keyed
1139
+ * by CSS custom-property name and flattened to a final CSS value. */
1140
+ type ResolvedTheme = Readonly<Record<TokenName, string>>;
1141
+ /** Every axis the chain declares. An axis declared more than once keeps every value; a descendant's value entries and default win. */
1142
+ declare function themeAxes(theme: Theme): AxisDefs;
1143
+ /**
1144
+ * Merge the extends chain at a selection, resolve every alias, and key the
1145
+ * result by CSS custom-property name. A missing or unknown axis value takes the
1146
+ * axis default.
1147
+ *
1148
+ * Pure — no DOM. An unresolvable reference throws rather than falling back.
1149
+ */
1150
+ declare function resolveTheme(theme: Theme, selection?: Selection): ResolvedTheme;
1151
+
1152
+ /** The categorical generator the swatch ramp uses, asked for `count` colors. */
1153
+ interface GeneratedColors {
1154
+ readonly generate: {
1155
+ readonly count: number;
1156
+ readonly gates?: CategoricalRampDef['gates'];
1157
+ };
1158
+ }
1159
+ /** A ramp of the active theme, by name — `{ ramp: 'swatch' }` walks its steps in order. */
1160
+ interface RampColors {
1161
+ readonly ramp: string;
1162
+ }
1163
+ /** The forms a theme definition can hold: everything but a function. */
1164
+ type SerializableColorList = readonly string[] | GeneratedColors | RampColors;
1165
+ /**
1166
+ * Several colors, read by index with `colorAt`, wrapping. Literals; the swatch
1167
+ * ramp's generator; a ramp of the active theme, which follows the mode; or a
1168
+ * function of the index.
1169
+ */
1170
+ type ColorList = SerializableColorList | ((i: number) => string);
1171
+ /** What a `ColorList` resolves against. `useTheme()`'s value is one. */
1172
+ interface ColorContext {
1173
+ readonly theme: Theme;
1174
+ readonly resolved: ResolvedTheme;
1175
+ }
1176
+ /** A ramp's step names, from the nearest theme in the chain that declares it. */
1177
+ declare function rampSteps(theme: Theme, ramp: string): readonly string[];
1178
+ /** The tone list a theme declares, from the nearest theme in its chain that has one. */
1179
+ declare function themeTones(theme: Theme): ColorList;
1180
+ /** The `i`th color of `list`, wrapping. A ramp list reads the resolved theme, so the answer follows its mode. */
1181
+ declare function colorAt(list: ColorList, i: number, ctx?: ColorContext): string;
1182
+ /**
1183
+ * As `colorAt`, but a ramp list answers with its custom property —
1184
+ * `var(--wzl-swatch-sky)` — so a color written into CSS follows a mode change
1185
+ * without re-rendering, provider or not.
1186
+ */
1187
+ declare function colorCssAt(list: ColorList, i: number, ctx?: ColorContext): string;
1188
+ /** How many distinct colors `list` holds before it wraps; `undefined` for a function, which never does. */
1189
+ declare function colorCount(list: ColorList, ctx?: ColorContext): number | undefined;
1190
+
1191
+ /** A number, or `{seeds.name}`. */
1192
+ type NumberParam = Varying<number | string>;
1193
+ interface PinObject {
1194
+ readonly value: TokenValue;
1195
+ readonly type?: string;
1196
+ readonly description?: string;
1197
+ readonly alpha?: number;
1198
+ }
1199
+ /** A bare value or `{ value, type?, description?, alpha? }`. The value may be a `{token}` reference. */
1200
+ type PinValue = TokenValue | PinObject;
1201
+ interface LightnessRampDef {
1202
+ readonly kind: 'lightness';
1203
+ readonly steps: Varying<readonly string[]>;
1204
+ /** First and last step's OKLCH lightness. */
1205
+ readonly lightness: Varying<readonly [NumberParam, NumberParam]>;
1206
+ /** 0 walks evenly; 1 follows a smoothstep S. */
1207
+ readonly curve?: NumberParam;
1208
+ /** Degrees. Ignored when an anchor is given. */
1209
+ readonly hue?: NumberParam;
1210
+ readonly chroma?: Varying<{
1211
+ readonly peak: NumberParam;
1212
+ readonly lightBias?: NumberParam;
1213
+ readonly darkBias?: NumberParam;
1214
+ }>;
1215
+ /**
1216
+ * Step name → exact hex (or `{seeds.name}`). An anchor's hue and chroma replace `hue` and `chroma.peak`; with several,
1217
+ * both blend by step between consecutive anchors, and steps outside them take the nearest anchor's.
1218
+ */
1219
+ readonly anchor?: Varying<Readonly<Record<string, Varying<string>>>>;
1220
+ readonly description?: string;
1221
+ readonly describe?: Readonly<Record<string, string>>;
1222
+ }
1223
+ interface CategoricalRampDef {
1224
+ readonly kind: 'categorical';
1225
+ readonly steps: Varying<readonly string[]>;
1226
+ /** Any of the palette generator's `Constraints` except `count` and `anchors`. */
1227
+ readonly gates?: Varying<Readonly<Record<string, Varying<number | string>>>>;
1228
+ readonly anchors?: readonly {
1229
+ readonly name: string;
1230
+ readonly hue: number;
1231
+ readonly lightness: number;
1232
+ readonly chroma?: number;
1233
+ }[];
1234
+ readonly description?: string;
1235
+ readonly describe?: Readonly<Record<string, string>>;
1236
+ }
1237
+ type RampDef = LightnessRampDef | CategoricalRampDef;
1238
+ interface ScaleDef {
1239
+ readonly steps: Varying<readonly string[]>;
1240
+ readonly base: NumberParam;
1241
+ /** Linear: `base + step × i`. */
1242
+ readonly step?: NumberParam;
1243
+ /** Geometric: `base × ratio^i`. */
1244
+ readonly ratio?: NumberParam;
1245
+ /** Explicit: `base × factors[i]`, one per step. For a ramp no single rule fits. */
1246
+ readonly factors?: Varying<readonly NumberParam[]>;
1247
+ readonly description?: string;
1248
+ readonly describe?: Readonly<Record<string, string>>;
1249
+ }
1250
+ interface SemanticCommon {
1251
+ readonly type?: string;
1252
+ readonly description?: string;
1253
+ /** Audited, never applied. */
1254
+ readonly check?: {
1255
+ readonly contrast: number;
1256
+ readonly against: readonly string[];
1257
+ };
1258
+ }
1259
+ type StepRule = SemanticCommon & {
1260
+ readonly ramp: string;
1261
+ readonly step: Varying<string>;
1262
+ };
1263
+ type OffsetRule = SemanticCommon & {
1264
+ readonly from: string;
1265
+ readonly offset: number;
1266
+ readonly dir: 'lighter' | 'darker' | 'away';
1267
+ };
1268
+ type ContrastRule = SemanticCommon & {
1269
+ readonly ramp: string;
1270
+ readonly contrast: {
1271
+ readonly min: number;
1272
+ readonly against: readonly string[];
1273
+ };
1274
+ };
1275
+ type RefRule = SemanticCommon & {
1276
+ readonly ref: string;
1277
+ readonly alpha?: number;
1278
+ };
1279
+ type LiteralRule = SemanticCommon & {
1280
+ readonly value: TokenValue;
1281
+ };
1282
+ type SemanticRule = StepRule | OffsetRule | ContrastRule | RefRule | LiteralRule;
1283
+ interface ThemeDefinition {
1284
+ readonly name: string;
1285
+ /** Another definition's name. Absent or null: extends nothing. */
1286
+ readonly extends?: string | null;
1287
+ readonly description?: string;
1288
+ readonly axes?: AxisDefs;
1289
+ readonly seeds?: Readonly<Record<string, Varying<number | string>>>;
1290
+ readonly ramps?: Readonly<Record<string, RampDef>>;
1291
+ readonly scales?: Readonly<Record<string, ScaleDef>>;
1292
+ readonly semantics?: Readonly<Record<string, Varying<SemanticRule>>>;
1293
+ readonly components?: Readonly<Record<string, Varying<PinValue>>>;
1294
+ readonly pins?: Readonly<Record<string, Varying<PinValue>>>;
1295
+ /** The colors a `tone` index picks from. Absent: the nearest theme it extends that has one, else the swatch ramp. */
1296
+ readonly tones?: SerializableColorList;
1297
+ }
1298
+
1299
+ export { weaselTheme as $, type AxisDefs as A, type BakedTheme as B, type CategoricalRampDef as C, THEME_SOURCES as D, type ThemeInput as E, type FlatTokens as F, type GeneratedColors as G, colorAt as H, colorCount as I, colorCssAt as J, defineTheme as K, type Lookup as L, enumerateSelections as M, type NumberParam as N, type OffsetRule as O, type PinObject as P, fullSelection as Q, type RawToken as R, type Selection as S, type ThemeDefinition as T, isByAxis as U, type Varying as V, rampSteps as W, resolveTheme as X, selectionKey as Y, themeAxes as Z, themeTones as _, type Theme as a, type ContrastRule as b, type LightnessRampDef as c, type LiteralRule as d, type PinValue as e, type RampDef as f, type RefRule as g, type ScaleDef as h, type SemanticRule as i, type StepRule as j, bake as k, bakeChain as l, mergeChain as m, type TokenName as n, type ResolvedTheme as o, type TokenValue as p, type AxisDef as q, type AxisValue as r, BAKED_THEMES as s, type ByAxis as t, type ColorContext as u, type ColorList as v, type GeneratedTheme as w, type RampColors as x, type SerializableColorList as y, THEMES as z };