@tenphi/glaze 1.0.0 → 1.1.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.
package/docs/api.md CHANGED
@@ -32,21 +32,37 @@ Full reference for every public method, option, and type exported by `@tenphi/gl
32
32
  | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
33
33
  | `glaze(hue, saturation?, config?)` | Create a theme from hue (0–360) and saturation (0–100). Optional `config` overrides the global config for this theme. |
34
34
  | `glaze({ hue, saturation }, config?)` | Create a theme from an options object, with optional per-theme config override. |
35
- | `glaze.from(data)` | Create a theme from an exported configuration (`theme.export()` snapshot). |
35
+ | `glaze.themeFrom(data)` | Create a theme from a `theme.export()` snapshot (`kind: 'theme'`). |
36
+ | `glaze.from(data)` | Compat alias for `glaze.themeFrom`. |
36
37
  | `glaze.fromHex(hex)` | Create a theme from a hex color (`#rgb` or `#rrggbb`). Extracts hue and saturation. |
37
38
  | `glaze.fromRgb(r, g, b)` | Create a theme from RGB values (0–255). Extracts hue and saturation. |
39
+ | `glaze.paletteFrom(data)` | Create a palette from a `palette.export()` snapshot (`kind: 'palette'`). |
40
+ | `glaze.colorFrom(data)` | Create a color token from a `token.export()` snapshot (`kind: 'color'`). |
41
+ | `glaze.isThemeExport(data)` | Type guard for theme authoring snapshots. |
42
+ | `glaze.isColorTokenExport(data)` | Type guard for color-token authoring snapshots. |
43
+ | `glaze.isPaletteExport(data)` | Type guard for palette authoring snapshots. |
38
44
 
39
45
  ```ts
40
46
  const a = glaze(280, 80);
41
47
  const b = glaze({ hue: 280, saturation: 80 });
42
48
  const c = glaze.fromHex('#7a4dbf');
43
49
  const d = glaze.fromRgb(122, 77, 191);
44
- const e = glaze.from(a.export());
50
+ const e = glaze.themeFrom(a.export());
45
51
 
46
52
  // Per-theme config override:
47
53
  const rawTheme = glaze(280, 80, { lightTone: false, darkTone: false });
48
54
  ```
49
55
 
