@faqir-ui/core 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.
Files changed (41) hide show
  1. package/README.md +45 -5
  2. package/cdn.json +38 -22
  3. package/dist/faqir-core.js +89 -52
  4. package/dist/faqir-core.min.js +3 -3
  5. package/dist/faqir-core.min.js.map +3 -3
  6. package/dist/faqir-core.mjs +61 -54
  7. package/dist/faqir.aurora.css +1209 -507
  8. package/dist/faqir.brutalist.css +1184 -489
  9. package/dist/faqir.candy.css +14152 -0
  10. package/dist/faqir.clinical.css +14152 -0
  11. package/dist/faqir.contrast.css +1198 -526
  12. package/dist/faqir.default.css +1261 -588
  13. package/dist/faqir.document-serif.css +1211 -491
  14. package/dist/faqir.document.css +1193 -490
  15. package/dist/faqir.editorial-document.css +14116 -0
  16. package/dist/faqir.editorial.css +14152 -0
  17. package/dist/faqir.fintech.css +14152 -0
  18. package/dist/faqir.glass.css +1214 -517
  19. package/dist/faqir.ink-document.css +14116 -0
  20. package/dist/faqir.ink.css +14127 -0
  21. package/dist/faqir.luxe.css +14211 -0
  22. package/dist/faqir.midnight.css +1229 -507
  23. package/dist/faqir.neo.css +14153 -0
  24. package/dist/faqir.neumorph.css +14151 -0
  25. package/dist/faqir.nordic.css +14151 -0
  26. package/dist/faqir.organic.css +14152 -0
  27. package/dist/faqir.paper.css +1200 -508
  28. package/dist/faqir.slate.css +1296 -564
  29. package/dist/faqir.soft.css +1180 -494
  30. package/dist/faqir.sunset.css +14153 -0
  31. package/dist/faqir.swiss-document.css +14116 -0
  32. package/dist/faqir.swiss.css +14153 -0
  33. package/dist/faqir.terminal.css +1187 -491
  34. package/dist/plugins/faqir-collapse.js +1 -1
  35. package/dist/plugins/faqir-intersect.js +2 -0
  36. package/dist/plugins/faqir-mask.js +27 -17
  37. package/dist/plugins/faqir-rules.js +63 -0
  38. package/dist/plugins/faqir-validate.js +471 -58
  39. package/dist/sri.json +36 -20
  40. package/faqir-core.d.ts +111 -5
  41. package/package.json +1 -1
@@ -131,6 +131,18 @@
131
131
  --font-mono: ui-monospace, 'Cascadia Code', 'JetBrains Mono', monospace;
132
132
  --font-serif: 'Georgia', 'Times New Roman', serif;
133
133
 
134
+ /* ── Font Roles (task 1.1A-01) ──
135
+ The three families above are the PALETTE; these three are the ROLES that
136
+ components actually read. A theme re-points a role once and every heading,
137
+ every paragraph and every control follows — "serif headings on a sans body"
138
+ is one declaration rather than sixty-four stylesheet edits. Components never
139
+ read --font-sans / --font-serif directly (gated by
140
+ tests/tokens/role-tokens.test.ts); --font-mono stays readable by name,
141
+ because "this is code" is a semantic choice, not a stylistic one. */
142
+ --font-heading: var(--font-sans); /* h1–h6, hero headline, card/dialog titles, stat values, doc headings */
143
+ --font-body: var(--font-sans); /* prose, text, document body, descriptions */
144
+ --font-ui: var(--font-sans); /* controls: button, input, select, badge, chip, tabs, menus */
145
+
134
146
  /* ── Font Sizes ── */
135
147
  --text-xs: 0.75rem; /* 12px */
136
148
  --text-sm: 0.875rem; /* 14px */
@@ -153,10 +165,29 @@
153
165
  --weight-medium: 500;
154
166
  --weight-semibold: 600;
155
167
  --weight-bold: 700;
168
+
169
+ /* ── Heading Voice (task 1.1A-01) ──
170
+ What makes a heading sound like the theme rather than like the body text one
171
+ size up: how heavy it is, how tightly the letters sit, whether it shouts, and
172
+ how close its own lines run. The defaults reproduce today's primary heading
173
+ exactly, so a project that sets none of them renders unchanged. A heading
174
+ that deliberately steps DOWN from the primary voice (prose h2–h4, a semibold
175
+ step below h1) keeps its own weight and leading and takes family, tracking
176
+ and case from the voice — the step is the design, not a value to re-derive. */
177
+ --heading-weight: var(--weight-bold);
178
+ --heading-tracking: 0em; /* letter-spacing — carries a unit so it
179
+ composes inside calc() where a heading
180
+ already has its own optical tightening */
181
+ --heading-transform: none; /* text-transform */
182
+ --heading-caps: normal; /* font-variant-caps — small caps are a
183
+ variant, not a transform (1.1A-25), so
184
+ they get a knob of their own that sits
185
+ beside --heading-transform */
186
+ --heading-leading: var(--leading-tight);
156
187
  }
157
188
 
158
189
  /* === tokens/effects.css === */
159
- /* @ui:tokens effects — radii, shadows, z-index */
190
+ /* @ui:tokens effects — radii, shape, shadows, focus, z-index */
160
191
 
161
192
  :root {
162
193
  /* ── Radii ── */
@@ -168,12 +199,49 @@
168
199
  --radius-2xl: 1rem; /* 16px */
169
200
  --radius-full: 9999px;
170
201
 
171
- /* ── Shadows ── */
172
- --shadow-xs: 0 1px 2px oklch(0 0 0 / 0.04);
173
- --shadow-sm: 0 1px 3px oklch(0 0 0 / 0.06), 0 1px 2px oklch(0 0 0 / 0.04);
174
- --shadow-md: 0 4px 6px oklch(0 0 0 / 0.05), 0 2px 4px oklch(0 0 0 / 0.04);
175
- --shadow-lg: 0 10px 15px oklch(0 0 0 / 0.06), 0 4px 6px oklch(0 0 0 / 0.04);
176
- --shadow-xl: 0 20px 25px oklch(0 0 0 / 0.08), 0 8px 10px oklch(0 0 0 / 0.04);
202
+ /* ── Shape ── */
203
+ /* The weight of an edge. A component names the ROLE (--border-width, or
204
+ --border-width-strong where the design leans on a thicker rule), never a
205
+ step, so a theme re-points every edge it ships with one declaration. */
206
+ --border-width-sm: 1px;
207
+ --border-width-md: 2px;
208
+ --border-width-lg: 3px;
209
+ --border-width: var(--border-width-sm); /* the default component border */
210
+ --border-width-strong: var(--border-width-md); /* emphasis: keycap, thick rule, active tab */
211
+ /* Progressive: CSS Borders 4. A browser without the property ignores it; a
212
+ value it does not know resolves to `round`, which is today's rendering. */
213
+ --corner-shape: round; /* bevel | scoop | notch where supported */
214
+
215
+ /* ── Depth ── */
216
+ /* The colour every shadow is cast in, as BARE OKLCH channels (L C H, no
217
+ `oklch()` around them) so each step can still set its own alpha:
218
+ `oklch(var(--shadow-color) / 0.06)`. A theme tints its depth warm, or
219
+ removes it entirely, with one declaration instead of rewriting five
220
+ multi-layer values. `0 0 0` is black — today's rendering, exactly. */
221
+ --shadow-color: 0 0 0;
222
+
223
+ --shadow-xs: 0 1px 2px oklch(var(--shadow-color) / 0.04);
224
+ --shadow-sm: 0 1px 3px oklch(var(--shadow-color) / 0.06), 0 1px 2px oklch(var(--shadow-color) / 0.04);
225
+ --shadow-md: 0 4px 6px oklch(var(--shadow-color) / 0.05), 0 2px 4px oklch(var(--shadow-color) / 0.04);
226
+ --shadow-lg: 0 10px 15px oklch(var(--shadow-color) / 0.06), 0 4px 6px oklch(var(--shadow-color) / 0.04);
227
+ --shadow-xl: 0 20px 25px oklch(var(--shadow-color) / 0.08), 0 8px 10px oklch(var(--shadow-color) / 0.04);
228
+
229
+ /* What an elevated surface does to whatever shows through it. Every surface
230
+ that can float — card, surface[data-variant="overlay"] and the seven
231
+ floating recipes — declares `backdrop-filter: var(--surface-backdrop)`
232
+ inside the same `@supports` guard, so a frosted theme is a token rather
233
+ than a stylesheet that reaches into seven components by selector.
234
+ `none` is the initial value of the property: no-op until a theme speaks. */
235
+ --surface-backdrop: none;
236
+
237
+ /* ── Focus ── */
238
+ /* base/reset.css owns the default ring and reads only these. Every control
239
+ that draws its own ring reads them too, so a theme changes focus once. */
240
+ --focus-ring-width: 2px;
241
+ --focus-ring-offset: 2px;
242
+ --focus-ring-style: solid;
243
+ --focus-ring-color: var(--color-ring);
244
+ --focus-shadow: none; /* a glow theme puts a shadow behind the ring */
177
245
 
178
246
  /* ── Z-Index ── */
179
247
  --z-base: 0;
@@ -186,8 +254,74 @@
186
254
  --z-max: 9999;
187
255
  }
188
256
 
257
+ /* ── Scheme islands ── */
258
+ /* The ring colour, restated where a scheme can change below the root: declared
259
+ on `:root` alone it resolves `--color-ring` once, from the page, and a nested
260
+ `data-theme="dark"` region would draw the light ring. See the same block in
261
+ tokens/aliases.css. `--focus-shadow` is deliberately NOT restated — it is a
262
+ depth value a theme owns, and restating it would replace the theme's glow
263
+ with `none` inside every island. */
264
+ [data-theme],
265
+ [data-skin] {
266
+ --focus-ring-color: var(--color-ring);
267
+ }
268
+
269
+ /* === tokens/textures.css === */
270
+ /* @ui:tokens textures — named surface materials (SVG data URIs) */
271
+
272
+ /* ══════════════════════════════════════════════════════════════════════════
273
+ The material palette.
274
+ ══════════════════════════════════════════════════════════════════════════
275
+ Six named textures, each a self-contained `url("data:image/svg+xml,…")` that
276
+ tiles. Nothing here is consumed directly: components read the two ROLE tokens
277
+ in `aliases.css` — `--texture-page` (body, document) and `--texture-surface`
278
+ (surface, card, hero) — both `none` by default, so the registry renders
279
+ exactly as it did before this file existed. A theme opts in with one
280
+ declaration:
281
+
282
+ --texture-page: var(--texture-grain);
283
+
284
+ This file is deliberately OUTSIDE the themeable surface (see
285
+ `NON_SURFACE_TOKEN_FILES` in `src/theme-manifest.ts`): a theme re-points the
286
+ two role tokens, it does not inherit six data URIs into its manifest.
287
+
288
+ On `currentColor`: the tint is written as `currentColor` so the markup states
289
+ its intent and a theme can re-point the whole token, but a data-URI SVG used
290
+ as `background-image` is its own document — `currentColor` there resolves to
291
+ that document's initial colour (black), not to the host element's `color`.
292
+ That IS the intended neutral for grain and paper, which are meant to darken a
293
+ surface slightly; the alpha in each texture, not the hue, is what carries the
294
+ effect. A theme wanting a different tint ships its own URI.
295
+
296
+ Every texture keeps its alpha low enough to survive on both schemes, and each
297
+ `<svg>` carries explicit `width`/`height` so the tile size is the token's,
298
+ not the browser's default 300×150.
299
+ ══════════════════════════════════════════════════════════════════════════ */
300
+
301
+ :root {
302
+ /* Film grain — fractal noise masking a flat currentColor fill. The mask is
303
+ what makes this a tint rather than the turbulence's own rainbow. */
304
+ --texture-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Cmask id='m'%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/mask%3E%3Crect width='160' height='160' fill='currentColor' mask='url(%23m)' opacity='0.14'/%3E%3C/svg%3E");
305
+
306
+ /* Paper fibre — lower frequency, more octaves, softer than grain. */
307
+ --texture-paper: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.04 0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Cmask id='m'%3E%3Crect width='200' height='200' filter='url(%23p)'/%3E%3C/mask%3E%3Crect width='200' height='200' fill='currentColor' mask='url(%23m)' opacity='0.1'/%3E%3C/svg%3E");
308
+
309
+ /* Dot field — one dot per 16px cell. */
310
+ --texture-dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Ccircle cx='2' cy='2' r='1' fill='currentColor' opacity='0.18'/%3E%3C/svg%3E");
311
+
312
+ /* Graph-paper grid — hairlines on a 24px cell. */
313
+ --texture-grid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath d='M24 0H0v24' fill='none' stroke='currentColor' stroke-width='1' opacity='0.12'/%3E%3C/svg%3E");
314
+
315
+ /* Diagonal hatching — 45°, 8px pitch. */
316
+ --texture-stripes: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M-2 2 2-2M0 8 8 0M6 10l4-4' stroke='currentColor' stroke-width='1' opacity='0.12'/%3E%3C/svg%3E");
317
+
318
+ /* Soft gradient mesh — three offset radial blooms, the only non-tiling
319
+ texture here (it is sized to cover, not to repeat). */
320
+ --texture-mesh: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='640'%3E%3CradialGradient id='a' cx='20%25' cy='20%25' r='60%25'%3E%3Cstop offset='0%25' stop-color='currentColor' stop-opacity='0.18'/%3E%3Cstop offset='100%25' stop-color='currentColor' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='b' cx='80%25' cy='30%25' r='55%25'%3E%3Cstop offset='0%25' stop-color='currentColor' stop-opacity='0.14'/%3E%3Cstop offset='100%25' stop-color='currentColor' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='c' cx='50%25' cy='90%25' r='60%25'%3E%3Cstop offset='0%25' stop-color='currentColor' stop-opacity='0.12'/%3E%3Cstop offset='100%25' stop-color='currentColor' stop-opacity='0'/%3E%3C/radialGradient%3E%3Crect width='640' height='640' fill='url(%23a)'/%3E%3Crect width='640' height='640' fill='url(%23b)'/%3E%3Crect width='640' height='640' fill='url(%23c)'/%3E%3C/svg%3E");
321
+ }
322
+
189
323
  /* === tokens/motion.css === */
190
- /* @ui:tokens motion — easings and durations */
324
+ /* @ui:tokens motion — easings, durations and motion personality */
191
325
 
192
326
  :root {
193
327
  /* ── Easings ── */
@@ -216,6 +350,35 @@
216
350
  /* Preset geometry */
217
351
  --motion-slide-distance: 0.5rem; /* slide-up travel */
218
352
  --motion-scale-from: 0.95; /* scale start/end factor */
353
+
354
+ /* ── Personality (1.1A-05 · §5.2 `motion`) ── */
355
+ /* The easing PALETTE gained a spring. Like --ease-bounce it has no consumer
356
+ of its own: a theme that wants everything to overshoot re-points
357
+ --ease-default at it, exactly as a serif theme re-points --font-body.
358
+ The declaration here is the cubic-bezier APPROXIMATION, because a custom
359
+ property stores whatever tokens it is given — a browser without `linear()`
360
+ would accept the spring happily and then drop every `transition` that used
361
+ it, landing on the initial easing rather than on a fallback. The @supports
362
+ block below is what makes the upgrade conditional. The approximation is
363
+ the bounce curve, deliberately: an overshoot-and-settle cubic-bezier is the
364
+ closest a browser without `linear()` can come to a spring. */
365
+ --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
366
+
367
+ /* How far an interactive surface rises under the pointer. A `translate`
368
+ VALUE, not a length: `none` is the initial value of that property, so the
369
+ default registry computes exactly what it computed before this token
370
+ existed, and a theme states the lift as `0 -1px`. `translate` rather than
371
+ `transform` so a component's own transform is never clobbered. */
372
+ --motion-hover-lift: none;
373
+ }
374
+
375
+ /* The real spring, where `linear()` is understood (Chrome 113+, Safari 17.2+,
376
+ Firefox 112+). Declared second so it wins; guarded so it is never declared at
377
+ all where it would be meaningless. */
378
+ @supports (animation-timing-function: linear(0, 1)) {
379
+ :root {
380
+ --ease-spring: linear(0, 0.3 6%, 0.7 13%, 0.95 20%, 1.03 27%, 1 40%, 1);
381
+ }
219
382
  }
220
383
 
221
384
  /* === tokens/semantic.css === */
@@ -307,27 +470,123 @@
307
470
  --section-gap-lg: var(--space-32); /* 8rem — spacious, one idea per screen */
308
471
  --content-gutter: var(--space-6); /* 1.5rem — page padding-inline */
309
472
 
473
+ /* ── Material ── */
474
+ /* The two textures a theme actually points at. Components never name a
475
+ texture from `tokens/textures.css` directly — they read one of these, so a
476
+ theme re-points two tokens rather than every surface in the registry.
477
+ `--texture-page` dresses the page itself (body, document);
478
+ `--texture-surface` dresses the things that sit ON it (surface, card,
479
+ hero). Both `none`: the initial value of `background-image`, so the
480
+ default registry renders exactly as it did before they existed. */
481
+ --texture-page: none;
482
+ --texture-surface: none;
483
+
484
+ /* ── Decoration (1.1A-05 · §5.2 `decoration`) ── */
485
+ /* The marks a theme draws that are not edges, fills or type: how a link is
486
+ underlined, how a divider is dashed, what selected text looks like, what
487
+ colour a list bullet is. Every default is the value the registry already
488
+ rendered, so this section is a set of handles, not a restyle.
489
+ `--marker-color` is `currentColor` — the initial value of `::marker`'s
490
+ colour — rather than the accent, so a list only changes when a theme says
491
+ it should. */
492
+ --link-decoration: underline;
493
+ --link-underline-offset: 0.2em;
494
+ --link-thickness: 1px;
495
+ --divider-style: solid;
496
+ /* The divider's own width, following the edge by default (1.1A-26). A theme
497
+ that asks for a `double` divider raises it to at least 3px: a double rule
498
+ only splits into two lines from 3px, and the family's 1px hairline would
499
+ paint it as one. */
500
+ --divider-width: var(--border-width);
501
+ /* The zebra, so a theme dials the stripe without restating the four selectors
502
+ the table's striped variant needs (stamped and nth-child, each with a hover
503
+ twin). Deliberately NOT `--table-stripe`: `--table-level`,
504
+ `--table-thead-h` and `--table-pin-offset` are stamped and MEASURED per
505
+ element by the table controller, so claiming the `--table-*` namespace for
506
+ a theme token would put runtime state on the themeable surface. */
507
+ --stripe-bg: var(--color-bg-subtle);
508
+ --selection-bg: var(--color-primary-subtle);
509
+ --selection-fg: var(--color-fg);
510
+ --marker-color: currentColor;
511
+ /* How far a disabled control is dimmed. Seventeen rules across the primitives
512
+ and recipes each spelled `opacity: 0.5`, which left a theme with an opinion
513
+ about disabled legibility no way to state it except by out-specifying every
514
+ one of them — which is exactly what `themes/contrast.css` did, with a
515
+ blanket `:root [data-ui]:disabled` rule, until 1.1A-15 turned it into this
516
+ one declaration. `0.5` is the value those seventeen rules already held. */
517
+ --disabled-opacity: 0.5;
518
+
310
519
  /* ── Button ── */
311
520
  --button-radius: var(--radius-md);
312
521
  --button-height-sm: var(--control-height-sm);
313
522
  --button-height-md: var(--control-height-md);
314
523
  --button-height-lg: var(--control-height-lg);
315
- --button-font: var(--font-sans);
524
+ --button-font: var(--font-ui);
316
525
  --button-weight: var(--weight-medium);
526
+ --button-text-transform: none;
317
527
 
318
528
  /* ── Card ── */
319
529
  --card-radius: var(--radius-lg);
320
530
  --card-shadow: var(--shadow-sm);
321
531
  --card-border: var(--color-surface-1-border);
532
+ --card-border-width: var(--border-width);
322
533
  --card-bg: var(--color-surface-1);
323
534
  --card-padding: var(--space-6);
324
535
 
325
536
  /* ── Input ── */
326
- --input-radius: var(--radius-md);
327
- --input-height: var(--control-height-md);
328
- --input-border: var(--color-border);
329
- --input-bg: var(--color-bg);
330
- --input-font: var(--font-sans);
537
+ /* The text-control silhouette. `--input-border-width` (1.1A-02) is the edge;
538
+ `--input-fill` is what the control paints, and `input`, `textarea` and
539
+ `select` all read it, so one declaration fills every text control.
540
+ `--input-fill` defaults to `--input-bg`, so a project that sets `--input-bg`
541
+ on `:root` — the 1.0 way to fill every input — still gets it. Set BELOW the
542
+ root, `--input-bg` no longer reaches the control: `--input-fill` has already
543
+ resolved it on `:root`, which is where a theme flips the fill, and a
544
+ per-element `--input-bg` winning over that would need the component to tell
545
+ "set here" from "inherited", which CSS cannot. To fill one input, or every
546
+ input in a region, set `--input-fill` there instead. `--input-bg-filled` is
547
+ the value a "filled" theme points `--input-fill` at — named here so the
548
+ silhouette is a token a theme flips rather than a colour it has to pick. */
549
+ --input-radius: var(--radius-md);
550
+ --input-height: var(--control-height-md);
551
+ --input-border: var(--color-border);
552
+ --input-border-width: var(--border-width);
553
+ --input-bg: var(--color-bg);
554
+ --input-bg-filled: var(--color-bg-subtle);
555
+ --input-fill: var(--input-bg);
556
+ --input-font: var(--font-ui);
557
+
558
+ /* ── Checkbox / Switch ── */
559
+ /* The two control shapes that do not follow `--radius-md`: a checkbox is a
560
+ small square with a small radius, a switch is a pill. Both were literal
561
+ `var(--radius-*)` reads in the components; named here, a theme squares its
562
+ switches without touching the radius ladder every other surface uses.
563
+
564
+ The geometry beside them is not decoration — it is the rest of the
565
+ namespace. Naming ONE token `--checkbox-radius` makes `--checkbox-*` a
566
+ token family, and the registry audit then (rightly) reads every other
567
+ `--checkbox-…`/`--switch-…` the components carried as a token wearing a
568
+ fallback as a disguise. They were always the default geometry; these are
569
+ the values the fallbacks already held, said once. */
570
+ --checkbox-size: 18px;
571
+ --checkbox-radius: var(--radius-sm);
572
+ --switch-width: 44px;
573
+ --switch-height: 24px;
574
+ --switch-thumb: 18px;
575
+ --switch-travel: 20px;
576
+ --switch-radius: var(--radius-full);
577
+ --switch-bg: var(--color-bg-muted);
578
+ --switch-thumb-shadow: var(--shadow-xs);
579
+
580
+ /* ── Floating panels ── */
581
+ /* What a panel that floats above the page is filled with: the dialog and
582
+ sheet panels, the drawer, the popover content (and its arrow), the dropdown
583
+ menu and the toast. They all painted `var(--color-bg)` directly, which left
584
+ a theme no way to make a floating surface differ from the page — the frost
585
+ half of that pairing is `--surface-backdrop` (1.1A-04), and a blur behind an
586
+ opaque fill renders nothing, so the fill has to be a token too. `card` has
587
+ had `--card-bg` since 1.0; this is the same handle for the things that have
588
+ no surface of their own. [1.1A-14] */
589
+ --panel-bg: var(--color-bg);
331
590
 
332
591
  /* ── Dialog ── */
333
592
  --dialog-radius: var(--radius-xl);
@@ -336,7 +595,7 @@
336
595
 
337
596
  /* ── Badge ── */
338
597
  --badge-radius: var(--radius-full);
339
- --badge-font: var(--font-sans);
598
+ --badge-font: var(--font-ui);
340
599
 
341
600
  /* ── Avatar ── */
342
601
  --avatar-radius: var(--radius-full);
@@ -345,6 +604,39 @@
345
604
  --avatar-size-lg: 56px;
346
605
  }
347
606
 
607
+ /* ── Scheme islands ── */
608
+ /* The colour aliases above, restated wherever a scheme can change below the
609
+ root. A custom property resolves its var() on the element that DECLARES it,
610
+ so `--panel-bg: var(--color-bg)` on `:root` is computed once, from the page's
611
+ colours, and a nested `<div data-theme="dark">` inherits that light value
612
+ even though its own `--color-bg` is dark — a white dialog on a dark island.
613
+ Components that read `var(--color-bg)` directly never had the problem; the
614
+ aliases 1.1 routed them through did. Restating the declaration on
615
+ `[data-theme]` and `[data-skin]` makes it resolve again there.
616
+
617
+ Only colours are restated. Geometry does not change with the scheme, and
618
+ shadows are the depth axis every theme owns on `:root`: restating either here
619
+ would replace a theme's own value with the default inside every island. A
620
+ theme that overrides one of THESE on `:root` and wants it honoured in an
621
+ island says so on the same selectors.
622
+
623
+ The values must match the `:root` declarations above exactly;
624
+ `tests/tokens/scheme-islands.test.ts` fails if they drift. */
625
+ [data-theme],
626
+ [data-skin] {
627
+ --stripe-bg: var(--color-bg-subtle);
628
+ --selection-bg: var(--color-primary-subtle);
629
+ --selection-fg: var(--color-fg);
630
+ --card-border: var(--color-surface-1-border);
631
+ --card-bg: var(--color-surface-1);
632
+ --input-border: var(--color-border);
633
+ --input-bg: var(--color-bg);
634
+ --input-bg-filled: var(--color-bg-subtle);
635
+ --input-fill: var(--input-bg);
636
+ --switch-bg: var(--color-bg-muted);
637
+ --panel-bg: var(--color-bg);
638
+ }
639
+
348
640
  /* === tokens/document.css === */
349
641
  /* @ui:tokens document — structural tokens for document/print rendering */
350
642
  /* These tokens control page geometry, document typography, table density,
@@ -376,10 +668,10 @@
376
668
  Separate from the base typography tokens because documents have
377
669
  different optimal sizes than screen UIs. 14px body + 12px legal
378
670
  is standard for A4 business documents. */
379
- --doc-font: var(--font-sans);
671
+ --doc-font: var(--font-body);
380
672
  --doc-font-size: var(--text-sm); /* 14px — optimal for A4 */
381
673
  --doc-line-height: var(--leading-normal); /* 1.5 */
382
- --doc-heading-font: var(--font-sans);
674
+ --doc-heading-font: var(--font-heading);
383
675
  --doc-heading-weight: var(--weight-bold);
384
676
  --doc-heading-size: var(--text-xl); /* 20px for doc titles */
385
677
  --doc-subheading-size: var(--text-lg); /* 18px for section titles */
@@ -430,6 +722,16 @@
430
722
  --doc-print-border-color: oklch(0.60 0 0); /* medium gray borders in print */
431
723
  }
432
724
 
725
+ /* ── Scheme islands ── */
726
+ /* `--doc-legal-color` is the one document colour screen components read (the
727
+ key-value label and the image caption), so it is restated where a scheme can
728
+ change below the root — see the same block in tokens/aliases.css. The rest
729
+ of this file is print ink, which does not follow the scheme. */
730
+ [data-theme],
731
+ [data-skin] {
732
+ --doc-legal-color: var(--color-fg-muted);
733
+ }
734
+
433
735
  /* === tokens/doc-aliases.css === */
434
736
  /* @ui:tokens doc-aliases — component-level document tokens */
435
737
  /* Maps document-layer tokens to specific primitive/recipe attribute selectors.
@@ -476,7 +778,10 @@
476
778
  --field-error-size: var(--doc-legal-size);
477
779
  --field-error-color: var(--color-destructive);
478
780
  --field-validating-color: var(--color-fg-muted); /* async validation in flight */
479
- --field-disabled-opacity: 0.55; /* honest disabled affordance */
781
+ /* The role `--disabled-opacity` sets for every control, nudged 10% lighter:
782
+ 0.55 at the 0.5 default, which is the value this alias always held, and it
783
+ follows a theme that states the role (1.1A-27). */
784
+ --field-disabled-opacity: calc(var(--disabled-opacity) * 1.1);
480
785
  --field-required-color: var(--color-destructive);
481
786
  --field-required-marker: ' *'; /* appended to required labels */
482
787
 
@@ -496,15 +801,47 @@
496
801
  --stat-change-negative: var(--color-destructive);
497
802
  }
498
803
 
804
+ /* ── Scheme islands ── */
805
+ /* The colour aliases above, restated where a scheme can change below the root —
806
+ a custom property resolves its var() on the element that declares it, so a
807
+ `:root`-only alias would carry the page's light value into a nested
808
+ `data-theme="dark"` region. See the same block in tokens/aliases.css; the
809
+ values must match the `:root` declarations above exactly. */
810
+ [data-theme],
811
+ [data-skin] {
812
+ --kv-label-color: var(--doc-legal-color);
813
+ --kv-value-color: var(--color-fg);
814
+ --callout-bg: var(--color-bg-subtle);
815
+ --callout-fg: var(--color-fg);
816
+ --image-border: var(--color-border);
817
+ --image-caption-color: var(--doc-legal-color);
818
+ --field-label-color: var(--color-fg);
819
+ --field-description-color: var(--color-fg-muted);
820
+ --field-error-color: var(--color-destructive);
821
+ --field-validating-color: var(--color-fg-muted);
822
+ --field-required-color: var(--color-destructive);
823
+ --page-break-screen-color: var(--color-border);
824
+ --page-break-screen-label-color: var(--color-fg-muted);
825
+ --stat-label-color: var(--color-fg-muted);
826
+ --stat-change-positive: var(--color-success);
827
+ --stat-change-negative: var(--color-destructive);
828
+ }
829
+
499
830
  /* === tokens/density.css === */
