@tenphi/cookbook 0.32.0 → 0.33.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.
Files changed (28) hide show
  1. package/docs/customization-rules.md +7 -5
  2. package/docs/migration.md +52 -26
  3. package/docs/theme-and-components.md +32 -15
  4. package/docs/upstream/glaze/README.md +46 -26
  5. package/docs/upstream/glaze/docs/contrast.mdx +751 -0
  6. package/docs/upstream/glaze/docs/exporting.mdx +634 -0
  7. package/docs/upstream/glaze/docs/getting-started.mdx +489 -0
  8. package/docs/upstream/glaze/docs/hdr.mdx +523 -0
  9. package/docs/upstream/glaze/docs/methodology.mdx +922 -0
  10. package/docs/upstream/glaze/docs/migration.md +477 -286
  11. package/docs/upstream/glaze/docs/mixes.mdx +348 -0
  12. package/docs/upstream/glaze/docs/okhst.mdx +679 -0
  13. package/docs/upstream/glaze/docs/reference/color-definitions.md +552 -0
  14. package/docs/upstream/glaze/docs/reference/color-tokens.md +420 -0
  15. package/docs/upstream/glaze/docs/reference/configuration.md +527 -0
  16. package/docs/upstream/glaze/docs/reference/contrast.md +277 -0
  17. package/docs/upstream/glaze/docs/reference/index.md +225 -0
  18. package/docs/upstream/glaze/docs/reference/output.md +713 -0
  19. package/docs/upstream/glaze/docs/reference/palette.md +434 -0
  20. package/docs/upstream/glaze/docs/reference/theme.md +331 -0
  21. package/docs/upstream/glaze/docs/reference/utilities.md +646 -0
  22. package/docs/upstream/glaze/docs/schemes.mdx +635 -0
  23. package/docs/upstream/glaze/docs/shadows-and-glows.mdx +519 -0
  24. package/docs/upstream/manifest.json +2 -2
  25. package/package.json +3 -3
  26. package/docs/upstream/glaze/docs/api.md +0 -2021
  27. package/docs/upstream/glaze/docs/methodology.md +0 -686
  28. package/docs/upstream/glaze/docs/okhst.md +0 -207