56
+ Authoring restore triad (parallel to `.export()` on each instance):
57
+
58
+ | Export | Restore |
59
+ | ------ | ------- |
60
+ | `theme.export()` | `glaze.themeFrom()` |
61
+ | `token.export()` | `glaze.colorFrom()` |
62
+ | `palette.export()` | `glaze.paletteFrom()` |
63
+
64
+ Every snapshot includes `kind` + `version` (`GLAZE_EXPORT_VERSION`, currently `1`). Legacy snapshots without those fields still restore. Wrong `kind`, or a `version` outside `1..=GLAZE_EXPORT_VERSION`, throws.
65
+
50
66
  The optional `config` parameter is a `GlazeConfigOverride` — see [Per-instance config override](#per-instance-config-override).
51
67
 
52
68
  ---
@@ -66,7 +82,7 @@ A `GlazeTheme` exposes:
66
82
  | `theme.has(name)` | Check if a color is defined. |
67
83
  | `theme.list()` | List all defined color names. |
68
84
  | `theme.reset()` | Clear all color definitions. |
69
- | `theme.export()` | Export the theme configuration as a JSON-safe object. |
85
+ | `theme.export(override?)` | Export the theme configuration as a JSON-safe object (optional config override at export time). |
70
86
  | `theme.extend(options)` | Create a child theme inheriting all color definitions (see [`extend`](#themeextendoptions) below). |
71
87
  | `theme.resolve()` | Resolve all colors and return a `Map<string, ResolvedColor>`. |
72
88
  | `theme.tokens(options?)` | Export as a flat token map grouped by scheme variant. |
@@ -334,16 +350,27 @@ A Tailwind CSS v4 `@theme` block (light baseline) plus dark / high-contrast over
334
350
  | `highContrastSelector` | `'.high-contrast'` | Selector wrapping the light high-contrast overrides. The combined dark + high-contrast block uses `${darkSelector}${highContrastSelector}` (e.g. `.dark.high-contrast`). |
335
351
  | `modes` | global config | Which scheme variants to include. The `@theme` block (light) is always emitted when colors exist. |
336
352
 
337
- ### `theme.export()`
353
+ ### `theme.export(override?)`
338
354
 
339
355
  ```ts
340
356
  const snapshot = theme.export();
341
- // → { hue: 280, saturation: 80, colors: { surface: { ... }, ... } }
357
+ // → {
358
+ // kind: 'theme',
359
+ // version: 1,
360
+ // hue: 280,
361
+ // saturation: 80,
362
+ // colors: { surface: { ... }, ... },
363
+ // config: { lightTone: {...}, darkTone: {...}, pastel: false, ... },
364
+ // }
342
365
 
343
- const restored = glaze.from(snapshot);
366
+ const restored = glaze.themeFrom(snapshot);
344
367
  ```
345
368
 
346
- The export contains only the configuration not resolved color values. Resolved values are recomputed on demand.
369
+ Returns a deep-cloned, JSON-safe authoring snapshot (definitions + frozen
370
+ effective config — not resolved color strings). Freezes
371
+ `getConfig() ∪ instance local ∪ override` at call time. Restored themes pin
372
+ that freeze as their local override. Distinct from `theme.json()`, which
373
+ emits resolved color strings.
347
374
 
348
375
  ---
349
376
 
@@ -395,7 +422,7 @@ type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
395
422
  | `mode` | `'auto' \| 'fixed' \| 'static'` | Adaptation mode. Default: `'auto'`. See [Adaptation modes](#adaptation-modes). |
396
423
  | `autoFlip` | `boolean` | Flip out-of-bounds results (relative `tone` overshoot / unmet `contrast`) to the opposite side instead of clamping. Default: the global `autoFlip` (`true`). See [`autoFlip`](#autoflip). |
397
424
  | `opacity` | `number` | Fixed alpha 0–1. Output includes alpha in the CSS value. Combining with `contrast` is not recommended (a `console.warn` is emitted). |
398
- | `pastel` | `boolean` | Per-color override for the hue-independent "safe" chroma limit used in OKHSL↔sRGB conversions (luminance, contrast solving, output formatting). Falls through to the global / per-theme `pastel` config when omitted. Default: unset. See [Per-color `pastel`](#per-color-pastel). |
425
+ | `pastel` | `boolean` | Per-color override for the hue-independent "safe" chroma limit used in OKHSL↔sRGB conversions (luminance, contrast solving, output formatting). Falls through to the per-theme / per-token `pastel` override when omitted. Default: unset. See [Per-color `pastel`](#per-color-pastel). |
399
426
  | `role` | `RoleInput` | Semantic role against `base` (`'text'` / `'surface'` / `'border'` or an alias). Fixes APCA contrast polarity. Resolved via: explicit `role` → name inference → opposite of the base's role → `'text'`. See [Roles](#roles). |
400
427
  | `inherit` | `boolean` | Whether this color is inherited by child themes via `extend()`. Default: `true`. Set to `false` to make the color local to the current theme. |
401
428
 
@@ -523,7 +550,7 @@ Relative hue is always relative to the **theme seed hue**, not to a base color.
523
550
 
524
551
  #### Per-color `pastel`
525
552
 
526
- `pastel: true` on a single color def overrides the global / per-theme `pastel` config for that color only. It toggles the hue-independent "safe" chroma limit used in every OKHSL↔sRGB conversion that touches this color: luminance calculations during contrast solving, gamut clamping during sRGB blend / mix edges, and output formatting. The effective flag is carried on the resolved variant (`ResolvedColorVariant.pastel`) so formatting matches the gamut mapping applied during resolution.
553
+ `pastel: true` on a single color def overrides the per-theme / per-token `pastel` override for that color only. It toggles the hue-independent "safe" chroma limit used in every OKHSL↔sRGB conversion that touches this color: luminance calculations during contrast solving, gamut clamping during sRGB blend / mix edges, and output formatting. The effective flag is carried on the resolved variant (`ResolvedColorVariant.pastel`) so formatting matches the gamut mapping applied during resolution.
527
554
 
528
555
  ```ts
529
556
  const theme = glaze(280, 80);
@@ -535,7 +562,7 @@ theme.colors({
535
562
  // theme.css().light contains different rgb() triples for `--plain` and `--soft`
536
563
  ```
537
564
 
538
- Omit the field to inherit the global / per-theme `pastel` config — useful for keeping the default behavior while opting a single accent into the pastel gamut.
565
+ Omit the field to inherit the theme/token `pastel` override (default `false`) — useful for keeping the default behavior while opting a single accent into the pastel gamut.
539
566
 
540
567
  The flag is part of the def object, so `extend()` copies it through to child themes alongside the rest of the def. Override it again on the child to flip a single color back:
541
568
 
@@ -665,7 +692,7 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
665
692
  | `opacity` | `number` | Fixed alpha 0–1. |
666
693
  | `base` | `GlazeColorToken \| GlazeColorValue` | Optional dependency. See [Pairing colors](#pairing-colors). |
667
694
  | `contrast` | `HCPair<ContrastSpec>` | Contrast floor against `base` (WCAG or APCA). Without `base`, anchored to the literal seed. |
668
- | `pastel` | `boolean` | Per-color `pastel` override. Falls through to the global / per-theme `pastel` config when omitted. See [Per-color `pastel`](#per-color-pastel). |
695
+ | `pastel` | `boolean` | Per-color `pastel` override. Falls through to the per-theme / per-token `pastel` override when omitted. See [Per-color `pastel`](#per-color-pastel). |
669
696
  | `role` | `RoleInput` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
670
697
  | `name` | `string` | Debug label for warnings; doesn't change output keys. Reserved names (`'value'`, `'seed'`, `'externalBase'`) are rejected. |
671
698
 
@@ -683,7 +710,7 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
683
710
  | `contrast` | Contrast floor (WCAG or APCA). Without `base`, anchored to the literal seed; with `base`, solved per scheme. |
684
711
  | `base` | `GlazeColorToken` or raw `GlazeColorValue`. See [Pairing colors](#pairing-colors). |
685
712
  | `opacity` | Fixed alpha 0–1. Combining with `contrast` is not recommended — `console.warn` is emitted. |
686
- | `pastel` | Per-color `pastel` override. Falls through to the global / per-theme `pastel` config when omitted. See [Per-color `pastel`](#per-color-pastel). |
713
+ | `pastel` | Per-color `pastel` override. Falls through to the per-theme / per-token `pastel` override when omitted. See [Per-color `pastel`](#per-color-pastel). |
687
714
  | `role` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
688
715
  | `name` | Debug label only — surfaces in warnings/errors. Does not change output keys. |
689
716
 
@@ -691,14 +718,14 @@ Named CSS colors (`'red'`, `'blueviolet'`) are not supported.
691
718
 
692
719
  ### Defaults
693
720
 
694
- Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color. The config snapshot taken at create time differs by input form:
721
+ Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color. Tokens store a **sparse local** config override; omitted fields fall through to the live global at resolve time (same as themes). Authoring `.export(override?)` freezes `getConfig() ∪ local ∪ override` at call time.
695
722
 
696
723
  - **Value-shorthand** (bare strings, value objects, and `{ from, ...overrides }`):
697
- - Light variant preserves the input tone exactly (`lightTone: false`).
698
- - All other config fields (`darkTone`, `darkDesaturation`, `autoFlip`) snapshot from `globalConfig` at create time.
724
+ - Light variant preserves the input tone exactly (`lightTone: false` as a local default).
725
+ - Other omitted fields track the live global config.
699
726
  - **Structured input** (`{ hue, saturation, tone, ... }`):
700
- - Both tone windows snapshot from `globalConfig` at create time (same as a theme color).
701
- - All fields are **snapshotted at color-creation time** later `glaze.configure()` calls don't retroactively change existing tokens.
727
+ - Omitted tone windows and other fields track the live global config (same as a theme color).
728
+ - `pastel` is instance-only set via the config override or per-color `pastel`, not `glaze.configure()`.
702
729
 
703
730
  ```ts
704
731
  // Bare string — adapts automatically
@@ -731,25 +758,27 @@ A `GlazeColorToken` exposes:
731
758
  | `token.dtcg(options?)` | DTCG color tokens, one per scheme variant (no color-name key). Each entry is a full `{ $type: 'color', $value }` token. Options: `colorSpace` (`'srgb'` \| `'oklch'`), `modes`. |
732
759
  | `token.dtcgResolver({ name, ... })` | A single DTCG Resolver-Module document for this color, keyed by `name` across all scheme variants. `name` is **required**. Same options as `theme.dtcgResolver()` plus `name`. |
733
760
  | `token.tailwind({ name, ... })` | Tailwind v4 `@theme` block + dark / high-contrast overrides for this color. `name` is **required** (forms `--color-<name>`). Same options as `theme.tailwind()` plus `name`. |
734
- | `token.export()` | JSON-safe snapshot — pass to `glaze.colorFrom(...)` to rehydrate. |
761
+ | `token.export(override?)` | JSON-safe snapshot — freezes effective config at call time; pass to `glaze.colorFrom(...)` to rehydrate. Optional `override` merges over the instance local (and nested `base` exports). |
735
762
 
736
763
  ### Per-instance config override
737
764
 
738
765
  The optional `config` argument (`GlazeConfigOverride`) overrides
739
- resolve-relevant global fields for a token or theme. A tone window can be
740
- `[lo, hi]`, `{ lo, hi, eps }`, or `false` (full range). Standalone tokens
741
- snapshot omitted fields at creation; themes continue reading omitted fields
742
- from the live global config at resolve time.
766
+ resolve-relevant fields for a token or theme. A tone window can be
767
+ `[lo, hi]`, `{ lo, hi, eps }`, or `false` (full range). Both themes and
768
+ standalone tokens keep a sparse local override omitted fields (except
769
+ instance-only `pastel`) fall through to the live global at resolve time.
743
770
 
744
771
  `GlazeConfigOverride`:
745
772
 
746
- | Field | Default (from global) | Description |
747
- | ------------------ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
748
- | `lightTone` | `[10, 100]` | Light tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
749
- | `darkTone` | `[15, 95]` | Dark tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
750
- | `darkDesaturation` | `0.1` | Saturation reduction in dark scheme (0–1). |
751
- | `autoFlip` | `true` | Default for each color's `autoFlip`: when solving `contrast` (or applying a relative `tone` that overshoots), allow crossing to the opposite side instead of clamping. |
752
- | `shadowTuning` | `undefined` | Default shadow tuning (meaningful for themes; harmless on color tokens). |
773
+ | Field | Default (from global / fixed) | Description |
774
+ | ------------------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
775
+ | `lightTone` | `[10, 100]` | Light tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
776
+ | `darkTone` | `[15, 95]` | Dark tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
777
+ | `darkDesaturation` | `0.1` | Saturation reduction in dark scheme (0–1). |
778
+ | `autoFlip` | `true` | Default for each color's `autoFlip`: when solving `contrast` (or applying a relative `tone` that overshoots), allow crossing to the opposite side instead of clamping. |
779
+ | `pastel` | `false` (instance-only) | Theme/token-level pastel default for colors that omit per-color `pastel`. Not available on `glaze.configure()`. |
780
+ | `inferRole` | `true` | Infer color `role` from the name when unset. |
781
+ | `shadowTuning` | `undefined` | Default shadow tuning (meaningful for themes; harmless on color tokens). |
753
782
 
754
783
  Config overrides apply to both `glaze.color()` tokens and `glaze()` themes:
755
784
 
@@ -764,16 +793,13 @@ glaze.color('#000000', {
764
793
  });
765
794
 
766
795
  // Structured form with config override
767
- glaze.color({ hue: 152, saturation: 95, tone: 74 }, { darkTone: false });
796
+ glaze.color({ hue: 152, saturation: 95, tone: 74 }, { darkTone: false, pastel: true });
768
797
 
769
798
  // Theme with config override
770
- const rawTheme = glaze(280, 80, { lightTone: false });
799
+ const rawTheme = glaze(280, 80, { lightTone: false, pastel: true });
771
800
  ```
772
801
 
773
- Standalone color tokens snapshot their effective override at creation time.
774
- Themes behave differently: overridden fields stay fixed, while fields omitted
775
- from the override are read from the live global config at resolve time. See
776
- [Theme config override](#theme-config-override).
802
+ See [Theme config override](#theme-config-override).
777
803
 
778
804
  ### Theme config override
779
805
 
@@ -797,11 +823,17 @@ const child = t.extend({ config: { darkTone: false } });
797
823
  // child: lightTone { lo: 0, hi: 50 } (inherited) + darkTone: false (added)
798
824
  ```
799
825
 
800
- `theme.export()` includes `config`; `glaze.from(data)` restores it.
826
+ `theme.export(override?)` freezes `getConfig() ∪ instance local ∪ override` at
827
+ call time. Restoring via `glaze.themeFrom(data)` (or the compat alias
828
+ `glaze.from`) pins that freeze as the restored theme's local override — matching
829
+ standalone color-token behavior.
801
830
 
802
831
  ### `glaze.colorFrom(data)`
803
832
 
804
- Inverse of `token.export()`. The exported snapshot includes the original input, all overrides (with any `base` token recursively serialized), and the full effective config — so later `glaze.configure()` calls don't change rehydrated tokens.
833
+ Inverse of `token.export()`. The exported snapshot includes the original input,
834
+ all overrides (with any `base` token recursively serialized), and the effective
835
+ config freeze from export time — so later `glaze.configure()` calls don't change
836
+ rehydrated tokens.
805
837
 
806
838
  ```ts
807
839
  const text = glaze.color({ from: '#1a1a1a', contrast: 'AA' });
@@ -1085,15 +1117,41 @@ const palette = glaze.palette(
1085
1117
 
1086
1118
  A `GlazePalette` exposes:
1087
1119
 
1088
- | Method | Description |
1089
- | -------------------------------- | ------------------------------------------------------------ |
1090
- | `palette.tokens(options?)` | Flat token map grouped by scheme variant. |
1091
- | `palette.tasty(options?)` | [Tasty](https://tasty.style) style-to-state bindings. |
1092
- | `palette.json(options?)` | Per-theme JSON map (no prefix needed — keyed by theme name). |
1093
- | `palette.css(options?)` | CSS custom property declaration strings. |
1094
- | `palette.dtcg(options?)` | Per-scheme W3C DTCG token trees. |
1095
- | `palette.dtcgResolver(options?)` | One DTCG Resolver-Module document for every scheme. |
1096
- | `palette.tailwind(options?)` | One Tailwind CSS v4 theme with scheme overrides. |
1120
+ | Method | Description |
1121
+ | -------------------------------- | ---------------------------------------------------------------------------------------------------- |
1122
+ | `palette.list()` | Theme names in insertion order. |
1123
+ | `palette.primary` | Primary theme name, if set. |
1124
+ | `palette.theme(name)` | Get a live theme instance by name. |
1125
+ | `palette.themes()` | Shallow copy of the theme map (same instances the palette holds). |
1126
+ | `palette.export(override?)` | Authoring snapshot restorable via `glaze.paletteFrom()`. Optional override forwarded to themes. |
1127
+ | `palette.tokens(options?)` | Flat token map grouped by scheme variant. |
1128
+ | `palette.tasty(options?)` | [Tasty](https://tasty.style) style-to-state bindings. |
1129
+ | `palette.json(options?)` | Per-theme **resolved** color JSON (not restorable as authoring config). |
1130
+ | `palette.css(options?)` | CSS custom property declaration strings. |
1131
+ | `palette.dtcg(options?)` | Per-scheme W3C DTCG token trees. |
1132
+ | `palette.dtcgResolver(options?)` | One DTCG Resolver-Module document for every scheme. |
1133
+ | `palette.tailwind(options?)` | One Tailwind CSS v4 theme with scheme overrides. |
1134
+
1135
+ ### `palette.export(override?)` / `glaze.paletteFrom()`
1136
+
1137
+ ```ts
1138
+ const snapshot = palette.export();
1139
+ // → {
1140
+ // kind: 'palette',
1141
+ // version: 1,
1142
+ // primary: 'brand',
1143
+ // themes: { brand: { kind: 'theme', ... }, danger: { ... } },
1144
+ // }
1145
+
1146
+ const restored = glaze.paletteFrom(JSON.parse(JSON.stringify(snapshot)));
1147
+ const brand = restored.theme('brand')!;
1148
+ ```
1149
+
1150
+ Optional `override` is forwarded to each nested `theme.export(override)`.
1151
+ Config snapshot vs resolved output: use `export()` / `paletteFrom()` to
1152
+ persist and restore the authoring graph (themes, color defs, relations). Use
1153
+ `json()` / `tokens()` / `css()` / … to emit resolved color strings for apps
1154
+ and design tools.
1097
1155
 
1098
1156
  ### `GlazePaletteExportOptions`
1099
1157
 
@@ -1297,7 +1355,7 @@ On `theme.css()`, `theme.tasty()`, `palette.css()`, `palette.tasty()`, and stand
1297
1355
  --accent-color: oklch(0.62 0.03 var(--accent-hue));
1298
1356
  ```
1299
1357
 
1300
- **Requirements:** every exported color must be pastel (`pastel: true` globally or per-color). Pastel mode bounds chroma by the hue-independent safe chroma at each lightness, so emitted `C` stays in sRGB for any rotated hue. Non-pastel palettes throw rather than emit values that would clip under rotation.
1358
+ **Requirements:** every exported color must be pastel (`pastel: true` on the theme/token override or per-color). Pastel mode bounds chroma by the hue-independent safe chroma at each lightness, so emitted `C` stays in sRGB for any rotated hue. Non-pastel palettes throw rather than emit values that would clip under rotation.
1301
1359
 
1302
1360
  **Limitations:** `oklch` only (native CSS `var()` in the hue slot). Shadow and mix colors stay inline (blended hue). Standalone `.token()` / `.tasty()` do not support `splitHue` (return shape cannot carry the `$name-hue` declaration).
1303
1361
 
@@ -1433,7 +1491,6 @@ boundaries, not the tone transfer.
1433
1491
  | `modes.highContrast` | `false` | Include HC variants. |
1434
1492
  | `shadowTuning` | `undefined` | Default tuning for all shadow colors. Per-color tuning merges field-by-field. |
1435
1493
  | `autoFlip` | `true` | Default for each color's `autoFlip`. When solving `contrast` (or applying a relative `tone` that overshoots `[0, 100]`), allow crossing to the opposite side instead of clamping. With `false`, only the requested direction is considered; unmet contrasts pin the tone to that direction's extreme (and emit a warning) and overshooting offsets clamp to the boundary. Override per color via [`autoFlip`](#autoflip). |
1436
- | `pastel` | `false` | Hue-independent "safe" chroma limit across all colors so scaling saturation never exceeds the sRGB boundary at any hue for the given lightness. Override per color via [`pastel`](#per-color-pastel). |
1437
1494
  | `inferRole` | `true` | Infer each color's [`role`](#roles) from its name when no explicit `role` is set. Set to `false` to opt out of name-based inference (the base-opposite and foreground-default fallbacks still apply). |
1438
1495
 
1439
1496
  | Method | Description |
@@ -1442,7 +1499,7 @@ boundaries, not the tone transfer.
1442
1499
  | `glaze.getConfig()` | Snapshot the current resolved config (shallow copy). |
1443
1500
  | `glaze.resetConfig()` | Reset to defaults (also bumps the version counter). |
1444
1501
 
1445
- Standalone `glaze.color()` tokens snapshot the resolve-relevant fields at create time, so later `configure()` calls don't change already-created tokens. Themes merge the live global at resolve time for fields not overridden via `GlazeConfigOverride`.
1502
+ Themes and standalone color tokens keep a sparse local `GlazeConfigOverride` and merge the live global at resolve time for omitted fields. Authoring `.export(override?)` freezes the effective merge at call time; restored instances pin that freeze. `pastel` is instance-only (theme/token override or per-color) — not set via `configure()`.
1446
1503
 
1447
1504
  ---
1448
1505
 
package/docs/migration.md CHANGED
@@ -16,6 +16,11 @@ If you're starting from scratch, see [methodology.md](methodology.md) first —
16
16
 
17
17
  ## Choosing an export
18
18
 
19
+ Glaze has two layers of “export”:
20
+
21
+ 1. **Authoring snapshots** — `theme.export(override?)` / `token.export(override?)` / `palette.export(override?)`, restored with `glaze.themeFrom` / `colorFrom` / `paletteFrom`. These carry definitions, relations, and a config freeze taken at export time (`kind` + `version`). Live instances keep only a sparse local override; omitted global fields track `configure()` until export.
22
+ 2. **Resolved output** — the seven shapes below. These are color strings / design-token documents for apps and tools, **not** restorable as authoring config.
23
+
19
24
  Glaze emits the same resolved colors in seven shapes. Pick one based on your
20
25
  renderer or tooling.
21
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/glaze",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "OKHST-based color theme generator with WCAG contrast solving for light, dark, and high-contrast schemes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",