@tenphi/cookbook 0.15.0 → 0.17.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/README.md +25 -0
- package/dist/config.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/docs/ai-agents.md +61 -0
- package/docs/architecture.md +91 -0
- package/docs/authoring.mdx +86 -0
- package/docs/cli.md +88 -0
- package/docs/configuration.md +587 -0
- package/docs/content-sources.md +178 -0
- package/docs/customization-rules.md +154 -0
- package/docs/deployment.md +95 -0
- package/docs/examples.md +101 -0
- package/docs/getting-started.md +134 -0
- package/docs/index.md +74 -0
- package/docs/migration.md +36 -0
- package/docs/starlight-comparison.md +124 -0
- package/docs/theme-and-components.md +745 -0
- package/docs/upstream/glaze/LICENSE +21 -0
- package/docs/upstream/glaze/README.md +156 -0
- package/docs/upstream/glaze/docs/api.md +2021 -0
- package/docs/upstream/glaze/docs/methodology.md +686 -0
- package/docs/upstream/glaze/docs/migration.md +351 -0
- package/docs/upstream/glaze/docs/okhst.md +207 -0
- package/docs/upstream/manifest.json +18 -0
- package/docs/upstream/tasty/LICENSE +21 -0
- package/docs/upstream/tasty/README.md +685 -0
- package/docs/upstream/tasty/docs/README.md +39 -0
- package/docs/upstream/tasty/docs/adoption.md +323 -0
- package/docs/upstream/tasty/docs/ai-agents.md +229 -0
- package/docs/upstream/tasty/docs/comparison.md +448 -0
- package/docs/upstream/tasty/docs/configuration.md +823 -0
- package/docs/upstream/tasty/docs/debug.md +335 -0
- package/docs/upstream/tasty/docs/design-system.md +455 -0
- package/docs/upstream/tasty/docs/dsl.md +1021 -0
- package/docs/upstream/tasty/docs/getting-started.md +238 -0
- package/docs/upstream/tasty/docs/injector.md +634 -0
- package/docs/upstream/tasty/docs/methodology.md +648 -0
- package/docs/upstream/tasty/docs/migration-v3.md +285 -0
- package/docs/upstream/tasty/docs/pipeline.md +749 -0
- package/docs/upstream/tasty/docs/plugins.md +353 -0
- package/docs/upstream/tasty/docs/react-api.md +681 -0
- package/docs/upstream/tasty/docs/runtime-benchmarks.md +351 -0
- package/docs/upstream/tasty/docs/ssr.md +610 -0
- package/docs/upstream/tasty/docs/styles.md +677 -0
- package/docs/upstream/tasty/docs/tasty-static.md +582 -0
- package/package.json +12 -7
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Theme and components
|
|
3
|
+
description: Build an accessible Glaze palette, customize Tasty tokens, and use the supported Astro components.
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 5
|
|
6
|
+
---
|
|
7
|
+
Cookbook uses Glaze to derive light, dark, and high-contrast values from one
|
|
8
|
+
brand input, then exposes the result through Tasty tokens and component
|
|
9
|
+
anatomy.
|
|
10
|
+
|
|
11
|
+
Start with the [customization rules](./customization-rules.md) for the consumer
|
|
12
|
+
contract, local package references, and guidance for coding agents.
|
|
13
|
+
|
|
14
|
+
Use the [Glaze documentation](./upstream/glaze/README.md) to learn how palette
|
|
15
|
+
inputs, color modes, and contrast targets are resolved. These Tasty references
|
|
16
|
+
cover the configuration language accepted by `theme.styles`:
|
|
17
|
+
|
|
18
|
+
* [Style DSL](./upstream/tasty/docs/dsl.md) for state maps, tokens, units,
|
|
19
|
+
conditional selectors, and merge behavior.
|
|
20
|
+
* [Style properties](./upstream/tasty/docs/styles.md) for every enhanced CSS
|
|
21
|
+
property and its accepted syntax.
|
|
22
|
+
* [Configuration](./upstream/tasty/docs/configuration.md) for shared states,
|
|
23
|
+
tokens, units, recipes, and typography presets.
|
|
24
|
+
* [Sub-element styling](./upstream/tasty/docs/react-api.md#sub-element-styling)
|
|
25
|
+
for the component anatomy model used by Cookbook's named style trees.
|
|
26
|
+
* [Tasty methodology](./upstream/tasty/docs/methodology.md) for the design-system
|
|
27
|
+
patterns behind roots, sub-elements, and controlled overrides.
|
|
28
|
+
|
|
29
|
+
## Brand color
|
|
30
|
+
|
|
31
|
+
The default brand is a calm blue with 68% OKHSL saturation. Set a brand color
|
|
32
|
+
with Glaze's `from` declaration:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
theme: {
|
|
36
|
+
brand: {
|
|
37
|
+
from: "#2f5bff";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Add a contrast target when the brand appears as text or focus color:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
theme: {
|
|
46
|
+
brand: {
|
|
47
|
+
from: "#2f5bff",
|
|
48
|
+
contrast: { apca: [45, 60] }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The authored color remains exact when it already satisfies the required
|
|
54
|
+
contrast against the page surface. Otherwise Glaze moves it only as far as the
|
|
55
|
+
floor requires. Dark and high-contrast schemes resolve independently.
|
|
56
|
+
|
|
57
|
+
Cookbook rejects a normal APCA target below 45 unless
|
|
58
|
+
`unsafeContrast: true` is present. That escape hatch is intentionally visible
|
|
59
|
+
in configuration reviews. Literal color shorthand and structured
|
|
60
|
+
`hue`/`saturation`/`tone` input also remain supported for the brand.
|
|
61
|
+
|
|
62
|
+
## Semantic palette
|
|
63
|
+
|
|
64
|
+
`brand` controls accent text, fills, and focus. The optional palette roles
|
|
65
|
+
control the reading surface, text, and callout colors. Declare color
|
|
66
|
+
relationships with Glaze's `tone`, `base`, and `contrast` properties:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
theme: {
|
|
70
|
+
brand: { from: "#2f5bff" },
|
|
71
|
+
palette: {
|
|
72
|
+
surface: { tone: 98, saturation: 0.05 },
|
|
73
|
+
text: {
|
|
74
|
+
base: "surface",
|
|
75
|
+
tone: "-10",
|
|
76
|
+
saturation: 0,
|
|
77
|
+
contrast: { wcag: [7, 10] }
|
|
78
|
+
},
|
|
79
|
+
textSoft: {
|
|
80
|
+
base: "surface",
|
|
81
|
+
tone: "-10",
|
|
82
|
+
saturation: 0.05,
|
|
83
|
+
contrast: { wcag: [4.5, 7] }
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
contrastLevel: "auto"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Glaze resolves each declaration for light, dark, normal, and high-contrast
|
|
91
|
+
modes. The first contrast value applies to normal mode; the second applies to
|
|
92
|
+
high contrast. Palette declarations inherit the brand hue and saturation:
|
|
93
|
+
`saturation` is a 0–1 factor of that seed, and `tone` is 0–100. They can set
|
|
94
|
+
an absolute tone or a tone relative to `base`. Use `from` on a palette role
|
|
95
|
+
when it needs its own color seed; otherwise relative declarations keep its
|
|
96
|
+
relationship to the brand and surrounding surface as the scheme or contrast
|
|
97
|
+
changes. `info`, `success`, `warning`, and `danger` also accept Glaze
|
|
98
|
+
declarations and expose border, `-text`, and `-surface` semantic tokens.
|
|
99
|
+
Cookbook keeps literal surface seeds desaturated in the dark scheme so a nearly
|
|
100
|
+
white tint does not become vivid dark chrome when its tone is inverted.
|
|
101
|
+
|
|
102
|
+
Components consume semantic colors consistently: `surface`, `header`, `surface-2`,
|
|
103
|
+
`surface-3`, `text`, `text-soft`, `border`, `border-strong`, `accent-text`,
|
|
104
|
+
`accent-surface`, `accent-surface-text`, and `focus`. Tasty components can use
|
|
105
|
+
these as `#surface`, `#text`, `#border`, and so on; the Astro shell consumes the
|
|
106
|
+
same resolved values. Glaze also generates hover and pressed states, subtle
|
|
107
|
+
accent fills, overlays, shadows, and the orange, green, blue, purple, and red
|
|
108
|
+
roles used by Starlight content components. No browser color mixes or
|
|
109
|
+
Starlight fallback palette values participate in the rendered theme. Surface
|
|
110
|
+
elevation uses Glaze's contrast-uniform tone axis: `surface-2` advances two tone
|
|
111
|
+
steps and `surface-3` advances four from the base surface, with proportionally
|
|
112
|
+
wider steps in high-contrast mode. Their saturation also steps down to 75% and
|
|
113
|
+
65% of the authored surface seed so tinted surfaces remain restrained as they
|
|
114
|
+
move farther from the base tone.
|
|
115
|
+
|
|
116
|
+
Borders stay intentionally quiet: Glaze derives their hue from `brand` but
|
|
117
|
+
uses only one quarter of the brand saturation. Normal and high-contrast modes
|
|
118
|
+
change border tone, not that restrained saturation relationship.
|
|
119
|
+
|
|
120
|
+
The Appearance button in the desktop and mobile header opens one panel with
|
|
121
|
+
Color scheme and Contrast sections. Color scheme offers Light, Dark, and Auto;
|
|
122
|
+
Contrast offers Normal, High, and Auto. Each preference is independent, and
|
|
123
|
+
existing saved choices are preserved. The panel supports keyboard navigation,
|
|
124
|
+
Escape, and outside-click dismissal. The popover fades and scales vertically
|
|
125
|
+
from 96% to 100% over 120ms using native entry and exit transitions. Reduced
|
|
126
|
+
motion disables the transition. Customize these states with
|
|
127
|
+
`theme.styles.ThemeSelect.Panel` and `OpenPanel`; the root `$popover-transition`
|
|
128
|
+
token controls the duration. Contrast can follow the system, force the
|
|
129
|
+
normal palette, or activate the Glaze high-contrast palette.
|
|
130
|
+
System mode responds to `prefers-contrast: more`; an explicit selection is
|
|
131
|
+
persisted and takes precedence over that media query.
|
|
132
|
+
|
|
133
|
+
Interactive controls step up exactly one surface level: a control on `surface`
|
|
134
|
+
uses `surface-2`, while a control on `surface-2` uses `surface-3`. Hover and
|
|
135
|
+
pressed states build on that elevated surface without changing the border.
|
|
136
|
+
Inputs stay on their surrounding surface so their border remains the visual
|
|
137
|
+
boundary. Selected navigation uses the fixed-mode `accent-surface` and its
|
|
138
|
+
paired `accent-surface-text`, so the brand fill does not drift toward the
|
|
139
|
+
adaptive link color in dark mode.
|
|
140
|
+
|
|
141
|
+
## Design tokens
|
|
142
|
+
|
|
143
|
+
Token names follow Tasty's
|
|
144
|
+
[token and unit syntax](./upstream/tasty/docs/dsl.md#built-in-units): `$name`
|
|
145
|
+
becomes the CSS custom property `--name`. Existing `--name` keys are still
|
|
146
|
+
accepted for compatibility.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
theme: {
|
|
150
|
+
tokens: {
|
|
151
|
+
"$gap": "0.5rem",
|
|
152
|
+
"$radius": "8px",
|
|
153
|
+
"$card-radius": "16px",
|
|
154
|
+
"$border-width": "1px",
|
|
155
|
+
"$outline-width": "2px",
|
|
156
|
+
"$outline-offset": "2px",
|
|
157
|
+
"$control-height": "2.5rem",
|
|
158
|
+
"$layout-width": "87.5rem",
|
|
159
|
+
"$content-width": "58rem",
|
|
160
|
+
"$sidebar-width": "17.5rem"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`layout-width` caps and centers the complete documentation shell, while
|
|
166
|
+
`content-width` limits the reading column inside it. `radius` is the control
|
|
167
|
+
and navigation radius; `card-radius` is the larger surface radius. Keeping
|
|
168
|
+
those roles separate makes a sharp control theme or a soft card theme possible
|
|
169
|
+
without one-off component overrides.
|
|
170
|
+
|
|
171
|
+
## Typography presets
|
|
172
|
+
|
|
173
|
+
The built-in [typography presets](./upstream/tasty/docs/styles.md#preset) are
|
|
174
|
+
`body`, `heading`, `h1` through `h6`, `navigation`, `small`, and `code`. Onest
|
|
175
|
+
is self-hosted and used for body and heading text by default; JetBrains Mono is
|
|
176
|
+
self-hosted for code.
|
|
177
|
+
|
|
178
|
+
### Change font families
|
|
179
|
+
|
|
180
|
+
Set `theme.fonts` to load fonts and apply them to the matching presets. A Google
|
|
181
|
+
Fonts family needs only its name:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
theme: {
|
|
185
|
+
fonts: {
|
|
186
|
+
body: "Inter",
|
|
187
|
+
heading: "Newsreader"
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The short form requests the family's default style. To use specific weights,
|
|
193
|
+
list them explicitly. Google Fonts must support the requested weights; see the
|
|
194
|
+
[Google Fonts CSS API](https://developers.google.com/fonts/docs/css2) for its
|
|
195
|
+
available styles and weight syntax.
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
theme: {
|
|
199
|
+
fonts: {
|
|
200
|
+
body: { google: "Inter", weights: [400, 600, 700] }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
For a font you own, put its files in `public/fonts/` and give Cookbook their
|
|
206
|
+
public paths. Cookbook checks that each file exists during the build and adjusts
|
|
207
|
+
its URL for the Astro `base` path. A variable font can cover a weight range;
|
|
208
|
+
use separate entries for regular and italic files when needed:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
theme: {
|
|
212
|
+
fonts: {
|
|
213
|
+
body: {
|
|
214
|
+
family: "Acme Sans",
|
|
215
|
+
files: [
|
|
216
|
+
{ src: "/fonts/acme-sans.woff2", weight: "100 900" },
|
|
217
|
+
{ src: "/fonts/acme-sans-italic.woff2", weight: "100 900", style: "italic" }
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The `body` role also feeds navigation and small text. `heading` feeds `h1`
|
|
225
|
+
through `h6`, while `code` covers code text. Each role has a system fallback.
|
|
226
|
+
Cookbook emits the font faces through Tasty. Google font names are resolved at
|
|
227
|
+
build time, so those builds need network access; the generated site has no
|
|
228
|
+
Google CSS stylesheet. Font files are requested from Google's font CDN when
|
|
229
|
+
visitors open the site. Use local files if you need a self-hosted site.
|
|
230
|
+
|
|
231
|
+
### Adjust presets
|
|
232
|
+
|
|
233
|
+
Presets merge property-by-property, so changing size, weight, or line height
|
|
234
|
+
does not require copying the rest of the preset. `theme.presets` takes precedence
|
|
235
|
+
over `theme.fonts` for an explicitly set `fontFamily`:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
theme: {
|
|
239
|
+
presets: {
|
|
240
|
+
body: {
|
|
241
|
+
boldFontWeight: 680
|
|
242
|
+
},
|
|
243
|
+
heading: {
|
|
244
|
+
fontWeight: 650,
|
|
245
|
+
boldFontWeight: 740
|
|
246
|
+
},
|
|
247
|
+
h1: {
|
|
248
|
+
fontSize: "3rem",
|
|
249
|
+
letterSpacing: "-0.02em"
|
|
250
|
+
},
|
|
251
|
+
code: { fontSize: "0.9rem" }
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
For a system or already loaded font, set its CSS family directly with
|
|
257
|
+
`theme.presets.<role>.fontFamily`. This does not load a font file. Additional
|
|
258
|
+
named presets are available to custom MDX components.
|
|
259
|
+
|
|
260
|
+
Heading presets reference the `heading` family and weights; body, navigation,
|
|
261
|
+
and controls reference `body`. Semantic `strong` and `b` elements use Tasty's
|
|
262
|
+
`strong` modifier, so their weight comes from the active preset's
|
|
263
|
+
`boldFontWeight` instead of a separate element-specific value. `strong` is a
|
|
264
|
+
reserved modifier keyword, not a named preset; the modifier-only form is
|
|
265
|
+
equivalent to `inherit / strong`. Body text uses a regular `400` weight and
|
|
266
|
+
neutral tracking, while
|
|
267
|
+
headings use a medium `610` weight and progressively gentle negative tracking.
|
|
268
|
+
The separate `720` heading bold weight keeps emphasized heading text distinct.
|
|
269
|
+
Navigation uses a lighter `450` weight with `580` for the current sidebar page,
|
|
270
|
+
while smaller group labels establish hierarchy without oversized bold text.
|
|
271
|
+
Top-level sidebar groups are always-visible section headings with their direct
|
|
272
|
+
links aligned beneath them. Deeper groups expand on click or keyboard activation;
|
|
273
|
+
the current group and its ancestors start open. Groups can have a parent-page
|
|
274
|
+
`link`; activating an unselected linked header selects that page and keeps its
|
|
275
|
+
children open. Activating the selected header toggles its children.
|
|
276
|
+
The current group can stay collapsed because its header remains visible. Only
|
|
277
|
+
the current page is highlighted; ancestors receive no extra emphasis. Explicit expansion choices are
|
|
278
|
+
remembered for the browser tab; automatically revealing the current page does
|
|
279
|
+
not overwrite them. Desktop scroll position is restored independently of mobile
|
|
280
|
+
menu scrolling, and the current page's ancestors remain open after navigation.
|
|
281
|
+
Nested groups use indentation without vertical rails. Customize section headings
|
|
282
|
+
with `theme.styles.Sidebar.SectionHeading`, indentation with `NestedItem`, and
|
|
283
|
+
disclosure icons with `Caret` and `ExpandedCaret`.
|
|
284
|
+
Adjacent sidebar items have a `1bw` gap. Inline code scales to `0.875em` of its
|
|
285
|
+
surrounding text, including smaller table text; code blocks keep the `code` preset
|
|
286
|
+
size. Customize inline code through `theme.styles.MarkdownInlineCode`.
|
|
287
|
+
Cookbook applies each semantic typography role through its complete Tasty
|
|
288
|
+
`preset`, so configured fields such as `fontStyle` and `textTransform` are not
|
|
289
|
+
silently omitted.
|
|
290
|
+
|
|
291
|
+
The exported `DEFAULT_THEME_TOKENS` and `DEFAULT_TYPOGRAPHY_PRESETS` constants
|
|
292
|
+
are useful when building a theme editor or presenting a reset action.
|
|
293
|
+
|
|
294
|
+
## Style customization
|
|
295
|
+
|
|
296
|
+
Cookbook-owned interface elements are direct `tasty()` components. Supported
|
|
297
|
+
Starlight-rendered surfaces use the same Tasty style trees through the global
|
|
298
|
+
bridge. Customize either kind by name under `theme.styles`; the configuration
|
|
299
|
+
is resolved before CSS generation, so this is not a selector-based CSS
|
|
300
|
+
override.
|
|
301
|
+
|
|
302
|
+
Provide only the root and named
|
|
303
|
+
[sub-element](./upstream/tasty/docs/dsl.md#sub-element) properties you want to
|
|
304
|
+
override. Cookbook deep-merges that partial style object into the complete
|
|
305
|
+
base style object inside the renderer, following Tasty's
|
|
306
|
+
[state-map merge semantics](./upstream/tasty/docs/dsl.md#extending-vs-replacing-state-maps):
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
theme: {
|
|
310
|
+
styles: {
|
|
311
|
+
ThemeSelect: {
|
|
312
|
+
Trigger: {
|
|
313
|
+
border: "#border-strong"
|
|
314
|
+
},
|
|
315
|
+
Panel: {
|
|
316
|
+
padding: "1x",
|
|
317
|
+
shadow: "0 1rem 3rem #shadow"
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
TopNavigation: {
|
|
321
|
+
Link: { preset: "body" },
|
|
322
|
+
CurrentLink: { color: "#accent-text" }
|
|
323
|
+
},
|
|
324
|
+
Sidebar: {
|
|
325
|
+
LinkLabel: { whiteSpace: "normal" }
|
|
326
|
+
},
|
|
327
|
+
TableOfContents: {
|
|
328
|
+
LinkLabel: { whiteSpace: "normal" }
|
|
329
|
+
},
|
|
330
|
+
MobileMenuToggle: {
|
|
331
|
+
Page: { color: "#accent-text" }
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
No merge helper or base style object is required in user configuration. Style
|
|
338
|
+
customization has one behavior: every supplied object is a partial override and
|
|
339
|
+
is merged into the base inside Cookbook.
|
|
340
|
+
|
|
341
|
+
Every configurable surface accepts styles at the root plus these named Tasty
|
|
342
|
+
sub-elements:
|
|
343
|
+
|
|
344
|
+
| Configuration name | Named sub-elements |
|
|
345
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
346
|
+
| `Card` | `Heading2`, `Heading3`, `Paragraph` |
|
|
347
|
+
| `Callout` | `Title`, `Body`, `Tip`, `Caution`, `Danger` |
|
|
348
|
+
| `CodeGroup` | `Caption`, `Pre`, `Code` |
|
|
349
|
+
| `Tab` | `Heading`, `Hidden`, `HiddenHeading` |
|
|
350
|
+
| `Footer` | `Meta`, `LoneMetaItem`, `MetaLink`, `HoverMetaLink`, `Credit`, `CreditLink`, `HoverCreditLink` |
|
|
351
|
+
| `Hero` | `Visual`, `Stack`, `Copy`, `Title`, `Tagline`, `Actions`, `Action`, `HoverAction`, `PrimaryAction`, `SecondaryAction`, `MinimalAction`, `ActionIcon` |
|
|
352
|
+
| `LanguageSelect` | `Label`, `HoverLabel`, `LabelIcon`, `Select`, `Caret`, `Option` |
|
|
353
|
+
| `Logo` | `Svg`, `Mark` |
|
|
354
|
+
| `MarkdownCodeBlock` | `Pre`, `CopyButton`, `HoverCopyButton`, `CopiedButton`, `CopyIcon`, `CopiedIcon` |
|
|
355
|
+
| `MarkdownHeading` | `Heading`, `Heading1`, `Heading2`, `Heading3`, `Heading4`, `Heading5`, `Heading6`, `Link`, `RevealedLink`, `HoverLink`, `LinkIcon`, `CopiedLink`, `CopiedLinkIcon`, `CopiedIcon` |
|
|
356
|
+
| `MarkdownInlineCode` | None |
|
|
357
|
+
| `MarkdownTable` | `Table`, `Cell`, `LastBodyRowCell`, `HeaderCell` |
|
|
358
|
+
| `Mermaid` | `Diagram`, `Text`, `MonoText` |
|
|
359
|
+
| `MobileMenuFooter` | `Social` |
|
|
360
|
+
| `MobileMenuToggle` | `Control`, `Icon`, `Section`, `Page`, `HoverControl`, `ActiveControl` |
|
|
361
|
+
| `MobileNavigationTabs` | `Trigger`, `Marker`, `Caret`, `ExpandedCaret`, `Label`, `List`, `Item`, `Link`, `HoverLink`, `CurrentLink` |
|
|
362
|
+
| `MobileTableOfContents` | `Item`, `Link`, `LinkLabel`, `HoverLink`, `CurrentLink`, `CurrentIndicator` |
|
|
363
|
+
| `PackageVersion` | None |
|
|
364
|
+
| `VersionSwitcher` | `Trigger`, `Panel`, `OpenPanel`, `Link`, `CurrentLink` |
|
|
365
|
+
| `Preview` | `Caption`, `Stage`, `Frame`, `Code`, `Summary`, `Pre` |
|
|
366
|
+
| `Sidebar` | `Backdrop`, `OpenBackdrop`, `MobileHeading`, `HomeLink`, `HomeLogo`, `HomeLabel`, `Close`, `HoverClose`, `CloseIcon`, `CurrentLink`, `OpenPane`, `Content`, `Tree`, `List`, `Item`, `TopLevelSpacing`, `GroupSpacing`, `NestedItem`, `SectionHeading`, `Control`, `Summary`, `GroupLabel`, `GroupLabelText`, `Link`, `LinkLabel`, `InteractiveControl`, `SummaryMarker`, `Caret`, `ExpandedCaret`, `LinkedSummary`, `GroupLink`, `LinkedSectionHeading`, `SectionLink`, `Badge`, `TopLevelLink` |
|
|
367
|
+
| `SocialIcons` | `Link`, `HoverLink`, `Icon` |
|
|
368
|
+
| `StarlightHeader` | `Primary`, `TitleAndSearch`, `Title`, `LogoLink`, `Logo`, `SiteTitle`, `Search`, `SearchElement`, `Tools`, `ToolItem`, `Social`, `MobileTheme` |
|
|
369
|
+
| `TableOfContentsLayout` | `Content` |
|
|
370
|
+
| `SearchButton` | `Label`, `Shortcut`, `Hover`, `Active`, `NativeIcon`, `Icon` |
|
|
371
|
+
| `Layout` | `LockedPage` |
|
|
372
|
+
| `HeaderLinks` | `Desktop`, `Link`, `HoverLink`, `PrimaryLink`, `HoverPrimaryLink`, `Trigger`, `HoverTrigger`, `Panel`, `PanelNavigation`, `PanelLink`, `FirstPanelLink`, `Close`, `HoverClose` |
|
|
373
|
+
| `HeaderFrame` | None |
|
|
374
|
+
| `PageFrame` | `MainFrame`, `SidebarFrame`, `Columns` |
|
|
375
|
+
| `Steps` | `Item`, `Marker` |
|
|
376
|
+
| `Tabs` | `List`, `Button`, `SelectedButton`, `FocusedButton` |
|
|
377
|
+
| `TableOfContents` | `Heading`, `List`, `Item`, `Link`, `LinkLabel`, `HoverLink`, `CurrentLink` |
|
|
378
|
+
| `ThemeSelect` | `Trigger`, `HoverTrigger`, `ActiveTrigger`, `Icon`, `Panel`, `OpenPanel`, `Section`, `SectionSpacing`, `SectionLabel`, `Option`, `HoverOption`, `CheckedOption`, `FocusedOption`, `Input`, `OptionIcon`, `Checkmark`, `SelectedCheckmark` |
|
|
379
|
+
| `TopNavigation` | `Scrollbar`, `Link`, `HoverLink`, `CurrentLink`, `ActiveIndicator` |
|
|
380
|
+
|
|
381
|
+
`COOKBOOK_COMPONENT_NAMES` publishes the configuration names, and
|
|
382
|
+
`COOKBOOK_COMPONENT_SUB_ELEMENTS` publishes the complete sub-element lists for
|
|
383
|
+
theme editors and other tooling. The corresponding TypeScript types are
|
|
384
|
+
`CookbookComponentName`, `CookbookComponentSubElementName`,
|
|
385
|
+
`CookbookComponentStyles`, `ComponentStyleConfig`, and `ComponentStylesConfig`.
|
|
386
|
+
Known configuration names provide editor suggestions for their named
|
|
387
|
+
sub-elements. `ThemeSelect` styles the combined Appearance panel; replace old
|
|
388
|
+
`Select` and `Picker` overrides with `Trigger` and `Panel`. The separate
|
|
389
|
+
`ContrastSelect` surface is replaced by the same `ThemeSelect` panel and option
|
|
390
|
+
sub-elements. `SocialIcons` styles the shared icon-button links in the header
|
|
391
|
+
and mobile menu. On wider layouts, heading permalinks sit to the left of the
|
|
392
|
+
heading and are revealed on heading hover or keyboard focus. On mobile they
|
|
393
|
+
stay visible and inline so the target is not clipped by the narrower content
|
|
394
|
+
gutter. Customize the behavior with `MarkdownHeading.Link`,
|
|
395
|
+
`MarkdownHeading.RevealedLink`, and `MarkdownHeading.LinkIcon`. Activating a
|
|
396
|
+
heading link copies the full page URL with that section’s fragment, without
|
|
397
|
+
scrolling or changing the current URL. A checkmark and screen-reader status
|
|
398
|
+
confirm the copy; clipboard failures are announced. Modified clicks and links
|
|
399
|
+
without JavaScript retain native anchor behavior. Customize the confirmation
|
|
400
|
+
with `MarkdownHeading.CopiedLink`, `MarkdownHeading.CopiedLinkIcon` (the hidden
|
|
401
|
+
original icon), and `MarkdownHeading.CopiedIcon` (the checkmark).
|
|
402
|
+
|
|
403
|
+
Root properties customize each navigation container. For example, overriding
|
|
404
|
+
`Sidebar.LinkLabel.whiteSpace` keeps the other base `LinkLabel` properties
|
|
405
|
+
because the configured object is merged by default.
|
|
406
|
+
By default, the footer credit uses the primary body text color, while its
|
|
407
|
+
Cookbook link uses the semantic brand link color.
|
|
408
|
+
|
|
409
|
+
`components.overrides` remains the structural escape hatch for replacing an
|
|
410
|
+
Astro component. Prefer `theme.styles` when the markup and behavior remain the
|
|
411
|
+
same.
|
|
412
|
+
|
|
413
|
+
Register custom names and their partial Tasty objects in `theme.customStyles`.
|
|
414
|
+
Built-in names belong in `theme.styles` and reject misspelled sub-elements.
|
|
415
|
+
Custom names can also target a matching user-authored `data-tasty-anatomy` attribute.
|
|
416
|
+
|
|
417
|
+
The default renderer runs Tasty in Astro extract mode. Direct components and
|
|
418
|
+
the remaining document/vendor bridge styles are collected into shared static
|
|
419
|
+
CSS during the build, while appearance controls add only the small client
|
|
420
|
+
behavior needed to persist selected theme and contrast modes. The compact
|
|
421
|
+
Cookbook logo is shown beside the project title in the default top bar, links
|
|
422
|
+
to the localized home page, and is also the default generated favicon. Use
|
|
423
|
+
[`site.favicon`](./configuration.md#site-icons) to generate the complete icon
|
|
424
|
+
set from project artwork.
|
|
425
|
+
|
|
426
|
+
## Diff snippets
|
|
427
|
+
|
|
428
|
+
Use a `diff` code fence to highlight changed lines. Insertions and deletions
|
|
429
|
+
receive subtle theme-aware backgrounds while their `+` and `-` markers remain
|
|
430
|
+
visible for readers who do not distinguish the colors.
|
|
431
|
+
|
|
432
|
+
```diff
|
|
433
|
+
-formatOkhsl(v.h, v.s * 100, l * 100);
|
|
434
|
+
+formatOkhsl(v.h, v.s, l);
|
|
435
|
+
|
|
436
|
+
-formatOkhst(v.h, v.s * 100, v.t * 100);
|
|
437
|
+
+formatOkhst(v.h, v.s, v.t);
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Astro and MDX components
|
|
441
|
+
|
|
442
|
+
The facade exposes supported components from `@tenphi/cookbook/components`:
|
|
443
|
+
|
|
444
|
+
```mdx
|
|
445
|
+
import { Card, Logo, Preview, Steps, Tabs } from "@tenphi/cookbook/components";
|
|
446
|
+
|
|
447
|
+
<Card title="Package-first" href="/getting-started/">
|
|
448
|
+
Generate a site from a locked npm artifact.
|
|
449
|
+
</Card>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
* `Card` renders a titled article or link.
|
|
453
|
+
* `Logo` renders the Cookbook mark using the active brand color.
|
|
454
|
+
* `Steps` provides an ordered steps container.
|
|
455
|
+
* `Tabs` and `Tab` provide accessible tabbed panels.
|
|
456
|
+
* `Callout` renders a note, tip, caution, or danger block.
|
|
457
|
+
* `CodeGroup` renders labeled source strings in tabs.
|
|
458
|
+
|
|
459
|
+
See [Authoring components](./authoring.mdx) for complete examples and props.
|
|
460
|
+
|
|
461
|
+
* `Preview` isolates HTML and CSS with declarative Shadow DOM, or JavaScript
|
|
462
|
+
in a sandboxed iframe.
|
|
463
|
+
|
|
464
|
+
Use MDX only for repository content you control. Locked package content remains
|
|
465
|
+
Markdown-only unless the consumer explicitly sets `trust: "mdx"` for that
|
|
466
|
+
source.
|
|
467
|
+
|
|
468
|
+
## Authoring custom components
|
|
469
|
+
|
|
470
|
+
Import styling tools from `@tenphi/cookbook/styling`. They use the same Tasty
|
|
471
|
+
runtime as Cookbook, with its semantic colors, typography presets, units, and
|
|
472
|
+
responsive states. The renderer package also exposes them from
|
|
473
|
+
`@tenphi/starlight/styling`.
|
|
474
|
+
|
|
475
|
+
| Export | Purpose |
|
|
476
|
+
| ------------------------ | ---------------------------------------------------------------------------------- |
|
|
477
|
+
| `defineComponent` | Create a named Tasty component with its `theme.customStyles[name]` overrides. |
|
|
478
|
+
| `tasty` | Use Tasty directly without binding a component to `theme.customStyles`. |
|
|
479
|
+
| `useGlobalStyles` | Collect a global Tasty style tree while rendering a page. |
|
|
480
|
+
| `resolveComponentStyles` | Merge `theme.customStyles[name]` into a complete base style tree for global rules. |
|
|
481
|
+
| `mergeStyles` | Compose your own base styles with Tasty's deep-merge semantics. |
|
|
482
|
+
| `Styles` | TypeScript type for a Tasty style object. |
|
|
483
|
+
|
|
484
|
+
Cookbook supplies the React renderer and extracts these styles into its static
|
|
485
|
+
CSS. No additional Tasty dependency, Astro integration, or `client:*` directive
|
|
486
|
+
is needed for static components. Set shared tokens, presets, and states in
|
|
487
|
+
`docs.config.ts` before rendering. Import the styling entry point in component
|
|
488
|
+
modules; configuration files should use the main `@tenphi/cookbook` entry point.
|
|
489
|
+
|
|
490
|
+
### A custom logo and site title
|
|
491
|
+
|
|
492
|
+
To put your own logo and title in one home link, create
|
|
493
|
+
`docs/components/site-title.ts`:
|
|
494
|
+
|
|
495
|
+
```ts
|
|
496
|
+
import { defineComponent } from "@tenphi/cookbook/styling";
|
|
497
|
+
|
|
498
|
+
export const SiteTitleRoot = defineComponent("ProjectSiteTitle", {
|
|
499
|
+
as: "a",
|
|
500
|
+
styles: {
|
|
501
|
+
display: "flex",
|
|
502
|
+
alignItems: "center",
|
|
503
|
+
gap: "1x",
|
|
504
|
+
inlineSize: "min 0",
|
|
505
|
+
color: "#text",
|
|
506
|
+
preset: { "": "h4 / strong", "@mobile": "h5 / strong" },
|
|
507
|
+
textDecoration: "none",
|
|
508
|
+
Logo: {
|
|
509
|
+
$: "> svg",
|
|
510
|
+
display: "block",
|
|
511
|
+
flexShrink: "0",
|
|
512
|
+
inlineSize: { "": "2rem", "@mobile": "1.75rem" },
|
|
513
|
+
blockSize: { "": "2rem", "@mobile": "1.75rem" },
|
|
514
|
+
color: "#accent-text",
|
|
515
|
+
},
|
|
516
|
+
Label: {
|
|
517
|
+
$: "> span",
|
|
518
|
+
inlineSize: "min 0",
|
|
519
|
+
overflow: "hidden",
|
|
520
|
+
textOverflow: "ellipsis",
|
|
521
|
+
whiteSpace: "nowrap",
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
});
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
Then create `docs/components/SiteTitle.astro`, using an SVG whose paths use
|
|
528
|
+
`currentColor` to follow the semantic accent color:
|
|
529
|
+
|
|
530
|
+
```astro
|
|
531
|
+
---
|
|
532
|
+
import ProjectLogo from "../../public/logo.svg";
|
|
533
|
+
import { SiteTitleRoot } from "./site-title.js";
|
|
534
|
+
|
|
535
|
+
const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute;
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
<SiteTitleRoot href={siteTitleHref}>
|
|
539
|
+
<ProjectLogo aria-hidden="true" focusable="false" />
|
|
540
|
+
<span translate="no">{siteTitle}</span>
|
|
541
|
+
</SiteTitleRoot>
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
Register the replacement in `docs.config.ts` and hide the default header mark.
|
|
545
|
+
The custom component supports root styles plus its complete list of named
|
|
546
|
+
sub-elements: `Logo` and `Label`.
|
|
547
|
+
|
|
548
|
+
```ts
|
|
549
|
+
components: {
|
|
550
|
+
overrides: {
|
|
551
|
+
SiteTitle: "./docs/components/SiteTitle.astro"
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
theme: {
|
|
555
|
+
styles: {
|
|
556
|
+
StarlightHeader: { LogoLink: { hide: true } }
|
|
557
|
+
},
|
|
558
|
+
customStyles: {
|
|
559
|
+
ProjectSiteTitle: { Logo: { color: "#text" } }
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
`defineComponent(name, options)` accepts Tasty factory options and a name for
|
|
565
|
+
`theme.customStyles[name]`. It merges the configured partial style object before
|
|
566
|
+
creating the component, retaining the other base properties and responsive
|
|
567
|
+
states. Tasty options such as `elements`, `variants`, `styleProps`, `modProps`,
|
|
568
|
+
and `tokenProps` keep their behavior and inferred types, including generated
|
|
569
|
+
subcomponents such as `Component.Label`.
|
|
570
|
+
Configured styles become the component's defaults; variants and styles passed
|
|
571
|
+
at render time follow Tasty's usual precedence.
|
|
572
|
+
|
|
573
|
+
Use `defineComponent` when authoring a component that should support
|
|
574
|
+
`theme.customStyles`. Use `tasty` directly for ordinary Tasty creation or composition
|
|
575
|
+
that does not need a configuration name. To define a named component around
|
|
576
|
+
an existing React component that forwards `className`, pass it as `as` in the options. Use `className`
|
|
577
|
+
when passing a class to a Tasty component from Astro.
|
|
578
|
+
|
|
579
|
+
### Global style trees
|
|
580
|
+
|
|
581
|
+
For markup you do not render through a Tasty component, call
|
|
582
|
+
`useGlobalStyles()` during rendering. For example, this Astro component
|
|
583
|
+
supports root styles and a `Label` sub-element through `theme.customStyles.ProjectNote`:
|
|
584
|
+
|
|
585
|
+
```astro
|
|
586
|
+
---
|
|
587
|
+
import {
|
|
588
|
+
resolveComponentStyles,
|
|
589
|
+
useGlobalStyles,
|
|
590
|
+
} from "@tenphi/cookbook/styling";
|
|
591
|
+
|
|
592
|
+
useGlobalStyles(
|
|
593
|
+
".project-note",
|
|
594
|
+
resolveComponentStyles("ProjectNote", {
|
|
595
|
+
padding: "2x",
|
|
596
|
+
fill: "#surface-2",
|
|
597
|
+
Label: { $: "> strong", color: "#text", preset: "strong" },
|
|
598
|
+
}),
|
|
599
|
+
);
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
<aside class="project-note"><strong>Note</strong><slot /></aside>
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
`defineComponent` and `resolveComponentStyles` read the same `theme.customStyles`
|
|
606
|
+
configuration; user configuration contains only the properties to change. They do not require a
|
|
607
|
+
`data-tasty-anatomy` attribute. That attribute remains available for older
|
|
608
|
+
components using the compatibility bridge described above.
|
|
609
|
+
|
|
610
|
+
## Linting custom styles
|
|
611
|
+
|
|
612
|
+
`@tenphi/cookbook/eslint-plugin` re-exports the Tasty ESLint plugin together with
|
|
613
|
+
Cookbook's `validationConfig`. The renderer offers the same exports from
|
|
614
|
+
`@tenphi/starlight/eslint-plugin`. Keep style definitions in `.ts` or `.tsx`
|
|
615
|
+
modules, as in the site title example above, to lint them with either ESLint or
|
|
616
|
+
oxlint.
|
|
617
|
+
|
|
618
|
+
Create `tasty.config.ts` at your project root:
|
|
619
|
+
|
|
620
|
+
```ts
|
|
621
|
+
export default {
|
|
622
|
+
extends: "@tenphi/cookbook",
|
|
623
|
+
};
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
Renderer-only consumers can use `extends: "@tenphi/starlight"` instead.
|
|
627
|
+
The preset registers both Cookbook styling import paths, its built-in tokens,
|
|
628
|
+
units, responsive states, and typography presets. It also describes
|
|
629
|
+
`defineComponent`, `resolveComponentStyles`, and `mergeStyles`, so their inline
|
|
630
|
+
style objects, variants, and named sub-elements receive the same checks as
|
|
631
|
+
`tasty()` calls. Partial overrides passed to `mergeStyles` may omit default state
|
|
632
|
+
values and retain the plugin's safeguards against fixes that replace base styles.
|
|
633
|
+
|
|
634
|
+
### ESLint
|
|
635
|
+
|
|
636
|
+
Install ESLint and a TypeScript parser:
|
|
637
|
+
|
|
638
|
+
```sh
|
|
639
|
+
pnpm add -D eslint @typescript-eslint/parser
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
Add the plugin to `eslint.config.mjs`:
|
|
643
|
+
|
|
644
|
+
```js
|
|
645
|
+
import parser from "@typescript-eslint/parser";
|
|
646
|
+
import tasty from "@tenphi/cookbook/eslint-plugin";
|
|
647
|
+
|
|
648
|
+
export default [
|
|
649
|
+
{
|
|
650
|
+
...tasty.configs.recommended,
|
|
651
|
+
files: ["**/*.{ts,tsx}"],
|
|
652
|
+
languageOptions: { parser },
|
|
653
|
+
},
|
|
654
|
+
];
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
Run `pnpm exec eslint docs/components --max-warnings 0`. Use
|
|
658
|
+
`tasty.configs.strict` for additional checks, including custom property names and
|
|
659
|
+
runtime style values. The named `recommended` and `strict` exports contain rule
|
|
660
|
+
maps for configurations that register the plugin themselves.
|
|
661
|
+
|
|
662
|
+
### oxlint
|
|
663
|
+
|
|
664
|
+
Install oxlint:
|
|
665
|
+
|
|
666
|
+
```sh
|
|
667
|
+
pnpm add -D oxlint
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
Create `oxlint.config.mjs` using its JavaScript plugin support:
|
|
671
|
+
|
|
672
|
+
```js
|
|
673
|
+
import { recommended } from "@tenphi/cookbook/eslint-plugin";
|
|
674
|
+
|
|
675
|
+
export default {
|
|
676
|
+
jsPlugins: [{ name: "tasty", specifier: "@tenphi/cookbook/eslint-plugin" }],
|
|
677
|
+
rules: recommended,
|
|
678
|
+
};
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
Run `pnpm exec oxlint --config oxlint.config.mjs docs/components --deny-warnings`.
|
|
682
|
+
The `tasty` alias keeps rule names such as `tasty/known-property` consistent with
|
|
683
|
+
ESLint. Import `strict` instead of `recommended` to enable the stricter rule map.
|
|
684
|
+
Both presets are tested with oxlint 1.83.0; JavaScript plugin support is experimental.
|
|
685
|
+
|
|
686
|
+
### Custom theme names
|
|
687
|
+
|
|
688
|
+
Add names introduced by your `docs.config.ts` theme to the validation config.
|
|
689
|
+
For example, after defining `theme.tokens["$project-gap"]`, `theme.states["@project-wide"]`,
|
|
690
|
+
and `theme.presets["project-title"]`:
|
|
691
|
+
|
|
692
|
+
```ts
|
|
693
|
+
import type { TastyValidationConfig } from "@tenphi/cookbook/eslint-plugin";
|
|
694
|
+
|
|
695
|
+
export default {
|
|
696
|
+
extends: "@tenphi/cookbook",
|
|
697
|
+
tokens: ["$project-gap"],
|
|
698
|
+
states: ["@project-wide"],
|
|
699
|
+
presets: ["project-title"],
|
|
700
|
+
} satisfies TastyValidationConfig;
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
`extends` merges and deduplicates these arrays with the inherited configuration,
|
|
704
|
+
so list only your additions. It also inherits the styling helper signatures;
|
|
705
|
+
entries you add to `styleFunctions` override inherited signatures by function name.
|
|
706
|
+
The exported `validationConfig` object remains available for programmatic use.
|
|
707
|
+
The entry point also exports the upstream `StyleFunctionConfig` and
|
|
708
|
+
`ResolvedConfig` types for shared lint configurations. Additional imported
|
|
709
|
+
helpers can be registered in `styleFunctions`; use `partial: true` for helpers
|
|
710
|
+
that merge overrides into existing styles.
|
|
711
|
+
|
|
712
|
+
## Static behavior
|
|
713
|
+
|
|
714
|
+
Documentation content, navigation, headings, code, and images remain readable
|
|
715
|
+
without client JavaScript. Search, mobile navigation, copy controls, appearance
|
|
716
|
+
persistence, and executable previews can progressively enhance the static
|
|
717
|
+
output.
|
|
718
|
+
|
|
719
|
+
### Responsive header and navigation
|
|
720
|
+
|
|
721
|
+
The header uses `#header`, generated from `theme.palette.header` (or the page
|
|
722
|
+
surface) at 70% opacity in all four appearance modes, with a 16px backdrop blur.
|
|
723
|
+
Customize the outer bar with `theme.styles.HeaderFrame`, its contents with
|
|
724
|
+
`StarlightHeader`, and header buttons with `HeaderLinks` and `SearchButton`.
|
|
725
|
+
|
|
726
|
+
Below 50rem, page navigation moves into a header row and opens a left drawer.
|
|
727
|
+
`MobileMenuToggle.Section` and `Page` style its breadcrumb labels. The drawer
|
|
728
|
+
contains the complete active section, a collapsible `MobileNavigationTabs`
|
|
729
|
+
selector, and a close button. The drawer slides in and out over 120ms and
|
|
730
|
+
disables motion when the reader prefers reduced motion. Its mobile shadow uses
|
|
731
|
+
the Glaze `shadow`-typed `#shadow` token. Customize the movement and shadow through
|
|
732
|
+
`theme.styles.Sidebar`, and the underlay through `Sidebar.Backdrop` and
|
|
733
|
+
`OpenBackdrop`. `theme.palette.overlay` supplies the underlay declaration, which defaults
|
|
734
|
+
to black at 50% opacity. Glaze resolves it in fixed mode with tone remapping
|
|
735
|
+
disabled, so it stays black in dark and high-contrast schemes.
|
|
736
|
+
Icon buttons retain their plain desktop appearance on mobile. More uses
|
|
737
|
+
left-aligned navigation links with a `1bw` gap, without primary button variants.
|
|
738
|
+
`HeaderLinks.PanelLink` styles the menu rows; `FirstPanelLink` reserves space
|
|
739
|
+
for the close button. The inset divider above the tabs belongs to `TopNavigation`.
|
|
740
|
+
|
|
741
|
+
The table of contents is hidden below 72rem through `TableOfContentsLayout`.
|
|
742
|
+
`MobileTableOfContents` remains a legacy style name for custom overrides; the
|
|
743
|
+
default renderer no longer renders that component. `Layout` controls shared
|
|
744
|
+
navigation dimensions and the drawer's scroll lock; `PageFrame` styles the
|
|
745
|
+
page container and content columns.
|