@@ -0,0 +1,331 @@
1
+ ---
2
+ title: Themes
3
+ description: Create themes with glaze(), restore them from snapshots, and manage their color definitions with the theme methods.
4
+ ---
5
+ A theme is one hue/saturation seed plus a map of named color definitions. Glaze resolves every definition against the seed into four scheme variants (`light`, `dark`, `lightContrast`, `darkContrast`). For a guided introduction, see [Getting started](../getting-started.mdx) and [Designing a palette](../methodology.mdx).
6
+
7
+ ## Creating a theme
8
+
9
+ | Call | Description |
10
+ | ---------------------------------- | ------------------------------------------------------------------------------------------ |
11
+ | `glaze(hue, saturation?, config?)` | Theme from a hue (0–360) and saturation (0–100). `saturation` defaults to `100`. |
12
+ | `glaze(seed, config?)` | Theme from a [`GlazeThemeSeed`](#glazethemeseed) object, which can also carry a dark seed. |
13
+ | `glaze.fromHex(hex)` | Theme seeded with the hue and saturation of a hex color. |
14
+ | `glaze.fromRgb(r, g, b)` | Theme seeded with the hue and saturation of an sRGB color (0–255 per channel). |
15
+ | `glaze.themeFrom(data)` | Theme restored from a [`theme.export()`](#themeexportoverride) snapshot. |
16
+ | `glaze.from(data)` | Alias for `glaze.themeFrom`, kept for compatibility. |
17
+
18
+ ```ts
19
+ import { glaze } from '@tenphi/glaze';
20
+
21
+ const a = glaze(280, 80);
22
+ const b = glaze({ hue: 280, saturation: 80 });
23
+ const c = glaze({
24
+ hue: 280,
25
+ saturation: 80,
26
+ darkHue: 268,
27
+ darkSaturation: 65,
28
+ });
29
+ const d = glaze.fromHex('#7a4dbf');
30
+ const e = glaze.fromRgb(122, 77, 191);
31
+ const f = glaze.themeFrom(a.export());
32
+
33
+ // Per-theme config override (last argument in both forms):
34
+ const raw = glaze(280, 80, { lightTone: false, darkTone: false });
35
+ const rawSeed = glaze({ hue: 280, saturation: 80 }, { pastel: true });
36
+ ```
37
+
38
+ ### `glaze(hue, saturation?, config?)`
39
+
40
+ | Parameter | Type | Description |
41
+ | ------------ | --------------------- | ------------------------------------------------------------------------------------------------ |
42
+ | `hue` | `number` | Hue seed, 0–360. |
43
+ | `saturation` | `number` | Saturation seed, 0–100. Default `100`. |
44
+ | `config` | `GlazeConfigOverride` | Optional per-theme config override. See [Per-theme config override](#per-theme-config-override). |
45
+
46
+ ### `glaze(seed, config?)`
47
+
48
+ The object form takes a `GlazeThemeSeed` first and an optional `GlazeConfigOverride` second. The older spelling `glaze(seed, undefined, config)` still works but is deprecated.
49
+
50
+ ### `GlazeThemeSeed`
51
+
52
+ | Field | Type | Description |
53
+ | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
54
+ | `hue` | `number` | Light-scheme hue seed, 0–360. Required. |
55
+ | `saturation` | `number` | Light-scheme saturation seed, 0–100. Required. |
56
+ | `darkHue` | `number` | Hue seed for the `dark` and `darkContrast` variants, 0–360. Defaults to `hue`. |
57
+ | `darkSaturation` | `number` | Saturation seed for the `dark` and `darkContrast` variants, 0–100. Defaults to `saturation`. When set, the global `darkDesaturation` reduction is not applied on top. A [`from`](./color-definitions.md#from) color without its own `saturation` or `darkSaturation` doesn't read this seed, so it is still reduced. |
58
+
59
+ How a dark seed combines with per-color `hue` / `darkHue` / `saturation` / `darkSaturation` is in [Color definitions](./color-definitions.md#dark-seed-darkhue--darksaturation); the concept is in [Dark seed](../schemes.mdx#dark-seed).
60
+
61
+ ### `glaze.fromHex(hex)` / `glaze.fromRgb(r, g, b)`
62
+
63
+ Both convert the color to OKHSL and seed the theme with its hue and saturation (OKHSL saturation × 100). The color's lightness is discarded: tones come from the color definitions you add.
64
+
65
+ * `fromHex` accepts `#rgb` or `#rrggbb`; the leading `#` is optional. Hex with alpha (`#rgba`, `#rrggbbaa`) and any other string throw `glaze: invalid hex color "<hex>".` (`glaze.color()` and `from` do accept alpha hex and drop the alpha with a warning.)
66
+ * `fromRgb` takes gamma-encoded sRGB channels on 0–255.
67
+ * Neither accepts a config override. Use `glaze(theme.hue, theme.saturation, config)` with the extracted seed if you need one.
68
+
69
+ ```ts
70
+ const brand = glaze.fromHex('#7a4dbf');
71
+ brand.hue; // ≈ 298.52
72
+ brand.saturation; // ≈ 70.41
73
+ ```
74
+
75
+ To keep a literal color's exact tone and saturation instead of only its hue, use the [`from`](./color-definitions.md#from) field on a color definition or a standalone [`glaze.color()`](./color-tokens.md#glazecolorinput-config) token.
76
+
77
+ ### `glaze.themeFrom(data)` / `glaze.from(data)`
78
+
79
+ Restores a theme from a [`theme.export()`](#themeexportoverride) snapshot (`GlazeThemeExport`). The restored theme pins the snapshot's frozen config as its own override. `glaze.from` is the same function.
80
+
81
+ `themeFrom` throws when:
82
+
83
+ | Condition | Error message |
84
+ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
85
+ | `data` is not an object | `glaze.themeFrom: expected an object from theme.export(), got <type>.` |
86
+ | `kind` is present and not `'theme'` | `glaze.themeFrom: expected kind "theme", got "<kind>".` |
87
+ | `version` is present and not an integer ≥ 1 | `glaze.themeFrom: invalid "version" field — expected an integer >= 1 (got <value>).` |
88
+ | `version` is greater than `GLAZE_EXPORT_VERSION` | `glaze.themeFrom: unsupported export version <n> (this library supports version 2). Upgrade @tenphi/glaze to load this snapshot.` |
89
+ | `version` is `1` and the snapshot has shadow colors or a `shadowTuning` | `glaze.themeFrom: this snapshot is export version 1 (Glaze 1.1–2) and contains …` — see [Upgrading to 3.0](../migration.md#30--shadows-and-glows). |
90
+ | `hue` or `saturation` is not a number | `glaze.themeFrom: expected numeric "hue" and "saturation" fields.` |
91
+ | `darkHue` / `darkSaturation` is present and not a number | `glaze.themeFrom: expected "darkHue" to be a number when present (got <value>).` |
92
+
93
+ Color definitions are not validated on restore; they are validated when the theme first resolves. The versioning rules shared by all snapshot kinds are in [Authoring snapshots](./index.md#authoring-snapshots-and-versioning).
94
+
95
+ ### Per-theme config override
96
+
97
+ The optional `config` argument is a `GlazeConfigOverride` — the resolve-relevant subset of the global config plus the instance-only `pastel` flag. Its fields are listed in [`GlazeConfigOverride`](./configuration.md#glazeconfigoverride).
98
+
99
+ * The override is merged over the **live** global config at resolve time. Fields the override doesn't set keep following later `glaze.configure()` calls.
100
+ * The override is copied when the theme is created (and by `extend()`), so changing the object or array you passed afterwards has no effect. Its fields are read by property access, so a class instance with getters or a proxy works as an override. Validation still happens at resolve.
101
+ * `pastel` is instance-only: it comes from the override (or a per-color `pastel`) and defaults to `false`; `glaze.configure()` can't set it.
102
+ * `modes` and `states` are not part of the override. They are global, or per call on the [output methods](./output.md).
103
+
104
+ ## Theme properties
105
+
106
+ | Member | Type | Description |
107
+ | ---------------------- | -------------------------------- | ------------------------------------------------------------------------------------------ |
108
+ | `theme.hue` | `number` (readonly) | The hue seed, 0–360. |
109
+ | `theme.saturation` | `number` (readonly) | The saturation seed, 0–100. |
110
+ | `theme.darkHue` | `number \| undefined` (readonly) | The dark-scheme hue seed, or `undefined` when the theme reuses `hue`. |
111
+ | `theme.darkSaturation` | `number \| undefined` (readonly) | The dark-scheme saturation seed, or `undefined` when the theme reuses `saturation`. |
112
+ | `theme.getConfig()` | `GlazeConfigResolved` | The effective config this theme resolves with. See [`theme.getConfig()`](#themegetconfig). |
113
+
114
+ ## Theme methods
115
+
116
+ | Method | Description |
117
+ | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
118
+ | `theme.colors(defs)` | Add or replace color definitions. Additive merge: adds new names, overwrites existing ones, keeps the rest. |
119
+ | `theme.color(name)` | Get one color definition, or `undefined`. |
120
+ | `theme.color(name, def)` | Set one color definition. |
121
+ | `theme.remove(name \| names[])` | Remove one or more color definitions. |
122
+ | `theme.has(name)` | Whether a color is defined. |
123
+ | `theme.list()` | Defined color names, in insertion order. |
124
+ | `theme.reset()` | Remove every color definition. |
125
+ | `theme.extend(options)` | Create a child theme that inherits the color definitions. |
126
+ | `theme.resolve()` | Resolve every color and return a `Map<string, ResolvedColor>`. |
127
+ | `theme.export(override?)` | JSON-safe authoring snapshot, restorable with `glaze.themeFrom()`. |
128
+ | `theme.getConfig()` | The effective resolved config. |
129
+ | `theme.tokens()` … `theme.tailwind()` | Output methods — see [Output methods](#output-methods). |
130
+
131
+ ### `theme.colors(defs)`
132
+
133
+ Takes a `ColorMap` (`Record<string, ColorDef>`). The definition shapes are in [Color definitions](./color-definitions.md).
134
+
135
+ ```ts
136
+ theme.colors({ surface: { tone: 97 } });
137
+ theme.colors({
138
+ 'surface-text': { base: 'surface', tone: '-52', contrast: 'AA' },
139
+ });
140
+ // Both 'surface' and 'surface-text' are now defined.
141
+ ```
142
+
143
+ ### `theme.color(name)` / `theme.color(name, def)`
144
+
145
+ ```ts
146
+ theme.color('surface', { tone: 97, saturation: 0.75 }); // set
147
+ theme.color('surface'); // get → { tone: 97, saturation: 0.75 }
148
+ theme.color('missing'); // → undefined
149
+ ```
150
+
151
+ The getter returns the stored definition object itself; replace it with the setter rather than mutating it, so the theme knows to re-resolve.
152
+
153
+ ### `theme.remove(names)`
154
+
155
+ ```ts
156
+ theme.remove('accent');
157
+ theme.remove(['accent', 'accent-text']);
158
+ ```
159
+
160
+ Removing a color that another color uses as `base`, `bg`, `fg`, or `target` makes the next resolve throw, for example `glaze: color "surface-text" references non-existent base "surface".` The full validation table is in [Validation](./configuration.md#validation).
161
+
162
+ ### `theme.has(name)` / `theme.list()` / `theme.reset()`
163
+
164
+ ```ts
165
+ theme.list(); // → ['surface', 'surface-text', 'accent']
166
+ theme.has('surface'); // → true
167
+ theme.reset();
168
+ theme.list(); // → []
169
+ ```
170
+
171
+ ### `theme.extend(options)`
172
+
173
+ Creates a new theme that inherits the parent's color definitions, optionally replacing the seed, overriding colors, and adding config:
174
+
175
+ ```ts
176
+ const danger = primary.extend({
177
+ hue: 23,
178
+ colors: { 'accent-fill': { tone: 48, mode: 'fixed' } },
179
+ });
180
+
181
+ // Inherit the parent's config override and widen the dark window further:
182
+ const wide = primary.extend({ config: { darkTone: [10, 100] } });
183
+ ```
184
+
185
+ `GlazeExtendOptions`:
186
+
187
+ | Field | Type | Description |
188
+ | ---------------- | --------------------- | --------------------------------------------------------------------------------------------------- |
189
+ | `hue` | `number` | Replace the hue seed. Defaults to the parent's `hue`. |
190
+ | `saturation` | `number` | Replace the saturation seed. Defaults to the parent's `saturation`. |
191
+ | `darkHue` | `number` | Replace the dark hue seed. Defaults to the parent's `darkHue`. |
192
+ | `darkSaturation` | `number` | Replace the dark saturation seed. Defaults to the parent's `darkSaturation`. |
193
+ | `colors` | `ColorMap` | Color overrides for the child, merged additively over the inherited map (same as `theme.colors()`). |
194
+ | `config` | `GlazeConfigOverride` | Config override for the child. Shallow-merged over the parent's override; child fields win. |
195
+
196
+ * Colors defined with `inherit: false` on the parent are **not** copied into the child (see [`inherit`](./color-definitions.md#inherit)).
197
+ * The child is independent: later changes to the parent don't reach it.
198
+ * Nested objects in `config` (tone windows, `shadowTuning`, `glowTuning`) replace the parent's value wholesale rather than merging field by field: a child `glowTuning` without `headroom` drops the parent's.
199
+
200
+ Building status themes with `extend` is walked through in [Designing a palette](../methodology.mdx).
201
+
202
+ ### `theme.resolve()`
203
+
204
+ Resolves the dependency graph and returns `Map<string, ResolvedColor>`, keyed by color name. Entries are in dependency order: definition order, except that a referenced color (`base`, `bg`, `fg`, `target`) not yet placed is inserted just before the first color that references it. With `a` based on `c` and defined as `a`, `b`, `c`, the order is `c`, `a`, `b`. The output methods emit tokens in the same order. Call `resolve()` directly for tests, diagnostics, or a custom output pipeline.
205
+
206
+ ```ts
207
+ const resolved = theme.resolve();
208
+ const surface = resolved.get('surface');
209
+ // surface.light
210
+ // → { h: 280, s: 0.8, t: 0.97148…, alpha: 1, pastel: false }
211
+ // t is canonical tone on 0–1.
212
+ ```
213
+
214
+ `ResolvedColor`:
215
+
216
+ | Field | Type | Description |
217
+ | --------------- | ----------------------------- | ------------------------------------------------------------------------------------------------ |
218
+ | `name` | `string` | The color name. |
219
+ | `light` | `ResolvedColorVariant` | Light, normal contrast. |
220
+ | `dark` | `ResolvedColorVariant` | Dark, normal contrast. |
221
+ | `lightContrast` | `ResolvedColorVariant` | Light, high contrast. |
222
+ | `darkContrast` | `ResolvedColorVariant` | Dark, high contrast. |
223
+ | `mode` | `AdaptationMode \| undefined` | The color's adaptation mode (`'auto'` when unset). `undefined` for shadow, glow, and mix colors. |
224
+
225
+ All four variants are always resolved, whatever `modes` says; `modes` only filters what the output methods emit.
226
+
227
+ `ResolvedColorVariant` stores OKHST:
228
+
229
+ | Field | Type | Description |
230
+ | -------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
231
+ | `h` | `number` | OKHSL hue, 0–360. |
232
+ | `s` | `number` | OKHSL saturation, 0–1. |
233
+ | `t` | `number` | Canonical [tone](../okhst.mdx), 0–1 (reference eps). |
234
+ | `alpha` | `number` | Opacity, 0–1. `1` for opaque colors. |
235
+ | `pastel` | `boolean` (optional) | The effective `pastel` flag used while resolving, so formatting applies the same gamut mapping. |
236
+ | `hdr` | `ResolvedHdr` (optional) | A glow's HDR value past SDR white, `{ h, s, t, exposure }`: an opaque base plus a gain in stops. Present only on a glow with a `headroom` whose step passes white; see [HDR values](./color-definitions.md#hdr-values-resolvedhdr). |
237
+
238
+ Format a variant with [`glaze.format()`](./utilities.md#glazeformatvariant-format-pastel) and its HDR value with [`glaze.formatHdr()`](./utilities.md#glazeformathdrvariant-hdrformat); convert tone to OKHSL lightness with `variantToOkhsl` from [OKHST tone utilities](./utilities.md#okhst-tone-utilities).
239
+
240
+ **Caching.** A theme caches its resolved map. Changing definitions (`colors`, `color(name, def)`, `remove`, `reset`) or calling `glaze.configure()` / `glaze.resetConfig()` invalidates it. `resolve()` returns a new `Map` each call, so adding or deleting entries doesn't affect the cache; the `ResolvedColor` objects inside are shared with it, so treat them as read-only.
241
+
242
+ ### `theme.export(override?)`
243
+
244
+ Returns a deep-cloned, JSON-safe **authoring snapshot**: the seed, the color definitions, and a frozen copy of the effective config — not resolved color strings. Restore it with [`glaze.themeFrom()`](#glazethemefromdata--glazefromdata). For resolved colors use the [output methods](./output.md); [Exporting and integration](../exporting.mdx) compares the two.
245
+
246
+ ```ts
247
+ const snapshot = theme.export();
248
+ // → {
249
+ // kind: 'theme',
250
+ // version: 2,
251
+ // hue: 280,
252
+ // saturation: 80,
253
+ // colors: {
254
+ // surface: { tone: 97 },
255
+ // 'surface-text': { base: 'surface', tone: '-52', contrast: 'AA' },
256
+ // accent: { tone: 52, mode: 'fixed' },
257
+ // },
258
+ // config: {
259
+ // lightTone: { lo: 10, hi: 100, eps: 0.05 },
260
+ // darkTone: { lo: 15, hi: 95, eps: 0.05 },
261
+ // darkDesaturation: 0.1,
262
+ // autoFlip: true,
263
+ // pastel: false,
264
+ // inferRole: true,
265
+ // },
266
+ // }
267
+
268
+ const restored = glaze.themeFrom(JSON.parse(JSON.stringify(snapshot)));
269
+ ```
270
+
271
+ `GlazeThemeExport`:
272
+
273
+ | Field | Type | Description |
274
+ | ---------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------ |
275
+ | `kind` | `'theme'` | Snapshot kind. Always written; optional on legacy or hand-written input. |
276
+ | `version` | `number` | Schema version, `GLAZE_EXPORT_VERSION` (`2`). Always written; optional on legacy input. |
277
+ | `hue` | `number` | Hue seed. |
278
+ | `saturation` | `number` | Saturation seed. |
279
+ | `darkHue` | `number` | Dark hue seed. Omitted when the theme reuses `hue`. |
280
+ | `darkSaturation` | `number` | Dark saturation seed. Omitted when the theme reuses `saturation`. |
281
+ | `colors` | `ColorMap` | Deep clone of the color definitions. |
282
+ | `config` | `GlazeConfigOverride` | Frozen effective config (below). May be sparse on legacy input; omitted fields then follow the live global config. |
283
+
284
+ **What the config freeze contains.** `export()` merges, later wins: the live global config, then the theme's own override, then the `override` argument. From that merge it writes:
285
+
286
+ | Field | Frozen |
287
+ | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
288
+ | `lightTone`, `darkTone`, `darkDesaturation`, `autoFlip`, `pastel`, `inferRole` | Always. |
289
+ | `shadowTuning`, `glowTuning` | When set anywhere in the merge. A nested tuning object replaces the earlier one wholesale. A `glowTuning.headroom` is written clamped to 0–2. |
290
+ | `contrastLevel` | Only when the theme's own override or the `override` argument sets it. A global level is a live user preference (an accessibility slider), so it is never frozen. |
291
+ | `modes`, `states` | Never — they are export-time choices, not theme data. |
292
+
293
+ A restored theme pins the frozen fields as its override, so later `glaze.configure()` calls no longer change them; unfrozen fields keep following the global config. The `override` argument affects only the snapshot, not the live theme.
294
+
295
+ ```ts
296
+ glaze.configure({ contrastLevel: 40 });
297
+ theme.export().config?.contrastLevel;
298
+ // → undefined (a global level is not frozen)
299
+ theme.export({ contrastLevel: 70 }).config?.contrastLevel;
300
+ // → 70
301
+ ```
302
+
303
+ ### `theme.getConfig()`
304
+
305
+ Returns the effective `GlazeConfigResolved` the theme resolves with: the live global config with the theme's override merged on top. `pastel` comes only from the override (default `false`); `states` and `modes` are always the global values. The field list is in [`GlazeConfigResolved`](./configuration.md#glazeconfigresolved).
306
+
307
+ The result is a deep copy: mutating it, nested windows, `states`, `modes`, and tunings included, changes nothing about the theme or the global config.
308
+
309
+ ```ts
310
+ const t = glaze(280, 80, { darkTone: [10, 100], pastel: true });
311
+ t.getConfig().darkTone; // → [10, 100]
312
+ t.getConfig().pastel; // → true
313
+ ```
314
+
315
+ ## Output methods
316
+
317
+ Each method resolves the theme (cached) and formats the result. Full options and return shapes are in [Output formats](./output.md).
318
+
319
+ | Method | Returns |
320
+ | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
321
+ | [`theme.tokens(options?)`](./output.md#tokensoptions) | Flat token map grouped by scheme variant: `{ light: { name: value }, dark: {…} }`. |
322
+ | [`theme.tasty(options?)`](./output.md#tastyoptions) | [Tasty](../../../tasty/README.md) style-to-state bindings: `{ '#name': { '': value, '<dark state>': value } }`. |
323
+ | [`theme.json(options?)`](./output.md#jsonoptions) | Per-color JSON: `{ name: { light: value, dark: value } }`. |
324
+ | [`theme.css(options?)`](./output.md#cssoptions) | CSS custom property declarations, one string per variant (`GlazeCssResult`). |
325
+ | [`theme.dtcg(options?)`](./output.md#dtcgoptions) | One W3C DTCG token document per scheme variant. |
326
+ | [`theme.dtcgResolver(options?)`](./output.md#dtcgresolveroptions) | One DTCG Resolver-Module document holding every scheme variant. |
327
+ | [`theme.tailwind(options?)`](./output.md#tailwindoptions) | A Tailwind CSS v4 `@theme` block plus dark / high-contrast overrides, as one CSS string. |
328
+
329
+ With `modes.hdr` (for `css()`, its own `hdr` option, which defaults to `modes.hdr`), each method also writes the HDR values of glows past SDR white ([`glowTuning.headroom`](./configuration.md#glow-headroom)): `tokens()` a `<scheme>Hdr` map after each scheme, `tasty()` a `states.hdr` key after each SDR key that has one, `json()` `<scheme>Hdr` keys, `css()` `result.hdr`, `dtcg()` and `dtcgResolver()` `$extensions['me.tenphi.glaze'].hdr` (`$value` stays SDR), and `tailwind()` blocks under `hdrSelector`. HDR strings are extended `color(srgb R G B)`, and the `css()`, `tasty()`, and `tailwind()` tiers are experimental. Off, every method's output is the same as with no headroom set. Shapes: [HDR output](./output.md#hdr-output); what each export is for: [HDR glows](../hdr.mdx#output-is-opt-in).
330
+
331
+ To combine several themes into one token namespace, use a [palette](./palette.md).