500
- /* @ui:tokens density — [data-density] subtree modifier (task 0.7-11, FAQIR-NEXT §B6)
831
+ /* @ui:tokens density — [data-density] subtree modifier (task 0.7-11, FAQIR-NEXT §B6;
832
+ `spacious` added 1.1A-09, SPEC-1.0.md §4)
501
833
 
502
834
  Put `data-density="compact"` on ANY container and its whole subtree renders
503
835
  tighter: spacing steps shrink by --density-scale and interactive controls drop
504
836
  to a shorter height ramp. `data-density="comfortable"` restores the base scale,
505
- so density can be reset on an inner subtree.
837
+ so density can be reset on an inner subtree. `data-density="spacious"` is the
838
+ third point on the ladder, above comfortable: spacing grows and the control
839
+ ramp grows with it, gentler than the spacing multiplier for the same reason
840
+ compact's ramp shrinks gentler — a usable hit target has a ceiling as well as
841
+ a floor.
506
842
 
507
843
  <section data-density="compact"> … dense form / table / toolbar … </section>
844
+ <section data-density="spacious"> … roomy landing hero, kiosk UI … </section>
508
845
 
509
846
  This is 100% CSS. `data-density` is NOT a sixth protocol attribute: no
510
847
  component contract, manifest, controller or audit rule knows about it — CSS
@@ -641,6 +978,57 @@
641
978
  --content-gutter: var(--space-6);
642
979
  }
643
980
 
981
+ /* The third density: roomier than the base scale, for a landing hero or a kiosk
982
+ UI meant to be read at arm's length. Control heights grow slower than the
983
+ spacing multiplier — the same asymmetry compact's ramp has, mirrored. */
984
+ [data-density="spacious"] {
985
+ --density-scale: 1.25;
986
+
987
+ /* ── Spacing scale (× --density-scale) ── */
988
+ --space-0h: calc(0.125rem * var(--density-scale));
989
+ --space-1: calc(0.25rem * var(--density-scale));
990
+ --space-1h: calc(0.375rem * var(--density-scale));
991
+ --space-2: calc(0.5rem * var(--density-scale));
992
+ --space-2h: calc(0.625rem * var(--density-scale));
993
+ --space-3: calc(0.75rem * var(--density-scale));
994
+ --space-3h: calc(0.875rem * var(--density-scale));
995
+ --space-4: calc(1rem * var(--density-scale));
996
+ --space-5: calc(1.25rem * var(--density-scale));
997
+ --space-6: calc(1.5rem * var(--density-scale));
998
+ --space-7: calc(1.75rem * var(--density-scale));
999
+ --space-8: calc(2rem * var(--density-scale));
1000
+ --space-10: calc(2.5rem * var(--density-scale));
1001
+ --space-12: calc(3rem * var(--density-scale));
1002
+ --space-16: calc(4rem * var(--density-scale));
1003
+ --space-20: calc(5rem * var(--density-scale));
1004
+ --space-24: calc(6rem * var(--density-scale));
1005
+ --space-32: calc(8rem * var(--density-scale));
1006
+ --space-40: calc(10rem * var(--density-scale));
1007
+ --space-48: calc(12rem * var(--density-scale));
1008
+ --space-64: calc(16rem * var(--density-scale));
1009
+
1010
+ /* ── Control height ramp ── */
1011
+ --control-height-sm: 36px;
1012
+ --control-height-md: 44px;
1013
+ --control-height-lg: 52px;
1014
+
1015
+ /* ── Aliases re-substituted in this scope (values identical to the base) ── */
1016
+ --button-height-sm: var(--control-height-sm);
1017
+ --button-height-md: var(--control-height-md);
1018
+ --button-height-lg: var(--control-height-lg);
1019
+ --input-height: var(--control-height-md);
1020
+ --card-padding: var(--space-6);
1021
+ --kv-pair-gap: var(--space-3);
1022
+ --kv-grid-gap: var(--space-4);
1023
+ --callout-padding-y: var(--space-3);
1024
+ --callout-padding-x: var(--space-4);
1025
+ --field-gap: var(--space-1h);
1026
+ --section-gap-sm: var(--space-12);
1027
+ --section-gap-md: var(--space-20);
1028
+ --section-gap-lg: var(--space-32);
1029
+ --content-gutter: var(--space-6);
1030
+ }
1031
+
644
1032
  /* === themes/document-serif.css === */
645
1033
  /* @ui:theme document-serif — formal serif theme for contracts, deeds, and legal documents */
646
1034
  /* @ui:schemes light — legal documents remain light for deterministic print output. */
@@ -701,7 +1089,6 @@
701
1089
  --radius-full: 0;
702
1090
  --card-radius: 0;
703
1091
  --card-shadow: none;
704
- --card-border: var(--color-border-strong);
705
1092
  --button-radius: 0;
706
1093
  --input-radius: 0;
707
1094
  --badge-radius: 0;
@@ -710,6 +1097,51 @@
710
1097
  --font-serif: 'Georgia', 'Times New Roman', serif;
711
1098
  --font-sans: 'Arial', 'Helvetica Neue', sans-serif;
712
1099
  --font-mono: 'Courier New', ui-monospace, monospace;
1100
+
1101
+ /* ══════════════════════════════════════════════════════════════════════
1102
+ The identity, in tokens. This theme has been serif since 0.6 — but only
1103
+ INSIDE a `data-ui="document"`, through the `--doc-*` family. Everything
1104
+ around the document (a card, a heading, prose on the screen it was
1105
+ proofed on) still rendered in Arial, because the role tokens the
1106
+ registry reads did not exist until 1.1A-01. [1.1A-15]
1107
+ ══════════════════════════════════════════════════════════════════════ */
1108
+
1109
+ /* ── Type: serif in the roles, not just in the document ──
1110
+ `--font-heading` and `--font-body` are what every heading, every piece of
1111
+ prose and every description in the registry reads, so pointing them at
1112
+ the serif palette is what makes this theme serif on the page as well as
1113
+ on the paper — and what makes `type.pairing` derive `serif-editorial`
1114
+ instead of `sans-grotesque`, which is what it has quietly been reporting.
1115
+ `--font-ui` deliberately stays sans: a form control is furniture, not
1116
+ text, and Arial at 11pt in a field label is legible where Georgia's
1117
+ old-style figures are not. That is the pairing `paper` makes too. */
1118
+ --font-heading: var(--font-serif);
1119
+ --font-body: var(--font-serif);
1120
+
1121
+ /* ── Type voice: set tight, the way a titled clause is ──
1122
+ Tracking is ADDITIVE (1.1A-01), so the heading primitive keeps its own
1123
+ optical tightening and this rides on top of it. */
1124
+ --heading-tracking: -0.01em;
1125
+
1126
+ /* ── Decoration: a ruled divider ──
1127
+ Dotted, and NOT the `double` rule a contract's section break traditionally
1128
+ carries. When this theme shipped (1.1A-15) `separator` drew its rule at
1129
+ `--border-width`, this theme's edge is the family's 1px hairline, and a
1130
+ 1px `double` border paints as a single solid line — measured in Chrome
1131
+ 149, one black pixel row, indistinguishable from `solid` (two rows appear
1132
+ only at 3px). A dotted leader is the other rule a legal form is full of,
1133
+ and it renders at the weight this theme draws. Since 1.1A-26 the divider
1134
+ has its own `--divider-width`, so a double rule is one declaration away
1135
+ (`--divider-style: double; --divider-width: 3px`) — a visual change this
1136
+ theme's screenshots would have to be re-approved for, so it is not made
1137
+ here. */
1138
+ --divider-style: dotted;
1139
+
1140
+ /* ── Controls: fields are ruled lines ──
1141
+ A printed form has no boxes — it has a rule you write on. The edge
1142
+ collapses to the bottom side alone, which is what makes `controls.input`
1143
+ derive `underline`, and `input`/`textarea`/`select` all read it. */
1144
+ --input-border-width: 0 0 var(--border-width) 0;
713
1145
  --doc-font: 'Georgia', 'Times New Roman', var(--font-serif);
714
1146
  --doc-font-size: 11pt;
715
1147
  --doc-line-height: 1.55;
@@ -718,7 +1150,6 @@
718
1150
  --doc-heading-size: 16pt;
719
1151
  --doc-subheading-size: 13pt;
720
1152
  --doc-legal-size: 8.5pt;
721
- --doc-legal-color: var(--color-fg-muted);
722
1153
  --doc-section-gap: var(--space-8);
723
1154
  --doc-component-gap: var(--space-4);
724
1155
  --doc-table-font-size: 9pt;
@@ -734,6 +1165,15 @@
734
1165
  --doc-print-border-color: oklch(0.42 0.015 55);
735
1166
  }
736
1167
 
1168
+ :root,
1169
+ [data-theme] {
1170
+ /* The token layer re-resolves these aliases on every scheme island
1171
+ (tokens/aliases.css), so a `:root`-only override would fall back to the
1172
+ default inside a nested `data-theme` region. */
1173
+ --card-border: var(--color-border-strong);
1174
+ --doc-legal-color: var(--color-fg-muted);
1175
+ }
1176
+
737
1177
  @media print {
738
1178
  :root {
739
1179
  --color-bg: white;
@@ -760,11 +1200,38 @@
760
1200
  padding: 0;
761
1201
  }
762
1202
 
1203
+ /* Colour scheme — the one place `data-theme` is translated into the platform's
1204
+ own scheme signal. `light-dark()` in a theme reads `color-scheme`, not
1205
+ `data-theme`, so a one-block theme [1.1A-06] resolves nothing at all without
1206
+ these three rules; declaring them here (rather than in each theme) is what
1207
+ makes the two authoring forms interchangeable. Nothing else in the registry
1208
+ declares `color-scheme`, so this is purely additive.
1209
+
1210
+ Specificity does the mapping: `:root` is (0,0,1) and each attribute selector
1211
+ is (0,1,0), so `<html data-theme="dark">` takes the dark rule over the root
1212
+ default while a bare `<html>` — and `data-theme="light"` — keeps light. The
1213
+ same rules apply to a NESTED element carrying `data-theme`, which is how a
1214
+ dark island inside a light page has always worked here. */
1215
+ :root {
1216
+ color-scheme: light;
1217
+ }
1218
+
1219
+ [data-theme="dark"] {
1220
+ color-scheme: dark;
1221
+ }
1222
+
1223
+ /* `auto` hands the choice to the OS: `light dark` means "either, system first",
1224
+ which is exactly what the `@media (prefers-color-scheme: dark)` mirror block
1225
+ does for a theme authored in the three-block form. */
1226
+ [data-theme="auto"] {
1227
+ color-scheme: light dark;
1228
+ }
1229
+
763
1230
  html {
764
1231
  -webkit-text-size-adjust: 100%;
765
1232
  -moz-tab-size: 4;
766
1233
  tab-size: 4;
767
- font-family: var(--font-sans);
1234
+ font-family: var(--font-body);
768
1235
  font-size: var(--text-base);
769
1236
  line-height: var(--leading-normal);
770
1237
  color: var(--color-fg);
@@ -775,6 +1242,11 @@ html {
775
1242
 
776
1243
  body {
777
1244
  min-height: 100dvh;
1245
+ /* The page's material. `none` by default (the initial value), so this is a
1246
+ no-op until a theme points --texture-page at one of tokens/textures.css.
1247
+ `html` keeps the background COLOUR; the texture rides on `body`, which
1248
+ covers the viewport, so the two compose instead of overwriting. */
1249
+ background-image: var(--texture-page);
778
1250
  }
779
1251
 
780
1252
  img,
@@ -844,10 +1316,32 @@ table {
844
1316
  }
845
1317
  }
846
1318
 
847
- /* Focus visible — default ring */
1319
+ /* Text selection — the decoration axis reaching the one surface no component
1320
+ owns. Until 1.1 the highlight was whatever the OS drew, which is the one part
1321
+ of a themed page that never matched the theme. Both values are tokens
1322
+ (tokens/aliases.css § Decoration), so a theme states its selection once. */
1323
+ ::selection {
1324
+ background-color: var(--selection-bg);
1325
+ color: var(--selection-fg);
1326
+ }
1327
+
1328
+ /* Focus visible — the default ring, and the only place it is spelled out.
1329
+ Every value is a token (tokens/effects.css § Focus), so a theme states its
1330
+ focus once and every element that has not drawn its own ring follows. */
848
1331
  :focus-visible {
849
- outline: 2px solid var(--color-ring);
850
- outline-offset: 2px;
1332
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
1333
+ outline-offset: var(--focus-ring-offset);
1334
+ }
1335
+
1336
+ /* The glow a theme may put behind the ring, at zero specificity. `box-shadow`
1337
+ is not a property focus owns: an element's resting shadow — a card's depth,
1338
+ an author's own — lives there too, and a (0,1,0) rule here replaced it with
1339
+ `none` (the default) on every keyboard focus. Under `:where()` ANY rule that
1340
+ sets a shadow outranks this one, so it lands only on an element nothing else
1341
+ shadows, and it never takes a shadow away. The controls that draw their own
1342
+ ring read `--focus-shadow` in their own `:focus-visible` rules. */
1343
+ :where(:focus-visible) {
1344
+ box-shadow: var(--focus-shadow);
851
1345
  }
852
1346
 
853
1347
  /* Hidden but accessible */
@@ -876,7 +1370,7 @@ table {
876
1370
  /* @ui:base prose — typography defaults for long-form content */
877
1371
 
878
1372
  [data-ui="prose"] {
879
- font-family: var(--font-sans);
1373
+ font-family: var(--font-body);
880
1374
  font-size: var(--text-base);
881
1375
  line-height: var(--leading-relaxed);
882
1376
  color: var(--color-fg);
@@ -884,29 +1378,45 @@ table {
884
1378
  }
885
1379
 
886
1380
  [data-ui="prose"] h1 {
1381
+ font-family: var(--font-heading);
887
1382
  font-size: var(--text-4xl);
888
- font-weight: var(--weight-bold);
889
- line-height: var(--leading-tight);
1383
+ font-weight: var(--heading-weight);
1384
+ letter-spacing: var(--heading-tracking);
1385
+ text-transform: var(--heading-transform);
1386
+ font-variant-caps: var(--heading-caps);
1387
+ line-height: var(--heading-leading);
890
1388
  margin-block: var(--space-8) var(--space-4);
891
1389
  }
892
1390
 
893
1391
  [data-ui="prose"] h2 {
1392
+ font-family: var(--font-heading);
894
1393
  font-size: var(--text-3xl);
895
1394
  font-weight: var(--weight-semibold);
896
- line-height: var(--leading-tight);
1395
+ letter-spacing: var(--heading-tracking);
1396
+ text-transform: var(--heading-transform);
1397
+ font-variant-caps: var(--heading-caps);
1398
+ line-height: var(--heading-leading);
897
1399
  margin-block: var(--space-8) var(--space-3);
898
1400
  }
899
1401
 
900
1402
  [data-ui="prose"] h3 {
1403
+ font-family: var(--font-heading);
901
1404
  font-size: var(--text-2xl);
902
1405
  font-weight: var(--weight-semibold);
1406
+ letter-spacing: var(--heading-tracking);
1407
+ text-transform: var(--heading-transform);
1408
+ font-variant-caps: var(--heading-caps);
903
1409
  line-height: var(--leading-snug);
904
1410
  margin-block: var(--space-6) var(--space-3);
905
1411
  }
906
1412
 
907
1413
  [data-ui="prose"] h4 {
1414
+ font-family: var(--font-heading);
908
1415
  font-size: var(--text-xl);
909
1416
  font-weight: var(--weight-semibold);
1417
+ letter-spacing: var(--heading-tracking);
1418
+ text-transform: var(--heading-transform);
1419
+ font-variant-caps: var(--heading-caps);
910
1420
  line-height: var(--leading-snug);
911
1421
  margin-block: var(--space-6) var(--space-2);
912
1422
  }
@@ -917,8 +1427,8 @@ table {
917
1427
 
918
1428
  [data-ui="prose"] a {
919
1429
  color: var(--color-primary);
920
- text-decoration: underline;
921
- text-underline-offset: 2px;
1430
+ text-decoration-line: var(--link-decoration);
1431
+ text-underline-offset: var(--link-underline-offset);
922
1432
  }
923
1433
 
924
1434
  [data-ui="prose"] a:hover {
@@ -955,7 +1465,7 @@ table {
955
1465
  }
956
1466
 
957
1467
  [data-ui="prose"] blockquote {
958
- border-inline-start: 3px solid var(--color-border-strong);
1468
+ border-inline-start: var(--border-width-lg) solid var(--color-border-strong);
959
1469
  padding-inline-start: var(--space-4);
960
1470
  color: var(--color-fg-muted);
961
1471
  margin-block: var(--space-4);
@@ -977,9 +1487,15 @@ table {
977
1487
  margin-block: var(--space-1);
978
1488
  }
979
1489
 
1490
+ /* The bullet. `currentColor` by default — the initial value — so a list looks
1491
+ exactly as it did; a theme that wants accented markers sets --marker-color. */
1492
+ [data-ui="prose"] li::marker {
1493
+ color: var(--marker-color);
1494
+ }
1495
+
980
1496
  [data-ui="prose"] hr {
981
1497
  border: none;
982
- border-block-start: 1px solid var(--color-border);
1498
+ border-block-start: var(--border-width) solid var(--color-border);
983
1499
  margin-block: var(--space-8);
984
1500
  }
985
1501
 
@@ -998,12 +1514,12 @@ table {
998
1514
  font-weight: var(--weight-semibold);
999
1515
  text-align: start;
1000
1516
  padding: var(--space-2) var(--space-3);
1001
- border-block-end: 2px solid var(--color-border-strong);
1517
+ border-block-end: var(--border-width-strong) solid var(--color-border-strong);
1002
1518
  }
1003
1519
 
1004
1520
  [data-ui="prose"] td {
1005
1521
  padding: var(--space-2) var(--space-3);
1006
- border-block-end: 1px solid var(--color-border);
1522
+ border-block-end: var(--border-width) solid var(--color-border);
1007
1523
  }
1008
1524
 
1009
1525
  /* First child no top margin, last child no bottom margin */
@@ -1188,7 +1704,7 @@ table {
1188
1704
 
1189
1705
  /* === primitives/avatar.css === */
1190
1706
  /* @ui:component avatar */
1191
- /* @ui:tokens color-bg-muted color-fg-muted radius-full font-sans text-xs text-sm weight-medium */
1707
+ /* @ui:tokens color-bg-muted color-fg-muted radius-full font-ui text-xs text-sm weight-medium */
1192
1708
 
1193
1709
  /* ── Base ── */
1194
1710
  [data-ui="avatar"] {
@@ -1218,7 +1734,7 @@ table {
1218
1734
  height: 100%;
1219
1735
  background: var(--color-bg-muted);
1220
1736
  color: var(--color-fg-muted);
1221
- font-family: var(--font-sans);
1737
+ font-family: var(--font-ui);
1222
1738
  font-size: var(--text-sm);
1223
1739
  font-weight: var(--weight-medium);
1224
1740
  text-transform: uppercase;
@@ -1243,7 +1759,7 @@ table {
1243
1759
 
1244
1760
  /* === primitives/badge.css === */
1245
1761
  /* @ui:component badge */
1246
- /* @ui:tokens color-bg-muted color-fg color-primary color-primary-fg color-primary-subtle color-secondary color-secondary-fg color-destructive color-destructive-fg color-destructive-subtle color-success color-success-subtle color-warning color-warning-subtle radius-full space-1 space-2 font-sans text-xs text-sm weight-medium */
1762
+ /* @ui:tokens color-bg-muted color-fg color-primary color-primary-fg color-primary-subtle color-secondary color-secondary-fg color-destructive color-destructive-fg color-destructive-subtle color-success color-success-subtle color-warning color-warning-subtle radius-full space-1 space-2 font-ui text-xs text-sm weight-medium corner-shape */
1247
1763
 
1248
1764
  /* ── Base ── */
1249
1765
  [data-ui="badge"] {
@@ -1253,9 +1769,10 @@ table {
1253
1769
  gap: var(--space-1);
1254
1770
  padding: 0.125rem var(--space-2);
1255
1771
  border-radius: var(--badge-radius, var(--radius-full));
1772
+ corner-shape: var(--corner-shape);
1256
1773
  background: var(--color-bg-muted);
1257
1774
  color: var(--color-fg);
1258
- font-family: var(--badge-font, var(--font-sans));
1775
+ font-family: var(--badge-font, var(--font-ui));
1259
1776
  font-size: var(--text-xs);
1260
1777
  font-weight: var(--weight-medium);
1261
1778
  line-height: 1.5;
@@ -1301,11 +1818,11 @@ table {
1301
1818
 
1302
1819
  /* === primitives/breadcrumb.css === */
1303
1820
  /* @ui:component breadcrumb */
1304
- /* @ui:tokens color-fg color-fg-muted color-fg-subtle color-primary-hover color-ring radius-sm space-2 text-xs text-sm text-base font-sans weight-medium duration-fast ease-default */
1821
+ /* @ui:tokens color-fg color-fg-muted color-fg-subtle color-primary-hover color-ring radius-sm space-2 text-xs text-sm text-base font-ui weight-medium duration-fast ease-default focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow link-decoration */
1305
1822
 
1306
1823
  /* ── Root ── */
1307
1824
  [data-ui="breadcrumb"] {
1308
- font-family: var(--breadcrumb-font, var(--font-sans));
1825
+ font-family: var(--breadcrumb-font, var(--font-ui));
1309
1826
  font-size: var(--breadcrumb-size, var(--text-sm));
1310
1827
  color: var(--color-fg-muted);
1311
1828
  }
@@ -1331,12 +1848,13 @@ table {
1331
1848
 
1332
1849
  [data-ui="breadcrumb"] [data-part="item"]:hover {
1333
1850
  color: var(--color-primary-hover);
1334
- text-decoration: underline;
1851
+ text-decoration-line: var(--link-decoration);
1335
1852
  }
1336
1853
 
1337
1854
  [data-ui="breadcrumb"] [data-part="item"]:focus-visible {
1338
- outline: 2px solid var(--color-ring);
1339
- outline-offset: 2px;
1855
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
1856
+ outline-offset: var(--focus-ring-offset);
1857
+ box-shadow: var(--focus-shadow);
1340
1858
  }
1341
1859
 
1342
1860
  /* ── Separator (presentational) ── */
@@ -1376,7 +1894,7 @@ table {
1376
1894
 
1377
1895
  /* === primitives/button.css === */
1378
1896
  /* @ui:component button */
1379
- /* @ui:tokens color-primary color-primary-hover color-primary-fg color-secondary color-secondary-hover color-secondary-fg color-destructive color-destructive-hover color-destructive-fg color-bg color-bg-muted color-bg-subtle color-fg color-border color-ring radius-md space-2 space-3 space-4 space-6 font-sans text-xs text-sm text-base weight-medium duration-fast ease-default shadow-xs radius-full */
1897
+ /* @ui:tokens color-primary color-primary-hover color-primary-fg color-secondary color-secondary-hover color-secondary-fg color-destructive color-destructive-hover color-destructive-fg color-bg color-bg-muted color-bg-subtle color-fg color-border color-ring radius-md space-2 space-3 space-4 space-6 font-ui text-xs text-sm text-base weight-medium duration-fast ease-default shadow-xs radius-full border-width border-width-strong corner-shape focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow button-text-transform motion-hover-lift link-decoration disabled-opacity */
1380
1898
 
1381
1899
  /* ── Base ── */
1382
1900
  [data-ui="button"] {
@@ -1386,18 +1904,21 @@ table {
1386
1904
  gap: var(--space-2);
1387
1905
  height: var(--button-height-md, 40px);
1388
1906
  padding-inline: var(--space-4);
1389
- border: 1px solid var(--color-border);
1907
+ border: var(--border-width) solid var(--color-border);
1390
1908
  border-radius: var(--button-radius, var(--radius-md));
1909
+ corner-shape: var(--corner-shape);
1391
1910
  background: var(--color-bg);
1392
1911
  color: var(--color-fg);
1393
- font-family: var(--font-sans);
1912
+ font-family: var(--font-ui);
1394
1913
  font-size: var(--text-sm);
1395
1914
  font-weight: var(--weight-medium);
1915
+ text-transform: var(--button-text-transform);
1396
1916
  line-height: 1;
1397
1917
  cursor: pointer;
1398
1918
  transition: background var(--duration-fast) var(--ease-default),
1399
1919
  border-color var(--duration-fast) var(--ease-default),
1400
1920
  color var(--duration-fast) var(--ease-default),
1921
+ translate var(--duration-fast) var(--ease-default),
1401
1922
  box-shadow var(--duration-fast) var(--ease-default);
1402
1923
  user-select: none;
1403
1924
  white-space: nowrap;
@@ -1406,11 +1927,16 @@ table {
1406
1927
 
1407
1928
  [data-ui="button"]:hover {
1408
1929
  background: var(--color-bg-muted);
1930
+ /* The hover lift. `none` by default — the initial value of `translate` — so
1931
+ this rule computes what the button computed before the token existed; a
1932
+ theme with a springy personality sets `--motion-hover-lift: 0 -1px`. */
1933
+ translate: var(--motion-hover-lift);
1409
1934
  }
1410
1935
 
1411
1936
  [data-ui="button"]:focus-visible {
1412
- outline: 2px solid var(--color-ring);
1413
- outline-offset: 2px;
1937
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
1938
+ outline-offset: var(--focus-ring-offset);
1939
+ box-shadow: var(--focus-shadow);
1414
1940
  }
1415
1941
 
1416
1942
  /* ── Variants ── */
@@ -1466,7 +1992,7 @@ table {
1466
1992
  padding: 0;
1467
1993
  }
1468
1994
  [data-ui="button"][data-variant="link"]:hover {
1469
- text-decoration: underline;
1995
+ text-decoration-line: var(--link-decoration);
1470
1996
  }
1471
1997
 
1472
1998
  /* ── Sizes ── */
@@ -1485,7 +2011,7 @@ table {
1485
2011
  /* ── States ── */
1486
2012
  [data-ui="button"]:disabled,
1487
2013
  [data-ui="button"][data-state="disabled"] {
1488
- opacity: 0.5;
2014
+ opacity: var(--disabled-opacity);
1489
2015
  cursor: not-allowed;
1490
2016
  pointer-events: none;
1491
2017
  }
@@ -1500,7 +2026,7 @@ table {
1500
2026
  position: absolute;
1501
2027
  width: 1em;
1502
2028
  height: 1em;
1503
- border: 2px solid currentColor;
2029
+ border: var(--border-width-strong) solid currentColor;
1504
2030
  border-inline-end-color: transparent;
1505
2031
  border-radius: var(--radius-full);
1506
2032
  animation: faqir-spin 0.6s linear infinite;
@@ -1547,7 +2073,7 @@ table {
1547
2073
 
1548
2074
  /* === primitives/callout.css === */
1549
2075
  /* @ui:component callout */
1550
- /* @ui:tokens callout-radius callout-padding-y callout-padding-x callout-border-left-width callout-font-size callout-icon-size callout-fg color-fg color-fg-muted color-info color-info-subtle color-warning color-warning-subtle color-destructive color-destructive-subtle color-success color-success-subtle color-bg-muted color-border color-ring space-1 radius-sm font-sans weight-semibold */
2076
+ /* @ui:tokens callout-radius callout-padding-y callout-padding-x callout-border-left-width callout-font-size callout-icon-size callout-fg color-fg color-fg-muted color-info color-info-subtle color-warning color-warning-subtle color-destructive color-destructive-subtle color-success color-success-subtle color-bg-muted color-border color-ring space-1 radius-sm font-heading font-body weight-semibold focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow */
1551
2077
 
1552
2078
  /* ── Base ── */
1553
2079
  [data-ui="callout"] {
@@ -1556,7 +2082,7 @@ table {
1556
2082
  padding: var(--callout-padding-y) var(--callout-padding-x);
1557
2083
  border-radius: var(--callout-radius);
1558
2084
  border-inline-start: var(--callout-border-left-width) solid;
1559
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
2085
+ font-family: var(--doc-font, var(--font-body));
1560
2086
  font-size: var(--callout-font-size);
1561
2087
  line-height: var(--doc-line-height, 1.5);
1562
2088
  }
@@ -1587,6 +2113,7 @@ table {
1587
2113
  /* ── Title ── */
1588
2114
  [data-ui="callout"] [data-part="title"] {
1589
2115
  display: block;
2116
+ font-family: var(--font-heading);
1590
2117
  font-weight: var(--weight-semibold);
1591
2118
  margin-bottom: var(--doc-label-gap, var(--space-1, 0.25rem));
1592
2119
  }
@@ -1613,8 +2140,9 @@ table {
1613
2140
  }
1614
2141
 
1615
2142
  [data-ui="callout"] [data-part="dismiss"]:focus-visible {
1616
- outline: 2px solid var(--color-ring, var(--color-info));
1617
- outline-offset: 2px;
2143
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
2144
+ outline-offset: var(--focus-ring-offset);
2145
+ box-shadow: var(--focus-shadow);
1618
2146
  opacity: 1;
1619
2147
  }
1620
2148
 
@@ -1700,17 +2228,36 @@ table {
1700
2228
 
1701
2229
  /* === primitives/card.css === */
1702
2230
  /* @ui:component card */
1703
- /* @ui:tokens color-surface-1 color-surface-2 color-surface-1-border color-surface-2-border color-fg color-fg-muted radius-lg shadow-sm space-4 space-6 font-sans text-sm text-lg text-xl weight-semibold leading-tight */
2231
+ /* @ui:tokens color-surface-1 color-surface-2 color-surface-1-border color-surface-2-border color-fg color-fg-muted radius-lg shadow-sm space-4 space-6 font-heading text-sm text-lg text-xl weight-semibold leading-tight border-width corner-shape card-border-width surface-backdrop texture-surface motion-hover-lift duration-fast ease-default */
1704
2232
 
1705
2233
  /* ── Base ── */
1706
2234
  [data-ui="card"] {
1707
2235
  display: flex;
1708
2236
  flex-direction: column;
1709
- border: 1px solid var(--card-border, var(--color-surface-1-border));
2237
+ border: var(--card-border-width) solid var(--card-border, var(--color-surface-1-border));
1710
2238
  border-radius: var(--card-radius, var(--radius-lg));
1711
- background: var(--card-bg, var(--color-surface-1));
2239
+ corner-shape: var(--corner-shape);
2240
+ /* One shorthand, two layers: the material on top, the fill beneath. The fill
2241
+ is the final layer, so `--card-bg` may be a colour OR a gradient — what 1.0
2242
+ projects set it to — and the texture (`none` by default) never clobbers it. */
2243
+ background: var(--texture-surface), var(--card-bg, var(--color-surface-1));
1712
2244
  box-shadow: var(--card-shadow, var(--shadow-sm));
1713
2245
  overflow: hidden;
2246
+ transition: translate var(--duration-fast) var(--ease-default);
2247
+ }
2248
+
2249
+ /* The hover lift, the same axis `button` reads. `none` by default (the initial
2250
+ value of `translate`), so a card sits exactly where it always sat until a
2251
+ theme says surfaces rise under the pointer. */
2252
+ [data-ui="card"]:hover {
2253
+ translate: var(--motion-hover-lift);
2254
+ }
2255
+
2256
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
2257
+ [data-ui="card"] {
2258
+ -webkit-backdrop-filter: var(--surface-backdrop);
2259
+ backdrop-filter: var(--surface-backdrop);
2260
+ }
1714
2261
  }
1715
2262
 
1716
2263
  /* ── Variants ── */
@@ -1719,7 +2266,7 @@ table {
1719
2266
  }
1720
2267
 
1721
2268
  [data-ui="card"][data-variant="filled"] {
1722
- background: var(--color-surface-2);
2269
+ background: var(--texture-surface), var(--color-surface-2);
1723
2270
  border-color: var(--color-surface-2-border);
1724
2271
  box-shadow: none;
1725
2272
  }
@@ -1734,7 +2281,7 @@ table {
1734
2281
  }
1735
2282
 
1736
2283
  [data-ui="card"] > [data-part="header"] > [data-part="title"] {
1737
- font-family: var(--font-sans);
2284
+ font-family: var(--font-heading);
1738
2285
  font-size: var(--text-lg);
1739
2286
  font-weight: var(--weight-semibold);
1740
2287
  line-height: var(--leading-tight);
@@ -1775,9 +2322,19 @@ table {
1775
2322
  padding-top: 0;
1776
2323
  }
1777
2324
 
2325
+ /* ── Motion ── */
2326
+ /* The hover lift is the only thing a card animates, and it is `none` until a
2327
+ theme states one — but the house rule is that a stylesheet which transitions
2328
+ carries its own opt-out, so a reader never has to check the token first. */
2329
+ @media (prefers-reduced-motion: reduce) {
2330
+ [data-ui="card"] {
2331
+ transition: none;
2332
+ }
2333
+ }
2334
+
1778
2335
  /* === primitives/checkbox.css === */
1779
2336
  /* @ui:component checkbox */
1780
- /* @ui:tokens color-bg color-fg color-primary color-primary-fg color-border color-border-strong color-ring radius-sm space-1 space-2 duration-fast ease-default */
2337
+ /* @ui:tokens color-bg color-fg color-primary color-primary-fg color-border color-border-strong color-ring space-1 space-2 duration-fast ease-default border-width focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow checkbox-radius checkbox-size disabled-opacity */
1781
2338
 
1782
2339
  /* -- Label wrapper -- */
1783
2340
  [data-ui="checkbox-label"] {
@@ -1789,7 +2346,7 @@ table {
1789
2346
 
1790
2347
  [data-ui="checkbox-label"]:has([data-ui="checkbox"]:disabled) {
1791
2348
  cursor: not-allowed;
1792
- opacity: 0.5;
2349
+ opacity: var(--disabled-opacity);
1793
2350
  }
1794
2351
 
1795
2352
  /* -- Base -- */
@@ -1801,8 +2358,8 @@ table {
1801
2358
  width: var(--checkbox-size, 18px);
1802
2359
  height: var(--checkbox-size, 18px);
1803
2360
  flex-shrink: 0;
1804
- border: 1px solid var(--color-border);
1805
- border-radius: var(--checkbox-radius, var(--radius-sm));
2361
+ border: var(--border-width) solid var(--color-border);
2362
+ border-radius: var(--checkbox-radius);
1806
2363
  background: var(--color-bg);
1807
2364
  cursor: pointer;
1808
2365
  transition: background var(--duration-fast) var(--ease-default),
@@ -1815,8 +2372,9 @@ table {
1815
2372
  }
1816
2373
 
1817
2374
  [data-ui="checkbox"]:focus-visible {
1818
- outline: 2px solid var(--color-ring);
1819
- outline-offset: 2px;
2375
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
2376
+ outline-offset: var(--focus-ring-offset);
2377
+ box-shadow: var(--focus-shadow);
1820
2378
  }
1821
2379
 
1822
2380
  /* -- Checked -- */
@@ -1907,7 +2465,7 @@ table {
1907
2465
  The mask has to opt out of the substitution to stay readable. [W3-3] */
1908
2466
  @media (forced-colors: active) {
1909
2467
  [data-ui="checkbox"] {
1910
- border: 1px solid ButtonText;
2468
+ border: var(--border-width) solid ButtonText;
1911
2469
  }
1912
2470
 
1913
2471
  [data-ui="checkbox"]:checked,
@@ -1931,7 +2489,7 @@ table {
1931
2489
 
1932
2490
  /* === primitives/chip.css === */
1933
2491
  /* @ui:component chip */
1934
- /* @ui:tokens color-bg-muted color-fg color-fg-muted color-primary color-primary-subtle color-destructive color-destructive-subtle color-border color-ring radius-full space-1 space-2 space-3 font-sans text-xs text-sm weight-medium */
2492
+ /* @ui:tokens color-bg-muted color-fg color-fg-muted color-primary color-primary-subtle color-destructive color-destructive-subtle color-border color-ring radius-full space-1 space-2 space-3 font-ui text-xs text-sm weight-medium border-width focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow */
1935
2493
 
1936
2494
  /* ── Base ── */
1937
2495
  [data-ui="chip"] {
@@ -1939,11 +2497,11 @@ table {
1939
2497
  align-items: center;
1940
2498
  gap: var(--space-1);
1941
2499
  padding: var(--space-1) var(--space-2);
1942
- border: 1px solid transparent;
2500
+ border: var(--border-width) solid transparent;
1943
2501
  border-radius: var(--chip-radius, var(--radius-full));
1944
2502
  background: var(--color-bg-muted);
1945
2503
  color: var(--color-fg);
1946
- font-family: var(--chip-font, var(--font-sans));
2504
+ font-family: var(--chip-font, var(--font-ui));
1947
2505
  font-size: var(--text-sm);
1948
2506
  font-weight: var(--weight-medium);
1949
2507
  line-height: 1.2;
@@ -1979,8 +2537,11 @@ table {
1979
2537
  }
1980
2538
 
1981
2539
  [data-ui="chip"] [data-part="dismiss"]:focus-visible {
1982
- outline: 2px solid var(--color-ring);
1983
- outline-offset: 1px;
2540
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
2541
+ /* Half the default gap — the dismiss target is small, and the full ring
2542
+ would collide with the chip's own edge. */
2543
+ outline-offset: calc(var(--focus-ring-offset) / 2);
2544
+ box-shadow: var(--focus-shadow);
1984
2545
  }
1985
2546
 
1986
2547
  /* ── Variants ── */
@@ -2203,12 +2764,12 @@ table {
2203
2764
 
2204
2765
  /* === primitives/collapsible.css === */
2205
2766
  /* @ui:component collapsible */
2206
- /* @ui:tokens color-fg color-fg-muted color-bg-subtle color-border color-ring radius-md space-2 space-3 text-sm text-base font-sans weight-medium duration-fast duration-normal ease-default */
2767
+ /* @ui:tokens color-fg color-fg-muted color-bg-subtle color-border color-ring radius-md space-2 space-3 text-sm text-base font-ui weight-medium duration-fast duration-normal ease-default border-width border-width-strong focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow */
2207
2768
 
2208
2769
  /* ── Root — native <details>, so it opens/closes with zero JavaScript ── */
2209
2770
  [data-ui="collapsible"] {
2210
2771
  border-radius: var(--collapsible-radius, var(--radius-md));
2211
- font-family: var(--collapsible-font, var(--font-sans));
2772
+ font-family: var(--collapsible-font, var(--font-ui));
2212
2773
  color: var(--color-fg);
2213
2774
  }
2214
2775
 
@@ -2238,8 +2799,9 @@ table {
2238
2799
  }
2239
2800
 
2240
2801
  [data-ui="collapsible"] [data-part="trigger"]:focus-visible {
2241
- outline: 2px solid var(--color-ring);
2242
- outline-offset: 2px;
2802
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
2803
+ outline-offset: var(--focus-ring-offset);
2804
+ box-shadow: var(--focus-shadow);
2243
2805
  }
2244
2806
 
2245
2807
  /* Chevron indicator — rotates when open, CSS-only */
@@ -2248,8 +2810,8 @@ table {
2248
2810
  flex: none;
2249
2811
  width: 0.5em;
2250
2812
  height: 0.5em;
2251
- border-inline-end: 2px solid var(--color-fg-muted);
2252
- border-block-end: 2px solid var(--color-fg-muted);
2813
+ border-inline-end: var(--border-width-strong) solid var(--color-fg-muted);
2814
+ border-block-end: var(--border-width-strong) solid var(--color-fg-muted);
2253
2815
  transform: rotate(45deg);
2254
2816
  transition: transform var(--duration-normal) var(--ease-default);
2255
2817
  }
@@ -2268,7 +2830,7 @@ table {
2268
2830
 
2269
2831
  /* ── Bordered variant ── */
2270
2832
  [data-ui="collapsible"][data-variant="bordered"] {
2271
- border: 1px solid var(--color-border);
2833
+ border: var(--border-width) solid var(--color-border);
2272
2834
  }
2273
2835
 
2274
2836
  /* ── Open/close animation via ::details-content, where supported ── */
@@ -2401,13 +2963,13 @@ table {
2401
2963
 
2402
2964
  /* === primitives/description-list.css === */
2403
2965
  /* @ui:component description-list */
2404
- /* @ui:tokens color-fg color-fg-muted color-border doc-font doc-line-height space-1 space-2 space-3 space-4 space-6 text-xs text-sm text-base font-sans weight-semibold */
2966
+ /* @ui:tokens color-fg color-fg-muted color-border doc-font doc-line-height space-1 space-2 space-3 space-4 space-6 text-xs text-sm text-base font-body weight-semibold border-width */
2405
2967
 
2406
2968
  /* ── Base ── */
2407
2969
  [data-ui="description-list"] {
2408
2970
  margin: 0;
2409
2971
  padding: 0;
2410
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
2972
+ font-family: var(--doc-font, var(--font-body));
2411
2973
  }
2412
2974
 
2413
2975
  /* ── Term ── */
@@ -2463,7 +3025,7 @@ table {
2463
3025
  [data-ui="description-list"][data-divided][data-variant="vertical"] [data-part="details"],
2464
3026
  [data-ui="description-list"][data-divided]:not([data-variant]) [data-part="details"] {
2465
3027
  padding-bottom: var(--space-4);
2466
- border-bottom: 1px solid var(--color-border);
3028
+ border-bottom: var(--border-width) solid var(--color-border);
2467
3029
  }
2468
3030
 
2469
3031
  [data-ui="description-list"][data-divided][data-variant="vertical"] [data-part="details"]:last-child,
@@ -2475,7 +3037,7 @@ table {
2475
3037
  [data-ui="description-list"][data-divided][data-variant="horizontal"] [data-part="term"],
2476
3038
  [data-ui="description-list"][data-divided][data-variant="horizontal"] [data-part="details"] {
2477
3039
  padding-bottom: var(--space-3);
2478
- border-bottom: 1px solid var(--color-border);
3040
+ border-bottom: var(--border-width) solid var(--color-border);
2479
3041
  }
2480
3042
 
2481
3043
  /* ── Size: Small ── */
@@ -2513,7 +3075,7 @@ table {
2513
3075
 
2514
3076
  /* === primitives/empty-state.css === */
2515
3077
  /* @ui:component empty-state */
2516
- /* @ui:tokens color-fg-muted color-fg-subtle space-3 space-4 space-6 space-8 text-sm text-lg text-3xl */
3078
+ /* @ui:tokens color-fg-muted color-fg-subtle space-3 space-4 space-6 space-8 text-sm text-lg text-3xl font-heading */
2517
3079
 
2518
3080
  /* ── Base ── */
2519
3081
  [data-ui="empty-state"] {
@@ -2534,6 +3096,7 @@ table {
2534
3096
 
2535
3097
  /* ── Title ── */
2536
3098
  [data-ui="empty-state"] [data-part="title"] {
3099
+ font-family: var(--font-heading);
2537
3100
  font-size: var(--text-lg);
2538
3101
  font-weight: var(--weight-medium);
2539
3102
  color: var(--color-fg);
@@ -2581,7 +3144,7 @@ table {
2581
3144
 
2582
3145
  /* === primitives/field-group.css === */
2583
3146
  /* @ui:component field-group */
2584
- /* @ui:tokens field-label-size field-label-weight field-label-color field-description-size field-description-color field-error-size field-error-color field-required-color field-required-marker field-validating-color field-disabled-opacity color-destructive color-success space-1 space-2 space-3 space-4 text-xs text-sm font-sans */
3147
+ /* @ui:tokens field-label-size field-label-weight field-label-color field-description-size field-description-color field-error-size field-error-color field-required-color field-required-marker field-validating-color field-disabled-opacity color-destructive color-success space-1 space-2 space-3 space-4 text-xs text-sm font-body border-width */
2585
3148
 
2586
3149
  /* ── Base / spacing ownership ──
2587
3150
  A field-group owns only its tight, density-aware intra-field step: label →
@@ -2593,7 +3156,7 @@ table {
2593
3156
  display: flex;
2594
3157
  flex-direction: column;
2595
3158
  gap: var(--space-2);
2596
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
3159
+ font-family: var(--doc-font, var(--font-body));
2597
3160
  }
2598
3161
 
2599
3162
  /* ── Label ── */
@@ -2663,7 +3226,7 @@ table {
2663
3226
  [data-ui="field-group"][data-state="invalid"] [data-ui="textarea"],
2664
3227
  [data-ui="field-group"][data-state="invalid"] [data-ui="select"] {
2665
3228
  border-color: var(--field-error-color);
2666
- box-shadow: 0 0 0 1px var(--field-error-color);
3229
+ box-shadow: 0 0 0 var(--border-width) var(--field-error-color);
2667
3230
  }
2668
3231
 
2669
3232
  /* ── State: Validating ──
@@ -2673,7 +3236,7 @@ table {
2673
3236
  [data-ui="field-group"][data-state="validating"] [data-ui="textarea"],
2674
3237
  [data-ui="field-group"][data-state="validating"] [data-ui="select"] {
2675
3238
  border-color: var(--field-validating-color);
2676
- box-shadow: 0 0 0 1px var(--field-validating-color);
3239
+ box-shadow: 0 0 0 var(--border-width) var(--field-validating-color);
2677
3240
  }
2678
3241
 
2679
3242
  /* ── State: Disabled ──
@@ -2692,8 +3255,8 @@ table {
2692
3255
  [data-ui="field-group"][data-state="valid"] [data-ui="input"],
2693
3256
  [data-ui="field-group"][data-state="valid"] [data-ui="textarea"],
2694
3257
  [data-ui="field-group"][data-state="valid"] [data-ui="select"] {
2695
- border-color: var(--color-success, oklch(0.62 0.19 145));
2696
- box-shadow: 0 0 0 1px var(--color-success, oklch(0.62 0.19 145));
3258
+ border-color: var(--color-success);
3259
+ box-shadow: 0 0 0 var(--border-width) var(--color-success);
2697
3260
  }
2698
3261
 
2699
3262
  /* ── Variant: Horizontal ── */
@@ -2998,7 +3561,7 @@ table {
2998
3561
 
2999
3562
  /* === primitives/image.css === */
3000
3563
  /* @ui:component image */
3001
- /* @ui:tokens image-radius image-border image-border-width image-caption-size image-caption-color color-bg-muted font-sans */
3564
+ /* @ui:tokens image-radius image-border image-border-width image-caption-size image-caption-color color-bg-muted font-body */
3002
3565
 
3003
3566
  /* ── Base ── */
3004
3567
  [data-ui="image"] {
@@ -3022,7 +3585,7 @@ table {
3022
3585
  [data-ui="image"] [data-part="caption"] {
3023
3586
  display: block;
3024
3587
  margin-top: var(--space-2);
3025
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
3588
+ font-family: var(--doc-font, var(--font-body));
3026
3589
  font-size: var(--image-caption-size);
3027
3590
  color: var(--image-caption-color);
3028
3591
  line-height: 1.4;
@@ -3119,7 +3682,7 @@ table {
3119
3682
 
3120
3683
  /* === primitives/input.css === */
3121
3684
  /* @ui:component input */
3122
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-ring color-destructive radius-md space-2 space-3 space-4 font-sans text-xs text-sm text-base duration-fast ease-default */
3685
+ /* @ui:tokens color-fg color-fg-muted color-border color-border-strong color-ring color-destructive radius-md space-2 space-3 space-4 font-ui text-xs text-sm text-base duration-fast ease-default border-width corner-shape focus-ring-width focus-ring-style focus-ring-color focus-shadow input-border-width input-fill disabled-opacity */
3123
3686
 
3124
3687
  /* ── Base ── */
3125
3688
  [data-ui="input"] {
@@ -3127,11 +3690,18 @@ table {
3127
3690
  width: 100%;
3128
3691
  height: var(--input-height, 40px);
3129
3692
  padding-inline: var(--space-3);
3130
- border: 1px solid var(--color-border);
3693
+ /* Longhands, not the `border:` shorthand: the shorthand's width slot takes
3694
+ ONE value, and `controls.input: underline` (1.1A-10) states the silhouette
3695
+ as a four-value box — `0 0 var(--border-width) 0` — so only a bottom rule
3696
+ is drawn. Identical to the shorthand at every other value of the token. */
3697
+ border-style: solid;
3698
+ border-color: var(--color-border);
3699
+ border-width: var(--input-border-width);
3131
3700
  border-radius: var(--input-radius, var(--radius-md));
3132
- background: var(--input-bg, var(--color-bg));
3701
+ corner-shape: var(--corner-shape);
3702
+ background: var(--input-fill);
3133
3703
  color: var(--color-fg);
3134
- font-family: var(--input-font, var(--font-sans));
3704
+ font-family: var(--input-font, var(--font-ui));
3135
3705
  font-size: var(--text-sm);
3136
3706
  line-height: 1;
3137
3707
  transition: border-color var(--duration-fast) var(--ease-default),
@@ -3147,8 +3717,11 @@ table {
3147
3717
  }
3148
3718
 
3149
3719
  [data-ui="input"]:focus {
3150
- outline: 2px solid var(--color-ring);
3151
- outline-offset: -1px;
3720
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
3721
+ /* The ring replaces the border rather than sitting outside it: inset by
3722
+ exactly the edge it covers, so a heavier shape theme stays aligned. */
3723
+ outline-offset: calc(-1 * var(--input-border-width));
3724
+ box-shadow: var(--focus-shadow);
3152
3725
  border-color: transparent;
3153
3726
  }
3154
3727
 
@@ -3176,7 +3749,7 @@ table {
3176
3749
  }
3177
3750
 
3178
3751
  [data-ui="input"]:disabled {
3179
- opacity: 0.5;
3752
+ opacity: var(--disabled-opacity);
3180
3753
  cursor: not-allowed;
3181
3754
  }
3182
3755
 
@@ -3239,7 +3812,7 @@ table {
3239
3812
 
3240
3813
  /* === primitives/kbd.css === */
3241
3814
  /* @ui:component kbd */
3242
- /* @ui:tokens color-bg-subtle color-fg color-border radius-sm space-1h font-mono text-xs */
3815
+ /* @ui:tokens color-bg-subtle color-fg color-border radius-sm space-1h font-mono text-xs border-width border-width-strong */
3243
3816
 
3244
3817
  /* ── Base ── */
3245
3818
  [data-ui="kbd"] {
@@ -3249,8 +3822,8 @@ table {
3249
3822
  height: 20px;
3250
3823
  min-width: 20px;
3251
3824
  padding-inline: var(--space-1h);
3252
- border: 1px solid var(--color-border);
3253
- border-bottom-width: 2px;
3825
+ border: var(--border-width) solid var(--color-border);
3826
+ border-bottom-width: var(--border-width-strong);
3254
3827
  border-radius: var(--radius-sm);
3255
3828
  background: var(--color-bg-subtle);
3256
3829
  color: var(--color-fg);
@@ -3263,7 +3836,7 @@ table {
3263
3836
 
3264
3837
  /* === primitives/key-value.css === */
3265
3838
  /* @ui:component key-value */
3266
- /* @ui:tokens kv-label-color kv-label-weight kv-label-size kv-value-color kv-value-size kv-value-weight kv-gap kv-pair-gap kv-grid-gap text-xs text-sm text-base font-sans */
3839
+ /* @ui:tokens kv-label-color kv-label-weight kv-label-size kv-value-color kv-value-size kv-value-weight kv-gap kv-pair-gap kv-grid-gap text-xs text-sm text-base font-body */
3267
3840
 
3268
3841
  /* ── Base ── */
3269
3842
  [data-ui="key-value"] {
@@ -3272,7 +3845,7 @@ table {
3272
3845
  gap: var(--kv-pair-gap);
3273
3846
  margin: 0;
3274
3847
  padding: 0;
3275
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
3848
+ font-family: var(--doc-font, var(--font-body));
3276
3849
  }
3277
3850
 
3278
3851
  /* ── Label ── */
@@ -3402,12 +3975,12 @@ table {
3402
3975
 
3403
3976
  /* === primitives/label.css === */
3404
3977
  /* @ui:component label */
3405
- /* @ui:tokens color-fg color-fg-muted color-destructive font-sans text-xs text-sm text-base weight-medium */
3978
+ /* @ui:tokens color-fg color-fg-muted color-destructive font-ui text-xs text-sm text-base weight-medium disabled-opacity */
3406
3979
 
3407
3980
  /* ── Base ── */
3408
3981
  [data-ui="label"] {
3409
3982
  display: block;
3410
- font-family: var(--font-sans);
3983
+ font-family: var(--font-ui);
3411
3984
  font-size: var(--text-sm);
3412
3985
  font-weight: var(--weight-medium);
3413
3986
  color: var(--color-fg);
@@ -3440,21 +4013,21 @@ table {
3440
4013
 
3441
4014
  /* ── States ── */
3442
4015
  [data-ui="label"][data-state="disabled"] {
3443
- opacity: 0.5;
4016
+ opacity: var(--disabled-opacity);
3444
4017
  cursor: not-allowed;
3445
4018
  }
3446
4019
 
3447
4020
  /* === primitives/link.css === */
3448
4021
  /* @ui:component link */
3449
- /* @ui:tokens color-primary color-primary-hover color-primary-active color-fg color-fg-muted color-ring radius-sm space-1 */
4022
+ /* @ui:tokens color-primary color-primary-hover color-primary-active color-fg color-fg-muted color-ring radius-sm space-1 focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow link-decoration link-thickness link-underline-offset */
3450
4023
 
3451
4024
  /* ── Base ── */
3452
4025
  [data-ui="link"] {
3453
4026
  color: var(--color-primary);
3454
4027
  font-family: inherit;
3455
- text-decoration: underline;
3456
- text-decoration-thickness: 1px;
3457
- text-underline-offset: 0.2em;
4028
+ text-decoration-line: var(--link-decoration);
4029
+ text-decoration-thickness: var(--link-thickness);
4030
+ text-underline-offset: var(--link-underline-offset);
3458
4031
  border-radius: var(--radius-sm);
3459
4032
  cursor: pointer;
3460
4033
  }
@@ -3468,8 +4041,9 @@ table {
3468
4041
  }
3469
4042
 
3470
4043
  [data-ui="link"]:focus-visible {
3471
- outline: 2px solid var(--color-ring);
3472
- outline-offset: 2px;
4044
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
4045
+ outline-offset: var(--focus-ring-offset);
4046
+ box-shadow: var(--focus-shadow);
3473
4047
  }
3474
4048
 
3475
4049
  /* ── Variants ── */
@@ -3493,7 +4067,7 @@ table {
3493
4067
 
3494
4068
  /* === primitives/nav.css === */
3495
4069
  /* @ui:component nav */
3496
- /* @ui:tokens color-fg color-fg-muted color-primary color-primary-subtle color-bg-subtle color-border text-sm weight-medium radius-md space-1 space-2 space-3 space-4 duration-fast ease-default */
4070
+ /* @ui:tokens color-fg color-fg-muted color-primary color-primary-subtle color-bg-subtle color-border text-sm weight-medium radius-md space-1 space-2 space-3 space-4 duration-fast ease-default border-width border-width-strong */
3497
4071
 
3498
4072
  /* ── Base ── */
3499
4073
  [data-ui="nav"] {
@@ -3543,14 +4117,14 @@ table {
3543
4117
 
3544
4118
  /* ── Underline variant ── */
3545
4119
  [data-ui="nav"][data-variant="underline"] {
3546
- border-bottom: 1px solid var(--color-border);
4120
+ border-bottom: var(--border-width) solid var(--color-border);
3547
4121
  gap: 0;
3548
4122
  }
3549
4123
 
3550
4124
  [data-ui="nav"][data-variant="underline"] [data-part="link"] {
3551
4125
  border-radius: 0;
3552
4126
  padding: var(--space-2) var(--space-4);
3553
- border-bottom: 2px solid transparent;
4127
+ border-bottom: var(--border-width-strong) solid transparent;
3554
4128
  margin-bottom: -1px;
3555
4129
  }
3556
4130
 
@@ -3606,7 +4180,7 @@ table {
3606
4180
 
3607
4181
  /* === primitives/page-break.css === */
3608
4182
  /* @ui:component page-break */
3609
- /* @ui:tokens page-break-screen-color page-break-screen-style page-break-screen-label-color page-break-screen-label-size doc-font font-sans space-4 space-6 */
4183
+ /* @ui:tokens page-break-screen-color page-break-screen-style page-break-screen-label-color page-break-screen-label-size doc-font font-body space-4 space-6 border-width */
3610
4184
 
3611
4185
  /* ── Base (Screen) ── */
3612
4186
  [data-ui="page-break"] {
@@ -3621,12 +4195,12 @@ table {
3621
4195
  [data-ui="page-break"]::after {
3622
4196
  content: "";
3623
4197
  flex: 1;
3624
- border-top: 1px var(--page-break-screen-style) var(--page-break-screen-color);
4198
+ border-top: var(--border-width) var(--page-break-screen-style) var(--page-break-screen-color);
3625
4199
  }
3626
4200
 
3627
4201
  /* ── Label (Screen) ── */
3628
4202
  [data-ui="page-break"] {
3629
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
4203
+ font-family: var(--doc-font, var(--font-body));
3630
4204
  font-size: var(--page-break-screen-label-size);
3631
4205
  color: var(--page-break-screen-label-color);
3632
4206
  letter-spacing: 0.05em;
@@ -3668,7 +4242,7 @@ table {
3668
4242
 
3669
4243
  /* === primitives/progress.css === */
3670
4244
  /* @ui:component progress */
3671
- /* @ui:tokens color-primary color-bg-muted color-success color-warning color-destructive radius-full radius-md space-1 duration-normal ease-default */
4245
+ /* @ui:tokens color-primary color-bg-muted color-success color-warning color-destructive radius-full radius-md space-1 duration-normal ease-default border-width */
3672
4246
 
3673
4247
  /* ── Base ── */
3674
4248
  [data-ui="progress"] {
@@ -3743,7 +4317,7 @@ table {
3743
4317
  substitution and paints `Highlight`; the track keeps a visible boundary. [W3-3] */
3744
4318
  @media (forced-colors: active) {
3745
4319
  [data-ui="progress"] [data-part="track"] {
3746
- border: 1px solid ButtonText;
4320
+ border: var(--border-width) solid ButtonText;
3747
4321
  }
3748
4322
 
3749
4323
  [data-ui="progress"] [data-part="fill"],
@@ -3757,7 +4331,7 @@ table {
3757
4331
 
3758
4332
  /* === primitives/radio.css === */
3759
4333
  /* @ui:component radio */
3760
- /* @ui:tokens color-bg color-fg color-primary color-primary-fg color-border color-border-strong color-ring radius-full space-1 space-2 duration-fast ease-default */
4334
+ /* @ui:tokens color-bg color-fg color-primary color-primary-fg color-border color-border-strong color-ring radius-full space-1 space-2 duration-fast ease-default border-width focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow disabled-opacity */
3761
4335
 
3762
4336
  /* -- Radio group -- */
3763
4337
  [data-ui="radio-group"] {
@@ -3779,7 +4353,7 @@ table {
3779
4353
 
3780
4354
  [data-ui="radio-label"]:has([data-ui="radio"]:disabled) {
3781
4355
  cursor: not-allowed;
3782
- opacity: 0.5;
4356
+ opacity: var(--disabled-opacity);
3783
4357
  }
3784
4358
 
3785
4359
  /* -- Base -- */
@@ -3791,7 +4365,7 @@ table {
3791
4365
  width: var(--radio-size, 18px);
3792
4366
  height: var(--radio-size, 18px);
3793
4367
  flex-shrink: 0;
3794
- border: 1px solid var(--color-border);
4368
+ border: var(--border-width) solid var(--color-border);
3795
4369
  border-radius: var(--radius-full);
3796
4370
  background: var(--color-bg);
3797
4371
  cursor: pointer;
@@ -3805,8 +4379,9 @@ table {
3805
4379
  }
3806
4380
 
3807
4381
  [data-ui="radio"]:focus-visible {
3808
- outline: 2px solid var(--color-ring);
3809
- outline-offset: 2px;
4382
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
4383
+ outline-offset: var(--focus-ring-offset);
4384
+ box-shadow: var(--focus-shadow);
3810
4385
  }
3811
4386
 
3812
4387
  /* -- Checked -- */
@@ -3859,7 +4434,7 @@ table {
3859
4434
  inside a `--color-primary` circle, and the OS collapses both to one colour. [W3-3] */
3860
4435
  @media (forced-colors: active) {
3861
4436
  [data-ui="radio"] {
3862
- border: 1px solid ButtonText;
4437
+ border: var(--border-width) solid ButtonText;
3863
4438
  }
3864
4439
 
3865
4440
  [data-ui="radio"]:checked {
@@ -3879,7 +4454,7 @@ table {
3879
4454
 
3880
4455
  /* === primitives/select.css === */
3881
4456
  /* @ui:component select */
3882
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-ring color-destructive radius-md space-2 space-3 space-4 font-sans text-xs text-sm text-base duration-fast ease-default */
4457
+ /* @ui:tokens color-fg color-fg-muted color-border color-border-strong color-ring color-destructive radius-md space-2 space-3 space-4 font-ui text-xs text-sm text-base duration-fast ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-shadow input-border-width input-fill disabled-opacity */
3883
4458
 
3884
4459
  /* -- Base -- */
3885
4460
  [data-ui="select"] {
@@ -3888,11 +4463,17 @@ table {
3888
4463
  height: var(--select-height, 40px);
3889
4464
  padding-inline: var(--space-3);
3890
4465
  padding-inline-end: var(--space-8, 2rem);
3891
- border: 1px solid var(--color-border);
4466
+ /* Longhands, not the `border:` shorthand: the shorthand's width slot takes
4467
+ ONE value, and `controls.input: underline` (1.1A-10) states the silhouette
4468
+ as a four-value box — `0 0 var(--border-width) 0` — so only a bottom rule
4469
+ is drawn. Identical to the shorthand at every other value of the token. */
4470
+ border-style: solid;
4471
+ border-color: var(--color-border);
4472
+ border-width: var(--input-border-width);
3892
4473
  border-radius: var(--select-radius, var(--radius-md));
3893
- background: var(--select-bg, var(--color-bg));
4474
+ background: var(--select-bg, var(--input-fill));
3894
4475
  color: var(--color-fg);
3895
- font-family: var(--select-font, var(--font-sans));
4476
+ font-family: var(--select-font, var(--font-ui));
3896
4477
  font-size: var(--text-sm);
3897
4478
  line-height: 1;
3898
4479
  cursor: pointer;
@@ -3922,8 +4503,11 @@ table {
3922
4503
  }
3923
4504
 
3924
4505
  [data-ui="select"]:focus {
3925
- outline: 2px solid var(--color-ring);
3926
- outline-offset: -1px;
4506
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
4507
+ /* The ring replaces the border rather than sitting outside it: inset by
4508
+ exactly the edge it covers, so a heavier shape theme stays aligned. */
4509
+ outline-offset: calc(-1 * var(--input-border-width));
4510
+ box-shadow: var(--focus-shadow);
3927
4511
  border-color: transparent;
3928
4512
  }
3929
4513
 
@@ -3956,7 +4540,7 @@ table {
3956
4540
  }
3957
4541
 
3958
4542
  [data-ui="select"]:disabled {
3959
- opacity: 0.5;
4543
+ opacity: var(--disabled-opacity);
3960
4544
  cursor: not-allowed;
3961
4545
  }
3962
4546
 
@@ -3969,12 +4553,12 @@ table {
3969
4553
 
3970
4554
  /* === primitives/separator.css === */
3971
4555
  /* @ui:component separator */
3972
- /* @ui:tokens color-border space-4 text-xs color-fg-muted font-sans */
4556
+ /* @ui:tokens color-border space-4 text-xs color-fg-muted font-ui border-width-strong divider-width divider-style */
3973
4557
 
3974
4558
  /* ── Base (horizontal) ── */
3975
4559
  [data-ui="separator"] {
3976
4560
  border: none;
3977
- border-top: 1px solid var(--color-border);
4561
+ border-top: var(--divider-width) var(--divider-style) var(--color-border);
3978
4562
  margin: 0;
3979
4563
  width: 100%;
3980
4564
  }
@@ -3982,7 +4566,7 @@ table {
3982
4566
  /* ── Vertical ── */
3983
4567
  [data-ui="separator"][data-variant="vertical"] {
3984
4568
  border-top: none;
3985
- border-inline-start: 1px solid var(--color-border);
4569
+ border-inline-start: var(--divider-width) var(--divider-style) var(--color-border);
3986
4570
  width: auto;
3987
4571
  height: 100%;
3988
4572
  align-self: stretch;
@@ -4000,11 +4584,11 @@ div[data-ui="separator"]::before,
4000
4584
  div[data-ui="separator"]::after {
4001
4585
  content: "";
4002
4586
  flex: 1;
4003
- border-top: 1px solid var(--color-border);
4587
+ border-top: var(--divider-width) var(--divider-style) var(--color-border);
4004
4588
  }
4005
4589
 
4006
4590
  [data-ui="separator"] [data-part="label"] {
4007
- font-family: var(--font-sans);
4591
+ font-family: var(--font-ui);
4008
4592
  font-size: var(--text-xs);
4009
4593
  color: var(--color-fg-muted);
4010
4594
  white-space: nowrap;
@@ -4042,17 +4626,17 @@ div[data-ui="separator"][data-style="dotted"]::after {
4042
4626
 
4043
4627
  /* ── Style: Thick ── */
4044
4628
  [data-ui="separator"][data-style="thick"] {
4045
- border-top-width: 2px;
4629
+ border-top-width: var(--border-width-strong);
4046
4630
  }
4047
4631
 
4048
4632
  [data-ui="separator"][data-style="thick"][data-variant="vertical"] {
4049
4633
  border-top-width: 0;
4050
- border-inline-start-width: 2px;
4634
+ border-inline-start-width: var(--border-width-strong);
4051
4635
  }
4052
4636
 
4053
4637
  div[data-ui="separator"][data-style="thick"]::before,
4054
4638
  div[data-ui="separator"][data-style="thick"]::after {
4055
- border-top-width: 2px;
4639
+ border-top-width: var(--border-width-strong);
4056
4640
  }
4057
4641
 
4058
4642
  /* ── Vertical Sizes ── */
@@ -4070,20 +4654,20 @@ div[data-ui="separator"][data-style="thick"]::after {
4070
4654
 
4071
4655
  /* === primitives/signature.css === */
4072
4656
  /* @ui:component signature */
4073
- /* @ui:tokens doc-signature-width doc-signature-gap doc-signature-line-color doc-signature-label-size doc-signature-label-color doc-font font-sans space-2 space-12 */
4657
+ /* @ui:tokens doc-signature-width doc-signature-gap doc-signature-line-color doc-signature-label-size doc-signature-label-color doc-font font-body space-2 space-12 border-width */
4074
4658
 
4075
4659
  /* ── Base ── */
4076
4660
  [data-ui="signature"] {
4077
4661
  display: flex;
4078
4662
  flex-direction: column;
4079
4663
  gap: var(--space-2);
4080
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
4664
+ font-family: var(--doc-font, var(--font-body));
4081
4665
  margin-top: var(--doc-signature-gap);
4082
4666
  }
4083
4667
 
4084
4668
  /* ── Line ── */
4085
4669
  [data-ui="signature"] [data-part="line"] {
4086
- border-top: 1px solid var(--doc-signature-line-color);
4670
+ border-top: var(--border-width) solid var(--doc-signature-line-color);
4087
4671
  min-height: 1px;
4088
4672
  }
4089
4673
 
@@ -4186,14 +4770,14 @@ div[data-ui="separator"][data-style="thick"]::after {
4186
4770
 
4187
4771
  /* === primitives/spinner.css === */
4188
4772
  /* @ui:component spinner */
4189
- /* @ui:tokens color-border color-primary radius-full duration-normal ease-default */
4773
+ /* @ui:tokens color-border color-primary radius-full duration-normal ease-default border-width-strong border-width-lg */
4190
4774
 
4191
4775
  /* ── Base ── */
4192
4776
  [data-ui="spinner"] {
4193
4777
  display: inline-block;
4194
4778
  width: 24px;
4195
4779
  height: 24px;
4196
- border: 2px solid var(--color-border);
4780
+ border: var(--border-width-strong) solid var(--color-border);
4197
4781
  border-top-color: var(--color-primary);
4198
4782
  border-radius: var(--radius-full);
4199
4783
  animation: faqir-spin 0.75s linear infinite;
@@ -4209,13 +4793,13 @@ div[data-ui="separator"][data-style="thick"]::after {
4209
4793
  [data-ui="spinner"][data-size="lg"] {
4210
4794
  width: 32px;
4211
4795
  height: 32px;
4212
- border-width: 3px;
4796
+ border-width: var(--border-width-lg);
4213
4797
  }
4214
4798
 
4215
4799
  [data-ui="spinner"][data-size="xl"] {
4216
4800
  width: 48px;
4217
4801
  height: 48px;
4218
- border-width: 3px;
4802
+ border-width: var(--border-width-lg);
4219
4803
  }
4220
4804
 
4221
4805
  /* ── Motion ── */
@@ -4797,14 +5381,14 @@ div[data-ui="separator"][data-style="thick"]::after {
4797
5381
 
4798
5382
  /* === primitives/stat.css === */
4799
5383
  /* @ui:component stat */
4800
- /* @ui:tokens stat-value-size stat-value-weight stat-value-num-font stat-label-size stat-label-color stat-change-positive stat-change-negative color-fg color-fg-muted color-bg color-border space-1 space-2 space-4 radius-md shadow-sm font-sans text-xs text-sm text-lg text-3xl weight-semibold */
5384
+ /* @ui:tokens stat-value-size stat-value-weight stat-value-num-font stat-label-size stat-label-color stat-change-positive stat-change-negative color-fg color-fg-muted color-bg color-border space-1 space-2 space-4 radius-md shadow-sm font-heading font-body text-xs text-sm text-lg text-3xl weight-semibold border-width */
4801
5385
 
4802
5386
  /* ── Base ── */
4803
5387
  [data-ui="stat"] {
4804
5388
  display: flex;
4805
5389
  flex-direction: column;
4806
5390
  gap: var(--space-1);
4807
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
5391
+ font-family: var(--doc-font, var(--font-body));
4808
5392
  }
4809
5393
 
4810
5394
  /* ── Label ── */
@@ -4818,6 +5402,7 @@ div[data-ui="separator"][data-style="thick"]::after {
4818
5402
 
4819
5403
  /* ── Value ── */
4820
5404
  [data-ui="stat"] [data-part="value"] {
5405
+ font-family: var(--font-heading);
4821
5406
  font-size: var(--stat-value-size);
4822
5407
  font-weight: var(--stat-value-weight);
4823
5408
  color: var(--color-fg);
@@ -4876,10 +5461,10 @@ div[data-ui="separator"][data-style="thick"]::after {
4876
5461
  /* ── Variant: Card ── */
4877
5462
  [data-ui="stat"][data-variant="card"] {
4878
5463
  padding: var(--space-4);
4879
- border: 1px solid var(--color-border);
5464
+ border: var(--border-width) solid var(--color-border);
4880
5465
  border-radius: var(--radius-md, 0.375rem);
4881
5466
  background: var(--color-bg);
4882
- box-shadow: var(--shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.05));
5467
+ box-shadow: var(--shadow-sm);
4883
5468
  }
4884
5469
 
4885
5470
  /* ── Value + Change Inline ── */
@@ -4891,7 +5476,7 @@ div[data-ui="separator"][data-style="thick"]::after {
4891
5476
  @media print {
4892
5477
  [data-ui="stat"][data-variant="card"] {
4893
5478
  box-shadow: none;
4894
- border: 1px solid var(--doc-print-border-color, var(--color-border, #ccc));
5479
+ border: var(--border-width) solid var(--doc-print-border-color, var(--color-border, #ccc));
4895
5480
  }
4896
5481
 
4897
5482
  [data-ui="stat"] {
@@ -4901,7 +5486,7 @@ div[data-ui="separator"][data-style="thick"]::after {
4901
5486
 
4902
5487
  /* === primitives/stepper.css === */
4903
5488
  /* @ui:component stepper */
4904
- /* @ui:tokens color-primary color-primary-fg color-bg-muted color-fg-muted color-success color-success-subtle color-border text-sm text-xs weight-medium radius-full space-2 space-3 space-1 */
5489
+ /* @ui:tokens color-primary color-primary-fg color-bg-muted color-fg-muted color-success color-success-subtle color-border text-sm text-xs weight-medium radius-full space-2 space-3 space-1 border-width-strong */
4905
5490
 
4906
5491
  /* ── Base ── */
4907
5492
  [data-ui="stepper"] {
@@ -4980,7 +5565,7 @@ div[data-ui="separator"][data-style="thick"]::after {
4980
5565
  The tight phone metrics are the base; the roomier ones arrive at `sm`. */
4981
5566
  [data-ui="stepper"] [data-part="connector"] {
4982
5567
  flex: 1;
4983
- height: 2px;
5568
+ height: var(--border-width-strong);
4984
5569
  background: var(--color-border);
4985
5570
  margin: 0 var(--space-1);
4986
5571
  min-width: var(--space-2);
@@ -5048,18 +5633,20 @@ div[data-ui="separator"][data-style="thick"]::after {
5048
5633
 
5049
5634
  /* === primitives/surface.css === */
5050
5635
  /* @ui:component surface */
5051
- /* @ui:tokens color-bg color-surface-1 color-surface-2 color-surface-1-border color-surface-2-border measure-content measure-narrow measure-prose measure-wide radius-lg shadow-sm shadow-md shadow-lg space-3 space-4 space-6 */
5636
+ /* @ui:tokens color-bg color-surface-1 color-surface-2 color-surface-1-border color-surface-2-border measure-content measure-narrow measure-prose measure-wide radius-lg shadow-sm shadow-md shadow-lg space-3 space-4 space-6 border-width corner-shape surface-backdrop texture-surface */
5052
5637
 
5053
5638
  /* ── Base ── */
5054
5639
  [data-ui="surface"] {
5055
- background: var(--color-surface-1);
5640
+ background-color: var(--color-surface-1);
5641
+ background-image: var(--texture-surface);
5056
5642
  border-radius: var(--radius-lg);
5057
- border: 1px solid var(--color-surface-1-border);
5643
+ corner-shape: var(--corner-shape);
5644
+ border: var(--border-width) solid var(--color-surface-1-border);
5058
5645
  }
5059
5646
 
5060
5647
  /* ── Elevation Variants ── */
5061
5648
  [data-ui="surface"][data-variant="flat"] {
5062
- background: var(--color-bg);
5649
+ background-color: var(--color-bg);
5063
5650
  border: none;
5064
5651
  box-shadow: none;
5065
5652
  }
@@ -5069,11 +5656,22 @@ div[data-ui="separator"][data-style="thick"]::after {
5069
5656
  }
5070
5657
 
5071
5658
  [data-ui="surface"][data-variant="overlay"] {
5072
- background: var(--color-surface-2);
5659
+ background-color: var(--color-surface-2);
5073
5660
  box-shadow: var(--shadow-lg);
5074
5661
  border-color: var(--color-surface-2-border);
5075
5662
  }
5076
5663
 
5664
+ /* An overlay is the one surface variant that floats over other content, so it
5665
+ is the one that can be frosted. Guarded exactly as themes/glass.css guards
5666
+ its own: a browser without backdrop-filter renders the solid surface above
5667
+ and never sees this rule. */
5668
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
5669
+ [data-ui="surface"][data-variant="overlay"] {
5670
+ -webkit-backdrop-filter: var(--surface-backdrop);
5671
+ backdrop-filter: var(--surface-backdrop);
5672
+ }
5673
+ }
5674
+
5077
5675
  /* ── Padding Sizes ── */
5078
5676
  [data-ui="surface"][data-size="sm"] {
5079
5677
  padding: var(--space-3);
@@ -5129,7 +5727,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5129
5727
 
5130
5728
  /* === primitives/switch.css === */
5131
5729
  /* @ui:component switch */
5132
- /* @ui:tokens color-bg-muted color-primary color-primary-fg color-border color-ring shadow-xs radius-full space-0h space-1 duration-fast ease-default */
5730
+ /* @ui:tokens color-bg-muted color-primary color-primary-fg color-border color-ring shadow-xs space-0h space-1 duration-fast ease-default border-width focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow switch-radius switch-width switch-height switch-thumb switch-travel switch-bg switch-thumb-shadow disabled-opacity */
5133
5731
 
5134
5732
  /* -- Label wrapper -- */
5135
5733
  [data-ui="switch-label"] {
@@ -5141,7 +5739,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5141
5739
 
5142
5740
  [data-ui="switch-label"]:has([data-ui="switch"]:disabled) {
5143
5741
  cursor: not-allowed;
5144
- opacity: 0.5;
5742
+ opacity: var(--disabled-opacity);
5145
5743
  }
5146
5744
 
5147
5745
  /* -- Base (track) -- */
@@ -5169,8 +5767,8 @@ div[data-ui="separator"][data-style="thick"]::after {
5169
5767
  width: var(--switch-width, 44px);
5170
5768
  height: var(--switch-height, 24px);
5171
5769
  padding: var(--space-0h, 2px);
5172
- border: 1px solid var(--color-border);
5173
- border-radius: var(--radius-full);
5770
+ border: var(--border-width) solid var(--color-border);
5771
+ border-radius: var(--switch-radius);
5174
5772
  background: var(--switch-bg, var(--color-bg-muted));
5175
5773
  cursor: pointer;
5176
5774
  position: relative;
@@ -5180,8 +5778,9 @@ div[data-ui="separator"][data-style="thick"]::after {
5180
5778
  }
5181
5779
 
5182
5780
  [data-ui="switch"]:focus-visible {
5183
- outline: 2px solid var(--color-ring);
5184
- outline-offset: 2px;
5781
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
5782
+ outline-offset: var(--focus-ring-offset);
5783
+ box-shadow: var(--focus-shadow);
5185
5784
  }
5186
5785
 
5187
5786
  /* -- Thumb (pseudo-element for <input>, child for custom markup) -- */
@@ -5190,7 +5789,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5190
5789
  display: block;
5191
5790
  width: var(--switch-thumb, 18px);
5192
5791
  height: var(--switch-thumb, 18px);
5193
- border-radius: var(--radius-full);
5792
+ border-radius: var(--switch-radius);
5194
5793
  background: var(--color-primary-fg);
5195
5794
  box-shadow: var(--switch-thumb-shadow, var(--shadow-xs));
5196
5795
  transition: transform var(--duration-fast) var(--ease-default);
@@ -5202,7 +5801,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5202
5801
  display: block;
5203
5802
  width: var(--switch-thumb, 18px);
5204
5803
  height: var(--switch-thumb, 18px);
5205
- border-radius: var(--radius-full);
5804
+ border-radius: var(--switch-radius);
5206
5805
  background: var(--color-primary-fg);
5207
5806
  box-shadow: var(--switch-thumb-shadow, var(--shadow-xs));
5208
5807
  transition: transform var(--duration-fast) var(--ease-default);
@@ -5284,7 +5883,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5284
5883
  the track's border is always visible, and ON fills it with `Highlight`. [W3-3] */
5285
5884
  @media (forced-colors: active) {
5286
5885
  [data-ui="switch"] {
5287
- border: 1px solid ButtonText;
5886
+ border: var(--border-width) solid ButtonText;
5288
5887
  background: ButtonFace;
5289
5888
  }
5290
5889
 
@@ -5441,25 +6040,31 @@ div[data-ui="separator"][data-style="thick"]::after {
5441
6040
 
5442
6041
  /* === primitives/text.css === */
5443
6042
  /* @ui:component text */
5444
- /* @ui:tokens color-fg color-fg-muted color-primary text-xs text-sm text-base text-lg text-xl text-2xl text-3xl text-4xl weight-normal weight-medium weight-semibold weight-bold leading-tight leading-snug leading-normal leading-relaxed font-sans font-mono */
6043
+ /* @ui:tokens color-fg color-fg-muted color-primary text-xs text-sm text-base text-lg text-xl text-2xl text-3xl text-4xl weight-normal weight-medium weight-semibold weight-bold leading-tight leading-snug leading-normal leading-relaxed font-heading font-body heading-weight heading-tracking heading-transform heading-caps heading-leading font-mono */
5445
6044
 
5446
6045
  /* ── Heading ── */
5447
6046
  [data-ui="heading"] {
5448
- font-family: var(--font-sans);
5449
- font-weight: var(--weight-bold);
6047
+ font-family: var(--font-heading);
6048
+ font-weight: var(--heading-weight);
5450
6049
  color: var(--color-fg);
5451
- line-height: var(--leading-tight);
5452
- letter-spacing: -0.01em;
6050
+ line-height: var(--heading-leading);
6051
+ text-transform: var(--heading-transform);
6052
+ font-variant-caps: var(--heading-caps);
6053
+ /* The optical tightening a large heading needs, PLUS whatever tracking the
6054
+ theme's voice asks for on top of it — so a theme that wants wide-tracked
6055
+ headings sets --heading-tracking once and every size follows, instead of
6056
+ each size having to re-derive its own number. */
6057
+ letter-spacing: calc(-0.01em + var(--heading-tracking));
5453
6058
  }
5454
6059
 
5455
6060
  [data-ui="heading"][data-size="1"] {
5456
6061
  font-size: var(--text-4xl);
5457
- letter-spacing: -0.02em;
6062
+ letter-spacing: calc(-0.02em + var(--heading-tracking));
5458
6063
  }
5459
6064
 
5460
6065
  [data-ui="heading"][data-size="2"] {
5461
6066
  font-size: var(--text-3xl);
5462
- letter-spacing: -0.02em;
6067
+ letter-spacing: calc(-0.02em + var(--heading-tracking));
5463
6068
  }
5464
6069
 
5465
6070
  [data-ui="heading"][data-size="3"] {
@@ -5483,7 +6088,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5483
6088
 
5484
6089
  /* ── Text ── */
5485
6090
  [data-ui="text"] {
5486
- font-family: var(--font-sans);
6091
+ font-family: var(--font-body);
5487
6092
  color: var(--color-fg);
5488
6093
  }
5489
6094
 
@@ -5561,7 +6166,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5561
6166
 
5562
6167
  /* === primitives/textarea.css === */
5563
6168
  /* @ui:component textarea */
5564
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-ring color-destructive radius-md space-2 space-3 space-4 font-sans text-xs text-sm text-base duration-fast ease-default */
6169
+ /* @ui:tokens color-fg color-fg-muted color-border color-border-strong color-ring color-destructive radius-md space-2 space-3 space-4 font-ui text-xs text-sm text-base duration-fast ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-shadow input-border-width input-fill disabled-opacity */
5565
6170
 
5566
6171
  /* -- Base -- */
5567
6172
  [data-ui="textarea"] {
@@ -5569,11 +6174,17 @@ div[data-ui="separator"][data-style="thick"]::after {
5569
6174
  width: 100%;
5570
6175
  min-height: var(--textarea-min-height, 80px);
5571
6176
  padding: var(--space-2) var(--space-3);
5572
- border: 1px solid var(--color-border);
6177
+ /* Longhands, not the `border:` shorthand: the shorthand's width slot takes
6178
+ ONE value, and `controls.input: underline` (1.1A-10) states the silhouette
6179
+ as a four-value box — `0 0 var(--border-width) 0` — so only a bottom rule
6180
+ is drawn. Identical to the shorthand at every other value of the token. */
6181
+ border-style: solid;
6182
+ border-color: var(--color-border);
6183
+ border-width: var(--input-border-width);
5573
6184
  border-radius: var(--textarea-radius, var(--radius-md));
5574
- background: var(--textarea-bg, var(--color-bg));
6185
+ background: var(--textarea-bg, var(--input-fill));
5575
6186
  color: var(--color-fg);
5576
- font-family: var(--textarea-font, var(--font-sans));
6187
+ font-family: var(--textarea-font, var(--font-ui));
5577
6188
  font-size: var(--text-sm);
5578
6189
  line-height: 1.5;
5579
6190
  resize: vertical;
@@ -5590,8 +6201,11 @@ div[data-ui="separator"][data-style="thick"]::after {
5590
6201
  }
5591
6202
 
5592
6203
  [data-ui="textarea"]:focus {
5593
- outline: 2px solid var(--color-ring);
5594
- outline-offset: -1px;
6204
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6205
+ /* The ring replaces the border rather than sitting outside it: inset by
6206
+ exactly the edge it covers, so a heavier shape theme stays aligned. */
6207
+ outline-offset: calc(-1 * var(--input-border-width));
6208
+ box-shadow: var(--focus-shadow);
5595
6209
  border-color: transparent;
5596
6210
  }
5597
6211
 
@@ -5619,7 +6233,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5619
6233
  }
5620
6234
 
5621
6235
  [data-ui="textarea"]:disabled {
5622
- opacity: 0.5;
6236
+ opacity: var(--disabled-opacity);
5623
6237
  cursor: not-allowed;
5624
6238
  resize: none;
5625
6239
  }
@@ -5633,7 +6247,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5633
6247
 
5634
6248
  /* === primitives/toggle.css === */
5635
6249
  /* @ui:component toggle */
5636
- /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-subtle color-ring radius-md space-1 space-1h space-2 space-3 space-4 text-xs text-sm text-base font-sans weight-medium duration-fast ease-default */
6250
+ /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-subtle color-ring radius-md space-1 space-1h space-2 space-3 space-4 text-xs text-sm text-base font-ui weight-medium duration-fast ease-default border-width focus-ring-width focus-ring-offset focus-ring-style focus-ring-color focus-shadow disabled-opacity */
5637
6251
 
5638
6252
  /* ── Base (off / unpressed) ── */
5639
6253
  [data-ui="toggle"] {
@@ -5642,11 +6256,11 @@ div[data-ui="separator"][data-style="thick"]::after {
5642
6256
  justify-content: center;
5643
6257
  gap: var(--space-1h);
5644
6258
  padding: var(--toggle-pad-y, var(--space-1h)) var(--toggle-pad-x, var(--space-3));
5645
- border: 1px solid var(--color-border);
6259
+ border: var(--border-width) solid var(--color-border);
5646
6260
  border-radius: var(--toggle-radius, var(--radius-md));
5647
6261
  background: var(--color-bg);
5648
6262
  color: var(--color-fg-muted);
5649
- font-family: var(--toggle-font, var(--font-sans));
6263
+ font-family: var(--toggle-font, var(--font-ui));
5650
6264
  font-size: var(--text-sm);
5651
6265
  font-weight: var(--weight-medium);
5652
6266
  line-height: 1;
@@ -5663,8 +6277,9 @@ div[data-ui="separator"][data-style="thick"]::after {
5663
6277
  }
5664
6278
 
5665
6279
  [data-ui="toggle"]:focus-visible {
5666
- outline: 2px solid var(--color-ring);
5667
- outline-offset: 2px;
6280
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6281
+ outline-offset: var(--focus-ring-offset);
6282
+ box-shadow: var(--focus-shadow);
5668
6283
  }
5669
6284
 
5670
6285
  /* ── Pressed / on — styled entirely off aria-pressed, no JS ── */
@@ -5681,7 +6296,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5681
6296
 
5682
6297
  /* ── Disabled ── */
5683
6298
  [data-ui="toggle"]:disabled {
5684
- opacity: 0.5;
6299
+ opacity: var(--disabled-opacity);
5685
6300
  cursor: not-allowed;
5686
6301
  }
5687
6302
 
@@ -5705,7 +6320,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5705
6320
 
5706
6321
  /* === primitives/watermark.css === */
5707
6322
  /* @ui:component watermark */
5708
- /* @ui:tokens color-fg-muted doc-font font-sans text-xl text-2xl text-4xl weight-bold leading-tight space-8 space-20 z-raised */
6323
+ /* @ui:tokens color-fg-muted doc-font font-body text-xl text-2xl text-4xl weight-bold leading-tight space-8 space-20 z-raised */
5709
6324
 
5710
6325
  [data-ui="watermark"] {
5711
6326
  position: fixed;
@@ -5724,7 +6339,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5724
6339
 
5725
6340
  [data-ui="watermark"] > [data-part="mark"] {
5726
6341
  color: var(--color-fg-muted);
5727
- font-family: var(--doc-font, var(--font-sans));
6342
+ font-family: var(--doc-font, var(--font-body));
5728
6343
  font-size: var(--text-4xl);
5729
6344
  font-weight: var(--weight-bold);
5730
6345
  line-height: var(--leading-tight);
@@ -5782,7 +6397,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5782
6397
 
5783
6398
  /* === recipes/accordion.css === */
5784
6399
  /* @ui:component accordion */
5785
- /* @ui:tokens color-bg color-fg color-fg-muted color-border space-3 space-4 text-sm text-base weight-medium duration-normal ease-default radius-lg */
6400
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border space-3 space-4 text-sm text-base weight-medium duration-normal ease-default radius-lg font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
5786
6401
 
5787
6402
  /* ── Root ── */
5788
6403
  [data-ui="accordion"] {
@@ -5791,7 +6406,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5791
6406
 
5792
6407
  /* ── Item ── */
5793
6408
  [data-ui="accordion"] [data-part="item"] {
5794
- border-bottom: 1px solid var(--color-border);
6409
+ border-bottom: var(--border-width) solid var(--color-border);
5795
6410
  }
5796
6411
 
5797
6412
  [data-ui="accordion"] [data-part="item"]:last-child {
@@ -5808,7 +6423,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5808
6423
  border: none;
5809
6424
  background: transparent;
5810
6425
  color: var(--color-fg);
5811
- font-family: var(--font-sans, system-ui, sans-serif);
6426
+ font-family: var(--font-ui);
5812
6427
  font-size: var(--text-base);
5813
6428
  font-weight: var(--weight-medium);
5814
6429
  text-align: start;
@@ -5822,8 +6437,8 @@ div[data-ui="separator"][data-style="thick"]::after {
5822
6437
  }
5823
6438
 
5824
6439
  [data-ui="accordion"] [data-part="trigger"]:focus-visible {
5825
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
5826
- outline-offset: -2px;
6440
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6441
+ outline-offset: calc(-1 * var(--focus-ring-offset));
5827
6442
  border-radius: var(--radius-sm, 0.25rem);
5828
6443
  }
5829
6444
 
@@ -5855,13 +6470,13 @@ div[data-ui="separator"][data-style="thick"]::after {
5855
6470
 
5856
6471
  /* ── Bordered Variant ── */
5857
6472
  [data-ui="accordion"][data-bordered="true"] {
5858
- border: 1px solid var(--color-border);
6473
+ border: var(--border-width) solid var(--color-border);
5859
6474
  border-radius: var(--radius-lg);
5860
6475
  overflow: hidden;
5861
6476
  }
5862
6477
 
5863
6478
  [data-ui="accordion"][data-bordered="true"] [data-part="item"] {
5864
- border-bottom: 1px solid var(--color-border);
6479
+ border-bottom: var(--border-width) solid var(--color-border);
5865
6480
  }
5866
6481
 
5867
6482
  [data-ui="accordion"][data-bordered="true"] [data-part="item"]:last-child {
@@ -5878,7 +6493,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5878
6493
 
5879
6494
  /* === recipes/alert-dialog.css === */
5880
6495
  /* @ui:component alert-dialog */
5881
- /* @ui:tokens radius-xl shadow-xl space-2 space-3 space-6 color-bg color-fg color-border color-fg-muted color-destructive duration-normal ease-default ease-out z-overlay z-modal */
6496
+ /* @ui:tokens radius-xl shadow-xl space-2 space-3 space-6 color-bg color-fg color-border color-fg-muted color-destructive duration-normal ease-default ease-out z-overlay z-modal font-heading border-width */
5882
6497
 
5883
6498
  /* ── Root ── */
5884
6499
  [data-ui="alert-dialog"] {
@@ -5914,7 +6529,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5914
6529
  max-height: 85vh;
5915
6530
  overflow-y: auto;
5916
6531
  background: var(--color-bg);
5917
- border: 1px solid var(--color-border);
6532
+ border: var(--border-width) solid var(--color-border);
5918
6533
  border-radius: var(--alert-dialog-radius, var(--radius-xl));
5919
6534
  box-shadow: var(--alert-dialog-shadow, var(--shadow-xl));
5920
6535
  opacity: 0;
@@ -5960,6 +6575,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5960
6575
  /* ── Title ── */
5961
6576
  [data-ui="alert-dialog"] [data-part="title"] {
5962
6577
  margin: 0;
6578
+ font-family: var(--font-heading);
5963
6579
  font-size: var(--text-lg, 1.125rem);
5964
6580
  font-weight: var(--weight-semibold, 600);
5965
6581
  color: var(--color-fg);
@@ -5999,7 +6615,7 @@ div[data-ui="separator"][data-style="thick"]::after {
5999
6615
 
6000
6616
  /* === recipes/barcode.css === */
6001
6617
  /* @ui:component barcode */
6002
- /* @ui:tokens color-fg color-bg color-fg-muted doc-font doc-legal-color doc-legal-size font-mono font-sans space-2 space-12 space-16 space-20 */
6618
+ /* @ui:tokens color-fg color-bg color-fg-muted doc-font doc-legal-color doc-legal-size font-mono font-body space-2 space-12 space-16 space-20 */
6003
6619
 
6004
6620
  [data-ui="barcode"] {
6005
6621
  display: inline-flex;
@@ -6026,7 +6642,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6026
6642
 
6027
6643
  [data-ui="barcode"] > [data-part="caption"] {
6028
6644
  color: var(--doc-legal-color, var(--color-fg-muted));
6029
- font-family: var(--font-mono, var(--doc-font, var(--font-sans)));
6645
+ font-family: var(--font-mono, var(--doc-font, var(--font-body)));
6030
6646
  font-size: var(--doc-legal-size);
6031
6647
  line-height: var(--leading-normal);
6032
6648
  text-align: center;
@@ -6046,7 +6662,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6046
6662
 
6047
6663
  /* === recipes/calendar.css === */
6048
6664
  /* @ui:component calendar */
6049
- /* @ui:tokens color-bg color-fg color-fg-muted color-fg-subtle color-border color-primary color-primary-fg color-primary-subtle color-ring radius-md radius-full space-0 space-1 space-2 text-xs text-sm text-base weight-medium duration-fast ease-default */
6665
+ /* @ui:tokens color-bg color-fg color-fg-muted color-fg-subtle color-border color-primary color-primary-fg color-primary-subtle color-ring radius-md radius-full space-0 space-1 space-2 text-xs text-sm text-base weight-medium duration-fast ease-default font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset disabled-opacity */
6050
6666
 
6051
6667
  /* ── Root ── */
6052
6668
  [data-ui="calendar"] {
@@ -6079,7 +6695,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6079
6695
  width: 28px;
6080
6696
  height: 28px;
6081
6697
  padding: 0;
6082
- border: 1px solid var(--color-border);
6698
+ border: var(--border-width) solid var(--color-border);
6083
6699
  border-radius: var(--radius-md);
6084
6700
  background: var(--color-bg);
6085
6701
  color: var(--color-fg);
@@ -6095,13 +6711,15 @@ div[data-ui="separator"][data-style="thick"]::after {
6095
6711
 
6096
6712
  [data-ui="calendar"] [data-part="nav-prev"]:focus-visible,
6097
6713
  [data-ui="calendar"] [data-part="nav-next"]:focus-visible {
6098
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
6099
- outline-offset: 2px;
6714
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6715
+ outline-offset: var(--focus-ring-offset);
6100
6716
  }
6101
6717
 
6102
6718
  [data-ui="calendar"] [data-part="nav-prev"]:disabled,
6103
6719
  [data-ui="calendar"] [data-part="nav-next"]:disabled {
6104
- opacity: 0.4;
6720
+ /* Dimmer than a disabled control — 0.4 at the 0.5 default — and it follows a
6721
+ theme's `--disabled-opacity` like every other disabled dim (1.1A-27). */
6722
+ opacity: calc(var(--disabled-opacity) * 0.8);
6105
6723
  cursor: not-allowed;
6106
6724
  }
6107
6725
 
@@ -6136,11 +6754,11 @@ div[data-ui="separator"][data-style="thick"]::after {
6136
6754
  width: 36px;
6137
6755
  height: 36px;
6138
6756
  padding: 0;
6139
- border: 1px solid transparent;
6757
+ border: var(--border-width) solid transparent;
6140
6758
  border-radius: var(--radius-full);
6141
6759
  background: transparent;
6142
6760
  color: var(--color-fg);
6143
- font-family: var(--font-sans, system-ui, sans-serif);
6761
+ font-family: var(--font-ui);
6144
6762
  font-size: var(--text-sm);
6145
6763
  cursor: pointer;
6146
6764
  transition: background var(--duration-fast) var(--ease-default),
@@ -6153,8 +6771,8 @@ div[data-ui="separator"][data-style="thick"]::after {
6153
6771
  }
6154
6772
 
6155
6773
  [data-ui="calendar"] [data-part="day"]:focus-visible {
6156
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
6157
- outline-offset: 2px;
6774
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6775
+ outline-offset: var(--focus-ring-offset);
6158
6776
  }
6159
6777
 
6160
6778
  /* ── Today ── */
@@ -6189,7 +6807,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6189
6807
  /* ── Disabled days (aria-disabled keeps them focusable; :disabled for hard-disabled) ── */
6190
6808
  [data-ui="calendar"] [data-part="day"][aria-disabled="true"],
6191
6809
  [data-ui="calendar"] [data-part="day"]:disabled {
6192
- opacity: 0.5;
6810
+ opacity: var(--disabled-opacity);
6193
6811
  cursor: not-allowed;
6194
6812
  text-decoration: line-through;
6195
6813
  }
@@ -6253,7 +6871,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6253
6871
 
6254
6872
  /* === recipes/carousel.css === */
6255
6873
  /* @ui:component carousel */
6256
- /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-ring radius-md radius-lg space-1 space-2 space-3 space-4 text-sm font-sans duration-fast ease-default */
6874
+ /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-ring radius-md radius-lg space-1 space-2 space-3 space-4 text-sm font-ui duration-fast ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset disabled-opacity */
6257
6875
 
6258
6876
  /* The sliding is CSS, not JavaScript: the viewport is a scroll-snap strip and
6259
6877
  every slide is a snap target. Everything below works with no controller
@@ -6267,7 +6885,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6267
6885
  inline-size: 100%;
6268
6886
  min-inline-size: 0;
6269
6887
  max-inline-size: 100%;
6270
- font-family: var(--carousel-font, var(--font-sans));
6888
+ font-family: var(--carousel-font, var(--font-ui));
6271
6889
  }
6272
6890
 
6273
6891
  /* ── Viewport: the scroll-snap strip ── */
@@ -6293,8 +6911,8 @@ div[data-ui="separator"][data-style="thick"]::after {
6293
6911
  }
6294
6912
 
6295
6913
  [data-ui="carousel"] [data-part="viewport"]:focus-visible {
6296
- outline: 2px solid var(--color-ring);
6297
- outline-offset: 2px;
6914
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6915
+ outline-offset: var(--focus-ring-offset);
6298
6916
  }
6299
6917
 
6300
6918
  /* ── Slide: one full-width snap target ── */
@@ -6302,7 +6920,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6302
6920
  flex: 0 0 var(--carousel-slide-size, 100%);
6303
6921
  min-inline-size: 0;
6304
6922
  padding: var(--space-4);
6305
- border: 1px solid var(--color-border);
6923
+ border: var(--border-width) solid var(--color-border);
6306
6924
  border-radius: var(--radius-lg);
6307
6925
  background: var(--color-bg);
6308
6926
  color: var(--color-fg);
@@ -6331,7 +6949,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6331
6949
  min-inline-size: 2rem;
6332
6950
  min-block-size: 2rem;
6333
6951
  padding: var(--space-1) var(--space-2);
6334
- border: 1px solid var(--color-border);
6952
+ border: var(--border-width) solid var(--color-border);
6335
6953
  border-radius: var(--radius-md);
6336
6954
  background: var(--color-bg);
6337
6955
  color: var(--color-fg);
@@ -6350,14 +6968,15 @@ div[data-ui="separator"][data-style="thick"]::after {
6350
6968
  [data-ui="carousel"] [data-part="prev"]:focus-visible,
6351
6969
  [data-ui="carousel"] [data-part="next"]:focus-visible,
6352
6970
  [data-ui="carousel"] [data-part="dot"]:focus-visible {
6353
- outline: 2px solid var(--color-ring);
6354
- outline-offset: 2px;
6971
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
6972
+ outline-offset: var(--focus-ring-offset);
6355
6973
  }
6356
6974
 
6357
6975
  /* Boundary contract "stop" — the controller disables the end button. */
6358
6976
  [data-ui="carousel"] [data-part="prev"]:disabled,
6359
6977
  [data-ui="carousel"] [data-part="next"]:disabled {
6360
- opacity: 0.4;
6978
+ /* 0.4 at the 0.5 default, and a theme's `--disabled-opacity` moves it (1.1A-27). */
6979
+ opacity: calc(var(--disabled-opacity) * 0.8);
6361
6980
  cursor: not-allowed;
6362
6981
  }
6363
6982
 
@@ -6366,7 +6985,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6366
6985
  inline-size: 0.625rem;
6367
6986
  block-size: 0.625rem;
6368
6987
  padding: 0;
6369
- border: 1px solid var(--color-border);
6988
+ border: var(--border-width) solid var(--color-border);
6370
6989
  border-radius: 50%;
6371
6990
  background: var(--color-bg-muted);
6372
6991
  cursor: pointer;
@@ -6402,7 +7021,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6402
7021
 
6403
7022
  /* === recipes/combobox.css === */
6404
7023
  /* @ui:component combobox */
6405
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle color-ring radius-md radius-lg shadow-md space-1 space-2 space-3 text-sm text-base z-dropdown duration-fast ease-default */
7024
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle radius-md radius-lg shadow-md space-1 space-2 space-3 text-sm text-base z-dropdown duration-fast ease-default font-ui border-width focus-ring-color focus-ring-width */
6406
7025
 
6407
7026
  /* ── Root ── */
6408
7027
  [data-ui="combobox"] {
@@ -6416,11 +7035,11 @@ div[data-ui="separator"][data-style="thick"]::after {
6416
7035
  display: block;
6417
7036
  width: 100%;
6418
7037
  padding: var(--space-2) var(--space-3);
6419
- border: 1px solid var(--color-border);
7038
+ border: var(--border-width) solid var(--color-border);
6420
7039
  border-radius: var(--radius-md);
6421
7040
  background: var(--color-bg);
6422
7041
  color: var(--color-fg);
6423
- font-family: var(--font-sans, system-ui, sans-serif);
7042
+ font-family: var(--font-ui);
6424
7043
  font-size: var(--text-sm);
6425
7044
  line-height: 1.5;
6426
7045
  outline: none;
@@ -6433,8 +7052,8 @@ div[data-ui="separator"][data-style="thick"]::after {
6433
7052
  }
6434
7053
 
6435
7054
  [data-ui="combobox"] [data-part="input"]:focus {
6436
- border-color: var(--color-ring, oklch(0.55 0.22 264));
6437
- box-shadow: 0 0 0 2px var(--color-ring, oklch(0.55 0.22 264));
7055
+ border-color: var(--focus-ring-color);
7056
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
6438
7057
  }
6439
7058
 
6440
7059
  /* ── Listbox ── */
@@ -6446,7 +7065,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6446
7065
  z-index: var(--z-dropdown);
6447
7066
  margin-top: var(--space-1);
6448
7067
  padding: var(--space-1);
6449
- border: 1px solid var(--color-border);
7068
+ border: var(--border-width) solid var(--color-border);
6450
7069
  border-radius: var(--radius-lg);
6451
7070
  background: var(--color-bg);
6452
7071
  box-shadow: var(--shadow-md);
@@ -6531,7 +7150,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6531
7150
 
6532
7151
  /* === recipes/command-palette.css === */
6533
7152
  /* @ui:component command-palette */
6534
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle color-bg-muted shadow-xl radius-xl space-2 space-3 space-4 text-sm text-xs text-base weight-medium font-mono z-overlay z-modal duration-fast duration-normal ease-out */
7153
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle color-bg-muted shadow-xl radius-xl space-2 space-3 space-4 text-sm text-xs text-base weight-medium font-mono z-overlay z-modal duration-fast duration-normal ease-out font-ui border-width */
6535
7154
 
6536
7155
  /* ── Root ── */
6537
7156
  [data-ui="command-palette"] {
@@ -6564,7 +7183,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6564
7183
  display: flex;
6565
7184
  flex-direction: column;
6566
7185
  background: var(--color-bg);
6567
- border: 1px solid var(--color-border);
7186
+ border: var(--border-width) solid var(--color-border);
6568
7187
  border-radius: var(--radius-xl);
6569
7188
  box-shadow: var(--shadow-xl);
6570
7189
  overflow: hidden;
@@ -6596,7 +7215,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6596
7215
  display: flex;
6597
7216
  align-items: center;
6598
7217
  padding: var(--space-3) var(--space-4);
6599
- border-bottom: 1px solid var(--color-border);
7218
+ border-bottom: var(--border-width) solid var(--color-border);
6600
7219
  }
6601
7220
 
6602
7221
  /* ── Search Input ── */
@@ -6606,7 +7225,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6606
7225
  border: none;
6607
7226
  background: transparent;
6608
7227
  color: var(--color-fg);
6609
- font-family: var(--font-sans, system-ui, sans-serif);
7228
+ font-family: var(--font-ui);
6610
7229
  font-size: var(--text-base);
6611
7230
  outline: none;
6612
7231
  }
@@ -6690,7 +7309,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6690
7309
  align-items: center;
6691
7310
  gap: var(--space-1, 0.25rem);
6692
7311
  padding: var(--space-1, 0.25rem) var(--space-2);
6693
- border: 1px solid var(--color-border);
7312
+ border: var(--border-width) solid var(--color-border);
6694
7313
  border-radius: var(--radius-sm, 0.25rem);
6695
7314
  background: var(--color-bg-muted, oklch(0.96 0.004 260));
6696
7315
  color: var(--color-fg-muted);
@@ -6719,7 +7338,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6719
7338
 
6720
7339
  /* === recipes/context-menu.css === */
6721
7340
  /* @ui:component context-menu */
6722
- /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-subtle color-ring space-px space-1 space-2 space-3 space-4 space-20 radius-md radius-lg shadow-md text-sm weight-medium font-sans duration-fast ease-out z-dropdown */
7341
+ /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-subtle color-ring space-px space-1 space-2 space-3 space-4 space-20 radius-md radius-lg shadow-md text-sm weight-medium font-ui duration-fast ease-out z-dropdown focus-ring-width focus-ring-style focus-ring-color focus-ring-offset disabled-opacity */
6723
7342
 
6724
7343
  [data-ui="context-menu"] {
6725
7344
  position: relative;
@@ -6732,12 +7351,12 @@ div[data-ui="separator"][data-style="thick"]::after {
6732
7351
  border-radius: var(--radius-lg);
6733
7352
  background: var(--color-bg-muted);
6734
7353
  color: var(--color-fg);
6735
- font-family: var(--font-sans, system-ui, sans-serif);
7354
+ font-family: var(--font-ui);
6736
7355
  }
6737
7356
 
6738
7357
  [data-ui="context-menu"] [data-part="target"]:focus-visible {
6739
- outline: calc(var(--space-px) * 2) solid var(--color-ring);
6740
- outline-offset: var(--space-1);
7358
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
7359
+ outline-offset: var(--focus-ring-offset);
6741
7360
  }
6742
7361
 
6743
7362
  [data-ui="context-menu"] [data-part="menu"] {
@@ -6769,7 +7388,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6769
7388
  border-radius: var(--radius-md);
6770
7389
  background: transparent;
6771
7390
  color: var(--color-fg);
6772
- font-family: var(--font-sans, system-ui, sans-serif);
7391
+ font-family: var(--font-ui);
6773
7392
  font-size: var(--text-sm);
6774
7393
  font-weight: var(--weight-medium);
6775
7394
  text-align: start;
@@ -6793,15 +7412,15 @@ div[data-ui="separator"][data-style="thick"]::after {
6793
7412
  focus additionally draws the ring, inset so it does not overlap the item
6794
7413
  above. [W3-3] */
6795
7414
  [data-ui="context-menu"] [data-part="item"]:focus-visible {
6796
- outline: calc(var(--space-px) * 2) solid var(--color-ring);
6797
- outline-offset: calc(var(--space-px) * -2);
7415
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
7416
+ outline-offset: calc(-1 * var(--focus-ring-offset));
6798
7417
  }
6799
7418
 
6800
7419
  [data-ui="context-menu"] [data-part="item"]:disabled,
6801
7420
  [data-ui="context-menu"] [data-part="item"][aria-disabled="true"] {
6802
7421
  color: var(--color-fg-muted);
6803
7422
  cursor: not-allowed;
6804
- opacity: 0.5;
7423
+ opacity: var(--disabled-opacity);
6805
7424
  }
6806
7425
 
6807
7426
  [data-ui="context-menu"] [data-part="separator"] {
@@ -6820,7 +7439,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6820
7439
 
6821
7440
  /* === recipes/date-picker.css === */
6822
7441
  /* @ui:component date-picker */
6823
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-ring shadow-lg radius-md radius-lg space-1 space-2 space-3 space-4 text-xs text-sm z-dropdown duration-fast ease-default */
7442
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-ring shadow-lg radius-md radius-lg space-1 space-2 space-3 space-4 text-xs text-sm z-dropdown duration-fast ease-default font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
6824
7443
  /* The month grid inside the popup is the `calendar` recipe — see calendar.css */
6825
7444
 
6826
7445
  /* ── Root ── */
@@ -6841,11 +7460,11 @@ div[data-ui="separator"][data-style="thick"]::after {
6841
7460
  width: 100%;
6842
7461
  padding: var(--space-2, 0.5rem) var(--space-3);
6843
7462
  padding-inline-end: var(--space-8, 2.5rem);
6844
- border: 1px solid var(--color-border);
7463
+ border: var(--border-width) solid var(--color-border);
6845
7464
  border-radius: var(--radius-md);
6846
7465
  background: var(--color-bg);
6847
7466
  color: var(--color-fg);
6848
- font-family: var(--font-sans, system-ui, sans-serif);
7467
+ font-family: var(--font-ui);
6849
7468
  font-size: var(--text-sm);
6850
7469
  line-height: 1.5;
6851
7470
  cursor: pointer;
@@ -6857,8 +7476,8 @@ div[data-ui="separator"][data-style="thick"]::after {
6857
7476
  }
6858
7477
 
6859
7478
  [data-ui="date-picker"] [data-part="input"]:focus-visible {
6860
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
6861
- outline-offset: 2px;
7479
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
7480
+ outline-offset: var(--focus-ring-offset);
6862
7481
  border-color: var(--color-primary);
6863
7482
  }
6864
7483
 
@@ -6881,7 +7500,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6881
7500
  z-index: var(--z-dropdown);
6882
7501
  margin-top: var(--space-1);
6883
7502
  padding: var(--space-3);
6884
- border: 1px solid var(--color-border);
7503
+ border: var(--border-width) solid var(--color-border);
6885
7504
  border-radius: var(--radius-lg);
6886
7505
  background: var(--color-bg);
6887
7506
  box-shadow: var(--shadow-lg);
@@ -6920,7 +7539,7 @@ div[data-ui="separator"][data-style="thick"]::after {
6920
7539
 
6921
7540
  /* === recipes/dialog.css === */
6922
7541
  /* @ui:component dialog */
6923
- /* @ui:tokens radius-xl shadow-xl space-4 space-6 space-8 color-bg color-fg color-border color-fg-muted duration-normal duration-slow ease-default ease-out z-overlay z-modal */
7542
+ /* @ui:tokens radius-xl shadow-xl space-4 space-6 space-8 color-bg panel-bg color-fg color-border color-fg-muted duration-normal duration-slow ease-default ease-out z-overlay z-modal font-heading corner-shape border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset surface-backdrop */
6924
7543
 
6925
7544
  /* ── Root ── */
6926
7545
  [data-ui="dialog"] {
@@ -6955,15 +7574,23 @@ div[data-ui="separator"][data-style="thick"]::after {
6955
7574
  width: 90%;
6956
7575
  max-height: 85vh;
6957
7576
  overflow-y: auto;
6958
- background: var(--color-bg);
6959
- border: 1px solid var(--color-border);
7577
+ background: var(--panel-bg);
7578
+ border: var(--border-width) solid var(--color-border);
6960
7579
  border-radius: var(--dialog-radius, var(--radius-xl));
7580
+ corner-shape: var(--corner-shape);
6961
7581
  box-shadow: var(--dialog-shadow, var(--shadow-xl));
6962
7582
  opacity: 0;
6963
7583
  transition: opacity var(--duration-normal) var(--ease-out),
6964
7584
  transform var(--duration-normal) var(--ease-out);
6965
7585
  }
6966
7586
 
7587
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
7588
+ [data-ui="dialog"] [data-part="panel"] {
7589
+ -webkit-backdrop-filter: var(--surface-backdrop);
7590
+ backdrop-filter: var(--surface-backdrop);
7591
+ }
7592
+ }
7593
+
6967
7594
  [data-ui="dialog"][data-state="open"] [data-part="panel"] {
6968
7595
  opacity: 1;
6969
7596
  transform: translate(-50%, -50%) scale(1);
@@ -7012,6 +7639,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7012
7639
  /* ── Title ── */
7013
7640
  [data-ui="dialog"] [data-part="title"] {
7014
7641
  margin: 0;
7642
+ font-family: var(--font-heading);
7015
7643
  font-size: var(--text-lg, 1.125rem);
7016
7644
  font-weight: var(--weight-semibold, 600);
7017
7645
  color: var(--color-fg);
@@ -7046,8 +7674,8 @@ div[data-ui="separator"][data-style="thick"]::after {
7046
7674
  }
7047
7675
 
7048
7676
  [data-ui="dialog"] [data-part="close"]:not([data-ui]):focus-visible {
7049
- outline: 2px solid var(--color-ring);
7050
- outline-offset: 2px;
7677
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
7678
+ outline-offset: var(--focus-ring-offset);
7051
7679
  }
7052
7680
 
7053
7681
  /* ── Description ── */
@@ -7083,7 +7711,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7083
7711
 
7084
7712
  /* === recipes/drawer.css === */
7085
7713
  /* @ui:component drawer */
7086
- /* @ui:tokens color-bg color-fg color-border shadow-xl space-4 space-6 radius-none z-overlay z-modal duration-normal duration-slow ease-out ease-default */
7714
+ /* @ui:tokens color-bg panel-bg color-fg color-border shadow-xl space-4 space-6 radius-none z-overlay z-modal duration-normal duration-slow ease-out ease-default font-heading border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset surface-backdrop */
7087
7715
 
7088
7716
  /* ── Root ── */
7089
7717
  [data-ui="drawer"] {
@@ -7118,17 +7746,24 @@ div[data-ui="separator"][data-style="thick"]::after {
7118
7746
  flex-direction: column;
7119
7747
  width: var(--drawer-width, 400px);
7120
7748
  max-width: 100vw;
7121
- background: var(--color-bg);
7749
+ background: var(--panel-bg);
7122
7750
  border: none;
7123
7751
  box-shadow: var(--drawer-shadow, var(--shadow-xl));
7124
7752
  transition: transform var(--duration-slow) var(--ease-out);
7125
7753
  }
7126
7754
 
7755
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
7756
+ [data-ui="drawer"] [data-part="panel"] {
7757
+ -webkit-backdrop-filter: var(--surface-backdrop);
7758
+ backdrop-filter: var(--surface-backdrop);
7759
+ }
7760
+ }
7761
+
7127
7762
  /* ── Side Variants ── */
7128
7763
  [data-ui="drawer"] [data-part="panel"][data-variant="left"] {
7129
7764
  inset-inline-start: 0;
7130
7765
  inset-inline-end: auto;
7131
- border-inline-end: 1px solid var(--color-border);
7766
+ border-inline-end: var(--border-width) solid var(--color-border);
7132
7767
  border-radius: 0 var(--radius-none, 0) var(--radius-none, 0) 0;
7133
7768
  transform: translateX(-100%);
7134
7769
  }
@@ -7136,7 +7771,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7136
7771
  [data-ui="drawer"] [data-part="panel"][data-variant="right"] {
7137
7772
  inset-inline-end: 0;
7138
7773
  inset-inline-start: auto;
7139
- border-inline-start: 1px solid var(--color-border);
7774
+ border-inline-start: var(--border-width) solid var(--color-border);
7140
7775
  border-radius: var(--radius-none, 0) 0 0 var(--radius-none, 0);
7141
7776
  transform: translateX(100%);
7142
7777
  }
@@ -7190,6 +7825,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7190
7825
  /* ── Title ── */
7191
7826
  [data-ui="drawer"] [data-part="title"] {
7192
7827
  margin: 0;
7828
+ font-family: var(--font-heading);
7193
7829
  font-size: var(--text-lg, 1.125rem);
7194
7830
  font-weight: var(--weight-semibold, 600);
7195
7831
  color: var(--color-fg);
@@ -7224,8 +7860,8 @@ div[data-ui="separator"][data-style="thick"]::after {
7224
7860
  }
7225
7861
 
7226
7862
  [data-ui="drawer"] [data-part="close"]:not([data-ui]):focus-visible {
7227
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
7228
- outline-offset: 2px;
7863
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
7864
+ outline-offset: var(--focus-ring-offset);
7229
7865
  }
7230
7866
 
7231
7867
  /* ── Body ── */
@@ -7244,7 +7880,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7244
7880
  gap: var(--space-3, 0.75rem);
7245
7881
  padding: var(--space-6);
7246
7882
  padding-top: var(--space-4);
7247
- border-top: 1px solid var(--color-border);
7883
+ border-top: var(--border-width) solid var(--color-border);
7248
7884
  flex-shrink: 0;
7249
7885
  }
7250
7886
 
@@ -7258,7 +7894,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7258
7894
 
7259
7895
  /* === recipes/dropdown.css === */
7260
7896
  /* @ui:component dropdown */
7261
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle color-primary space-1 space-2 space-3 space-4 radius-md radius-lg shadow-md text-sm weight-medium duration-fast ease-default ease-out z-dropdown */
7897
+ /* @ui:tokens color-bg panel-bg color-fg color-fg-muted color-border color-primary-subtle color-primary space-1 space-2 space-3 space-4 radius-md radius-lg shadow-md text-sm weight-medium duration-fast ease-default ease-out z-dropdown font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset surface-backdrop disabled-opacity */
7262
7898
 
7263
7899
  /* ── Root ── */
7264
7900
  [data-ui="dropdown"] {
@@ -7272,11 +7908,11 @@ div[data-ui="separator"][data-style="thick"]::after {
7272
7908
  align-items: center;
7273
7909
  gap: var(--space-2);
7274
7910
  padding: var(--space-2) var(--space-3);
7275
- border: 1px solid var(--color-border);
7911
+ border: var(--border-width) solid var(--color-border);
7276
7912
  border-radius: var(--radius-md);
7277
7913
  background: var(--color-bg);
7278
7914
  color: var(--color-fg);
7279
- font-family: var(--font-sans, system-ui, sans-serif);
7915
+ font-family: var(--font-ui);
7280
7916
  font-size: var(--text-sm);
7281
7917
  font-weight: var(--weight-medium);
7282
7918
  cursor: pointer;
@@ -7290,8 +7926,8 @@ div[data-ui="separator"][data-style="thick"]::after {
7290
7926
  }
7291
7927
 
7292
7928
  [data-ui="dropdown"] [data-part="trigger"]:focus-visible {
7293
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
7294
- outline-offset: 2px;
7929
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
7930
+ outline-offset: var(--focus-ring-offset);
7295
7931
  }
7296
7932
 
7297
7933
  /* ── Menu ── */
@@ -7303,9 +7939,9 @@ div[data-ui="separator"][data-style="thick"]::after {
7303
7939
  min-width: 180px;
7304
7940
  margin-top: var(--space-1);
7305
7941
  padding: var(--space-1);
7306
- border: 1px solid var(--color-border);
7942
+ border: var(--border-width) solid var(--color-border);
7307
7943
  border-radius: var(--radius-lg);
7308
- background: var(--color-bg);
7944
+ background: var(--panel-bg);
7309
7945
  box-shadow: var(--shadow-md);
7310
7946
  opacity: 0;
7311
7947
  transform: translateY(-4px);
@@ -7313,6 +7949,13 @@ div[data-ui="separator"][data-style="thick"]::after {
7313
7949
  transform var(--duration-fast) var(--ease-out);
7314
7950
  }
7315
7951
 
7952
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
7953
+ [data-ui="dropdown"] [data-part="menu"] {
7954
+ -webkit-backdrop-filter: var(--surface-backdrop);
7955
+ backdrop-filter: var(--surface-backdrop);
7956
+ }
7957
+ }
7958
+
7316
7959
  [data-ui="dropdown"][data-state="open"] [data-part="menu"] {
7317
7960
  opacity: 1;
7318
7961
  transform: translateY(0);
@@ -7335,7 +7978,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7335
7978
  border-radius: var(--radius-md);
7336
7979
  background: transparent;
7337
7980
  color: var(--color-fg);
7338
- font-family: var(--font-sans, system-ui, sans-serif);
7981
+ font-family: var(--font-ui);
7339
7982
  font-size: var(--text-sm);
7340
7983
  text-align: start;
7341
7984
  cursor: pointer;
@@ -7357,12 +8000,12 @@ div[data-ui="separator"][data-style="thick"]::after {
7357
8000
  focus additionally draws the ring, inset so it does not overlap the item
7358
8001
  above. [W3-3] */
7359
8002
  [data-ui="dropdown"] [data-part="item"]:focus-visible {
7360
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
7361
- outline-offset: -2px;
8003
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
8004
+ outline-offset: calc(-1 * var(--focus-ring-offset));
7362
8005
  }
7363
8006
 
7364
8007
  [data-ui="dropdown"] [data-part="item"]:disabled {
7365
- opacity: 0.5;
8008
+ opacity: var(--disabled-opacity);
7366
8009
  cursor: not-allowed;
7367
8010
  pointer-events: none;
7368
8011
  }
@@ -7415,14 +8058,14 @@ div[data-ui="separator"][data-style="thick"]::after {
7415
8058
 
7416
8059
  /* === recipes/file-upload.css === */
7417
8060
  /* @ui:component file-upload */
7418
- /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-border-strong color-primary color-primary-subtle color-ring color-destructive color-destructive-subtle space-px space-1 space-2 space-3 space-4 space-8 radius-md radius-lg text-xs text-sm text-base weight-semibold font-sans duration-fast ease-default */
8061
+ /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-border-strong color-primary color-primary-subtle color-ring color-destructive color-destructive-subtle space-px space-1 space-2 space-3 space-4 space-8 radius-md radius-lg text-xs text-sm text-base weight-semibold font-ui duration-fast ease-default focus-ring-width focus-ring-style focus-ring-color focus-ring-offset border-width disabled-opacity */
7419
8062
 
7420
8063
  [data-ui="file-upload"] {
7421
8064
  display: grid;
7422
8065
  gap: var(--space-4);
7423
8066
  inline-size: 100%;
7424
8067
  color: var(--color-fg);
7425
- font-family: var(--font-sans);
8068
+ font-family: var(--font-ui);
7426
8069
  }
7427
8070
 
7428
8071
  [data-ui="file-upload"] [data-part="dropzone"] {
@@ -7457,14 +8100,14 @@ div[data-ui="separator"][data-style="thick"]::after {
7457
8100
  }
7458
8101
 
7459
8102
  [data-ui="file-upload"]:has([data-part="input"]:focus-visible) [data-part="dropzone"] {
7460
- outline: var(--space-px) solid var(--color-ring);
7461
- outline-offset: var(--space-1);
8103
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
8104
+ outline-offset: var(--focus-ring-offset);
7462
8105
  }
7463
8106
 
7464
8107
  [data-ui="file-upload"][data-state="dragging"] [data-part="dropzone"] {
7465
8108
  border-color: var(--color-primary);
7466
8109
  background: var(--color-primary-subtle);
7467
- box-shadow: 0 0 0 var(--space-px) var(--color-primary);
8110
+ box-shadow: 0 0 0 var(--border-width) var(--color-primary);
7468
8111
  }
7469
8112
 
7470
8113
  [data-ui="file-upload"] [data-part="prompt"] {
@@ -7538,8 +8181,8 @@ div[data-ui="separator"][data-style="thick"]::after {
7538
8181
  }
7539
8182
 
7540
8183
  [data-ui="file-upload"] [data-part="remove"]:focus-visible {
7541
- outline: var(--space-px) solid var(--color-ring);
7542
- outline-offset: var(--space-1);
8184
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
8185
+ outline-offset: var(--focus-ring-offset);
7543
8186
  }
7544
8187
 
7545
8188
  [data-ui="file-upload"] [data-part="empty"] {
@@ -7561,7 +8204,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7561
8204
  }
7562
8205
 
7563
8206
  [data-ui="file-upload"][data-disabled] {
7564
- opacity: 0.5;
8207
+ opacity: var(--disabled-opacity);
7565
8208
  }
7566
8209
 
7567
8210
  [data-ui="file-upload"][data-disabled] [data-part="dropzone"],
@@ -7577,7 +8220,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7577
8220
 
7578
8221
  /* === recipes/input-otp.css === */
7579
8222
  /* @ui:component input-otp */
7580
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-ring color-primary color-destructive radius-md space-2 space-3 text-base text-lg font-sans duration-fast ease-default */
8223
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-ring color-primary color-destructive radius-md space-2 space-3 text-base text-lg font-ui duration-fast ease-default border-width disabled-opacity */
7581
8224
 
7582
8225
  /* ── Root ── */
7583
8226
  [data-ui="input-otp"] {
@@ -7592,7 +8235,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7592
8235
  gutter. The transparent input is `inset: 0`, so it follows the box the
7593
8236
  segments settle into however many rows that takes. */
7594
8237
  max-inline-size: 100%;
7595
- font-family: var(--font-sans, system-ui, sans-serif);
8238
+ font-family: var(--font-ui);
7596
8239
  }
7597
8240
 
7598
8241
  /* ── Real input ──
@@ -7637,14 +8280,14 @@ div[data-ui="separator"][data-style="thick"]::after {
7637
8280
  justify-content: center;
7638
8281
  inline-size: var(--input-otp-segment-size);
7639
8282
  block-size: var(--input-otp-segment-size);
7640
- border: 1px solid var(--color-border);
8283
+ border: var(--border-width) solid var(--color-border);
7641
8284
  border-radius: var(--radius-md);
7642
8285
  background: var(--color-bg);
7643
8286
  color: var(--color-fg);
7644
8287
  font-size: var(--text-lg, 1.125rem);
7645
8288
  font-variant-numeric: tabular-nums;
7646
8289
  line-height: 1;
7647
- transition: border-color var(--duration-fast, 120ms) var(--ease-default, ease),
8290
+ transition: border-color var(--duration-fast) var(--ease-default),
7648
8291
  box-shadow var(--duration-fast, 120ms) var(--ease-default, ease);
7649
8292
  }
7650
8293
 
@@ -7656,7 +8299,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7656
8299
  /* Active (caret / selected) segment while focused */
7657
8300
  [data-ui="input-otp"] [data-part="segment"][data-active] {
7658
8301
  border-color: var(--color-ring);
7659
- box-shadow: 0 0 0 1px var(--color-ring);
8302
+ box-shadow: 0 0 0 var(--border-width) var(--color-ring);
7660
8303
  }
7661
8304
 
7662
8305
  /* Blinking caret in the next-to-fill empty slot */
@@ -7704,7 +8347,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7704
8347
 
7705
8348
  /* ── Disabled ── */
7706
8349
  [data-ui="input-otp"][data-disabled] {
7707
- opacity: 0.5;
8350
+ opacity: var(--disabled-opacity);
7708
8351
  cursor: not-allowed;
7709
8352
  }
7710
8353
  [data-ui="input-otp"][data-disabled] [data-part="input"] {
@@ -7728,7 +8371,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7728
8371
 
7729
8372
  /* === recipes/menubar.css === */
7730
8373
  /* @ui:component menubar */
7731
- /* @ui:tokens color-bg color-border color-fg color-fg-muted color-primary color-primary-subtle color-ring space-px space-1 space-2 space-3 space-4 space-20 radius-md radius-lg shadow-md text-xs text-sm text-base weight-medium duration-fast ease-out z-dropdown font-sans */
8374
+ /* @ui:tokens color-bg color-border color-fg color-fg-muted color-primary color-primary-subtle space-px space-1 space-2 space-3 space-4 space-20 radius-md radius-lg shadow-md text-xs text-sm text-base weight-medium duration-fast ease-out z-dropdown font-ui focus-ring-color focus-ring-width disabled-opacity */
7732
8375
 
7733
8376
  [data-ui="menubar"] {
7734
8377
  position: relative;
@@ -7746,7 +8389,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7746
8389
  border-radius: var(--radius-lg);
7747
8390
  background: var(--color-bg);
7748
8391
  color: var(--color-fg);
7749
- font-family: var(--font-sans);
8392
+ font-family: var(--font-ui);
7750
8393
  }
7751
8394
 
7752
8395
  [data-ui="menubar"] [data-part="group"] {
@@ -7788,7 +8431,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7788
8431
 
7789
8432
  [data-ui="menubar"] [data-part="trigger"]:focus-visible,
7790
8433
  [data-ui="menubar"] [data-part="item"]:focus-visible {
7791
- box-shadow: 0 0 0 calc(var(--space-px) * 2) var(--color-ring);
8434
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
7792
8435
  }
7793
8436
 
7794
8437
  [data-ui="menubar"] [data-part="submenu"] {
@@ -7823,7 +8466,10 @@ div[data-ui="separator"][data-style="thick"]::after {
7823
8466
  [data-ui="menubar"] [role="menuitem"][aria-disabled="true"] {
7824
8467
  color: var(--color-fg-muted);
7825
8468
  cursor: not-allowed;
7826
- opacity: 0.6;
8469
+ /* 0.6 at the 0.5 default — lighter than a control, since the muted colour
8470
+ already carries half the signal — and a theme's `--disabled-opacity` moves
8471
+ it (1.1A-27). */
8472
+ opacity: calc(var(--disabled-opacity) * 1.2);
7827
8473
  }
7828
8474
 
7829
8475
  [data-ui="menubar"] [data-part="separator"] {
@@ -7855,7 +8501,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7855
8501
 
7856
8502
  /* === recipes/pagination.css === */
7857
8503
  /* @ui:component pagination */
7858
- /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-primary color-primary-fg color-border radius-md space-1 space-2 space-3 text-xs text-sm text-base weight-medium duration-fast ease-default */
8504
+ /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-primary color-primary-fg color-border radius-md space-1 space-2 space-3 text-xs text-sm text-base weight-medium duration-fast ease-default font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset disabled-opacity */
7859
8505
 
7860
8506
  /* ── Root ── */
7861
8507
  [data-ui="pagination"] {
@@ -7891,11 +8537,11 @@ div[data-ui="separator"][data-style="thick"]::after {
7891
8537
  min-width: 36px;
7892
8538
  height: 36px;
7893
8539
  padding: 0 var(--space-2);
7894
- border: 1px solid var(--color-border);
8540
+ border: var(--border-width) solid var(--color-border);
7895
8541
  border-radius: var(--radius-md);
7896
8542
  background: var(--color-bg);
7897
8543
  color: var(--color-fg);
7898
- font-family: var(--font-sans, system-ui, sans-serif);
8544
+ font-family: var(--font-ui);
7899
8545
  font-size: var(--text-sm);
7900
8546
  font-weight: var(--weight-medium);
7901
8547
  cursor: pointer;
@@ -7916,8 +8562,8 @@ div[data-ui="separator"][data-style="thick"]::after {
7916
8562
  [data-ui="pagination"] [data-part="page"]:focus-visible,
7917
8563
  [data-ui="pagination"] [data-part="prev"]:focus-visible,
7918
8564
  [data-ui="pagination"] [data-part="next"]:focus-visible {
7919
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
7920
- outline-offset: 2px;
8565
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
8566
+ outline-offset: var(--focus-ring-offset);
7921
8567
  }
7922
8568
 
7923
8569
  /* ── Active page ── */
@@ -7941,7 +8587,7 @@ div[data-ui="separator"][data-style="thick"]::after {
7941
8587
  /* ── Disabled ── */
7942
8588
  [data-ui="pagination"] [data-part="prev"]:disabled,
7943
8589
  [data-ui="pagination"] [data-part="next"]:disabled {
7944
- opacity: 0.5;
8590
+ opacity: var(--disabled-opacity);
7945
8591
  cursor: not-allowed;
7946
8592
  pointer-events: none;
7947
8593
  }
@@ -8011,7 +8657,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8011
8657
 
8012
8658
  /* === recipes/popover.css === */
8013
8659
  /* @ui:component popover */
8014
- /* @ui:tokens color-bg color-fg color-border shadow-md radius-lg space-3 space-4 z-dropdown duration-fast ease-default */
8660
+ /* @ui:tokens color-bg panel-bg color-fg color-border shadow-md radius-lg space-3 space-4 z-dropdown duration-fast ease-default font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset surface-backdrop */
8015
8661
 
8016
8662
  /* ── Root ── */
8017
8663
  [data-ui="popover"] {
@@ -8025,11 +8671,11 @@ div[data-ui="separator"][data-style="thick"]::after {
8025
8671
  align-items: center;
8026
8672
  gap: var(--space-2, 0.5rem);
8027
8673
  padding: var(--space-2, 0.5rem) var(--space-3);
8028
- border: 1px solid var(--color-border);
8674
+ border: var(--border-width) solid var(--color-border);
8029
8675
  border-radius: var(--radius-md, 0.375rem);
8030
8676
  background: var(--color-bg);
8031
8677
  color: var(--color-fg);
8032
- font-family: var(--font-sans, system-ui, sans-serif);
8678
+ font-family: var(--font-ui);
8033
8679
  font-size: var(--text-sm, 0.875rem);
8034
8680
  font-weight: var(--weight-medium, 500);
8035
8681
  cursor: pointer;
@@ -8043,8 +8689,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8043
8689
  }
8044
8690
 
8045
8691
  [data-ui="popover"] [data-part="trigger"]:focus-visible {
8046
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
8047
- outline-offset: 2px;
8692
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
8693
+ outline-offset: var(--focus-ring-offset);
8048
8694
  }
8049
8695
 
8050
8696
  /* ── Content ── */
@@ -8053,9 +8699,9 @@ div[data-ui="separator"][data-style="thick"]::after {
8053
8699
  z-index: var(--z-dropdown);
8054
8700
  min-width: 200px;
8055
8701
  padding: var(--space-4);
8056
- border: 1px solid var(--color-border);
8702
+ border: var(--border-width) solid var(--color-border);
8057
8703
  border-radius: var(--radius-lg);
8058
- background: var(--color-bg);
8704
+ background: var(--panel-bg);
8059
8705
  color: var(--color-fg);
8060
8706
  box-shadow: var(--shadow-md);
8061
8707
  opacity: 0;
@@ -8064,6 +8710,13 @@ div[data-ui="separator"][data-style="thick"]::after {
8064
8710
  transform var(--duration-fast) var(--ease-default);
8065
8711
  }
8066
8712
 
8713
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
8714
+ [data-ui="popover"] [data-part="content"] {
8715
+ -webkit-backdrop-filter: var(--surface-backdrop);
8716
+ backdrop-filter: var(--surface-backdrop);
8717
+ }
8718
+ }
8719
+
8067
8720
  [data-ui="popover"][data-state="open"] [data-part="content"] {
8068
8721
  opacity: 1;
8069
8722
  transform: scale(1);
@@ -8151,8 +8804,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8151
8804
  position: absolute;
8152
8805
  width: 8px;
8153
8806
  height: 8px;
8154
- background: var(--color-bg);
8155
- border: 1px solid var(--color-border);
8807
+ background: var(--panel-bg);
8808
+ border: var(--border-width) solid var(--color-border);
8156
8809
  transform: rotate(45deg);
8157
8810
  }
8158
8811
 
@@ -8253,8 +8906,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8253
8906
  }
8254
8907
 
8255
8908
  [data-ui="popover"] [data-part="close"]:focus-visible {
8256
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
8257
- outline-offset: 2px;
8909
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
8910
+ outline-offset: var(--focus-ring-offset);
8258
8911
  }
8259
8912
 
8260
8913
  /* ── Motion ── */
@@ -8267,7 +8920,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8267
8920
 
8268
8921
  /* === recipes/qr-code.css === */
8269
8922
  /* @ui:component qr-code */
8270
- /* @ui:tokens color-fg color-bg doc-legal-color doc-legal-size doc-font font-sans space-2 */
8923
+ /* @ui:tokens color-fg color-bg doc-legal-color doc-legal-size doc-font font-body space-2 */
8271
8924
 
8272
8925
  /* ── Base ── */
8273
8926
  [data-ui="qr-code"] {
@@ -8285,7 +8938,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8285
8938
 
8286
8939
  /* ── Caption ── */
8287
8940
  [data-ui="qr-code"] [data-part="caption"] {
8288
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
8941
+ font-family: var(--doc-font, var(--font-body));
8289
8942
  font-size: var(--doc-legal-size, var(--text-xs));
8290
8943
  color: var(--doc-legal-color, var(--color-fg-muted));
8291
8944
  text-align: center;
@@ -8326,7 +8979,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8326
8979
 
8327
8980
  /* === recipes/select-custom.css === */
8328
8981
  /* @ui:component select-custom */
8329
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-primary color-primary-subtle color-ring radius-md radius-lg shadow-md space-1 space-2 space-3 space-4 text-sm text-xs z-dropdown duration-fast ease-default */
8982
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-border-strong color-primary color-primary-subtle color-ring radius-md radius-lg shadow-md space-1 space-2 space-3 space-4 text-sm text-xs z-dropdown duration-fast ease-default font-ui border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
8330
8983
 
8331
8984
  /* ── Root ── */
8332
8985
  [data-ui="select-custom"] {
@@ -8343,11 +8996,11 @@ div[data-ui="separator"][data-style="thick"]::after {
8343
8996
  width: 100%;
8344
8997
  min-width: 180px;
8345
8998
  padding: var(--space-2) var(--space-3);
8346
- border: 1px solid var(--color-border);
8999
+ border: var(--border-width) solid var(--color-border);
8347
9000
  border-radius: var(--radius-md);
8348
9001
  background: var(--color-bg);
8349
9002
  color: var(--color-fg);
8350
- font-family: var(--font-sans, system-ui, sans-serif);
9003
+ font-family: var(--font-ui);
8351
9004
  font-size: var(--text-sm);
8352
9005
  cursor: pointer;
8353
9006
  white-space: nowrap;
@@ -8360,8 +9013,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8360
9013
  }
8361
9014
 
8362
9015
  [data-ui="select-custom"] [data-part="trigger"]:focus-visible {
8363
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
8364
- outline-offset: 2px;
9016
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
9017
+ outline-offset: var(--focus-ring-offset);
8365
9018
  }
8366
9019
 
8367
9020
  /* ── Value ── */
@@ -8397,7 +9050,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8397
9050
  z-index: var(--z-dropdown);
8398
9051
  margin-top: var(--space-1);
8399
9052
  padding: var(--space-1);
8400
- border: 1px solid var(--color-border);
9053
+ border: var(--border-width) solid var(--color-border);
8401
9054
  border-radius: var(--radius-lg);
8402
9055
  background: var(--color-bg);
8403
9056
  box-shadow: var(--shadow-md);
@@ -8421,11 +9074,11 @@ div[data-ui="separator"][data-style="thick"]::after {
8421
9074
  padding: var(--space-2) var(--space-3);
8422
9075
  margin-bottom: var(--space-1);
8423
9076
  border: none;
8424
- border-bottom: 1px solid var(--color-border);
9077
+ border-bottom: var(--border-width) solid var(--color-border);
8425
9078
  border-radius: 0;
8426
9079
  background: transparent;
8427
9080
  color: var(--color-fg);
8428
- font-family: var(--font-sans, system-ui, sans-serif);
9081
+ font-family: var(--font-ui);
8429
9082
  font-size: var(--text-sm);
8430
9083
  outline: none;
8431
9084
  }
@@ -8519,7 +9172,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8519
9172
 
8520
9173
  /* === recipes/sheet.css === */
8521
9174
  /* @ui:component sheet */
8522
- /* @ui:tokens color-bg color-fg color-border shadow-xl radius-xl space-4 space-6 z-overlay z-modal duration-normal duration-slow ease-out */
9175
+ /* @ui:tokens color-bg panel-bg color-fg color-border shadow-xl radius-xl space-4 space-6 z-overlay z-modal duration-normal duration-slow ease-out font-heading border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset surface-backdrop */
8523
9176
 
8524
9177
  /* ── Root ── */
8525
9178
  [data-ui="sheet"] {
@@ -8550,11 +9203,18 @@ div[data-ui="separator"][data-style="thick"]::after {
8550
9203
  z-index: var(--z-modal);
8551
9204
  display: flex;
8552
9205
  flex-direction: column;
8553
- background: var(--color-bg);
9206
+ background: var(--panel-bg);
8554
9207
  box-shadow: var(--shadow-xl);
8555
9208
  transition: transform var(--duration-slow) var(--ease-out);
8556
9209
  }
8557
9210
 
9211
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
9212
+ [data-ui="sheet"] [data-part="panel"] {
9213
+ -webkit-backdrop-filter: var(--surface-backdrop);
9214
+ backdrop-filter: var(--surface-backdrop);
9215
+ }
9216
+ }
9217
+
8558
9218
  /* ── Side: Bottom ── */
8559
9219
  [data-ui="sheet"] [data-part="panel"][data-variant="bottom"] {
8560
9220
  bottom: 0;
@@ -8582,7 +9242,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8582
9242
  bottom: 0;
8583
9243
  max-width: 100vw;
8584
9244
  border-radius: 0 var(--radius-xl) var(--radius-xl) 0;
8585
- border-inline-end: 1px solid var(--color-border);
9245
+ border-inline-end: var(--border-width) solid var(--color-border);
8586
9246
  transform: translateX(-100%);
8587
9247
  }
8588
9248
 
@@ -8593,7 +9253,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8593
9253
  bottom: 0;
8594
9254
  max-width: 100vw;
8595
9255
  border-radius: var(--radius-xl) 0 0 var(--radius-xl);
8596
- border-inline-start: 1px solid var(--color-border);
9256
+ border-inline-start: var(--border-width) solid var(--color-border);
8597
9257
  transform: translateX(100%);
8598
9258
  }
8599
9259
 
@@ -8670,6 +9330,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8670
9330
  /* ── Title ── */
8671
9331
  [data-ui="sheet"] [data-part="title"] {
8672
9332
  margin: 0;
9333
+ font-family: var(--font-heading);
8673
9334
  font-size: var(--text-lg, 1.125rem);
8674
9335
  font-weight: var(--weight-semibold, 600);
8675
9336
  color: var(--color-fg);
@@ -8704,8 +9365,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8704
9365
  }
8705
9366
 
8706
9367
  [data-ui="sheet"] [data-part="close"]:not([data-ui]):focus-visible {
8707
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
8708
- outline-offset: 2px;
9368
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
9369
+ outline-offset: var(--focus-ring-offset);
8709
9370
  }
8710
9371
 
8711
9372
  /* ── Body ── */
@@ -8726,7 +9387,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8726
9387
 
8727
9388
  /* === recipes/sidebar.css === */
8728
9389
  /* @ui:component sidebar */
8729
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-primary-subtle color-bg-muted color-ring shadow-xl space-1 space-2 space-3 space-4 radius-md radius-lg z-overlay z-modal text-sm text-lg weight-medium weight-semibold duration-normal duration-slow ease-out ease-default */
9390
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-primary-subtle color-bg-muted color-ring shadow-xl space-1 space-2 space-3 space-4 radius-md radius-lg z-overlay z-modal text-sm text-lg weight-medium weight-semibold duration-normal duration-slow ease-out ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
8730
9391
 
8731
9392
  /* ── Root ──
8732
9393
  The root owns the layout column from `md` up; the panel is the visual surface.
@@ -8770,7 +9431,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8770
9431
  flex-direction: column;
8771
9432
  gap: var(--space-2);
8772
9433
  background: var(--sidebar-bg);
8773
- border-inline-end: 1px solid var(--color-border);
9434
+ border-inline-end: var(--border-width) solid var(--color-border);
8774
9435
  border-start-end-radius: var(--radius-lg, 0.5rem);
8775
9436
  border-end-end-radius: var(--radius-lg, 0.5rem);
8776
9437
  box-shadow: var(--shadow-xl);
@@ -8851,8 +9512,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8851
9512
  }
8852
9513
 
8853
9514
  [data-ui="sidebar"] [data-part="trigger"]:focus-visible {
8854
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
8855
- outline-offset: 2px;
9515
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
9516
+ outline-offset: var(--focus-ring-offset);
8856
9517
  }
8857
9518
 
8858
9519
  /* ── Navigation ── */
@@ -8888,8 +9549,8 @@ div[data-ui="separator"][data-style="thick"]::after {
8888
9549
  }
8889
9550
 
8890
9551
  [data-ui="sidebar"] [data-part="item"]:focus-visible {
8891
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
8892
- outline-offset: -2px;
9552
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
9553
+ outline-offset: calc(-1 * var(--focus-ring-offset));
8893
9554
  }
8894
9555
 
8895
9556
  [data-ui="sidebar"] [data-part="item"][aria-current="page"] {
@@ -8916,7 +9577,7 @@ div[data-ui="separator"][data-style="thick"]::after {
8916
9577
  [data-ui="sidebar"] [data-part="footer"] {
8917
9578
  flex-shrink: 0;
8918
9579
  padding: var(--space-3) var(--space-4);
8919
- border-block-start: 1px solid var(--color-border);
9580
+ border-block-start: var(--border-width) solid var(--color-border);
8920
9581
  }
8921
9582
 
8922
9583
  /* ── Rail (icons only) ── */
@@ -9009,7 +9670,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9009
9670
 
9010
9671
  /* === recipes/slider.css === */
9011
9672
  /* @ui:component slider */
9012
- /* @ui:tokens color-bg color-fg-muted color-border color-primary color-primary-subtle color-ring color-bg-muted space-2 space-3 space-4 radius-full text-sm text-base shadow-sm duration-fast ease-default */
9673
+ /* @ui:tokens color-bg color-fg-muted color-border color-primary color-primary-subtle color-ring color-bg-muted space-2 space-3 space-4 radius-full text-sm text-base shadow-sm duration-fast ease-default font-ui border-width border-width-strong focus-ring-width focus-ring-style focus-ring-color focus-ring-offset disabled-opacity */
9013
9674
 
9014
9675
  /* ── Root ── */
9015
9676
  [data-ui="slider"] {
@@ -9059,28 +9720,28 @@ div[data-ui="separator"][data-style="thick"]::after {
9059
9720
  value in both LTR and RTL (translateX is physical, so -50% always recentres). */
9060
9721
  transform: translate(-50%, -50%);
9061
9722
  background: var(--color-bg, white);
9062
- border: 2px solid var(--color-primary);
9723
+ border: var(--border-width-strong) solid var(--color-primary);
9063
9724
  border-radius: var(--radius-full, 9999px);
9064
- box-shadow: var(--shadow-sm, 0 1px 3px oklch(0 0 0 / 0.1));
9725
+ box-shadow: var(--shadow-sm);
9065
9726
  cursor: grab;
9066
9727
  touch-action: none;
9067
- transition: box-shadow var(--duration-fast, 120ms) var(--ease-default, ease);
9728
+ transition: box-shadow var(--duration-fast) var(--ease-default);
9068
9729
  }
9069
9730
 
9070
9731
  [data-ui="slider"] [data-part="thumb"]:hover {
9071
- box-shadow: var(--shadow-sm, 0 1px 3px oklch(0 0 0 / 0.1)),
9072
- 0 0 0 4px var(--color-primary-subtle, oklch(0.95 0.03 264 / 0.6));
9732
+ box-shadow: var(--shadow-sm),
9733
+ 0 0 0 4px var(--color-primary-subtle);
9073
9734
  }
9074
9735
 
9075
9736
  [data-ui="slider"] [data-part="thumb"]:focus-visible {
9076
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
9077
- outline-offset: 2px;
9737
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
9738
+ outline-offset: var(--focus-ring-offset);
9078
9739
  }
9079
9740
 
9080
9741
  [data-ui="slider"] [data-part="thumb"][data-state="dragging"] {
9081
9742
  cursor: grabbing;
9082
- box-shadow: var(--shadow-sm, 0 1px 3px oklch(0 0 0 / 0.1)),
9083
- 0 0 0 5px var(--color-primary-subtle, oklch(0.95 0.03 264 / 0.6));
9743
+ box-shadow: var(--shadow-sm),
9744
+ 0 0 0 5px var(--color-primary-subtle);
9084
9745
  }
9085
9746
 
9086
9747
  /* ── Value output ── */
@@ -9088,7 +9749,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9088
9749
  flex: 0 0 auto;
9089
9750
  min-inline-size: 3ch;
9090
9751
  color: var(--color-fg-muted);
9091
- font-family: var(--font-sans, system-ui, sans-serif);
9752
+ font-family: var(--font-ui);
9092
9753
  font-size: var(--text-sm);
9093
9754
  font-variant-numeric: tabular-nums;
9094
9755
  text-align: end;
@@ -9107,7 +9768,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9107
9768
 
9108
9769
  /* ── Disabled ── */
9109
9770
  [data-ui="slider"][data-disabled] {
9110
- opacity: 0.5;
9771
+ opacity: var(--disabled-opacity);
9111
9772
  cursor: not-allowed;
9112
9773
  pointer-events: none;
9113
9774
  }
@@ -9125,7 +9786,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9125
9786
  the substitution so the control still reads as "this much, up to here". [W3-3] */
9126
9787
  @media (forced-colors: active) {
9127
9788
  [data-ui="slider"] [data-part="track"] {
9128
- border: 1px solid ButtonText;
9789
+ border: var(--border-width) solid ButtonText;
9129
9790
  }
9130
9791
 
9131
9792
  [data-ui="slider"] [data-part="range"] {
@@ -9136,7 +9797,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9136
9797
  [data-ui="slider"] [data-part="thumb"] {
9137
9798
  forced-color-adjust: none;
9138
9799
  background: ButtonText;
9139
- border: 1px solid ButtonFace;
9800
+ border: var(--border-width) solid ButtonFace;
9140
9801
  }
9141
9802
 
9142
9803
  [data-ui="slider"] [data-part="thumb"]:focus-visible {
@@ -9146,7 +9807,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9146
9807
 
9147
9808
  /* === recipes/table.css === */
9148
9809
  /* @ui:component table */
9149
- /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-fg-subtle color-border color-border-strong color-primary color-primary-subtle color-ring color-destructive color-destructive-subtle space-0h space-1 space-2 space-3 space-4 space-5 space-8 text-xs text-sm weight-semibold weight-bold radius-sm radius-md radius-full duration-fast ease-default doc-table-footer-bg doc-table-footer-weight doc-print-border-color */
9810
+ /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-fg-subtle color-border color-border-strong color-primary color-primary-subtle color-ring color-destructive color-destructive-subtle space-0h space-1 space-2 space-3 space-4 space-5 space-8 text-xs text-sm weight-semibold weight-bold radius-sm radius-md radius-full duration-fast ease-default doc-table-footer-bg doc-table-footer-weight doc-print-border-color font-body border-width border-width-strong focus-ring-width focus-ring-style focus-ring-color focus-ring-offset stripe-bg */
9150
9811
 
9151
9812
  /* ── Root ── */
9152
9813
  [data-ui="table"] {
@@ -9172,7 +9833,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9172
9833
  width: 100%;
9173
9834
  border-collapse: separate;
9174
9835
  border-spacing: 0;
9175
- font-family: var(--font-sans, system-ui, sans-serif);
9836
+ font-family: var(--font-body);
9176
9837
  }
9177
9838
 
9178
9839
  /* Once any column is resized the layout freezes so widths are exact. */
@@ -9194,7 +9855,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9194
9855
  font-weight: var(--weight-semibold);
9195
9856
  color: var(--color-fg-muted);
9196
9857
  background: var(--color-bg);
9197
- border-bottom: 2px solid var(--color-border);
9858
+ border-bottom: var(--border-width-strong) solid var(--color-border);
9198
9859
  white-space: nowrap;
9199
9860
  user-select: none;
9200
9861
  }
@@ -9252,8 +9913,8 @@ div[data-ui="separator"][data-style="thick"]::after {
9252
9913
  /* Keyboard focus on cells (sortable headers + navigable grids). */
9253
9914
  [data-ui="table"] [data-part="th"]:focus-visible,
9254
9915
  [data-ui="table"] [data-part="td"]:focus-visible {
9255
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
9256
- outline-offset: -2px;
9916
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
9917
+ outline-offset: calc(-1 * var(--focus-ring-offset));
9257
9918
  }
9258
9919
 
9259
9920
  /* ── Data Cell ── */
@@ -9261,7 +9922,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9261
9922
  padding: var(--space-3) var(--space-4);
9262
9923
  font-size: var(--text-sm);
9263
9924
  color: var(--color-fg);
9264
- border-bottom: 1px solid var(--color-border);
9925
+ border-bottom: var(--border-width) solid var(--color-border);
9265
9926
  background: var(--color-bg);
9266
9927
  transition: background var(--duration-fast) var(--ease-default);
9267
9928
  }
@@ -9290,31 +9951,31 @@ div[data-ui="separator"][data-style="thick"]::after {
9290
9951
  Static fallback via nth-child; once the controller stamps data-stripe on the
9291
9952
  visible rows (so hidden rows never break the pattern), the stamped rules win. */
9292
9953
  [data-ui="table"][data-variant="striped"] [data-part="tbody"] [data-part="tr"]:not([data-stripe]):nth-child(even):not([data-selected]) [data-part="td"] {
9293
- background: var(--color-bg-subtle, oklch(0.97 0.004 260));
9954
+ background: var(--stripe-bg);
9294
9955
  }
9295
9956
 
9296
9957
  [data-ui="table"][data-variant="striped"] [data-part="tbody"] [data-part="tr"]:not([data-stripe]):nth-child(even):not([data-selected]):hover [data-part="td"] {
9297
- background: var(--color-bg-subtle, oklch(0.95 0.006 260));
9958
+ background: var(--stripe-bg);
9298
9959
  }
9299
9960
 
9300
9961
  [data-ui="table"][data-variant="striped"] [data-part="tbody"] [data-part="tr"][data-stripe="even"]:not([data-selected]) [data-part="td"] {
9301
- background: var(--color-bg-subtle, oklch(0.97 0.004 260));
9962
+ background: var(--stripe-bg);
9302
9963
  }
9303
9964
 
9304
9965
  [data-ui="table"][data-variant="striped"] [data-part="tbody"] [data-part="tr"][data-stripe="even"]:not([data-selected]):hover [data-part="td"] {
9305
- background: var(--color-bg-subtle, oklch(0.95 0.006 260));
9966
+ background: var(--stripe-bg);
9306
9967
  }
9307
9968
 
9308
9969
  /* ── Bordered Variant ── */
9309
9970
  [data-ui="table"][data-variant="bordered"] [data-part="table"] {
9310
- border: 1px solid var(--color-border);
9971
+ border: var(--border-width) solid var(--color-border);
9311
9972
  border-radius: var(--radius-md, 0.375rem);
9312
9973
  overflow: hidden;
9313
9974
  }
9314
9975
 
9315
9976
  [data-ui="table"][data-variant="bordered"] [data-part="th"],
9316
9977
  [data-ui="table"][data-variant="bordered"] [data-part="td"] {
9317
- border: 1px solid var(--color-border);
9978
+ border: var(--border-width) solid var(--color-border);
9318
9979
  }
9319
9980
 
9320
9981
  /* ── Size: Small ── */
@@ -9342,7 +10003,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9342
10003
  /* ── Footer ── */
9343
10004
  [data-ui="table"] [data-part="tfoot"] [data-part="td"] {
9344
10005
  font-weight: var(--doc-table-footer-weight, var(--weight-semibold));
9345
- border-top: 2px solid var(--color-border);
10006
+ border-top: var(--border-width-strong) solid var(--color-border);
9346
10007
  border-bottom: none;
9347
10008
  background: var(--doc-table-footer-bg, var(--color-bg-subtle, oklch(0.97 0.004 260)));
9348
10009
  }
@@ -9468,7 +10129,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9468
10129
  [data-ui="table"] [data-part="filter-row"] [data-part="th"] {
9469
10130
  padding: var(--space-1) var(--space-2);
9470
10131
  background: var(--color-bg);
9471
- border-bottom: 1px solid var(--color-border);
10132
+ border-bottom: var(--border-width) solid var(--color-border);
9472
10133
  }
9473
10134
 
9474
10135
  [data-ui="table"] [data-part="filter-input"],
@@ -9480,14 +10141,14 @@ div[data-ui="separator"][data-style="thick"]::after {
9480
10141
  font-size: var(--text-xs);
9481
10142
  color: var(--color-fg);
9482
10143
  background: var(--color-bg);
9483
- border: 1px solid var(--color-border);
10144
+ border: var(--border-width) solid var(--color-border);
9484
10145
  border-radius: var(--radius-sm);
9485
10146
  }
9486
10147
 
9487
10148
  [data-ui="table"] [data-part="filter-input"]:focus,
9488
10149
  [data-ui="table"] [data-part="filter"]:focus {
9489
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
9490
- outline-offset: -1px;
10150
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
10151
+ outline-offset: calc(-1 * var(--border-width));
9491
10152
  border-color: var(--color-primary);
9492
10153
  }
9493
10154
 
@@ -9508,7 +10169,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9508
10169
  text-align: inherit;
9509
10170
  color: var(--color-fg);
9510
10171
  background: var(--color-bg);
9511
- border: 1px solid var(--color-primary);
10172
+ border: var(--border-width) solid var(--color-primary);
9512
10173
  border-radius: var(--radius-sm);
9513
10174
  outline: none;
9514
10175
  }
@@ -9561,11 +10222,11 @@ div[data-ui="separator"][data-style="thick"]::after {
9561
10222
  }
9562
10223
 
9563
10224
  [data-ui="table"] [data-part="tr"][data-drop-target][data-drop-pos="before"] [data-part="td"] {
9564
- border-block-start: 2px solid var(--color-primary);
10225
+ border-block-start: var(--border-width-strong) solid var(--color-primary);
9565
10226
  }
9566
10227
 
9567
10228
  [data-ui="table"] [data-part="tr"][data-drop-target][data-drop-pos="after"] [data-part="td"] {
9568
- border-block-end: 2px solid var(--color-primary);
10229
+ border-block-end: var(--border-width-strong) solid var(--color-primary);
9569
10230
  }
9570
10231
 
9571
10232
  [data-ui="table"] [data-part="th"][data-dragging] {
@@ -9573,11 +10234,11 @@ div[data-ui="separator"][data-style="thick"]::after {
9573
10234
  }
9574
10235
 
9575
10236
  [data-ui="table"] [data-part="th"][data-drop-target][data-drop-pos="before"] {
9576
- border-inline-start: 2px solid var(--color-primary);
10237
+ border-inline-start: var(--border-width-strong) solid var(--color-primary);
9577
10238
  }
9578
10239
 
9579
10240
  [data-ui="table"] [data-part="th"][data-drop-target][data-drop-pos="after"] {
9580
- border-inline-end: 2px solid var(--color-primary);
10241
+ border-inline-end: var(--border-width-strong) solid var(--color-primary);
9581
10242
  }
9582
10243
 
9583
10244
  /* ── Column Resize Handles (injected by the controller) ── */
@@ -9650,11 +10311,11 @@ div[data-ui="separator"][data-style="thick"]::after {
9650
10311
  }
9651
10312
 
9652
10313
  [data-ui="table"] [data-pin="start"][data-pin-edge] {
9653
- border-inline-end: 1px solid var(--color-border-strong, oklch(0.85 0.006 260));
10314
+ border-inline-end: var(--border-width) solid var(--color-border-strong, oklch(0.85 0.006 260));
9654
10315
  }
9655
10316
 
9656
10317
  [data-ui="table"] [data-pin="end"][data-pin-edge] {
9657
- border-inline-start: 1px solid var(--color-border-strong, oklch(0.85 0.006 260));
10318
+ border-inline-start: var(--border-width) solid var(--color-border-strong, oklch(0.85 0.006 260));
9658
10319
  }
9659
10320
 
9660
10321
  /* ── Column Visibility ── */
@@ -9726,7 +10387,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9726
10387
  [data-ui="table"][data-stacked] [data-part="tfoot"] [data-part="tr"] {
9727
10388
  display: block;
9728
10389
  margin-block-end: var(--space-3);
9729
- border: 1px solid var(--color-border);
10390
+ border: var(--border-width) solid var(--color-border);
9730
10391
  border-radius: var(--radius-md);
9731
10392
  background: var(--color-bg);
9732
10393
  overflow: hidden;
@@ -9740,7 +10401,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9740
10401
  gap: var(--space-4);
9741
10402
  text-align: end;
9742
10403
  border-bottom: none;
9743
- border-block-end: 1px solid var(--color-border);
10404
+ border-block-end: var(--border-width) solid var(--color-border);
9744
10405
  }
9745
10406
 
9746
10407
  [data-ui="table"][data-stacked] [data-part="tr"] [data-part="td"]:last-child,
@@ -9837,7 +10498,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9837
10498
 
9838
10499
  /* === recipes/tabs.css === */
9839
10500
  /* @ui:component tabs */
9840
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-primary-subtle space-1 space-2 space-3 space-4 radius-md radius-lg text-sm text-base weight-medium duration-fast ease-default */
10501
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-primary-subtle space-1 space-2 space-3 space-4 radius-md radius-lg text-sm text-base weight-medium duration-fast ease-default font-ui border-width border-width-strong focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
9841
10502
 
9842
10503
  /* ── Root ── */
9843
10504
  [data-ui="tabs"] {
@@ -9866,7 +10527,7 @@ div[data-ui="separator"][data-style="thick"]::after {
9866
10527
  border: none;
9867
10528
  background: transparent;
9868
10529
  color: var(--color-fg-muted);
9869
- font-family: var(--font-sans, system-ui, sans-serif);
10530
+ font-family: var(--font-ui);
9870
10531
  font-size: var(--text-sm);
9871
10532
  font-weight: var(--weight-medium);
9872
10533
  cursor: pointer;
@@ -9881,8 +10542,8 @@ div[data-ui="separator"][data-style="thick"]::after {
9881
10542
  }
9882
10543
 
9883
10544
  [data-ui="tabs"] [data-part="trigger"]:focus-visible {
9884
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
9885
- outline-offset: -2px;
10545
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
10546
+ outline-offset: calc(-1 * var(--focus-ring-offset));
9886
10547
  border-radius: var(--radius-md);
9887
10548
  }
9888
10549
 
@@ -9892,12 +10553,12 @@ div[data-ui="separator"][data-style="thick"]::after {
9892
10553
 
9893
10554
  /* ── Underline Variant ── */
9894
10555
  [data-ui="tabs"][data-variant="underline"] [data-part="list"] {
9895
- border-bottom: 1px solid var(--color-border);
10556
+ border-bottom: var(--border-width) solid var(--color-border);
9896
10557
  gap: 0;
9897
10558
  }
9898
10559
 
9899
10560
  [data-ui="tabs"][data-variant="underline"] [data-part="trigger"] {
9900
- border-bottom: 2px solid transparent;
10561
+ border-bottom: var(--border-width-strong) solid transparent;
9901
10562
  margin-bottom: -1px;
9902
10563
  border-radius: 0;
9903
10564
  }
@@ -9929,17 +10590,17 @@ div[data-ui="separator"][data-style="thick"]::after {
9929
10590
  [data-ui="tabs"][data-variant="pill"] [data-part="trigger"][aria-selected="true"] {
9930
10591
  background: var(--color-bg);
9931
10592
  color: var(--color-fg);
9932
- box-shadow: var(--shadow-xs, 0 1px 2px oklch(0 0 0 / 0.04));
10593
+ box-shadow: var(--shadow-xs);
9933
10594
  }
9934
10595
 
9935
10596
  /* ── Enclosed Variant ── */
9936
10597
  [data-ui="tabs"][data-variant="enclosed"] [data-part="list"] {
9937
- border-bottom: 1px solid var(--color-border);
10598
+ border-bottom: var(--border-width) solid var(--color-border);
9938
10599
  gap: 0;
9939
10600
  }
9940
10601
 
9941
10602
  [data-ui="tabs"][data-variant="enclosed"] [data-part="trigger"] {
9942
- border: 1px solid transparent;
10603
+ border: var(--border-width) solid transparent;
9943
10604
  border-bottom: none;
9944
10605
  border-radius: var(--radius-md) var(--radius-md) 0 0;
9945
10606
  margin-bottom: -1px;
@@ -9984,8 +10645,8 @@ div[data-ui="separator"][data-style="thick"]::after {
9984
10645
  @media (forced-colors: active) {
9985
10646
  [data-ui="tabs"] [data-part="trigger"][aria-selected="true"] {
9986
10647
  /* An outline the OS preserves, on every variant. */
9987
- outline: 2px solid Highlight;
9988
- outline-offset: -2px;
10648
+ outline: var(--border-width-strong) solid Highlight;
10649
+ outline-offset: calc(-1 * var(--border-width-strong));
9989
10650
  }
9990
10651
 
9991
10652
  [data-ui="tabs"][data-variant="underline"] [data-part="trigger"][aria-selected="true"] {
@@ -10000,7 +10661,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10000
10661
 
10001
10662
  /* === recipes/tag-input.css === */
10002
10663
  /* @ui:component tag-input */
10003
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle color-ring radius-md radius-lg shadow-md space-1 space-1h space-2 space-3 text-sm z-dropdown duration-fast ease-default font-sans */
10664
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary-subtle radius-md radius-lg shadow-md space-1 space-1h space-2 space-3 text-sm z-dropdown duration-fast ease-default font-ui border-width focus-ring-color focus-ring-width */
10004
10665
 
10005
10666
  /* NOTE: the tags themselves are `data-ui="chip"` elements — their styling comes
10006
10667
  entirely from chip.css. This file styles only the field wrapper, the tag row,
@@ -10021,7 +10682,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10021
10682
  gap: var(--space-1h);
10022
10683
  width: 100%;
10023
10684
  padding: var(--space-1h) var(--space-2);
10024
- border: 1px solid var(--color-border);
10685
+ border: var(--border-width) solid var(--color-border);
10025
10686
  border-radius: var(--radius-md);
10026
10687
  background: var(--color-bg);
10027
10688
  list-style: none;
@@ -10030,8 +10691,8 @@ div[data-ui="separator"][data-style="thick"]::after {
10030
10691
  }
10031
10692
 
10032
10693
  [data-ui="tag-input"] [data-part="taglist"]:focus-within {
10033
- border-color: var(--color-ring, oklch(0.55 0.22 264));
10034
- box-shadow: 0 0 0 2px var(--color-ring, oklch(0.55 0.22 264));
10694
+ border-color: var(--focus-ring-color);
10695
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--focus-ring-color);
10035
10696
  }
10036
10697
 
10037
10698
  /* ── Text input: borderless, grows to fill the remaining row space ── */
@@ -10042,7 +10703,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10042
10703
  border: none;
10043
10704
  background: transparent;
10044
10705
  color: var(--color-fg);
10045
- font-family: var(--font-sans, system-ui, sans-serif);
10706
+ font-family: var(--font-ui);
10046
10707
  font-size: var(--text-sm);
10047
10708
  line-height: 1.5;
10048
10709
  outline: none;
@@ -10061,7 +10722,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10061
10722
  z-index: var(--z-dropdown);
10062
10723
  margin-top: var(--space-1);
10063
10724
  padding: var(--space-1);
10064
- border: 1px solid var(--color-border);
10725
+ border: var(--border-width) solid var(--color-border);
10065
10726
  border-radius: var(--radius-lg);
10066
10727
  background: var(--color-bg);
10067
10728
  box-shadow: var(--shadow-md);
@@ -10108,7 +10769,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10108
10769
 
10109
10770
  /* === recipes/toast.css === */
10110
10771
  /* @ui:component toast */
10111
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-success color-destructive color-warning shadow-lg radius-lg space-2 space-3 space-4 text-sm weight-medium z-toast duration-normal duration-slow ease-out */
10772
+ /* @ui:tokens color-bg panel-bg color-fg color-fg-muted color-border color-success color-destructive color-warning shadow-lg radius-lg space-2 space-3 space-4 text-sm weight-medium z-toast duration-normal duration-slow ease-out font-ui border-width border-width-lg focus-ring-width focus-ring-style focus-ring-color focus-ring-offset surface-backdrop */
10112
10773
 
10113
10774
  /* ── Container ── */
10114
10775
  [data-ui="toast"][data-part="container"] {
@@ -10157,8 +10818,8 @@ div[data-ui="separator"][data-style="thick"]::after {
10157
10818
  max-width: 380px;
10158
10819
  width: max-content;
10159
10820
  padding: var(--space-3) var(--space-4);
10160
- background: var(--color-bg);
10161
- border: 1px solid var(--color-border);
10821
+ background: var(--panel-bg);
10822
+ border: var(--border-width) solid var(--color-border);
10162
10823
  border-radius: var(--radius-lg);
10163
10824
  box-shadow: var(--shadow-lg);
10164
10825
  pointer-events: auto;
@@ -10168,6 +10829,13 @@ div[data-ui="separator"][data-style="thick"]::after {
10168
10829
  transform var(--duration-normal) var(--ease-out);
10169
10830
  }
10170
10831
 
10832
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
10833
+ [data-ui="toast"] [data-part="toast"] {
10834
+ -webkit-backdrop-filter: var(--surface-backdrop);
10835
+ backdrop-filter: var(--surface-backdrop);
10836
+ }
10837
+ }
10838
+
10171
10839
  /* ── State: Entering ── */
10172
10840
  [data-ui="toast"][data-variant="top-right"] [data-part="toast"][data-state="entering"],
10173
10841
  [data-ui="toast"][data-variant="top-left"] [data-part="toast"][data-state="entering"] {
@@ -10207,7 +10875,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10207
10875
 
10208
10876
  /* ── Tone Variants ── */
10209
10877
  [data-ui="toast"] [data-part="toast"][data-variant="success"] {
10210
- border-inline-start: 3px solid var(--color-success, oklch(0.55 0.18 145));
10878
+ border-inline-start: var(--border-width-lg) solid var(--color-success, oklch(0.55 0.18 145));
10211
10879
  }
10212
10880
 
10213
10881
  [data-ui="toast"] [data-part="toast"][data-variant="success"] [data-part="icon"] {
@@ -10215,7 +10883,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10215
10883
  }
10216
10884
 
10217
10885
  [data-ui="toast"] [data-part="toast"][data-variant="error"] {
10218
- border-inline-start: 3px solid var(--color-destructive, oklch(0.55 0.22 25));
10886
+ border-inline-start: var(--border-width-lg) solid var(--color-destructive, oklch(0.55 0.22 25));
10219
10887
  }
10220
10888
 
10221
10889
  [data-ui="toast"] [data-part="toast"][data-variant="error"] [data-part="icon"] {
@@ -10223,7 +10891,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10223
10891
  }
10224
10892
 
10225
10893
  [data-ui="toast"] [data-part="toast"][data-variant="warning"] {
10226
- border-inline-start: 3px solid var(--color-warning, oklch(0.7 0.18 85));
10894
+ border-inline-start: var(--border-width-lg) solid var(--color-warning, oklch(0.7 0.18 85));
10227
10895
  }
10228
10896
 
10229
10897
  [data-ui="toast"] [data-part="toast"][data-variant="warning"] [data-part="icon"] {
@@ -10245,7 +10913,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10245
10913
  /* ── Message ── */
10246
10914
  [data-ui="toast"] [data-part="message"] {
10247
10915
  flex: 1;
10248
- font-family: var(--font-sans, system-ui, sans-serif);
10916
+ font-family: var(--font-ui);
10249
10917
  font-size: var(--text-sm);
10250
10918
  font-weight: var(--weight-medium);
10251
10919
  color: var(--color-fg);
@@ -10256,11 +10924,11 @@ div[data-ui="separator"][data-style="thick"]::after {
10256
10924
  [data-ui="toast"] [data-part="action"] {
10257
10925
  flex-shrink: 0;
10258
10926
  padding: var(--space-1, 0.25rem) var(--space-2);
10259
- border: 1px solid var(--color-border);
10927
+ border: var(--border-width) solid var(--color-border);
10260
10928
  border-radius: var(--radius-md, 0.375rem);
10261
10929
  background: transparent;
10262
10930
  color: var(--color-fg);
10263
- font-family: var(--font-sans, system-ui, sans-serif);
10931
+ font-family: var(--font-ui);
10264
10932
  font-size: var(--text-xs, 0.75rem);
10265
10933
  font-weight: var(--weight-medium);
10266
10934
  cursor: pointer;
@@ -10273,8 +10941,8 @@ div[data-ui="separator"][data-style="thick"]::after {
10273
10941
  }
10274
10942
 
10275
10943
  [data-ui="toast"] [data-part="action"]:focus-visible {
10276
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
10277
- outline-offset: 2px;
10944
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
10945
+ outline-offset: var(--focus-ring-offset);
10278
10946
  }
10279
10947
 
10280
10948
  /* ── Close Button ── */
@@ -10300,8 +10968,8 @@ div[data-ui="separator"][data-style="thick"]::after {
10300
10968
  }
10301
10969
 
10302
10970
  [data-ui="toast"] [data-part="close"]:focus-visible {
10303
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
10304
- outline-offset: 2px;
10971
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
10972
+ outline-offset: var(--focus-ring-offset);
10305
10973
  }
10306
10974
 
10307
10975
  /* ── Motion ── */
@@ -10314,14 +10982,14 @@ div[data-ui="separator"][data-style="thick"]::after {
10314
10982
 
10315
10983
  /* === recipes/toggle-group.css === */
10316
10984
  /* @ui:component toggle-group */
10317
- /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-subtle color-ring radius-md space-1 space-1h space-2 space-3 text-sm font-sans weight-medium duration-fast ease-default */
10985
+ /* @ui:tokens color-bg color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-subtle color-ring radius-md space-1 space-1h space-2 space-3 text-sm font-ui weight-medium duration-fast ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset disabled-opacity */
10318
10986
 
10319
10987
  /* ── Root: a segmented row of toggle buttons ── */
10320
10988
  [data-ui="toggle-group"] {
10321
10989
  display: inline-flex;
10322
10990
  gap: var(--space-1);
10323
10991
  padding: var(--space-1);
10324
- border: 1px solid var(--color-border);
10992
+ border: var(--border-width) solid var(--color-border);
10325
10993
  border-radius: var(--radius-md);
10326
10994
  background: var(--color-bg);
10327
10995
  }
@@ -10336,7 +11004,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10336
11004
  border-radius: var(--radius-md);
10337
11005
  background: transparent;
10338
11006
  color: var(--color-fg-muted);
10339
- font-family: var(--toggle-group-font, var(--font-sans));
11007
+ font-family: var(--toggle-group-font, var(--font-ui));
10340
11008
  font-size: var(--text-sm);
10341
11009
  font-weight: var(--weight-medium);
10342
11010
  line-height: 1;
@@ -10377,13 +11045,13 @@ div[data-ui="separator"][data-style="thick"]::after {
10377
11045
 
10378
11046
  /* ── Keyboard focus ring on the item (focus lives on the hidden control) ── */
10379
11047
  [data-ui="toggle-group"] [data-part="item"]:has([data-part="control"]:focus-visible) {
10380
- outline: 2px solid var(--color-ring);
10381
- outline-offset: 2px;
11048
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
11049
+ outline-offset: var(--focus-ring-offset);
10382
11050
  }
10383
11051
 
10384
11052
  /* ── Disabled control ── */
10385
11053
  [data-ui="toggle-group"] [data-part="item"]:has([data-part="control"]:disabled) {
10386
- opacity: 0.5;
11054
+ opacity: var(--disabled-opacity);
10387
11055
  cursor: not-allowed;
10388
11056
  }
10389
11057
 
@@ -10396,7 +11064,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10396
11064
 
10397
11065
  /* === recipes/tooltip.css === */
10398
11066
  /* @ui:component tooltip */
10399
- /* @ui:tokens color-bg color-fg radius-md space-1h space-2 text-xs z-dropdown duration-fast ease-default */
11067
+ /* @ui:tokens color-bg color-fg radius-md space-1h space-2 text-xs z-dropdown duration-fast ease-default font-ui surface-backdrop */
10400
11068
 
10401
11069
  /* ── Root ── */
10402
11070
  [data-ui="tooltip"] {
@@ -10417,7 +11085,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10417
11085
  color: var(--color-bg);
10418
11086
  border-radius: var(--radius-md);
10419
11087
  padding: var(--space-1h, 0.375rem) var(--space-2);
10420
- font-family: var(--font-sans, system-ui, sans-serif);
11088
+ font-family: var(--font-ui);
10421
11089
  font-size: var(--text-xs, 0.75rem);
10422
11090
  line-height: 1.4;
10423
11091
  white-space: nowrap;
@@ -10428,6 +11096,13 @@ div[data-ui="separator"][data-style="thick"]::after {
10428
11096
  transform var(--duration-fast) var(--ease-default);
10429
11097
  }
10430
11098
 
11099
+ @supports ((-webkit-backdrop-filter: blur(1rem)) or (backdrop-filter: blur(1rem))) {
11100
+ [data-ui="tooltip"] [data-part="content"] {
11101
+ -webkit-backdrop-filter: var(--surface-backdrop);
11102
+ backdrop-filter: var(--surface-backdrop);
11103
+ }
11104
+ }
11105
+
10431
11106
  /* Default position (top) when no variant is specified */
10432
11107
  [data-ui="tooltip"]:not([data-variant]) [data-part="content"] {
10433
11108
  bottom: 100%;
@@ -10543,7 +11218,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10543
11218
 
10544
11219
  /* === recipes/tree-view.css === */
10545
11220
  /* @ui:component tree-view */
10546
- /* @ui:tokens color-bg-muted color-fg color-fg-muted color-fg-subtle color-primary color-primary-subtle color-ring space-px space-1 space-2 space-5 radius-md text-sm font-sans weight-medium duration-fast ease-default */
11221
+ /* @ui:tokens color-bg-muted color-fg color-fg-muted color-fg-subtle color-primary color-primary-subtle color-ring space-px space-1 space-2 space-5 radius-md text-sm font-ui weight-medium duration-fast ease-default focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
10547
11222
 
10548
11223
  [data-ui="tree-view"],
10549
11224
  [data-ui="tree-view"] [data-part="group"] {
@@ -10556,7 +11231,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10556
11231
  inline-size: 100%;
10557
11232
  padding: var(--space-1);
10558
11233
  color: var(--color-fg);
10559
- font-family: var(--font-sans);
11234
+ font-family: var(--font-ui);
10560
11235
  font-size: var(--text-sm);
10561
11236
  }
10562
11237
 
@@ -10584,8 +11259,8 @@ div[data-ui="separator"][data-style="thick"]::after {
10584
11259
  }
10585
11260
 
10586
11261
  [data-ui="tree-view"] [data-part="item"]:focus-visible > [data-part="label"] {
10587
- outline: var(--space-px) solid var(--color-ring);
10588
- outline-offset: var(--space-px);
11262
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
11263
+ outline-offset: var(--focus-ring-offset);
10589
11264
  }
10590
11265
 
10591
11266
  [data-ui="tree-view"] [data-part="item"][aria-selected="true"] > [data-part="label"] {
@@ -10624,7 +11299,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10624
11299
 
10625
11300
  /* === patterns/auth-form.css === */
10626
11301
  /* @ui:component auth-form */
10627
- /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-border-strong color-ring color-primary color-primary-hover color-primary-fg color-destructive color-destructive-subtle color-success color-success-subtle radius-lg radius-xl shadow-sm shadow-md space-1 space-2 space-3 space-4 space-5 space-6 space-8 font-sans text-xs text-sm text-base text-lg text-xl text-2xl weight-medium weight-semibold weight-bold leading-tight leading-normal duration-fast duration-normal ease-default */
11302
+ /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-border-strong color-ring color-primary color-primary-hover color-primary-fg color-destructive color-destructive-subtle color-success color-success-subtle radius-lg radius-xl shadow-sm shadow-md space-1 space-2 space-3 space-4 space-5 space-6 space-8 font-heading font-body heading-weight heading-tracking heading-transform heading-caps heading-leading text-xs text-sm text-base text-lg text-xl text-2xl weight-medium weight-semibold weight-bold leading-tight leading-normal duration-fast duration-normal ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset link-decoration */
10628
11303
 
10629
11304
  /* ── Root Container ── */
10630
11305
  [data-ui="auth-form"] {
@@ -10632,7 +11307,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10632
11307
  align-items: center;
10633
11308
  justify-content: center;
10634
11309
  width: 100%;
10635
- font-family: var(--font-sans);
11310
+ font-family: var(--font-body);
10636
11311
  }
10637
11312
 
10638
11313
  /* Mobile-first (task 0.8-09): on a phone the card IS the page — edge to edge,
@@ -10664,9 +11339,13 @@ div[data-ui="separator"][data-style="thick"]::after {
10664
11339
 
10665
11340
  [data-ui="auth-form"] [data-part="title"] {
10666
11341
  margin: 0;
11342
+ font-family: var(--font-heading);
10667
11343
  font-size: var(--text-xl);
10668
- font-weight: var(--weight-bold);
10669
- line-height: var(--leading-tight);
11344
+ font-weight: var(--heading-weight);
11345
+ letter-spacing: var(--heading-tracking);
11346
+ text-transform: var(--heading-transform);
11347
+ font-variant-caps: var(--heading-caps);
11348
+ line-height: var(--heading-leading);
10670
11349
  color: var(--color-fg);
10671
11350
  }
10672
11351
 
@@ -10683,7 +11362,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10683
11362
  margin: var(--space-4) var(--space-6) 0;
10684
11363
  padding: var(--space-3);
10685
11364
  background: var(--color-destructive-subtle);
10686
- border: 1px solid var(--color-destructive);
11365
+ border: var(--border-width) solid var(--color-destructive);
10687
11366
  border-radius: var(--radius-lg);
10688
11367
  color: var(--color-destructive);
10689
11368
  font-size: var(--text-sm);
@@ -10761,13 +11440,13 @@ div[data-ui="separator"][data-style="thick"]::after {
10761
11440
  }
10762
11441
 
10763
11442
  [data-ui="auth-form"] [data-part="footer"] a:hover {
10764
- text-decoration: underline;
11443
+ text-decoration-line: var(--link-decoration);
10765
11444
  color: var(--color-primary-hover);
10766
11445
  }
10767
11446
 
10768
11447
  [data-ui="auth-form"] [data-part="footer"] a:focus-visible {
10769
- outline: 2px solid var(--color-ring);
10770
- outline-offset: 2px;
11448
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
11449
+ outline-offset: var(--focus-ring-offset);
10771
11450
  border-radius: var(--radius-sm, 0.25rem);
10772
11451
  }
10773
11452
 
@@ -10895,8 +11574,8 @@ div[data-ui="separator"][data-style="thick"]::after {
10895
11574
  max-width: var(--auth-form-max-width, 400px);
10896
11575
  border-radius: var(--card-radius, var(--radius-lg));
10897
11576
  box-shadow: var(--card-shadow, var(--shadow-sm));
10898
- border-inline-start: 1px solid var(--card-border, var(--color-border));
10899
- border-inline-end: 1px solid var(--card-border, var(--color-border));
11577
+ border-inline-start: var(--border-width) solid var(--card-border, var(--color-border));
11578
+ border-inline-end: var(--border-width) solid var(--card-border, var(--color-border));
10900
11579
  }
10901
11580
  }
10902
11581
 
@@ -10911,7 +11590,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10911
11590
 
10912
11591
  /* === patterns/crud-table.css === */
10913
11592
  /* @ui:component crud-table */
10914
- /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-fg color-destructive color-destructive-fg radius-md radius-lg shadow-sm space-1 space-2 space-3 space-4 space-6 space-8 font-sans text-sm text-base text-lg weight-medium weight-semibold duration-fast duration-normal ease-default */
11593
+ /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-fg color-destructive color-destructive-fg radius-md radius-lg shadow-sm space-1 space-2 space-3 space-4 space-6 space-8 font-body text-sm text-base text-lg weight-medium weight-semibold duration-fast duration-normal ease-default border-width */
10915
11594
 
10916
11595
  /* ── Root ── */
10917
11596
  [data-ui="crud-table"] {
@@ -10919,7 +11598,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10919
11598
  flex-direction: column;
10920
11599
  gap: var(--space-4);
10921
11600
  width: 100%;
10922
- font-family: var(--font-sans, system-ui, sans-serif);
11601
+ font-family: var(--font-body);
10923
11602
  }
10924
11603
 
10925
11604
  /* ── Toolbar ── */
@@ -10977,7 +11656,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10977
11656
  gap: var(--space-3);
10978
11657
  padding: var(--space-3) var(--space-4);
10979
11658
  background: var(--color-bg-subtle);
10980
- border: 1px solid var(--color-border);
11659
+ border: var(--border-width) solid var(--color-border);
10981
11660
  border-radius: var(--radius-md);
10982
11661
  }
10983
11662
 
@@ -10992,7 +11671,7 @@ div[data-ui="separator"][data-style="thick"]::after {
10992
11671
  [data-ui="crud-table"] [data-part="table-wrapper"] {
10993
11672
  width: 100%;
10994
11673
  overflow-x: auto;
10995
- border: 1px solid var(--color-border);
11674
+ border: var(--border-width) solid var(--color-border);
10996
11675
  border-radius: var(--radius-lg);
10997
11676
  background: var(--color-bg);
10998
11677
  }
@@ -11022,7 +11701,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11022
11701
  padding: var(--space-8) var(--space-4);
11023
11702
  text-align: center;
11024
11703
  min-height: 240px;
11025
- border: 1px dashed var(--color-border);
11704
+ border: var(--border-width) dashed var(--color-border);
11026
11705
  border-radius: var(--radius-lg);
11027
11706
  background: var(--color-bg);
11028
11707
  }
@@ -11135,7 +11814,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11135
11814
 
11136
11815
  /* === patterns/dashboard-shell.css === */
11137
11816
  /* @ui:component dashboard-shell */
11138
- /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-border-strong color-primary color-primary-subtle color-primary-fg space-2 space-3 space-4 space-5 space-6 space-8 space-12 space-16 radius-md radius-lg shadow-sm shadow-md font-sans text-xs text-sm text-base text-lg weight-medium weight-semibold leading-tight leading-normal duration-normal duration-slow ease-default ease-out z-sticky */
11817
+ /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-border-strong color-primary color-primary-subtle color-primary-fg space-2 space-3 space-4 space-5 space-6 space-8 space-12 space-16 radius-md radius-lg shadow-sm shadow-md font-body font-ui text-xs text-sm text-base text-lg weight-medium weight-semibold leading-tight leading-normal duration-normal duration-slow ease-default ease-out z-sticky border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
11139
11818
 
11140
11819
  /* ── Shell Grid Layout ──
11141
11820
  Mobile-first (task 0.8-09): the base is the PHONE shell — one column, header
@@ -11160,7 +11839,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11160
11839
  "footer";
11161
11840
  min-height: 100vh;
11162
11841
  background: var(--color-bg);
11163
- font-family: var(--font-sans);
11842
+ font-family: var(--font-body);
11164
11843
  color: var(--color-fg);
11165
11844
  }
11166
11845
 
@@ -11184,7 +11863,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11184
11863
  gap: var(--space-2);
11185
11864
  padding: var(--space-4);
11186
11865
  background: var(--color-bg-subtle);
11187
- border-inline-end: 1px solid var(--color-border);
11866
+ border-inline-end: var(--border-width) solid var(--color-border);
11188
11867
  overflow-y: auto;
11189
11868
  position: fixed;
11190
11869
  top: 0;
@@ -11204,7 +11883,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11204
11883
 
11205
11884
  [data-ui="dashboard-shell"][data-variant="right"] > [data-part="sidebar"] {
11206
11885
  border-inline-end: none;
11207
- border-inline-start: 1px solid var(--color-border);
11886
+ border-inline-start: var(--border-width) solid var(--color-border);
11208
11887
  inset-inline-start: auto;
11209
11888
  inset-inline-end: 0;
11210
11889
  transform: translateX(100%);
@@ -11279,7 +11958,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11279
11958
  gap: var(--space-3);
11280
11959
  padding: var(--space-2) var(--space-3);
11281
11960
  border-radius: var(--radius-md);
11282
- font-family: var(--font-sans);
11961
+ font-family: var(--font-ui);
11283
11962
  font-size: var(--text-sm);
11284
11963
  font-weight: var(--weight-medium);
11285
11964
  line-height: var(--leading-normal);
@@ -11298,8 +11977,8 @@ div[data-ui="separator"][data-style="thick"]::after {
11298
11977
  }
11299
11978
 
11300
11979
  [data-ui="dashboard-shell"] > [data-part="sidebar"] [data-part="nav-item"]:focus-visible {
11301
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
11302
- outline-offset: -2px;
11980
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
11981
+ outline-offset: calc(-1 * var(--focus-ring-offset));
11303
11982
  }
11304
11983
 
11305
11984
  /* ── Nav Item Active ── */
@@ -11346,7 +12025,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11346
12025
  gap: var(--space-2);
11347
12026
  padding: 0 var(--space-3);
11348
12027
  background: var(--color-bg);
11349
- border-bottom: 1px solid var(--color-border);
12028
+ border-bottom: var(--border-width) solid var(--color-border);
11350
12029
  position: sticky;
11351
12030
  top: 0;
11352
12031
  z-index: var(--z-sticky);
@@ -11427,7 +12106,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11427
12106
  align-items: center;
11428
12107
  gap: var(--space-3);
11429
12108
  padding: var(--space-4) var(--space-6);
11430
- border-top: 1px solid var(--color-border);
12109
+ border-top: var(--border-width) solid var(--color-border);
11431
12110
  font-size: var(--text-xs);
11432
12111
  color: var(--color-fg-muted);
11433
12112
  }
@@ -11510,7 +12189,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11510
12189
 
11511
12190
  /* === patterns/document.css === */
11512
12191
  /* @ui:component document */
11513
- /* @ui:tokens doc-max-width doc-font doc-font-size doc-line-height doc-heading-font doc-heading-weight doc-heading-size doc-subheading-size doc-legal-size doc-legal-color doc-section-gap doc-component-gap doc-running-header-height doc-running-footer-height doc-running-gap doc-bg doc-fg doc-print-border-color doc-table-header-bg doc-table-header-fg doc-table-header-weight doc-table-border doc-table-cell-pad-y doc-table-cell-pad-x doc-table-font-size doc-table-num-font doc-table-footer-bg doc-table-footer-weight doc-table-stripe-bg page-format page-orientation page-margin page-margin-top page-margin-bottom page-margin-left page-margin-right color-bg color-fg color-fg-muted color-border space-4 space-6 space-8 space-12 shadow-lg radius-md font-serif z-raised */
12192
+ /* @ui:tokens doc-max-width doc-font doc-font-size doc-line-height doc-heading-font doc-heading-weight doc-heading-size doc-subheading-size doc-legal-size doc-legal-color doc-section-gap doc-component-gap doc-running-header-height doc-running-footer-height doc-running-gap doc-bg doc-fg doc-print-border-color doc-table-header-bg doc-table-header-fg doc-table-header-weight doc-table-border doc-table-cell-pad-y doc-table-cell-pad-x doc-table-font-size doc-table-num-font doc-table-footer-bg doc-table-footer-weight doc-table-stripe-bg page-format page-orientation page-margin page-margin-top page-margin-bottom page-margin-left page-margin-right color-bg color-fg color-fg-muted color-border space-4 space-6 space-8 space-12 shadow-lg radius-md font-body weight-bold z-raised border-width texture-page */
11514
12193
 
11515
12194
  /* ── Page Rules ── */
11516
12195
  @page {
@@ -11550,14 +12229,17 @@ div[data-ui="separator"][data-style="thick"]::after {
11550
12229
  max-width: var(--doc-max-width);
11551
12230
  margin: var(--space-4) auto;
11552
12231
  padding: var(--space-6) var(--space-4);
11553
- background: var(--color-bg, #fff);
12232
+ background-color: var(--color-bg, #fff);
12233
+ background-image: var(--texture-page);
11554
12234
  color: var(--color-fg);
11555
- font-family: var(--doc-font, var(--font-sans, system-ui, sans-serif));
12235
+ font-family: var(--doc-font, var(--font-body));
11556
12236
  font-size: var(--doc-font-size);
11557
12237
  line-height: var(--doc-line-height);
11558
- box-shadow: var(--shadow-lg,
11559
- 0 10px 15px -3px rgba(0, 0, 0, 0.1),
11560
- 0 4px 6px -4px rgba(0, 0, 0, 0.1));
12238
+ /* The fallback here used to spell out two rgba() layers, which is a shadow
12239
+ colour no theme could reach. --shadow-lg is always defined by the token
12240
+ layer, and it now carries --shadow-color, so the fallback is gone rather
12241
+ than re-tokenised. */
12242
+ box-shadow: var(--shadow-lg);
11561
12243
  border-radius: 0;
11562
12244
  position: relative;
11563
12245
  }
@@ -11573,7 +12255,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11573
12255
  [data-ui="document"] > [data-part="header"] {
11574
12256
  margin-block-end: var(--doc-section-gap);
11575
12257
  padding-block-end: var(--doc-component-gap);
11576
- border-block-end: 1px solid var(--color-border);
12258
+ border-block-end: var(--border-width) solid var(--color-border);
11577
12259
  }
11578
12260
 
11579
12261
  /* ── Body ── */
@@ -11583,13 +12265,25 @@ div[data-ui="separator"][data-style="thick"]::after {
11583
12265
  gap: var(--doc-section-gap);
11584
12266
  }
11585
12267
 
12268
+ /* ── Headings ──
12269
+ The document's own heading face and weight (1.1A-21): a print theme sets
12270
+ --doc-heading-font / --doc-heading-weight to give its titles a voice apart
12271
+ from the body copy (document-serif's Times titles over Georgia text). Both
12272
+ default to the page's heading role in tokens/document.css, and each falls
12273
+ back to what a heading rendered before the tokens had a reader. A heading
12274
+ that carries its own data-weight keeps it — that is the author asking. */
12275
+ [data-ui="document"] :is(h1, h2, h3, h4, h5, h6) {
12276
+ font-family: var(--doc-heading-font, var(--font-body));
12277
+ font-weight: var(--doc-heading-weight, var(--weight-bold));
12278
+ }
12279
+
11586
12280
  /* ── Running footer ──
11587
12281
  footer remains a non-breaking selector alias for pre-1.1.0 documents. */
11588
12282
  [data-ui="document"] > [data-part="doc-footer"],
11589
12283
  [data-ui="document"] > [data-part="footer"] {
11590
12284
  margin-block-start: var(--doc-section-gap);
11591
12285
  padding-block-start: var(--doc-component-gap);
11592
- border-block-start: 1px solid var(--color-border);
12286
+ border-block-start: var(--border-width) solid var(--color-border);
11593
12287
  font-size: var(--doc-legal-size);
11594
12288
  color: var(--doc-legal-color);
11595
12289
  }
@@ -11627,7 +12321,13 @@ div[data-ui="separator"][data-style="thick"]::after {
11627
12321
 
11628
12322
  /* ── Variant: Report ── */
11629
12323
  [data-ui="document"][data-variant="report"] {
11630
- font-family: var(--font-serif, Georgia, "Times New Roman", serif);
12324
+ /* A report is serif-set by definition. It re-points the document's own font
12325
+ ROLE rather than its `font-family`, so every doc primitive nested inside it
12326
+ (key-value, callout, signature — all of which read --doc-font) follows the
12327
+ report into serif instead of staying sans inside a serif page. `report` is
12328
+ the author asking for serif; a theme that wants its own document face
12329
+ declares --doc-font at :root, which this variant deliberately outranks. */
12330
+ --doc-font: Georgia, 'Times New Roman', serif;
11631
12331
  line-height: 1.6;
11632
12332
  }
11633
12333
 
@@ -11722,7 +12422,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11722
12422
  z-index: var(--z-raised);
11723
12423
  margin-block-end: 0;
11724
12424
  padding-block-end: var(--doc-running-gap);
11725
- border-block-end: 1px solid var(--doc-print-border-color);
12425
+ border-block-end: var(--border-width) solid var(--doc-print-border-color);
11726
12426
  background: var(--doc-bg);
11727
12427
  transform: translateZ(0);
11728
12428
  }
@@ -11738,7 +12438,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11738
12438
  z-index: var(--z-raised);
11739
12439
  margin-block-start: 0;
11740
12440
  padding-block-start: var(--doc-running-gap);
11741
- border-block-start: 1px solid var(--doc-print-border-color);
12441
+ border-block-start: var(--border-width) solid var(--doc-print-border-color);
11742
12442
  background: var(--doc-bg);
11743
12443
  transform: translateZ(0);
11744
12444
  }
@@ -11767,7 +12467,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11767
12467
 
11768
12468
  /* === patterns/empty-state.css === */
11769
12469
  /* @ui:component empty-state */
11770
- /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-primary radius-lg shadow-sm space-2 space-3 space-4 space-6 space-8 space-10 font-sans text-sm text-base text-lg text-xl text-2xl weight-semibold leading-tight leading-normal duration-normal ease-default */
12470
+ /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-primary radius-lg shadow-sm space-2 space-3 space-4 space-6 space-8 space-10 font-heading font-body heading-tracking heading-transform heading-caps heading-leading text-sm text-base text-lg text-xl text-2xl weight-semibold leading-tight leading-normal duration-normal ease-default */
11771
12471
 
11772
12472
  /* ── Root ── */
11773
12473
  [data-ui="empty-state"] {
@@ -11778,7 +12478,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11778
12478
  text-align: center;
11779
12479
  padding: var(--space-8) var(--space-6);
11780
12480
  gap: var(--space-3);
11781
- font-family: var(--font-sans, system-ui, sans-serif);
12481
+ font-family: var(--font-body);
11782
12482
  }
11783
12483
 
11784
12484
  /* ── Icon ── */
@@ -11801,10 +12501,13 @@ div[data-ui="separator"][data-style="thick"]::after {
11801
12501
 
11802
12502
  /* ── Title ── */
11803
12503
  [data-ui="empty-state"] [data-part="title"] {
11804
- font-family: var(--font-sans, system-ui, sans-serif);
12504
+ font-family: var(--font-heading);
11805
12505
  font-size: var(--text-lg);
11806
12506
  font-weight: var(--weight-semibold);
11807
- line-height: var(--leading-tight);
12507
+ letter-spacing: var(--heading-tracking);
12508
+ text-transform: var(--heading-transform);
12509
+ font-variant-caps: var(--heading-caps);
12510
+ line-height: var(--heading-leading);
11808
12511
  color: var(--color-fg);
11809
12512
  margin: 0;
11810
12513
  }
@@ -11902,7 +12605,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11902
12605
 
11903
12606
  /* === patterns/feature-grid.css === */
11904
12607
  /* @ui:component feature-grid */
11905
- /* @ui:tokens color-bg color-fg color-fg-muted color-primary color-primary-subtle space-2 space-3 space-4 space-6 space-8 space-10 space-12 space-16 text-base text-lg text-xl text-3xl font-sans weight-semibold weight-bold leading-tight leading-normal leading-relaxed radius-md radius-lg */
12608
+ /* @ui:tokens color-bg color-fg color-fg-muted color-primary color-primary-subtle space-2 space-3 space-4 space-6 space-8 space-10 space-12 space-16 text-base text-lg text-xl text-3xl font-body weight-semibold weight-bold leading-tight leading-normal leading-relaxed radius-md radius-lg */
11906
12609
 
11907
12610
  /* ── Root ──
11908
12611
  Mobile-first (task 0.8-09): everything outside the two `@media` blocks at the
@@ -11912,7 +12615,7 @@ div[data-ui="separator"][data-style="thick"]::after {
11912
12615
  gap: var(--space-4);
11913
12616
  padding-block: var(--space-12);
11914
12617
  padding-inline: var(--space-4);
11915
- font-family: var(--font-sans, system-ui, sans-serif);
12618
+ font-family: var(--font-body);
11916
12619
  color: var(--color-fg);
11917
12620
  background: var(--color-bg);
11918
12621
  }
@@ -12054,7 +12757,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12054
12757
  max-inline-size: var(--measure-narrow);
12055
12758
  margin-inline: auto;
12056
12759
  padding-block: var(--space-8);
12057
- font-family: var(--font-sans);
12760
+ font-family: var(--font-body);
12058
12761
  }
12059
12762
 
12060
12763
  :where(form[l-data]:not([data-ui]) > h1) {
@@ -12074,7 +12777,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12074
12777
 
12075
12778
  /* === patterns/hero.css === */
12076
12779
  /* @ui:component hero */
12077
- /* @ui:tokens color-bg color-fg color-fg-muted space-3 space-4 space-6 space-8 space-12 space-16 space-20 text-sm text-base text-lg text-xl text-3xl text-4xl font-sans weight-bold weight-normal leading-tight leading-relaxed radius-lg */
12780
+ /* @ui:tokens color-bg color-fg color-fg-muted space-3 space-4 space-6 space-8 space-12 space-16 space-20 text-sm text-base text-lg text-xl text-3xl text-4xl font-heading font-body heading-weight heading-tracking heading-transform heading-caps heading-leading weight-bold weight-normal leading-tight leading-relaxed radius-lg texture-surface */
12078
12781
 
12079
12782
  /* ── Root ──
12080
12783
  A one-column grid by default; the layout variants only change how that grid
@@ -12088,9 +12791,10 @@ div[data-ui="separator"][data-style="thick"]::after {
12088
12791
  gap: var(--space-4);
12089
12792
  padding-block: var(--space-12);
12090
12793
  padding-inline: var(--space-4);
12091
- font-family: var(--font-sans, system-ui, sans-serif);
12794
+ font-family: var(--font-body);
12092
12795
  color: var(--color-fg);
12093
- background: var(--color-bg);
12796
+ background-color: var(--color-bg);
12797
+ background-image: var(--texture-surface);
12094
12798
  }
12095
12799
 
12096
12800
  /* ── Eyebrow ── */
@@ -12102,9 +12806,13 @@ div[data-ui="separator"][data-style="thick"]::after {
12102
12806
  /* ── Headline ── */
12103
12807
  [data-ui="hero"] [data-part="headline"] {
12104
12808
  margin: 0;
12809
+ font-family: var(--font-heading);
12105
12810
  font-size: var(--text-3xl);
12106
- font-weight: var(--weight-bold);
12107
- line-height: var(--leading-tight);
12811
+ font-weight: var(--heading-weight);
12812
+ letter-spacing: var(--heading-tracking);
12813
+ text-transform: var(--heading-transform);
12814
+ font-variant-caps: var(--heading-caps);
12815
+ line-height: var(--heading-leading);
12108
12816
  color: var(--color-fg);
12109
12817
  text-wrap: balance;
12110
12818
  }
@@ -12223,7 +12931,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12223
12931
 
12224
12932
  /* === patterns/inbox.css === */
12225
12933
  /* @ui:component inbox */
12226
- /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-destructive color-primary color-primary-subtle color-ring space-1 space-2 space-3 space-4 space-6 space-px font-sans text-xs text-sm text-base text-xl weight-medium weight-semibold leading-tight leading-normal leading-relaxed radius-md radius-lg */
12934
+ /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-destructive color-primary color-primary-subtle color-ring space-1 space-2 space-3 space-4 space-6 space-px font-body text-xs text-sm text-base text-xl weight-medium weight-semibold leading-tight leading-normal leading-relaxed radius-md radius-lg focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
12227
12935
 
12228
12936
  /* ── Root ──
12229
12937
  ONE pane, because that is what a phone has room for. Each pane's `data-state`
@@ -12243,7 +12951,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12243
12951
  overflow: hidden;
12244
12952
  border: var(--space-px, 1px) solid var(--color-border);
12245
12953
  border-radius: var(--radius-lg);
12246
- font-family: var(--font-sans, system-ui, sans-serif);
12954
+ font-family: var(--font-body);
12247
12955
  color: var(--color-fg);
12248
12956
  background: var(--color-bg);
12249
12957
  }
@@ -12335,8 +13043,8 @@ div[data-ui="separator"][data-style="thick"]::after {
12335
13043
  }
12336
13044
 
12337
13045
  [data-ui="inbox"] [data-part="item"]:focus-visible {
12338
- outline: 2px solid var(--color-ring);
12339
- outline-offset: 2px;
13046
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
13047
+ outline-offset: var(--focus-ring-offset);
12340
13048
  }
12341
13049
 
12342
13050
  [data-ui="inbox"] [data-part="item"][data-state="selected"] {
@@ -12495,7 +13203,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12495
13203
 
12496
13204
  /* === patterns/pricing.css === */
12497
13205
  /* @ui:component pricing */
12498
- /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-primary-subtle color-primary-fg space-1 space-2 space-3 space-4 space-6 space-8 space-10 space-12 space-16 text-sm text-base text-lg text-3xl font-sans weight-semibold weight-bold leading-tight leading-normal leading-relaxed radius-lg shadow-md */
13206
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border color-primary color-primary-subtle color-primary-fg space-1 space-2 space-3 space-4 space-6 space-8 space-10 space-12 space-16 text-sm text-base text-lg text-3xl font-heading font-body heading-tracking heading-transform heading-caps heading-leading weight-semibold weight-bold leading-tight leading-normal leading-relaxed radius-lg shadow-md border-width-strong */
12499
13207
 
12500
13208
  /* ── Root ──
12501
13209
  Mobile-first (task 0.8-09): everything outside the two `@media` blocks at the
@@ -12505,7 +13213,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12505
13213
  gap: var(--space-4);
12506
13214
  padding-block: var(--space-12);
12507
13215
  padding-inline: var(--space-4);
12508
- font-family: var(--font-sans, system-ui, sans-serif);
13216
+ font-family: var(--font-body);
12509
13217
  color: var(--color-fg);
12510
13218
  background: var(--color-bg);
12511
13219
  }
@@ -12555,9 +13263,13 @@ div[data-ui="separator"][data-style="thick"]::after {
12555
13263
 
12556
13264
  [data-ui="pricing"] [data-part="tier"] [data-part="title"] {
12557
13265
  margin: 0;
13266
+ font-family: var(--font-heading);
12558
13267
  font-size: var(--text-lg);
12559
13268
  font-weight: var(--weight-semibold);
12560
- line-height: var(--leading-tight);
13269
+ letter-spacing: var(--heading-tracking);
13270
+ text-transform: var(--heading-transform);
13271
+ font-variant-caps: var(--heading-caps);
13272
+ line-height: var(--heading-leading);
12561
13273
  }
12562
13274
 
12563
13275
  [data-ui="pricing"] [data-part="tier"] [data-part="header"] [data-part="description"] {
@@ -12618,7 +13330,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12618
13330
  [data-ui="pricing"] [data-part="tier"][data-state="featured"] {
12619
13331
  border-color: var(--color-primary);
12620
13332
  box-shadow: var(--shadow-md);
12621
- outline: var(--space-px, 1px) solid var(--color-primary);
13333
+ outline: var(--border-width-strong) solid var(--color-primary);
12622
13334
  }
12623
13335
 
12624
13336
  /* ── Footnote ── */
@@ -12663,14 +13375,14 @@ div[data-ui="separator"][data-style="thick"]::after {
12663
13375
 
12664
13376
  /* === patterns/search-results.css === */
12665
13377
  /* @ui:component search-results */
12666
- /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-fg radius-md radius-lg shadow-sm space-1 space-2 space-3 space-4 space-6 space-8 font-sans text-xs text-sm text-base text-lg weight-medium weight-semibold leading-tight leading-normal duration-fast duration-normal ease-default */
13378
+ /* @ui:tokens color-bg color-bg-subtle color-bg-muted color-fg color-fg-muted color-border color-primary color-primary-fg radius-md radius-lg shadow-sm space-1 space-2 space-3 space-4 space-6 space-8 font-body text-xs text-sm text-base text-lg weight-medium weight-semibold leading-tight leading-normal duration-fast duration-normal ease-default border-width focus-ring-width focus-ring-style focus-ring-color focus-ring-offset */
12667
13379
 
12668
13380
  /* ── Root ── */
12669
13381
  [data-ui="search-results"] {
12670
13382
  display: flex;
12671
13383
  flex-direction: column;
12672
13384
  gap: var(--space-4);
12673
- font-family: var(--font-sans, system-ui, sans-serif);
13385
+ font-family: var(--font-body);
12674
13386
  }
12675
13387
 
12676
13388
  /* ── Search Input ── */
@@ -12698,7 +13410,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12698
13410
  justify-content: space-between;
12699
13411
  gap: var(--space-4);
12700
13412
  padding-bottom: var(--space-2);
12701
- border-bottom: 1px solid var(--color-border);
13413
+ border-bottom: var(--border-width) solid var(--color-border);
12702
13414
  }
12703
13415
 
12704
13416
  [data-ui="search-results"] [data-part="results-count"] {
@@ -12733,7 +13445,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12733
13445
  flex-direction: column;
12734
13446
  gap: var(--space-2);
12735
13447
  padding: var(--space-4);
12736
- border: 1px solid var(--color-border);
13448
+ border: var(--border-width) solid var(--color-border);
12737
13449
  border-radius: var(--radius-md);
12738
13450
  background: var(--color-bg);
12739
13451
  transition: background var(--duration-fast) var(--ease-default),
@@ -12792,7 +13504,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12792
13504
  display: flex;
12793
13505
  justify-content: center;
12794
13506
  padding-top: var(--space-4);
12795
- border-top: 1px solid var(--color-border);
13507
+ border-top: var(--border-width) solid var(--color-border);
12796
13508
  }
12797
13509
 
12798
13510
  /* ── Loading ── */
@@ -12832,7 +13544,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12832
13544
 
12833
13545
  /* ── Error State ── */
12834
13546
  [data-ui="search-results"][data-state="error"] [data-part="results-list"] {
12835
- border: 1px solid var(--color-border);
13547
+ border: var(--border-width) solid var(--color-border);
12836
13548
  border-radius: var(--radius-md);
12837
13549
  padding: var(--space-6);
12838
13550
  text-align: center;
@@ -12841,8 +13553,8 @@ div[data-ui="separator"][data-style="thick"]::after {
12841
13553
 
12842
13554
  /* ── Focus management ── */
12843
13555
  [data-ui="search-results"] [data-part="result-item"]:focus-visible {
12844
- outline: 2px solid var(--color-ring, oklch(0.55 0.22 264));
12845
- outline-offset: 2px;
13556
+ outline: var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color);
13557
+ outline-offset: var(--focus-ring-offset);
12846
13558
  }
12847
13559
 
12848
13560
  /* ── Motion ── */
@@ -12858,7 +13570,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12858
13570
 
12859
13571
  /* === patterns/settings-page.css === */
12860
13572
  /* @ui:component settings-page */
12861
- /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-primary color-primary-fg space-1 space-2 space-3 space-4 space-6 space-8 space-10 space-12 space-48 radius-md radius-lg shadow-sm shadow-md font-sans text-sm text-base text-lg text-xl weight-medium weight-semibold leading-tight leading-normal duration-fast duration-normal ease-default z-sticky */
13573
+ /* @ui:tokens color-bg color-bg-subtle color-fg color-fg-muted color-border color-primary color-primary-fg space-1 space-2 space-3 space-4 space-6 space-8 space-10 space-12 space-48 radius-md radius-lg shadow-sm shadow-md font-heading font-body heading-tracking heading-transform heading-caps heading-leading text-sm text-base text-lg text-xl weight-medium weight-semibold leading-tight leading-normal duration-fast duration-normal ease-default z-sticky border-width border-width-strong */
12862
13574
 
12863
13575
  /* ── Root ── */
12864
13576
  [data-ui="settings-page"] {
@@ -12868,7 +13580,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12868
13580
  width: 100%;
12869
13581
  max-width: 768px;
12870
13582
  margin-inline: auto;
12871
- font-family: var(--font-sans, system-ui, sans-serif);
13583
+ font-family: var(--font-body);
12872
13584
  color: var(--color-fg);
12873
13585
  }
12874
13586
 
@@ -12882,9 +13594,13 @@ div[data-ui="separator"][data-style="thick"]::after {
12882
13594
  /* ── Title ── */
12883
13595
  [data-ui="settings-page"] [data-part="title"] {
12884
13596
  margin: 0;
13597
+ font-family: var(--font-heading);
12885
13598
  font-size: var(--text-xl, 1.25rem);
12886
13599
  font-weight: var(--weight-semibold, 600);
12887
- line-height: var(--leading-tight);
13600
+ letter-spacing: var(--heading-tracking);
13601
+ text-transform: var(--heading-transform);
13602
+ font-variant-caps: var(--heading-caps);
13603
+ line-height: var(--heading-leading);
12888
13604
  color: var(--color-fg);
12889
13605
  }
12890
13606
 
@@ -12948,7 +13664,7 @@ div[data-ui="separator"][data-style="thick"]::after {
12948
13664
  gap: var(--space-3, 0.75rem);
12949
13665
  padding: var(--space-4);
12950
13666
  background: var(--color-bg);
12951
- border-top: 1px solid var(--color-border);
13667
+ border-top: var(--border-width) solid var(--color-border);
12952
13668
  border-radius: var(--radius-lg);
12953
13669
  box-shadow: var(--shadow-md);
12954
13670
  position: sticky;
@@ -13012,7 +13728,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13012
13728
  flex-direction: row;
13013
13729
  flex-wrap: wrap;
13014
13730
  border-inline-end: none;
13015
- border-bottom: 1px solid var(--color-border);
13731
+ border-bottom: var(--border-width) solid var(--color-border);
13016
13732
  padding-inline-end: 0;
13017
13733
  position: static;
13018
13734
  }
@@ -13031,7 +13747,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13031
13747
  [data-ui="settings-page"][data-variant="horizontal"] [data-ui="tabs"] [data-part="list"] {
13032
13748
  flex-direction: column;
13033
13749
  border-bottom: none;
13034
- border-inline-end: 1px solid var(--color-border);
13750
+ border-inline-end: var(--border-width) solid var(--color-border);
13035
13751
  padding-inline-end: var(--space-4);
13036
13752
  position: sticky;
13037
13753
  top: var(--space-4);
@@ -13049,7 +13765,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13049
13765
  justify-content: flex-start;
13050
13766
  text-align: start;
13051
13767
  border-bottom: none;
13052
- border-inline-start: 2px solid transparent;
13768
+ border-inline-start: var(--border-width-strong) solid transparent;
13053
13769
  margin-bottom: 0;
13054
13770
  margin-inline-end: -1px;
13055
13771
  padding: var(--space-2) var(--space-3);
@@ -13083,7 +13799,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13083
13799
 
13084
13800
  /* === patterns/site-footer.css === */
13085
13801
  /* @ui:component site-footer */
13086
- /* @ui:tokens color-bg-subtle color-fg color-fg-muted color-border space-1 space-2 space-3 space-4 space-6 space-8 space-10 space-12 text-sm text-base text-lg font-sans weight-semibold weight-bold leading-normal */
13802
+ /* @ui:tokens color-bg-subtle color-fg color-fg-muted color-border space-1 space-2 space-3 space-4 space-6 space-8 space-10 space-12 text-sm text-base text-lg font-body weight-semibold weight-bold leading-normal border-width */
13087
13803
 
13088
13804
  /* ── Root ──
13089
13805
  Mobile-first (task 0.8-09): everything outside the two `@media` blocks at the
@@ -13093,11 +13809,11 @@ div[data-ui="separator"][data-style="thick"]::after {
13093
13809
  gap: var(--space-8);
13094
13810
  padding-block: var(--space-10);
13095
13811
  padding-inline: var(--space-4);
13096
- font-family: var(--font-sans, system-ui, sans-serif);
13812
+ font-family: var(--font-body);
13097
13813
  font-size: var(--text-sm);
13098
13814
  color: var(--color-fg-muted);
13099
13815
  background: var(--color-bg-subtle);
13100
- border-block-start: 1px solid var(--color-border);
13816
+ border-block-start: var(--border-width) solid var(--color-border);
13101
13817
  }
13102
13818
 
13103
13819
  /* ── Brand ── */
@@ -13229,7 +13945,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13229
13945
 
13230
13946
  /* === patterns/stats-dashboard.css === */
13231
13947
  /* @ui:component stats-dashboard */
13232
- /* @ui:tokens color-bg color-fg color-fg-muted color-border space-1 space-2 space-3 space-4 space-6 space-8 space-12 space-px font-sans text-sm text-base text-lg text-3xl weight-semibold weight-bold leading-tight leading-normal leading-relaxed */
13948
+ /* @ui:tokens color-bg color-fg color-fg-muted color-border space-1 space-2 space-3 space-4 space-6 space-8 space-12 space-px font-heading font-body heading-tracking heading-transform heading-caps heading-leading text-sm text-base text-lg text-3xl weight-semibold weight-bold leading-tight leading-normal leading-relaxed */
13233
13949
 
13234
13950
  /* ── Root ──
13235
13951
  A reporting page: title block, KPI row, then the panel region. The KPI row
@@ -13242,7 +13958,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13242
13958
  gap: var(--space-3);
13243
13959
  padding-block: var(--space-8);
13244
13960
  padding-inline: var(--space-4);
13245
- font-family: var(--font-sans, system-ui, sans-serif);
13961
+ font-family: var(--font-body);
13246
13962
  color: var(--color-fg);
13247
13963
  background: var(--color-bg);
13248
13964
  }
@@ -13316,9 +14032,13 @@ div[data-ui="separator"][data-style="thick"]::after {
13316
14032
 
13317
14033
  [data-ui="stats-dashboard"] [data-part="report"] [data-part="title"] {
13318
14034
  margin: 0;
14035
+ font-family: var(--font-heading);
13319
14036
  font-size: var(--text-lg);
13320
14037
  font-weight: var(--weight-semibold);
13321
- line-height: var(--leading-tight);
14038
+ letter-spacing: var(--heading-tracking);
14039
+ text-transform: var(--heading-transform);
14040
+ font-variant-caps: var(--heading-caps);
14041
+ line-height: var(--heading-leading);
13322
14042
  }
13323
14043
 
13324
14044
  [data-ui="stats-dashboard"] [data-part="report"] [data-part="header"] [data-part="description"] {
@@ -13409,7 +14129,7 @@ div[data-ui="separator"][data-style="thick"]::after {
13409
14129
  gap: var(--space-6);
13410
14130
  max-inline-size: var(--measure-narrow);
13411
14131
  margin-inline: auto;
13412
- font-family: var(--font-sans);
14132
+ font-family: var(--font-body);
13413
14133
  }
13414
14134
 
13415
14135
  [data-ui="wizard"] [data-part="heading"] {