Remove the Claude Design round-trip
Deletes script/build_design_bundle.rb, the rake design task, the Claude
Design README section, and the now-unused design-bundle/ gitignore entry.
Not needed — the site itself is the deliverable now.
change
commit e2c2f1d8c491a410d548855ba951f395f39f29d3
author Claude <noreply@anthropic.com>
date
parent 5ee7bb89
diff --git a/.gitignore b/.gitignore
index fc7f745..291ccd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
 _site/
-design-bundle/
 vendor/bundle/
 .bundle/
diff --git a/README.md b/README.md
index 53d06d5..628c138 100644
--- a/README.md
+++ b/README.md
@@ -83,38 +83,6 @@ The site's `BASEURL` is a constant in `lib/build.rb` rather than coming from
 `actions/configure-pages`, which keeps the build independent of the Pages
 API. Change it there if the site ever moves off a project page.
 
-## Claude Design
-
-`rake design` renders the bundle that Claude Design's Design System pane
-wants, into `design-bundle/`:
-
-```console
-$ bundle exec rake design
-```
-
-One card per documentation page — five foundations, sixteen components,
-two patterns — each a standalone HTML file with the compiled tokens and
-component CSS inlined and a first-line `<!-- @dsCard group="…" -->` marker
-for the pane's card index. `design-bundle/css/` carries the two compiled
-stylesheets as well, so the project holds the artifact a consumer would link
-and not only the previews.
-
-The cards are generated from `_site` by `script/build_design_bundle.rb`
-rather than written by hand, for the same reason the docs are: a second copy
-of the system maintained separately starts disagreeing with the first one
-immediately. Rebuild them whenever a token changes.
-
-Pushing the bundle needs `DesignSync`, which requires design-system
-authorization via `/design-login` — an interactive terminal, so it cannot run
-in Claude Code on the web. From a local Claude Code session:
-
-```console
-$ bundle exec rake design
-$ claude   # then: /design-login, and ask it to sync design-bundle/
-```
-
-`design-bundle/` is gitignored; it is a build artifact.
-
 ## Using the CSS elsewhere
 
 Two files, in this order, and almost no JavaScript:
diff --git a/Rakefile b/Rakefile
index b292c78..0dbdb97 100644
--- a/Rakefile
+++ b/Rakefile
@@ -27,9 +27,4 @@ task :serve do
   server.start
 end
 
-desc "Build the Claude Design upload bundle into design-bundle/"
-task design: :build do
-  sh "ruby script/build_design_bundle.rb"
-end
-
 task default: :build
diff --git a/design-bundle/components/badge.html b/design-bundle/components/badge.html
new file mode 100644
index 0000000..39a6c93
--- /dev/null
+++ b/design-bundle/components/badge.html
@@ -0,0 +1,1815 @@
+<!-- @dsCard group="Core" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Badge</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Badge</h1>
+</header>
+<p class="ad-lead">Mono, uppercase, tracked — the catalog-label convention for status and meta values. An archivist's tag, not a badge asking for attention.</p>
+<p>Labels are catalog-style: short, mono, uppercase — <code>SAVED</code>, <code>RECOMMENDED</code>,
+<code>OVERDUE</code>. Never a click handler on one; a Badge is a label, not a button.</p>
+
+<p>A <code>&lt;span&gt;</code> is too generic to style bare — it shows up all over running prose
+for unrelated reasons — so Badge keeps one class. Tone is an attribute, not a
+modifier class.</p>
+
+<h2 id="tones">Tones</h2>
+
+<figure class="example">
+<figcaption>Tones</figcaption>
+<div>
+<span class="badge">Unassigned</span>
+<span class="badge" data-tone="accent">Draft</span>
+<span class="badge" data-tone="success">Saved</span>
+<span class="badge" data-tone="danger">Overdue</span>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;span class=&quot;badge&quot;&gt;Unassigned&lt;/span&gt;
+&lt;span class=&quot;badge&quot; data-tone=&quot;accent&quot;&gt;Draft&lt;/span&gt;
+&lt;span class=&quot;badge&quot; data-tone=&quot;success&quot;&gt;Saved&lt;/span&gt;
+&lt;span class=&quot;badge&quot; data-tone=&quot;danger&quot;&gt;Overdue&lt;/span&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="in-a-set">In a set</h2>
+
+<figure class="example">
+<figcaption>Badge set</figcaption>
+<div>
+<div class="badge-set">
+  <span class="badge" data-tone="accent">Recommended</span>
+  <span class="badge">Every 2 weeks</span>
+  <span class="badge" data-tone="danger">3d overdue</span>
+</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div class=&quot;badge-set&quot;&gt;
+  &lt;span class=&quot;badge&quot; data-tone=&quot;accent&quot;&gt;Recommended&lt;/span&gt;
+  &lt;span class=&quot;badge&quot;&gt;Every 2 weeks&lt;/span&gt;
+  &lt;span class=&quot;badge&quot; data-tone=&quot;danger&quot;&gt;3d overdue&lt;/span&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>A badge is never interactive.</strong> No click handlers, no <code>&lt;button&gt;</code>, no cursor
+change. If it does something, it is a button that happens to be small.</li>
+  <li><strong>Two or three words at most.</strong> A badge that wraps is a sentence in the wrong clothes.</li>
+  <li><strong><code>danger</code> means something needs attention, not that something failed.</strong> The
+source uses it for overdue, not for a system error — that is what prose is for.</li>
+</ul>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>span.badge</code></td><td></td><td>Required base.</td></tr>
+    <tr><td><code>data-tone</code></td><td><code>accent | success | danger</code></td><td>Omit for the default neutral tone.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/button.html b/design-bundle/components/button.html
new file mode 100644
index 0000000..015e413
--- /dev/null
+++ b/design-bundle/components/button.html
@@ -0,0 +1,1913 @@
+<!-- @dsCard group="Core" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Button</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Button</h1>
+</header>
+<p class="ad-lead">A flat, quiet button that recedes rather than performs — no gradients, no shine. Five variants, three sizes, one geometry.</p>
+<h2 id="variants">Variants</h2>
+
+<p><code>default</code> is bordered and neutral. <code>primary</code> is the accent fill — one
+committing action per view, at most. <code>dark</code> is reserved for the single most
+committing action in a screen, typically a final Save; it should be rare.
+<code>ghost</code> has no border or fill, for dismissals and tertiary actions. <code>danger</code>
+is destructive and irreversible only.</p>
+
+<figure class="example">
+<figcaption>Variants</figcaption>
+<div>
+<button>Cancel</button>
+<button data-variant="primary">Save</button>
+<button data-variant="dark">Finish setup</button>
+<button data-variant="ghost">Dismiss</button>
+<button data-variant="danger">Delete</button>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;button&gt;Cancel&lt;/button&gt;
+&lt;button data-variant=&quot;primary&quot;&gt;Save&lt;/button&gt;
+&lt;button data-variant=&quot;dark&quot;&gt;Finish setup&lt;/button&gt;
+&lt;button data-variant=&quot;ghost&quot;&gt;Dismiss&lt;/button&gt;
+&lt;button data-variant=&quot;danger&quot;&gt;Delete&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="sizes">Sizes</h2>
+
+<p>Sizes adjust padding only — the font stays on the type scale, it does not
+grow a step of its own.</p>
+
+<figure class="example">
+<figcaption>Sizes</figcaption>
+<div>
+<button data-variant="primary" data-size="sm">Small</button>
+<button data-variant="primary">Medium</button>
+<button data-variant="primary" data-size="lg">Large</button>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;button data-variant=&quot;primary&quot; data-size=&quot;sm&quot;&gt;Small&lt;/button&gt;
+&lt;button data-variant=&quot;primary&quot;&gt;Medium&lt;/button&gt;
+&lt;button data-variant=&quot;primary&quot; data-size=&quot;lg&quot;&gt;Large&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="states">States</h2>
+
+<p>Disabled buttons drop to 50% opacity and keep their variant colors, so a
+disabled primary still reads as the primary.</p>
+
+<figure class="example">
+<figcaption>States</figcaption>
+<div>
+<button data-variant="primary" disabled="">Disabled</button>
+<button aria-disabled="true">Not yet available</button>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;button data-variant=&quot;primary&quot; disabled=&quot;&quot;&gt;Disabled&lt;/button&gt;
+&lt;button aria-disabled=&quot;true&quot;&gt;Not yet available&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<div class="ad-callout">
+  <p class="type-label" style="margin-bottom: var(--ad-space-2xs); display:block;">disabled vs. aria-disabled</p>
+  <p style="margin:0; font-size: var(--ad-step--1);">
+    A <code>disabled</code> button is removed from the tab order, so a reader
+    navigating by keyboard never learns it is there. When a button is
+    temporarily unavailable and the reason matters, use
+    <code>aria-disabled="true"</code> instead — it stays focusable and can
+    carry an explanation.
+  </p>
+</div>
+
+<h2 id="with-an-icon">With an icon</h2>
+
+<p>Pass an icon as the first child. The gap is <code>--ad-space-2xs</code>, set by the
+button itself.</p>
+
+<figure class="example">
+<figcaption>Icon</figcaption>
+<div>
+<button data-variant="primary">
+  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
+  New
+</button>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;button data-variant=&quot;primary&quot;&gt;
+  &lt;svg width=&quot;14&quot; height=&quot;14&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.9&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M12 5v14M5 12h14&quot; /&gt;&lt;/svg&gt;
+  New
+&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="groups">Groups</h2>
+
+<p><code>[role="group"]</code> is already the correct ARIA role for a toolbar of related
+buttons, so it doubles as the styling hook — no wrapper class.</p>
+
+<figure class="example">
+<figcaption>Button group</figcaption>
+<div>
+<div role="group" aria-label="View">
+  <button data-size="sm">List</button>
+  <button data-size="sm">Board</button>
+  <button data-size="sm">Calendar</button>
+</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div role=&quot;group&quot; aria-label=&quot;View&quot;&gt;
+  &lt;button data-size=&quot;sm&quot;&gt;List&lt;/button&gt;
+  &lt;button data-size=&quot;sm&quot;&gt;Board&lt;/button&gt;
+  &lt;button data-size=&quot;sm&quot;&gt;Calendar&lt;/button&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="full-width">Full width</h2>
+
+<figure class="example">
+<figcaption>Block</figcaption>
+<div data-layout="stack">
+<button data-variant="primary" data-block="">Take a photo</button>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;button data-variant=&quot;primary&quot; data-block&gt;Take a photo&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="links-that-act-like-buttons">Links that act like buttons</h2>
+
+<p>An <code>&lt;a&gt;</code> with <code>.btn</code> is fine when the thing it does is navigate. A <code>&lt;button&gt;</code>
+is required when it changes something. <code>.btn</code> exists only because a bare <code>a</code>
+selector would catch every ordinary prose link on the site — it is the one
+class Button needs, and only anchors reach for it.</p>
+
+<figure class="example">
+<figcaption>Anchor as button</figcaption>
+<div>
+<a class="btn" data-variant="primary" href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/icon-button/">Next: IconButton</a>
+<a class="btn" data-variant="ghost" href="https://kejadlen.github.io/arbitrary-definitions-design-system/foundations/color/">Back to color</a>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;a class=&quot;btn&quot; data-variant=&quot;primary&quot; href=&quot;/arbitrary-definitions-design-system/components/icon-button/&quot;&gt;Next: IconButton&lt;/a&gt;
+&lt;a class=&quot;btn&quot; data-variant=&quot;ghost&quot; href=&quot;/arbitrary-definitions-design-system/foundations/color/&quot;&gt;Back to color&lt;/a&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>button</code></td><td></td><td>Required base. A bare <code>&lt;button&gt;</code> is styled directly — no class. Use <code>&lt;a class="btn"&gt;</code> instead when the control navigates.</td></tr>
+    <tr><td><code>data-variant</code></td><td><code>primary | dark | ghost | danger</code></td><td>Omit for the default, bordered look.</td></tr>
+    <tr><td><code>data-size</code></td><td><code>sm | lg</code></td><td>Omit for the default (medium) size. Padding only.</td></tr>
+    <tr><td><code>data-block</code></td><td>boolean</td><td>Full width of its container.</td></tr>
+    <tr><td><code>disabled</code></td><td>boolean</td><td>Removes the button from the tab order.</td></tr>
+    <tr><td><code>aria-disabled</code></td><td><code>"true"</code></td><td>Looks disabled, stays focusable.</td></tr>
+    <tr><td><code>[role="group"]</code></td><td></td><td>Wrap adjacent buttons in a group to join their borders and radii.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/card-row.html b/design-bundle/components/card-row.html
new file mode 100644
index 0000000..b7b2b77
--- /dev/null
+++ b/design-bundle/components/card-row.html
@@ -0,0 +1,1845 @@
+<!-- @dsCard group="Core" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>CardRow</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>CardRow</h1>
+</header>
+<p class="ad-lead">A hairline-divided list row for use inside Card — entry lists, task lists, settings rows. The first row's top border removes itself automatically.</p>
+<p>CardRow is a bare <code>&lt;li&gt;</code> inside a <code>&lt;ul class="card"&gt;</code> — the divider styling
+comes entirely from the <code>.card &gt; li</code> descendant selector, so there is no
+class of CardRow’s own.</p>
+
+<h2 id="basic">Basic</h2>
+
+<figure class="example">
+<figcaption>Rows</figcaption>
+<div>
+<ul class="card" style="max-width: 22rem;">
+  <li>Renew passport</li>
+  <li>Dentist checkup</li>
+  <li>Rotate mattress</li>
+</ul>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;ul class=&quot;card&quot; style=&quot;max-width: 22rem;&quot;&gt;
+  &lt;li&gt;Renew passport&lt;/li&gt;
+  &lt;li&gt;Dentist checkup&lt;/li&gt;
+  &lt;li&gt;Rotate mattress&lt;/li&gt;
+&lt;/ul&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="clickable">Clickable</h2>
+
+<p>Wrap the row’s content in a real <code>&lt;button&gt;</code> or <code>&lt;a&gt;</code> when the row navigates
+or opens something — an accessible clickable row, not a <code>&lt;li&gt;</code> with a click
+handler and no keyboard support. It fills the row edge-to-edge and picks up
+a hover fill on its own; no <code>--clickable</code> modifier to remember.</p>
+
+<figure class="example">
+<figcaption>Clickable rows</figcaption>
+<div>
+<ul class="card" style="max-width: 22rem;">
+  <li><button>Tax return 2025.pdf</button></li>
+  <li><button>Warranty card.pdf</button></li>
+</ul>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;ul class=&quot;card&quot; style=&quot;max-width: 22rem;&quot;&gt;
+  &lt;li&gt;&lt;button&gt;Tax return 2025.pdf&lt;/button&gt;&lt;/li&gt;
+  &lt;li&gt;&lt;button&gt;Warranty card.pdf&lt;/button&gt;&lt;/li&gt;
+&lt;/ul&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="with-content-on-both-ends">With content on both ends</h2>
+
+<p>The row is a flex container — a leading icon, a two-line middle column, and a
+trailing mono value is the most common shape (see the Loop and Archive
+patterns for it in context).</p>
+
+<figure class="example">
+<figcaption>Leading icon, trailing meta</figcaption>
+<div>
+<ul class="card" style="max-width: 24rem;">
+  <li>
+    <span class="avatar" data-square="">
+      <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg>
+    </span>
+    <div style="flex:1; min-width:0;">
+      <div style="font-weight: 550;">Dishwasher manual</div>
+      <div class="type-label" style="margin-top: 2px;">PDF · 2.1MB</div>
+    </div>
+    <span class="type-mono" style="color: var(--ad-color-text-tertiary);">2h</span>
+  </li>
+</ul>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;ul class=&quot;card&quot; style=&quot;max-width: 24rem;&quot;&gt;
+  &lt;li&gt;
+    &lt;span class=&quot;avatar&quot; data-square&gt;
+      &lt;svg width=&quot;17&quot; height=&quot;17&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.75&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M21 8 12 3 3 8v8l9 5 9-5V8Z&quot; /&gt;&lt;path d=&quot;M3 8l9 5 9-5M12 13v8&quot; /&gt;&lt;/svg&gt;
+    &lt;/span&gt;
+    &lt;div style=&quot;flex:1; min-width:0;&quot;&gt;
+      &lt;div style=&quot;font-weight: 550;&quot;&gt;Dishwasher manual&lt;/div&gt;
+      &lt;div class=&quot;type-label&quot; style=&quot;margin-top: 2px;&quot;&gt;PDF · 2.1MB&lt;/div&gt;
+    &lt;/div&gt;
+    &lt;span class=&quot;type-mono&quot; style=&quot;color: var(--ad-color-text-tertiary);&quot;&gt;2h&lt;/span&gt;
+  &lt;/li&gt;
+&lt;/ul&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>li</code></td><td></td><td>Required — a direct child of <code>ul.card</code>. No class of its own.</td></tr>
+    <tr><td><code>li &gt; button</code> / <code>li &gt; a</code></td><td></td><td>Wrap the row's content to make it clickable, in place of an <code>onClick</code> prop.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/card.html b/design-bundle/components/card.html
new file mode 100644
index 0000000..cfb0e1e
--- /dev/null
+++ b/design-bundle/components/card.html
@@ -0,0 +1,1841 @@
+<!-- @dsCard group="Core" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Card</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Card</h1>
+</header>
+<p class="ad-lead">Flat surface, hairline border, radius-lg. Elevation is opt-in, reserved for the one focused card in a view — a dialog, the primary capture card.</p>
+<p>A <code>&lt;div&gt;</code>/<code>&lt;article&gt;</code> is too generic to style bare, so Card keeps one
+sanctioned class. <code>[data-elevated]</code> is for the single most-elevated element on
+screen — never a whole grid of cards at once.</p>
+
+<h2 id="flat-vs-elevated">Flat vs. elevated</h2>
+
+<figure class="example">
+<figcaption>Flat and elevated</figcaption>
+<div data-surface="sunken">
+<div class="card" style="width: 14rem; padding: var(--ad-space-s);">Flat — the default.</div>
+<div class="card" data-elevated="" style="width: 14rem; padding: var(--ad-space-s);">Elevated — one per view.</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div class=&quot;card&quot; style=&quot;width: 14rem; padding: var(--ad-space-s);&quot;&gt;Flat — the default.&lt;/div&gt;
+&lt;div class=&quot;card&quot; data-elevated style=&quot;width: 14rem; padding: var(--ad-space-s);&quot;&gt;Elevated — one per view.&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="as-a-content-tile">As a content tile</h2>
+
+<p>Used standalone (not as a row-list), <code>.card</code> is fine on its own — <code>.card-body</code>
+and <code>.card-footer</code> are two more sanctioned classes, for the one shape inside
+it that has no element of its own to hang a selector on.</p>
+
+<figure class="example">
+<figcaption>Content tile</figcaption>
+<div>
+<article class="card" style="max-width: 18rem;">
+  <div class="card-body">
+    <p class="type-label" style="margin:0;">Recommended</p>
+    <h3 style="margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);">Rename the caution color</h3>
+    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">Three people have called it "yellow" in review this month.</p>
+  </div>
+  <div class="card-footer">
+    <button data-variant="primary" data-size="sm">Approve</button>
+    <button data-variant="ghost" data-size="sm">Dismiss</button>
+  </div>
+</article>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;article class=&quot;card&quot; style=&quot;max-width: 18rem;&quot;&gt;
+  &lt;div class=&quot;card-body&quot;&gt;
+    &lt;p class=&quot;type-label&quot; style=&quot;margin:0;&quot;&gt;Recommended&lt;/p&gt;
+    &lt;h3 style=&quot;margin:0; font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans);&quot;&gt;Rename the caution color&lt;/h3&gt;
+    &lt;p style=&quot;margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);&quot;&gt;Three people have called it &quot;yellow&quot; in review this month.&lt;/p&gt;
+  &lt;/div&gt;
+  &lt;div class=&quot;card-footer&quot;&gt;
+    &lt;button data-variant=&quot;primary&quot; data-size=&quot;sm&quot;&gt;Approve&lt;/button&gt;
+    &lt;button data-variant=&quot;ghost&quot; data-size=&quot;sm&quot;&gt;Dismiss&lt;/button&gt;
+  &lt;/div&gt;
+&lt;/article&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="as-a-list--with-cardrow">As a list — with CardRow</h2>
+
+<p>Card’s most common job in this system is holding a list of
+<a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/card-row/">CardRow</a>s: entry lists, task
+lists, settings rows. In that shape Card is a real <code>&lt;ul class="card"&gt;</code> and
+CardRow is a bare <code>&lt;li&gt;</code> — the divider between rows comes from the <code>.card &gt;
+li</code> descendant selector, no second class needed.</p>
+
+<figure class="example">
+<figcaption>Card of rows</figcaption>
+<div>
+<ul class="card" style="max-width: 22rem;">
+  <li>Dishwasher manual</li>
+  <li>Sofa receipt</li>
+  <li>Passport scan</li>
+</ul>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;ul class=&quot;card&quot; style=&quot;max-width: 22rem;&quot;&gt;
+  &lt;li&gt;Dishwasher manual&lt;/li&gt;
+  &lt;li&gt;Sofa receipt&lt;/li&gt;
+  &lt;li&gt;Passport scan&lt;/li&gt;
+&lt;/ul&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>.card</code></td><td></td><td>Required base, on a <code>&lt;div&gt;</code>/<code>&lt;article&gt;</code> for a standalone tile or a <code>&lt;ul&gt;</code> for a list of rows.</td></tr>
+    <tr><td><code>data-elevated</code></td><td>boolean</td><td>Applies <code>--ad-shadow-float</code>. One per view.</td></tr>
+    <tr><td><code>&gt; li</code></td><td></td><td>A CardRow, when Card is a <code>&lt;ul&gt;</code>. See <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/card-row/">CardRow</a>.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/checkbox.html b/design-bundle/components/checkbox.html
new file mode 100644
index 0000000..7701288
--- /dev/null
+++ b/design-bundle/components/checkbox.html
@@ -0,0 +1,1847 @@
+<!-- @dsCard group="Forms" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Checkbox</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Checkbox</h1>
+</header>
+<p class="ad-lead">Native checkbox, tinted with the accent color. No hand-drawn box.</p>
+<h2 id="basic">Basic</h2>
+
+<p><code>input[type="checkbox"]</code> is the component — styled bare with <code>accent-color</code>
+rather than a custom box, so the browser draws its own check. This is a real
+reduction, not just a rename: it deletes the hand-drawn SVG-checkmark markup
+that a <code>.ad-choice__box</code> span used to need. The wrapping <code>&lt;label&gt;</code> is told
+apart from Field’s label structurally — it <code>:has()</code> a checkbox as a direct
+child — so it needs no class either.</p>
+
+<figure class="example">
+<figcaption>Checkbox</figcaption>
+<div>
+<label>
+  <input type="checkbox" />
+  Notify me
+</label>
+<label>
+  <input type="checkbox" checked="" />
+  Ship on merge
+</label>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;label&gt;
+  &lt;input type=&quot;checkbox&quot; /&gt;
+  Notify me
+&lt;/label&gt;
+&lt;label&gt;
+  &lt;input type=&quot;checkbox&quot; checked=&quot;&quot; /&gt;
+  Ship on merge
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="disabled">Disabled</h2>
+
+<figure class="example">
+<figcaption>Disabled</figcaption>
+<div>
+<label>
+  <input type="checkbox" disabled="" />
+  Not available on this plan
+</label>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;label&gt;
+  &lt;input type=&quot;checkbox&quot; disabled=&quot;&quot; /&gt;
+  Not available on this plan
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="in-a-fieldset">In a fieldset</h2>
+
+<p><code>&lt;fieldset&gt;</code>/<code>&lt;legend&gt;</code> are styled bare too — they already mean this.</p>
+
+<figure class="example">
+<figcaption>Fieldset</figcaption>
+<div>
+<fieldset>
+  <legend>Notify me about</legend>
+  <label>
+    <input type="checkbox" checked="" />
+    Overdue tasks
+  </label>
+  <label>
+    <input type="checkbox" />
+    Weekly digest
+  </label>
+</fieldset>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;fieldset&gt;
+  &lt;legend&gt;Notify me about&lt;/legend&gt;
+  &lt;label&gt;
+    &lt;input type=&quot;checkbox&quot; checked=&quot;&quot; /&gt;
+    Overdue tasks
+  &lt;/label&gt;
+  &lt;label&gt;
+    &lt;input type=&quot;checkbox&quot; /&gt;
+    Weekly digest
+  &lt;/label&gt;
+&lt;/fieldset&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>input[type="checkbox"]</code></td><td></td><td>Required base — no class. Tinted with <code>accent-color</code>.</td></tr>
+    <tr><td><code>checked</code></td><td>boolean</td><td></td></tr>
+    <tr><td><code>disabled</code></td><td>boolean</td><td></td></tr>
+    <tr><td><code>label</code></td><td>text content</td><td>Wrap the input directly — <code>label:has(&gt; input[type="checkbox"])</code> is what applies the row layout.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/dialog.html b/design-bundle/components/dialog.html
new file mode 100644
index 0000000..24b57cd
--- /dev/null
+++ b/design-bundle/components/dialog.html
@@ -0,0 +1,1825 @@
+<!-- @dsCard group="Feedback" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Dialog</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Dialog</h1>
+</header>
+<p class="ad-lead">A centered modal. Flat surface, no colored header, hairline dividers between title, body, and footer.</p>
+<p>Dialog is the native <code>&lt;dialog&gt;</code> element: a <code>&lt;header&gt;</code> for the title, a
+<code>&lt;footer&gt;</code> for the button row, and everything else in between is the body —
+no wrapper classes at all.</p>
+
+<p>The example below is shown with a plain <code>open</code> attribute, scoped to its own
+preview box rather than the real viewport-covering overlay, so it renders
+without JavaScript and can sit safely inside a documentation page. It
+centers itself using the browser’s own default <code>&lt;dialog&gt;</code> styling
+(<code>position: absolute; inset: 0; margin: auto</code>) against the preview box,
+which is why it needs that box to be <code>position: relative</code>. Call
+<code>.showModal()</code> in the consuming app for the real fixed-overlay behavior —
+a plain <code>open</code> attribute never paints a <code>::backdrop</code>, since that
+pseudo-element only exists for a dialog shown modally.</p>
+
+<figure class="example">
+<figcaption>Dialog</figcaption>
+<div data-layout="stack">
+<div class="dialog-demo">
+  <dialog open="">
+    <header>Delete series?</header>
+    <p>This removes all of its task history. This cannot be undone.</p>
+    <footer>
+      <button>Cancel</button>
+      <button data-variant="danger">Delete</button>
+    </footer>
+  </dialog>
+</div>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;dialog open&gt;
+  &lt;header&gt;Delete series?&lt;/header&gt;
+  &lt;p&gt;This removes all of its task history. This cannot be undone.&lt;/p&gt;
+  &lt;footer&gt;
+    &lt;button&gt;Cancel&lt;/button&gt;
+    &lt;button data-variant=&quot;danger&quot;&gt;Delete&lt;/button&gt;
+  &lt;/footer&gt;
+&lt;/dialog&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="without-a-footer">Without a footer</h2>
+
+<p>A body-only dialog for a notice rather than a decision.</p>
+
+<figure class="example">
+<figcaption>No footer</figcaption>
+<div data-layout="stack">
+<div class="dialog-demo" style="min-height: 14rem;">
+  <dialog open="" style="width: 20rem;">
+    <header>Backup complete</header>
+    <p>412 files, 1.2GB, archived to the household drive.</p>
+  </dialog>
+</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;dialog open style=&quot;width: 20rem;&quot;&gt;
+  &lt;header&gt;Backup complete&lt;/header&gt;
+  &lt;p&gt;412 files, 1.2GB, archived to the household drive.&lt;/p&gt;
+&lt;/dialog&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>dialog</code></td><td></td><td>Required base. Call <code>.showModal()</code> to open it for real — a plain <code>open</code> attribute is for static, always-open documentation only.</td></tr>
+    <tr><td><code>dialog &gt; header</code></td><td></td><td>Optional — a body-only dialog omits it.</td></tr>
+    <tr><td><code>dialog &gt; footer</code></td><td></td><td>Optional. Usually a pair of Buttons — the least committing action first.</td></tr>
+    <tr><td><code>dialog::backdrop</code></td><td></td><td>The dimmed overlay. Only renders once the dialog is shown via <code>.showModal()</code>.</td></tr>
+    <tr><td><code>close</code> event</td><td></td><td>Fired on cancel — wire it, or a form's <code>method="dialog"</code>, instead of an <code>onClose</code> prop.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/field.html b/design-bundle/components/field.html
new file mode 100644
index 0000000..4d44b8e
--- /dev/null
+++ b/design-bundle/components/field.html
@@ -0,0 +1,1861 @@
+<!-- @dsCard group="Forms" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Field</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Field</h1>
+</header>
+<p class="ad-lead">The labeled field wrapper. Mono, uppercase, tracked label — the same catalog-label convention as Badge and type-label — with an optional hint.</p>
+<h2 id="basic">Basic</h2>
+
+<p>Field is a <code>&lt;label&gt;</code> that wraps its caption text together with the control —
+association is native, no <code>for</code>/<code>id</code> pair to keep in sync. A <code>&lt;label&gt;</code> plays
+three different roles in this system (this wrapper, Checkbox/Radio’s row,
+Switch’s row), so it cannot be styled bare without one leaking into another;
+<code>.field</code> is the one of the three with no distinguishing attribute, so it is
+the one that keeps a class. Hint text is a native <code>&lt;small&gt;</code>.</p>
+
+<figure class="example">
+<figcaption>Field</figcaption>
+<div>
+<label class="field" style="max-width: 20rem;">
+  Name
+  <input type="text" placeholder="Call Mom" />
+  <small>First line becomes the display name.</small>
+</label>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;label class=&quot;field&quot; style=&quot;max-width: 20rem;&quot;&gt;
+  Name
+  &lt;input type=&quot;text&quot; placeholder=&quot;Call Mom&quot; /&gt;
+  &lt;small&gt;First line becomes the display name.&lt;/small&gt;
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="holding-any-control">Holding any control</h2>
+
+<p>Field wraps <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/input/">Input</a>,
+<a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/select/">Select</a>, or anything else — it
+only owns the caption and the hint line, never the control’s own styling.</p>
+
+<figure class="example">
+<figcaption>Field with a select</figcaption>
+<div>
+<label class="field" style="max-width: 20rem;">
+  Unit
+  <select>
+    <option>Day</option>
+    <option selected="">Week</option>
+    <option>Month</option>
+    <option>Year</option>
+  </select>
+</label>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;label class=&quot;field&quot; style=&quot;max-width: 20rem;&quot;&gt;
+  Unit
+  &lt;select&gt;
+    &lt;option&gt;Day&lt;/option&gt;
+    &lt;option selected=&quot;&quot;&gt;Week&lt;/option&gt;
+    &lt;option&gt;Month&lt;/option&gt;
+    &lt;option&gt;Year&lt;/option&gt;
+  &lt;/select&gt;
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="in-a-row">In a row</h2>
+
+<p><code>.form-row</code> is a sanctioned class for the one shape here with no element of
+its own — a row grouping two fields side by side.</p>
+
+<figure class="example">
+<figcaption>Two fields in a row</figcaption>
+<div>
+<form style="max-width: none;">
+  <div class="form-row">
+    <label class="field">
+      Every
+      <input type="number" placeholder="2" />
+    </label>
+    <label class="field">
+      Unit
+      <select>
+        <option>Day</option><option selected="">Week</option><option>Month</option>
+      </select>
+    </label>
+  </div>
+</form>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;form style=&quot;max-width: none;&quot;&gt;
+  &lt;div class=&quot;form-row&quot;&gt;
+    &lt;label class=&quot;field&quot;&gt;
+      Every
+      &lt;input type=&quot;number&quot; placeholder=&quot;2&quot; /&gt;
+    &lt;/label&gt;
+    &lt;label class=&quot;field&quot;&gt;
+      Unit
+      &lt;select&gt;
+        &lt;option&gt;Day&lt;/option&gt;&lt;option selected=&quot;&quot;&gt;Week&lt;/option&gt;&lt;option&gt;Month&lt;/option&gt;
+      &lt;/select&gt;
+    &lt;/label&gt;
+  &lt;/div&gt;
+&lt;/form&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>label.field</code></td><td></td><td>Required base. Wraps the caption text and the control together.</td></tr>
+    <tr><td><code>&gt; small</code></td><td>string</td><td>The hint. Renders below the control.</td></tr>
+    <tr><td><code>&gt; small[role="alert"]</code></td><td>string</td><td>An error instead of a hint — see <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/input/">Input</a>.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/icon-button.html b/design-bundle/components/icon-button.html
new file mode 100644
index 0000000..dda31e2
--- /dev/null
+++ b/design-bundle/components/icon-button.html
@@ -0,0 +1,1840 @@
+<!-- @dsCard group="Core" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>IconButton</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>IconButton</h1>
+</header>
+<p class="ad-lead">A square icon-only button. Always pass a label — it becomes the accessible name and the native tooltip, since there is no visible text to fall back on.</p>
+<h2 id="variants">Variants</h2>
+
+<p><code>ghost</code> is the default and transparent. <code>outline</code> is a bordered surface, for
+an icon button sitting alone rather than in a toolbar. <code>accent</code> is a soft
+accent tint, for a toggled or active state — the segmented-tabs pattern this
+system does not otherwise reach for.</p>
+
+<p>A square icon-only button is still a <code>&lt;button&gt;</code>, but there is no attribute
+that tells it apart from a plain <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/button/">Button</a>
+sitting alone — <code>variant</code>/<code>size</code> mean different things for each — so
+<code>.icon-button</code> is the one class this component needs.</p>
+
+<figure class="example">
+<figcaption>Variants</figcaption>
+<div>
+<button class="icon-button" aria-label="Delete">
+  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" /></svg>
+</button>
+<button class="icon-button" data-variant="outline" aria-label="Settings">
+  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3" /><path d="M12 2.5v3M12 18.5v3M3.6 7.2l2.6 1.5M17.8 15.3l2.6 1.5M3.6 16.8l2.6-1.5M17.8 8.7l2.6-1.5" /></svg>
+</button>
+<button class="icon-button" data-variant="accent" aria-label="Filter (active)">
+  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16l-6 8v5l-4 2v-7z" /></svg>
+</button>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;button class=&quot;icon-button&quot; aria-label=&quot;Delete&quot;&gt;
+  &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.75&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13&quot; /&gt;&lt;/svg&gt;
+&lt;/button&gt;
+&lt;button class=&quot;icon-button&quot; data-variant=&quot;outline&quot; aria-label=&quot;Settings&quot;&gt;
+  &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.75&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;3&quot; /&gt;&lt;path d=&quot;M12 2.5v3M12 18.5v3M3.6 7.2l2.6 1.5M17.8 15.3l2.6 1.5M3.6 16.8l2.6-1.5M17.8 8.7l2.6-1.5&quot; /&gt;&lt;/svg&gt;
+&lt;/button&gt;
+&lt;button class=&quot;icon-button&quot; data-variant=&quot;accent&quot; aria-label=&quot;Filter (active)&quot;&gt;
+  &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.75&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M4 5h16l-6 8v5l-4 2v-7z&quot; /&gt;&lt;/svg&gt;
+&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="sizes">Sizes</h2>
+
+<figure class="example">
+<figcaption>Sizes</figcaption>
+<div>
+<button class="icon-button" data-variant="outline" data-size="sm" aria-label="Back"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
+<button class="icon-button" data-variant="outline" aria-label="Back"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
+<button class="icon-button" data-variant="outline" data-size="lg" aria-label="Back"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;button class=&quot;icon-button&quot; data-variant=&quot;outline&quot; data-size=&quot;sm&quot; aria-label=&quot;Back&quot;&gt;&lt;svg width=&quot;14&quot; height=&quot;14&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.9&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M15 18l-6-6 6-6&quot; /&gt;&lt;/svg&gt;&lt;/button&gt;
+&lt;button class=&quot;icon-button&quot; data-variant=&quot;outline&quot; aria-label=&quot;Back&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.9&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M15 18l-6-6 6-6&quot; /&gt;&lt;/svg&gt;&lt;/button&gt;
+&lt;button class=&quot;icon-button&quot; data-variant=&quot;outline&quot; data-size=&quot;lg&quot; aria-label=&quot;Back&quot;&gt;&lt;svg width=&quot;18&quot; height=&quot;18&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.9&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M15 18l-6-6 6-6&quot; /&gt;&lt;/svg&gt;&lt;/button&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="paired-with-tooltip">Paired with Tooltip</h2>
+
+<p>An icon-only control almost always wants a <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/tooltip/">Tooltip</a> too — the <code>aria-label</code> covers accessibility, the tooltip covers a sighted mouse user glancing for a hint.</p>
+
+<figure class="example">
+<figcaption>With a tooltip</figcaption>
+<div>
+<span>
+  <button class="icon-button" aria-label="Delete" aria-describedby="icon-btn-tip">
+    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" /></svg>
+  </button>
+  <span role="tooltip" id="icon-btn-tip">Delete</span>
+</span>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;span&gt;
+  &lt;button class=&quot;icon-button&quot; aria-label=&quot;Delete&quot; aria-describedby=&quot;icon-btn-tip&quot;&gt;
+    &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.75&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13&quot; /&gt;&lt;/svg&gt;
+  &lt;/button&gt;
+  &lt;span role=&quot;tooltip&quot; id=&quot;icon-btn-tip&quot;&gt;Delete&lt;/span&gt;
+&lt;/span&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>button.icon-button</code></td><td></td><td>Required base — the one class in this component, since nothing distinguishes it from Button structurally.</td></tr>
+    <tr><td><code>aria-label</code></td><td>string</td><td>Required — becomes the accessible name and the native tooltip.</td></tr>
+    <tr><td><code>data-size</code></td><td><code>sm | lg</code></td><td>28 / 40px square. Omit for the default 34px.</td></tr>
+    <tr><td><code>data-variant</code></td><td><code>outline | accent</code></td><td>Omit for the default, transparent ghost look.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/input.html b/design-bundle/components/input.html
new file mode 100644
index 0000000..cfa85fb
--- /dev/null
+++ b/design-bundle/components/input.html
@@ -0,0 +1,1817 @@
+<!-- @dsCard group="Forms" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Input</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Input</h1>
+</header>
+<p class="ad-lead">A bordered text input, styled to match Select exactly. Usually wrapped in Field for its label and hint.</p>
+<h2 id="basic">Basic</h2>
+
+<p><code>&lt;input&gt;</code> is the component — styled bare, no class. Nothing else on this
+site uses a text input, so there is nothing for the selector to clash with.</p>
+
+<figure class="example">
+<figcaption>Input</figcaption>
+<div>
+<input type="text" placeholder="Dishwasher manual" style="max-width: 20rem;" />
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;input type=&quot;text&quot; placeholder=&quot;Dishwasher manual&quot; style=&quot;max-width: 20rem;&quot; /&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="focus-and-disabled">Focus and disabled</h2>
+
+<figure class="example">
+<figcaption>States</figcaption>
+<div data-layout="stack">
+<input type="text" value="Focused" style="max-width: 20rem; border-color: var(--ad-color-accent); box-shadow: 0 0 0 2px var(--ad-color-accent-soft);" />
+<input type="text" value="Disabled" disabled="" style="max-width: 20rem;" />
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;input type=&quot;text&quot; value=&quot;Focused&quot; style=&quot;max-width: 20rem; border-color: var(--ad-color-accent); box-shadow: 0 0 0 2px var(--ad-color-accent-soft);&quot; /&gt;
+&lt;input type=&quot;text&quot; value=&quot;Disabled&quot; disabled=&quot;&quot; style=&quot;max-width: 20rem;&quot; /&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="invalid">Invalid</h2>
+
+<p>Invalid state is expressed on the control itself, so it works with native
+form validation, plus an error line below. <code>role="alert"</code> is a real
+live-region role for validation text, so it doubles as the selector that
+turns a <code>&lt;small&gt;</code> hint red.</p>
+
+<figure class="example">
+<figcaption>Invalid</figcaption>
+<div>
+<label class="field" style="max-width: 20rem;">
+  Accent hex
+  <input type="text" value="not-a-color" aria-invalid="true" />
+  <small role="alert">Not a valid hex color.</small>
+</label>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;label class=&quot;field&quot; style=&quot;max-width: 20rem;&quot;&gt;
+  Accent hex
+  &lt;input type=&quot;text&quot; value=&quot;not-a-color&quot; aria-invalid=&quot;true&quot; /&gt;
+  &lt;small role=&quot;alert&quot;&gt;Not a valid hex color.&lt;/small&gt;
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>input</code></td><td></td><td>Required base — no class.</td></tr>
+    <tr><td><code>type</code></td><td>string</td><td>Any native input type except <code>checkbox</code>/<code>radio</code>, which are their own components.</td></tr>
+    <tr><td><code>placeholder</code></td><td>string</td><td></td></tr>
+    <tr><td><code>disabled</code></td><td>boolean</td><td></td></tr>
+    <tr><td><code>aria-invalid</code></td><td><code>"true"</code></td><td>Reddens the border and fill.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/radio.html b/design-bundle/components/radio.html
new file mode 100644
index 0000000..1f7a554
--- /dev/null
+++ b/design-bundle/components/radio.html
@@ -0,0 +1,1828 @@
+<!-- @dsCard group="Forms" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Radio</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Radio</h1>
+</header>
+<p class="ad-lead">Native radio, the same accent-color treatment as Checkbox.</p>
+<h2 id="basic">Basic</h2>
+
+<figure class="example">
+<figcaption>Radio</figcaption>
+<div>
+<label>
+  <input type="radio" name="demo-radio-1" checked="" />
+  Weekly
+</label>
+<label>
+  <input type="radio" name="demo-radio-1" />
+  Monthly
+</label>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;label&gt;
+  &lt;input type=&quot;radio&quot; name=&quot;demo-radio-1&quot; checked=&quot;&quot; /&gt;
+  Weekly
+&lt;/label&gt;
+&lt;label&gt;
+  &lt;input type=&quot;radio&quot; name=&quot;demo-radio-1&quot; /&gt;
+  Monthly
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="as-a-group">As a group</h2>
+
+<figure class="example">
+<figcaption>Interval</figcaption>
+<div>
+<fieldset>
+  <legend>Repeat</legend>
+  <label>
+    <input type="radio" name="demo-radio-2" checked="" />
+    Every week
+  </label>
+  <label>
+    <input type="radio" name="demo-radio-2" />
+    Every month
+  </label>
+  <label>
+    <input type="radio" name="demo-radio-2" />
+    Every year
+  </label>
+</fieldset>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;fieldset&gt;
+  &lt;legend&gt;Repeat&lt;/legend&gt;
+  &lt;label&gt;
+    &lt;input type=&quot;radio&quot; name=&quot;demo-radio-2&quot; checked=&quot;&quot; /&gt;
+    Every week
+  &lt;/label&gt;
+  &lt;label&gt;
+    &lt;input type=&quot;radio&quot; name=&quot;demo-radio-2&quot; /&gt;
+    Every month
+  &lt;/label&gt;
+  &lt;label&gt;
+    &lt;input type=&quot;radio&quot; name=&quot;demo-radio-2&quot; /&gt;
+    Every year
+  &lt;/label&gt;
+&lt;/fieldset&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>input[type="radio"]</code></td><td></td><td>Required base — no class. Tinted with <code>accent-color</code>.</td></tr>
+    <tr><td><code>checked</code></td><td>boolean</td><td></td></tr>
+    <tr><td><code>name</code></td><td>string</td><td>Groups mutually exclusive radios.</td></tr>
+    <tr><td><code>label</code></td><td>text content</td><td>Wrap the input directly — <code>label:has(&gt; input[type="radio"])</code> is what applies the row layout.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/select.html b/design-bundle/components/select.html
new file mode 100644
index 0000000..e4efce9
--- /dev/null
+++ b/design-bundle/components/select.html
@@ -0,0 +1,1806 @@
+<!-- @dsCard group="Forms" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Select</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Select</h1>
+</header>
+<p class="ad-lead">Native select, styled to match Input exactly.</p>
+<h2 id="basic">Basic</h2>
+
+<p><code>&lt;select&gt;</code> is the component — styled bare, no class.</p>
+
+<figure class="example">
+<figcaption>Select</figcaption>
+<div>
+<select style="max-width: 20rem;">
+  <option>Day</option>
+  <option selected="">Week</option>
+  <option>Month</option>
+  <option>Year</option>
+</select>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;select style=&quot;max-width: 20rem;&quot;&gt;
+  &lt;option&gt;Day&lt;/option&gt;
+  &lt;option selected=&quot;&quot;&gt;Week&lt;/option&gt;
+  &lt;option&gt;Month&lt;/option&gt;
+  &lt;option&gt;Year&lt;/option&gt;
+&lt;/select&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="disabled">Disabled</h2>
+
+<figure class="example">
+<figcaption>Disabled</figcaption>
+<div>
+<select disabled="" style="max-width: 20rem;"><option>Week</option></select>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;select disabled=&quot;&quot; style=&quot;max-width: 20rem;&quot;&gt;&lt;option&gt;Week&lt;/option&gt;&lt;/select&gt;</code></pre>
+</details>
+</figure>
+
+<div class="ad-callout">
+  <p style="margin:0; font-size: var(--ad-step--1);">
+    The chevron is the one place in this component set that cannot reach a
+    <code>var(--ad-*)</code> token — a data-URI <code>background-image</code>
+    cannot reference a custom property, so its stroke is a literal hex, kept
+    close to <code>--ad-color-text-secondary</code> and commented in the source.
+  </p>
+</div>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>select</code></td><td></td><td>Required base — no class.</td></tr>
+    <tr><td><code>option</code></td><td></td><td></td></tr>
+    <tr><td><code>disabled</code></td><td>boolean</td><td></td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/switch.html b/design-bundle/components/switch.html
new file mode 100644
index 0000000..9c91dc2
--- /dev/null
+++ b/design-bundle/components/switch.html
@@ -0,0 +1,1821 @@
+<!-- @dsCard group="Forms" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Switch</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Switch</h1>
+</header>
+<p class="ad-lead">Toggle switch for on/off settings. The one moving part in this system — everything else transitions color or border, never position.</p>
+<h2 id="basic">Basic</h2>
+
+<p><code>role="switch"</code> is the correct ARIA role for a toggle, so it doubles as the
+attribute that tells Switch’s <code>input[type="checkbox"]</code> apart from a plain
+Checkbox — real accessibility markup doing double duty as a style hook. The
+track and thumb still need <code>.switch</code>, one sanctioned fallback class: the
+thumb’s independent position and transition need a second element, more than
+<code>appearance: none</code> plus pseudo-elements on the input itself can cleanly
+carry.</p>
+
+<figure class="example">
+<figcaption>Switch</figcaption>
+<div>
+<label class="switch">
+  <input type="checkbox" role="switch" checked="" />
+  <span></span>
+  Dark mode
+</label>
+<label class="switch">
+  <input type="checkbox" role="switch" />
+  <span></span>
+  Weekly digest
+</label>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;label class=&quot;switch&quot;&gt;
+  &lt;input type=&quot;checkbox&quot; role=&quot;switch&quot; checked=&quot;&quot; /&gt;
+  &lt;span&gt;&lt;/span&gt;
+  Dark mode
+&lt;/label&gt;
+&lt;label class=&quot;switch&quot;&gt;
+  &lt;input type=&quot;checkbox&quot; role=&quot;switch&quot; /&gt;
+  &lt;span&gt;&lt;/span&gt;
+  Weekly digest
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="disabled">Disabled</h2>
+
+<figure class="example">
+<figcaption>Disabled</figcaption>
+<div>
+<label class="switch">
+  <input type="checkbox" role="switch" checked="" disabled="" />
+  <span></span>
+  Always on for this plan
+</label>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;label class=&quot;switch&quot;&gt;
+  &lt;input type=&quot;checkbox&quot; role=&quot;switch&quot; checked=&quot;&quot; disabled=&quot;&quot; /&gt;
+  &lt;span&gt;&lt;/span&gt;
+  Always on for this plan
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>label.switch</code></td><td></td><td>Required wrapper.</td></tr>
+    <tr><td><code>input[type="checkbox"][role="switch"]</code></td><td></td><td>Required — the role is what makes it a Switch instead of a Checkbox.</td></tr>
+    <tr><td><code>&gt; span</code></td><td></td><td>Required — the track and thumb. No class, just structural position.</td></tr>
+    <tr><td><code>checked</code></td><td>boolean</td><td></td></tr>
+    <tr><td><code>disabled</code></td><td>boolean</td><td></td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/tabs.html b/design-bundle/components/tabs.html
new file mode 100644
index 0000000..1b2a5ca
--- /dev/null
+++ b/design-bundle/components/tabs.html
@@ -0,0 +1,1848 @@
+<!-- @dsCard group="Navigation" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Tabs</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Tabs</h1>
+</header>
+<p class="ad-lead">Two real variants: underline for primary section navigation, segmented for filters. The WAI-ARIA tabs pattern, wired up in vanilla JavaScript — arrows move, Home/End jump to the ends.</p>
+<p>Tabs follows the real WAI-ARIA tabs pattern: <code>[role="tablist"]</code> contains
+<code>[role="tab"]</code> buttons controlling <code>[role="tabpanel"]</code>s. Those roles are
+required for the pattern to be accessible in the first place, so they are the
+entire styling contract too — no classes anywhere in this component. The
+keyboard wiring (<code>assets/js/system.js</code>) only looks for <code>[data-tabs]</code> /
+<code>[role=tab]</code>, so the root wrapper keeps that one data attribute and needs
+nothing else.</p>
+
+<h2 id="underline">Underline</h2>
+
+<p>Mono, with an accent underline. For primary section navigation — a project’s
+own tabs, never a filter. This is the default; no <code>data-variant</code> needed.</p>
+
+<figure class="example">
+<figcaption>Underline</figcaption>
+<div data-layout="stack">
+<div data-tabs="">
+  <div role="tablist" aria-label="Repository">
+    <button role="tab" id="tabs-code-tab" aria-controls="tabs-code-panel" aria-selected="true" tabindex="0">Code</button>
+    <button role="tab" id="tabs-ci-tab" aria-controls="tabs-ci-panel" aria-selected="false" tabindex="-1">CI</button>
+    <button role="tab" id="tabs-issues-tab" aria-controls="tabs-issues-panel" aria-selected="false" tabindex="-1">Issues</button>
+  </div>
+  <div role="tabpanel" id="tabs-code-panel" aria-labelledby="tabs-code-tab" tabindex="0">Repository contents.</div>
+  <div role="tabpanel" id="tabs-ci-panel" aria-labelledby="tabs-ci-tab" tabindex="0" hidden="">Build history.</div>
+  <div role="tabpanel" id="tabs-issues-panel" aria-labelledby="tabs-issues-tab" tabindex="0" hidden="">Open issues.</div>
+</div>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;div data-tabs=&quot;&quot;&gt;
+  &lt;div role=&quot;tablist&quot; aria-label=&quot;Repository&quot;&gt;
+    &lt;button role=&quot;tab&quot; id=&quot;tabs-code-tab&quot; aria-controls=&quot;tabs-code-panel&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;Code&lt;/button&gt;
+    &lt;button role=&quot;tab&quot; id=&quot;tabs-ci-tab&quot; aria-controls=&quot;tabs-ci-panel&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;CI&lt;/button&gt;
+    &lt;button role=&quot;tab&quot; id=&quot;tabs-issues-tab&quot; aria-controls=&quot;tabs-issues-panel&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;Issues&lt;/button&gt;
+  &lt;/div&gt;
+  &lt;div role=&quot;tabpanel&quot; id=&quot;tabs-code-panel&quot; aria-labelledby=&quot;tabs-code-tab&quot; tabindex=&quot;0&quot;&gt;Repository contents.&lt;/div&gt;
+  &lt;div role=&quot;tabpanel&quot; id=&quot;tabs-ci-panel&quot; aria-labelledby=&quot;tabs-ci-tab&quot; tabindex=&quot;0&quot; hidden=&quot;&quot;&gt;Build history.&lt;/div&gt;
+  &lt;div role=&quot;tabpanel&quot; id=&quot;tabs-issues-panel&quot; aria-labelledby=&quot;tabs-issues-tab&quot; tabindex=&quot;0&quot; hidden=&quot;&quot;&gt;Open issues.&lt;/div&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="segmented">Segmented</h2>
+
+<p>A pill track; the active segment lifts to the surface. For filters — <em>All ·
+Overdue · Upcoming</em> — never primary navigation. <code>data-variant="segmented"</code> on
+the tablist is the only attribute either variant needs, since neither has a
+natural one of its own.</p>
+
+<figure class="example">
+<figcaption>Segmented</figcaption>
+<div data-layout="stack">
+<div data-tabs="">
+  <div role="tablist" data-variant="segmented" aria-label="Filter">
+    <button role="tab" id="tabs-all-tab" aria-controls="tabs-all-panel" aria-selected="true" tabindex="0">All</button>
+    <button role="tab" id="tabs-overdue-tab" aria-controls="tabs-overdue-panel" aria-selected="false" tabindex="-1">Overdue</button>
+    <button role="tab" id="tabs-upcoming-tab" aria-controls="tabs-upcoming-panel" aria-selected="false" tabindex="-1">Upcoming</button>
+  </div>
+  <div role="tabpanel" id="tabs-all-panel" aria-labelledby="tabs-all-tab" tabindex="0">7 series.</div>
+  <div role="tabpanel" id="tabs-overdue-panel" aria-labelledby="tabs-overdue-tab" tabindex="0" hidden="">2 series.</div>
+  <div role="tabpanel" id="tabs-upcoming-panel" aria-labelledby="tabs-upcoming-tab" tabindex="0" hidden="">5 series.</div>
+</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div data-tabs=&quot;&quot;&gt;
+  &lt;div role=&quot;tablist&quot; data-variant=&quot;segmented&quot; aria-label=&quot;Filter&quot;&gt;
+    &lt;button role=&quot;tab&quot; id=&quot;tabs-all-tab&quot; aria-controls=&quot;tabs-all-panel&quot; aria-selected=&quot;true&quot; tabindex=&quot;0&quot;&gt;All&lt;/button&gt;
+    &lt;button role=&quot;tab&quot; id=&quot;tabs-overdue-tab&quot; aria-controls=&quot;tabs-overdue-panel&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;Overdue&lt;/button&gt;
+    &lt;button role=&quot;tab&quot; id=&quot;tabs-upcoming-tab&quot; aria-controls=&quot;tabs-upcoming-panel&quot; aria-selected=&quot;false&quot; tabindex=&quot;-1&quot;&gt;Upcoming&lt;/button&gt;
+  &lt;/div&gt;
+  &lt;div role=&quot;tabpanel&quot; id=&quot;tabs-all-panel&quot; aria-labelledby=&quot;tabs-all-tab&quot; tabindex=&quot;0&quot;&gt;7 series.&lt;/div&gt;
+  &lt;div role=&quot;tabpanel&quot; id=&quot;tabs-overdue-panel&quot; aria-labelledby=&quot;tabs-overdue-tab&quot; tabindex=&quot;0&quot; hidden=&quot;&quot;&gt;2 series.&lt;/div&gt;
+  &lt;div role=&quot;tabpanel&quot; id=&quot;tabs-upcoming-panel&quot; aria-labelledby=&quot;tabs-upcoming-tab&quot; tabindex=&quot;0&quot; hidden=&quot;&quot;&gt;5 series.&lt;/div&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>Never both variants in one view.</strong> Underline is for the page’s own
+sections; segmented is for filtering what is already on screen.</li>
+  <li><strong>Segmented is not primary navigation.</strong> If it decides which screen the
+reader is on, it should be underline.</li>
+</ul>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>[data-tabs]</code></td><td></td><td>Required on the root wrapper — what the keyboard wiring in <code>system.js</code> looks for.</td></tr>
+    <tr><td><code>[role="tablist"]</code></td><td></td><td>Required. Contains the tab buttons.</td></tr>
+    <tr><td><code>[role="tab"]</code></td><td></td><td>Required, one per item. <code>aria-selected</code> and <code>tabindex</code> are managed by the JS.</td></tr>
+    <tr><td><code>[role="tabpanel"]</code></td><td></td><td>Required, one per item, referenced by the tab's <code>aria-controls</code>.</td></tr>
+    <tr><td><code>data-variant</code></td><td><code>segmented</code></td><td>On the tablist. Omit for the default underline look.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/tag.html b/design-bundle/components/tag.html
new file mode 100644
index 0000000..dc4dee4
--- /dev/null
+++ b/design-bundle/components/tag.html
@@ -0,0 +1,1805 @@
+<!-- @dsCard group="Core" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Tag</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Tag</h1>
+</header>
+<p class="ad-lead">A removable mono chip for freeform tags — locations, categories. `[data-dashed]` renders an "add tag" affordance instead of a value.</p>
+<h2 id="default-and-removable">Default and removable</h2>
+
+<p>Same reasoning as Badge: a <code>&lt;span&gt;</code> is too generic to select bare, so Tag
+keeps one class. The remove control is a real <code>&lt;button&gt;</code>, styled through the
+descendant selector <code>.tag button</code> — no class of its own.</p>
+
+<figure class="example">
+<figcaption>Tags</figcaption>
+<div>
+<span class="tag">location:garage</span>
+<span class="tag">category:appliance</span>
+<span class="tag">
+  category:receipt
+  <button aria-label="Remove tag">×</button>
+</span>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;span class=&quot;tag&quot;&gt;location:garage&lt;/span&gt;
+&lt;span class=&quot;tag&quot;&gt;category:appliance&lt;/span&gt;
+&lt;span class=&quot;tag&quot;&gt;
+  category:receipt
+  &lt;button aria-label=&quot;Remove tag&quot;&gt;×&lt;/button&gt;
+&lt;/span&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="dashed--the-add-tag-affordance">Dashed — the “add tag” affordance</h2>
+
+<figure class="example">
+<figcaption>Add tag</figcaption>
+<div>
+<div class="tag-set">
+  <span class="tag">location:garage</span>
+  <span class="tag" data-dashed="">+ add tag</span>
+</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div class=&quot;tag-set&quot;&gt;
+  &lt;span class=&quot;tag&quot;&gt;location:garage&lt;/span&gt;
+  &lt;span class=&quot;tag&quot; data-dashed&gt;+ add tag&lt;/span&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>span.tag</code></td><td></td><td>Required base.</td></tr>
+    <tr><td><code>button</code></td><td></td><td>Nest a real <code>&lt;button aria-label="Remove tag"&gt;</code> to render the × affordance — styled via <code>.tag button</code>, no class needed.</td></tr>
+    <tr><td><code>data-dashed</code></td><td>boolean</td><td>Renders an "add tag" affordance instead of a value.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/toast.html b/design-bundle/components/toast.html
new file mode 100644
index 0000000..ac1e35c
--- /dev/null
+++ b/design-bundle/components/toast.html
@@ -0,0 +1,1809 @@
+<!-- @dsCard group="Feedback" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Toast</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Toast</h1>
+</header>
+<p class="ad-lead">A fixed bottom-right flash bar — the real pattern used for delete confirmations. Auto-dismisses after roughly 8 seconds in practice; wire that timer into the consuming app.</p>
+<h2 id="basic">Basic</h2>
+
+<p><code>role="status"</code> is the correct live-region role for a transient status
+message, so it doubles as the entire styling hook — no base class. The
+example below stays in document flow so it does not cover the page;
+<code>[data-fixed]</code> is what actually pins it bottom-right in a real app. The
+action and dismiss buttons are plain <code>&lt;button&gt;</code>s told apart by
+<code>aria-label="Dismiss"</code>, an attribute the icon-only close control needs
+anyway.</p>
+
+<figure class="example">
+<figcaption>Toast</figcaption>
+<div>
+<div role="status">
+  <span>Deleted "Call Mom"</span>
+  <button>Undo</button>
+  <button aria-label="Dismiss">×</button>
+</div>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;div role=&quot;status&quot;&gt;
+  &lt;span&gt;Deleted &quot;Call Mom&quot;&lt;/span&gt;
+  &lt;button&gt;Undo&lt;/button&gt;
+  &lt;button aria-label=&quot;Dismiss&quot;&gt;×&lt;/button&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="without-an-action">Without an action</h2>
+
+<figure class="example">
+<figcaption>No action</figcaption>
+<div>
+<div role="status">
+  <span>Series created</span>
+  <button aria-label="Dismiss">×</button>
+</div>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div role=&quot;status&quot;&gt;
+  &lt;span&gt;Series created&lt;/span&gt;
+  &lt;button aria-label=&quot;Dismiss&quot;&gt;×&lt;/button&gt;
+&lt;/div&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>[role="status"]</code></td><td></td><td>Required base, on a <code>&lt;div&gt;</code>.</td></tr>
+    <tr><td><code>&gt; span</code></td><td>string</td><td>The message. Required.</td></tr>
+    <tr><td><code>&gt; button</code></td><td></td><td>Renders a destructive-colored action, typically "Undo".</td></tr>
+    <tr><td><code>&gt; button[aria-label="Dismiss"]</code></td><td></td><td>The × control — the label is what tells it apart from the action button.</td></tr>
+    <tr><td><code>data-fixed</code></td><td>boolean</td><td>Pins the toast bottom-right of the viewport. Omit to stay in document flow.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/components/tooltip.html b/design-bundle/components/tooltip.html
new file mode 100644
index 0000000..a87954e
--- /dev/null
+++ b/design-bundle/components/tooltip.html
@@ -0,0 +1,1812 @@
+<!-- @dsCard group="Feedback" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Tooltip</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Components</span>
+  <h1>Tooltip</h1>
+</header>
+<p class="ad-lead">Dark mono tooltip on hover, positioned above the child. Pure CSS — shown on hover and keyboard focus, no JavaScript required.</p>
+<h2 id="basic">Basic</h2>
+
+<p><code>role="tooltip"</code> is the correct ARIA role for the bubble itself, so it
+doubles as the styling hook — no class on the bubble. The wrapping <code>&lt;span&gt;</code>
+has no attribute of its own, but it does not need one: <code>:has()</code> selects “a
+span that contains a <code>[role=tooltip]</code> bubble” precisely, so the wrapper stays
+bare too. Pair the trigger’s <code>aria-describedby</code> with the bubble’s <code>id</code> so the
+tooltip is announced, not just shown.</p>
+
+<p>Hover or tab to the button below.</p>
+
+<figure class="example">
+<figcaption>Tooltip</figcaption>
+<div>
+<span>
+  <button class="icon-button" aria-label="Delete" aria-describedby="tooltip-basic">
+    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" /></svg>
+  </button>
+  <span role="tooltip" id="tooltip-basic">Delete</span>
+</span>
+</div>
+<details open=""><summary>Markup</summary>
+<pre><code>&lt;span&gt;
+  &lt;button class=&quot;icon-button&quot; aria-label=&quot;Delete&quot; aria-describedby=&quot;tooltip-basic&quot;&gt;
+    &lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;1.75&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot;&gt;&lt;path d=&quot;M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13&quot; /&gt;&lt;/svg&gt;
+  &lt;/button&gt;
+  &lt;span role=&quot;tooltip&quot; id=&quot;tooltip-basic&quot;&gt;Delete&lt;/span&gt;
+&lt;/span&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="on-any-element">On any element</h2>
+
+<p>A Tooltip wraps whatever it labels — most often an <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/icon-button/">IconButton</a>, since that is the control with no visible text of its own.</p>
+
+<figure class="example">
+<figcaption>On a badge</figcaption>
+<div>
+<span>
+  <span class="badge" data-tone="danger" tabindex="0" aria-describedby="tooltip-badge">3d overdue</span>
+  <span role="tooltip" id="tooltip-badge">Due Tuesday, was Saturday</span>
+</span>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;span&gt;
+  &lt;span class=&quot;badge&quot; data-tone=&quot;danger&quot; tabindex=&quot;0&quot; aria-describedby=&quot;tooltip-badge&quot;&gt;3d overdue&lt;/span&gt;
+  &lt;span role=&quot;tooltip&quot; id=&quot;tooltip-badge&quot;&gt;Due Tuesday, was Saturday&lt;/span&gt;
+&lt;/span&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="api">API</h2>
+
+<table>
+  <thead><tr><th scope="col">Element / attribute</th><th scope="col">Values</th><th scope="col">Notes</th></tr></thead>
+  <tbody>
+    <tr><td><code>span</code></td><td></td><td>Required wrapper around the trigger and the bubble. Bare — matched structurally via <code>:has()</code>, no class.</td></tr>
+    <tr><td><code>[role="tooltip"]</code></td><td>string content</td><td>Required — the bubble. Give it an <code>id</code>.</td></tr>
+    <tr><td><code>aria-describedby</code></td><td>the bubble's <code>id</code></td><td>Put it on the trigger element, which needs a real accessible name of its own — a tooltip is not one.</td></tr>
+  </tbody>
+</table>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/css/style.css b/design-bundle/css/style.css
new file mode 100644
index 0000000..b3f3073
--- /dev/null
+++ b/design-bundle/css/style.css
@@ -0,0 +1,1459 @@
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
diff --git a/design-bundle/css/tokens.css b/design-bundle/css/tokens.css
new file mode 100644
index 0000000..34ff530
--- /dev/null
+++ b/design-bundle/css/tokens.css
@@ -0,0 +1,134 @@
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
diff --git a/design-bundle/foundations/color.html b/design-bundle/foundations/color.html
new file mode 100644
index 0000000..56cf6c1
--- /dev/null
+++ b/design-bundle/foundations/color.html
@@ -0,0 +1,2399 @@
+<!-- @dsCard group="Foundations" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Color</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Foundations</span>
+  <h1>Color</h1>
+</header>
+<p class="ad-lead">Two neutral ramps, five accents, two fixed semantic colors, seventeen semantic aliases. Low-chroma warm-gray, never stark white or black.</p>
+<h2 id="the-two-layers">The two layers</h2>
+
+<p>The system separates <em>what a color is</em> from <em>what a color is for</em>.</p>
+
+<p>The <strong>ramps</strong> below are raw material: ten steps of neutral (light), the same
+ten inverted for dark mode, and five accent hues. No component references
+them directly.</p>
+
+<p>The <strong>aliases</strong> underneath are the working vocabulary — <code>--ad-color-text-primary</code>,
+<code>--ad-color-surface-card</code>, <code>--ad-color-accent</code>. Every component stylesheet
+reads from these. Retheming, or switching to dark, means repointing aliases
+at different values — which is exactly what the dark block does.</p>
+
+<div class="ad-callout">
+  <p style="margin:0; font-size: var(--ad-step--1);">
+    The neutral ramps were authored in <code>oklch()</code> by the three
+    projects this system was synthesized from (see
+    <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/rationale/">Why arbitrary</a>). Every
+    value below is that same color converted to flat sRGB hex — not
+    re-picked, not rounded. The contrast figures on this page are computed
+    from those hex values with the standard WCAG 2.1 relative-luminance
+    formula, then transcribed here as fact rather than typed by eye.
+  </p>
+</div>
+
+<h2 id="neutral">Neutral</h2>
+
+<p>Low-chroma warm-gray — the intersection of ketchup’s plain grays, quire’s
+warm cream/dark palette, and domus’s warm paper. Ten steps, not twelve or
+sixteen: the source defines exactly these.</p>
+
+<p class="ad-muted">Low-chroma warm-gray — the intersection of ketchup's plain grays, quire's warm cream/dark palette, and domus's warm paper. Not stark white or black, and not any one project's specific warmth. Ten steps, not twelve: the source defines exactly 0/50/100/150/200/300/500/600/800/900 — steps 400 and 700 do not exist.</p>
+<ul class="ad-swatch-grid">
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #faf9f7; color: #171512;">n-0</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#faf9f7</span>
+      <span class="ad-swatch__ratio">1.05 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #fdfdfb; color: #171512;">n-50</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#fdfdfb</span>
+      <span class="ad-swatch__ratio">1.02 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #f1f0ed; color: #171512;">n-100</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#f1f0ed</span>
+      <span class="ad-swatch__ratio">1.14 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #e8e6e2; color: #171512;">n-150</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#e8e6e2</span>
+      <span class="ad-swatch__ratio">1.25 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #dcdad7; color: #171512;">n-200</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#dcdad7</span>
+      <span class="ad-swatch__ratio">1.40 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #c0bdb9; color: #171512;">n-300</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#c0bdb9</span>
+      <span class="ad-swatch__ratio">1.87 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #888681; color: #171512;">n-500</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#888681</span>
+      <span class="ad-swatch__ratio">3.64 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #5f5d59; color: #ffffff;">n-600</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#5f5d59</span>
+      <span class="ad-swatch__ratio">6.57 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #2a2926; color: #ffffff;">n-800</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#2a2926</span>
+      <span class="ad-swatch__ratio">14.55 on white</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #100f0d; color: #ffffff;">n-900</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#100f0d</span>
+      <span class="ad-swatch__ratio">19.16 on white</span>
+    </div>
+  </li>
+</ul>
+
+<p class="ad-muted">The same low-chroma warm-gray scale, inverted, matching quire's OS-preference dark palette. Same ten step numbers as `neutral`; `0` is the darkest step here (the dark-theme page background) rather than the lightest.</p>
+<ul class="ad-swatch-grid">
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #0e0d0b; color: #ffffff;">nd-0</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#0e0d0b</span>
+      <span class="ad-swatch__ratio">1.08 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #151412; color: #ffffff;">nd-50</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#151412</span>
+      <span class="ad-swatch__ratio">1.14 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #1e1d1a; color: #ffffff;">nd-100</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#1e1d1a</span>
+      <span class="ad-swatch__ratio">1.25 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #252421; color: #ffffff;">nd-150</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#252421</span>
+      <span class="ad-swatch__ratio">1.35 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #2c2b29; color: #ffffff;">nd-200</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#2c2b29</span>
+      <span class="ad-swatch__ratio">1.48 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #44423f; color: #ffffff;">nd-300</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#44423f</span>
+      <span class="ad-swatch__ratio">2.10 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #7c7a76; color: #ffffff;">nd-500</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#7c7a76</span>
+      <span class="ad-swatch__ratio">4.90 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #a09e9a; color: #171512;">nd-600</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#a09e9a</span>
+      <span class="ad-swatch__ratio">7.85 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #d9d7d4; color: #171512;">nd-800</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#d9d7d4</span>
+      <span class="ad-swatch__ratio">14.62 on black</span>
+    </div>
+  </li>
+  <li class="ad-swatch">
+    <div class="ad-swatch__chip" style="background: #e9e8e6; color: #171512;">nd-900</div>
+    <div class="ad-swatch__meta">
+      <span class="ad-swatch__hex">#e9e8e6</span>
+      <span class="ad-swatch__ratio">17.15 on black</span>
+    </div>
+  </li>
+</ul>
+
+<h2 id="accent">Accent</h2>
+
+<p>One swappable accent per project — never two in the same view. Signal Teal is
+the default; the other four are the sanctioned menu a project can switch to.</p>
+
+<ul class="ad-accent-grid">
+  <li>
+    <div class="ad-accent-demo" style="background: #3a6a63;">teal (default)</div>
+    <div class="ad-specimen__meta"><code>#3a6a63</code><span>6.14:1 on white</span></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Default. Neutral, technical.</p>
+  </li>
+  <li>
+    <div class="ad-accent-demo" style="background: #9a5a3c;">clay</div>
+    <div class="ad-specimen__meta"><code>#9a5a3c</code><span>5.38:1 on white</span></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Warm, archival — domus's flavor.</p>
+  </li>
+  <li>
+    <div class="ad-accent-demo" style="background: #2b4a78;">ink-blue</div>
+    <div class="ad-specimen__meta"><code>#2b4a78</code><span>8.92:1 on white</span></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Sober, utilitarian.</p>
+  </li>
+  <li>
+    <div class="ad-accent-demo" style="background: #93701f;">ochre</div>
+    <div class="ad-specimen__meta"><code>#93701f</code><span>4.59:1 on white</span></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Dry, papery.</p>
+  </li>
+  <li>
+    <div class="ad-accent-demo" style="background: #6a3a5c;">plum</div>
+    <div class="ad-specimen__meta"><code>#6a3a5c</code><span>8.85:1 on white</span></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Quiet, personal.</p>
+  </li>
+</ul>
+
+<div class="ad-callout">
+  <p style="margin:0; font-size: var(--ad-step--1);">
+    All five clear AA (4.5:1) for white text at their own value, but Ochre is
+    the tightest of the five at roughly 4.6:1 — closer to the floor than the
+    others (Ink Blue and Plum both clear 8.5:1). That is a real property of a
+    dry, papery ochre and is not being rounded away; a project choosing Ochre
+    as its accent should re-check any place it sets small white text directly
+    on the accent fill, rather than through <code>--ad-color-accent-fg</code>
+    on a full-size Button.
+  </p>
+</div>
+
+<h2 id="semantic-aliases">Semantic aliases</h2>
+
+<p>Both themes, side by side. The left half of each chip is the light value and
+the right half is the dark one.</p>
+
+<h3 id="surfaces">Surfaces</h3>
+
+<p class="ad-muted">Backgrounds, from the page itself up to a card sitting on it.</p>
+
+<table>
+    <thead>
+      <tr>
+        <th scope="col">Token</th>
+        <th scope="col">Light</th>
+        <th scope="col">Dark</th>
+        <th scope="col">Use for</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #faf9f7"></span>
+              <span style="background: #0e0d0b"></span>
+            </span>
+            <code>--ad-color-surface-page</code>
+          </div>
+        </td>
+        <td><code>neutral.0</code></td>
+        <td><code>neutral_dark.0</code></td>
+        <td>The page itself. Nothing sits behind it.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #fdfdfb"></span>
+              <span style="background: #151412"></span>
+            </span>
+            <code>--ad-color-surface-card</code>
+          </div>
+        </td>
+        <td><code>neutral.50</code></td>
+        <td><code>neutral_dark.50</code></td>
+        <td>Cards, dialogs, toasts — anything that reads as a sheet on the page.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #f1f0ed"></span>
+              <span style="background: #1e1d1a"></span>
+            </span>
+            <code>--ad-color-surface-fill</code>
+          </div>
+        </td>
+        <td><code>neutral.100</code></td>
+        <td><code>neutral_dark.100</code></td>
+        <td>Recessed fill — a hovered row, a segmented-tab track, a photo placeholder.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #e8e6e2"></span>
+              <span style="background: #252421"></span>
+            </span>
+            <code>--ad-color-surface-fill-2</code>
+          </div>
+        </td>
+        <td><code>neutral.150</code></td>
+        <td><code>neutral_dark.150</code></td>
+        <td>A second, deeper fill step — the diagonal-grain stripe inside an empty photo slot.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<h3 id="borders">Borders</h3>
+
+<p class="ad-muted">Two weights. Hairlines do most of the elevation work in this system, so there was never a reason for a third.</p>
+
+<table>
+    <thead>
+      <tr>
+        <th scope="col">Token</th>
+        <th scope="col">Light</th>
+        <th scope="col">Dark</th>
+        <th scope="col">Use for</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #dcdad7"></span>
+              <span style="background: #2c2b29"></span>
+            </span>
+            <code>--ad-color-border-hairline</code>
+          </div>
+        </td>
+        <td><code>neutral.200</code></td>
+        <td><code>neutral_dark.200</code></td>
+        <td>Card edges, row dividers, dialog dividers. The default edge everywhere.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #c0bdb9"></span>
+              <span style="background: #44423f"></span>
+            </span>
+            <code>--ad-color-border-default</code>
+          </div>
+        </td>
+        <td><code>neutral.300</code></td>
+        <td><code>neutral_dark.300</code></td>
+        <td>Input and button borders — anything a reader has to recognize as a control.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<h3 id="text">Text</h3>
+
+<p class="ad-muted">Three levels of emphasis, deliberately not four. Past three, a reader stops perceiving a hierarchy and starts perceiving noise.</p>
+
+<table>
+    <thead>
+      <tr>
+        <th scope="col">Token</th>
+        <th scope="col">Light</th>
+        <th scope="col">Dark</th>
+        <th scope="col">Use for</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #100f0d"></span>
+              <span style="background: #e9e8e6"></span>
+            </span>
+            <code>--ad-color-text-primary</code>
+          </div>
+        </td>
+        <td><code>neutral.900</code></td>
+        <td><code>neutral_dark.900</code></td>
+        <td>Body copy, headings, and every control label.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #5f5d59"></span>
+              <span style="background: #a09e9a"></span>
+            </span>
+            <code>--ad-color-text-secondary</code>
+          </div>
+        </td>
+        <td><code>neutral.600</code></td>
+        <td><code>neutral_dark.600</code></td>
+        <td>Supporting copy, hints, mono meta values, type-label's color.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #888681"></span>
+              <span style="background: #7c7a76"></span>
+            </span>
+            <code>--ad-color-text-tertiary</code>
+          </div>
+        </td>
+        <td><code>neutral.500</code></td>
+        <td><code>neutral_dark.500</code></td>
+        <td>Placeholders and de-emphasized metadata only — never body text. This step is intentionally sub-AA against the page; see the caveat on the Color page.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<h3 id="accent-1">Accent</h3>
+
+<p class="ad-muted">One swappable accent per project, held constant across a whole view. `-ink` and `-soft` re-derive from `--ad-color-accent` via `color-mix()` exactly as the source computes them, so retheming the accent retones both automatically.</p>
+
+<table>
+    <thead>
+      <tr>
+        <th scope="col">Token</th>
+        <th scope="col">Light</th>
+        <th scope="col">Dark</th>
+        <th scope="col">Use for</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #3a6a63"></span>
+              <span style="background: #3a6a63"></span>
+            </span>
+            <code>--ad-color-accent</code>
+          </div>
+        </td>
+        <td><code>accent.teal</code></td>
+        <td><code>accent.teal</code></td>
+        <td>Primary buttons, links, focus affordance, the active tab underline. Never two accents in one view.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #ffffff"></span>
+              <span style="background: #ffffff"></span>
+            </span>
+            <code>--ad-color-accent-fg</code>
+          </div>
+        </td>
+        <td><code>#ffffff</code></td>
+        <td><code>#ffffff</code></td>
+        <td>Label and icon color on a filled accent surface. Fixed white, not a ramp reference.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: repeating-linear-gradient(45deg, var(--ad-color-surface-fill) 0 4px, var(--ad-color-surface-card) 4px 8px);"></span>
+            <code>--ad-color-accent-ink</code>
+          </div>
+        </td>
+        <td><code>color-mix(in oklch, var(--ad-color-accent) 78%, black)</code></td>
+        <td><code>color-mix(in oklch, var(--ad-color-accent) 78%, black)</code></td>
+        <td>Text sitting on an `-soft` accent tint — an IconButton's active state, an accent avatar's initials.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: repeating-linear-gradient(45deg, var(--ad-color-surface-fill) 0 4px, var(--ad-color-surface-card) 4px 8px);"></span>
+            <code>--ad-color-accent-soft</code>
+          </div>
+        </td>
+        <td><code>color-mix(in oklch, var(--ad-color-accent) 12%, white)</code></td>
+        <td><code>color-mix(in oklch, var(--ad-color-accent) 12%, white)</code></td>
+        <td>The tint behind an accent Badge, a toggled IconButton, an accent avatar chip.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<h3 id="status">Status</h3>
+
+<p class="ad-muted">Exactly two states, both fixed — they read the same in every project and are never swapped the way the accent is.</p>
+
+<table>
+    <thead>
+      <tr>
+        <th scope="col">Token</th>
+        <th scope="col">Light</th>
+        <th scope="col">Dark</th>
+        <th scope="col">Use for</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #3f7a4a"></span>
+              <span style="background: #3f7a4a"></span>
+            </span>
+            <code>--ad-color-success</code>
+          </div>
+        </td>
+        <td><code>#3f7a4a</code></td>
+        <td><code>#3f7a4a</code></td>
+        <td>Success text and icons — a completed task's check, a saved-state badge.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: repeating-linear-gradient(45deg, var(--ad-color-surface-fill) 0 4px, var(--ad-color-surface-card) 4px 8px);"></span>
+            <code>--ad-color-success-bg</code>
+          </div>
+        </td>
+        <td><code>color-mix(in oklch, var(--ad-color-success) 12%, white)</code></td>
+        <td><code>color-mix(in oklch, var(--ad-color-success) 12%, white)</code></td>
+        <td>Tint behind a success Badge. Mixed against literal white, so it stays constant across themes.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip ad-alias-chip--pair" aria-hidden="true">
+              <span style="background: #ad3a2c"></span>
+              <span style="background: #ad3a2c"></span>
+            </span>
+            <code>--ad-color-danger</code>
+          </div>
+        </td>
+        <td><code>#ad3a2c</code></td>
+        <td><code>#ad3a2c</code></td>
+        <td>Overdue/destructive text, the Toast undo action, a danger Button's fill.</td>
+      </tr>
+      <tr>
+        <td>
+          <div class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: repeating-linear-gradient(45deg, var(--ad-color-surface-fill) 0 4px, var(--ad-color-surface-card) 4px 8px);"></span>
+            <code>--ad-color-danger-bg</code>
+          </div>
+        </td>
+        <td><code>color-mix(in oklch, var(--ad-color-danger) 10%, white)</code></td>
+        <td><code>color-mix(in oklch, var(--ad-color-danger) 10%, white)</code></td>
+        <td>Tint behind a danger Badge. Mixed against literal white, so it stays constant across themes.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<h2 id="contrast-that-has-to-hold">Contrast that has to hold</h2>
+
+<p>Color is the one part of this system that is not arbitrary: a ratio is a
+fact about two colors and a pair of eyes, and it does not care what the
+palette wants. The pairings below are fixed facts about the token values
+above, computed once with the standard WCAG 2.1 relative-luminance formula
+and checked by hand rather than by a build-time test.</p>
+
+<h3 id="text--451-minimum">Text — 4.5:1 minimum</h3>
+
+<p class="ad-muted">WCAG 2.1 SC 1.4.3 (normal-size text)</p>
+
+<table>
+    <thead>
+      <tr>
+        <th scope="col">Pairing</th>
+        <th scope="col">Where it shows up</th>
+        <th scope="col" class="num">Light</th>
+        <th scope="col" class="num">Dark</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>
+          <span class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: #faf9f7; color: #100f0d; display: grid; place-items: center; font-size: 10px;">Aa</span>
+            <code>color-text-primary<br /><span class="ad-subtle">on color-surface-page</span></code>
+          </span>
+        </td>
+        <td>Body copy</td>
+        <td class="num">18.21</td>
+        <td class="num">15.86</td>
+      </tr>
+      <tr>
+        <td>
+          <span class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: #faf9f7; color: #5f5d59; display: grid; place-items: center; font-size: 10px;">Aa</span>
+            <code>color-text-secondary<br /><span class="ad-subtle">on color-surface-page</span></code>
+          </span>
+        </td>
+        <td>Supporting copy</td>
+        <td class="num">6.24</td>
+        <td class="num">7.26</td>
+      </tr>
+      <tr>
+        <td>
+          <span class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: #3a6a63; color: #ffffff; display: grid; place-items: center; font-size: 10px;">Aa</span>
+            <code>color-accent-fg<br /><span class="ad-subtle">on color-accent</span></code>
+          </span>
+        </td>
+        <td>The label on a primary or dark-variant Button.</td>
+        <td class="num">6.14</td>
+        <td class="num">6.14</td>
+      </tr>
+      <tr>
+        <td>
+          <span class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: #ffffff; color: #3f7a4a; display: grid; place-items: center; font-size: 10px;">Aa</span>
+            <code>color-success<br /><span class="ad-subtle">on color-accent-fg</span></code>
+          </span>
+        </td>
+        <td>Success text on a light backdrop — proxied by color-accent-fg</td>
+        <td class="num">5.13</td>
+        <td class="num">5.13</td>
+      </tr>
+      <tr>
+        <td>
+          <span class="ad-alias-row">
+            <span class="ad-alias-chip" aria-hidden="true" style="background: #ffffff; color: #ad3a2c; display: grid; place-items: center; font-size: 10px;">Aa</span>
+            <code>color-danger<br /><span class="ad-subtle">on color-accent-fg</span></code>
+          </span>
+        </td>
+        <td>Overdue/destructive text on a light backdrop</td>
+        <td class="num">6.14</td>
+        <td class="num">6.14</td>
+      </tr>
+    </tbody>
+  </table>
+
+<div class="ad-callout">
+  <p style="margin:0; font-size: var(--ad-step--1);">
+    Two things this contract deliberately does not assert.
+    <strong>Text tertiary</strong> — <code>--ad-color-text-tertiary</code>
+    (neutral.500) is roughly 3.46:1 against the page in light mode, under the
+    4.5:1 floor. The source documents that step as muted-faint text —
+    placeholders and de-emphasized metadata, never body copy — so this is a
+    real, intentional property of the palette, not a bug to patch by
+    darkening the step.
+    <strong>Borders</strong> — <code>--ad-color-border-hairline</code> and
+    <code>--ad-color-border-default</code> sit well under the 3:1 that WCAG
+    1.4.11 asks of a meaningful boundary. The source's own words are
+    "hairline (1px) borders and dividers do most of the elevation work" —
+    borders here are deliberately quiet, and the source never claims a 3:1
+    bar for them, so this contract does not invent one.
+  </p>
+</div>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>Never write a hex outside <code>assets/css/tokens.css</code>.</strong> If a component
+needs a color that does not exist yet, add the alias.</li>
+  <li><strong>One accent per project, never two in a view.</strong> Swapping <code>--ad-color-accent</code>
+re-derives <code>-ink</code> and <code>-soft</code> automatically via <code>color-mix()</code>.</li>
+  <li><strong><code>--ad-color-success</code> and <code>--ad-color-danger</code> are fixed.</strong> They read the
+same in every project and are never swapped the way the accent is.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/foundations/elevation.html b/design-bundle/foundations/elevation.html
new file mode 100644
index 0000000..670422e
--- /dev/null
+++ b/design-bundle/foundations/elevation.html
@@ -0,0 +1,1821 @@
+<!-- @dsCard group="Foundations" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Elevation</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Foundations</span>
+  <h1>Elevation</h1>
+</header>
+<p class="ad-lead">Two shadow levels only. Hairline (1px) borders do most of the elevation work in this system; shadow is reserved for the one floating layer in a view.</p>
+<h2 id="borders-do-the-work">Borders do the work</h2>
+
+<p>The source’s own rule: “hairline (1px) borders and dividers do most of the
+elevation work”. A flat, bordered <a href="https://kejadlen.github.io/arbitrary-definitions-design-system/components/card/">Card</a>
+is the default everywhere. Shadow is the exception, not the baseline.</p>
+
+<h2 id="the-two-levels">The two levels</h2>
+
+<ul class="ad-elevation-grid">
+  <li>
+    <div class="ad-elevation-demo" style="box-shadow: 0 1px 2px rgba(20, 18, 14, 0.05);"></div>
+    <div class="ad-specimen__meta"><code>shadow-sm</code></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Barely-there separation — a Switch thumb, a focused Input.</p>
+  </li>
+  <li>
+    <div class="ad-elevation-demo" style="box-shadow: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);"></div>
+    <div class="ad-specimen__meta"><code>shadow-float</code></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">The one floating layer in a view. Apply it to at most one element on screen at a time.</p>
+  </li>
+</ul>
+
+<figure class="example">
+<figcaption>Flat vs. float</figcaption>
+<div data-layout="grid" data-surface="sunken">
+<article class="card">
+  <div class="card-body">
+    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Flat</h3>
+    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">The default. A hairline border, no shadow.</p>
+  </div>
+</article>
+<article class="card" data-elevated="">
+  <div class="card-body">
+    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Elevated</h3>
+    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">shadow-float. Reserved for one element per view — a Dialog, a Toast.</p>
+  </div>
+</article>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;article class="card"&gt;
+  &lt;div class="card-body"&gt;
+    &lt;h3&gt;Flat&lt;/h3&gt;
+    &lt;p&gt;The default. A hairline border, no shadow.&lt;/p&gt;
+  &lt;/div&gt;
+&lt;/article&gt;
+&lt;article class="card" data-elevated&gt;
+  &lt;div class="card-body"&gt;
+    &lt;h3&gt;Elevated&lt;/h3&gt;
+    &lt;p&gt;shadow-float. Reserved for one element per view — a Dialog, a Toast.&lt;/p&gt;
+  &lt;/div&gt;
+&lt;/article&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="elevation-in-the-dark-theme">Elevation in the dark theme</h2>
+
+<p>Shadows barely register on a near-black surface. The dark theme leans on
+surface lightness instead — <code>--ad-color-surface-card</code> is one neutral step
+lighter than <code>--ad-color-surface-page</code>, same as in light mode. The shadow
+tokens still apply; they simply stop being the primary signal.</p>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>At most one <code>--ad-shadow-float</code> on screen.</strong> If two things both claim to
+be the topmost layer, neither is.</li>
+  <li><strong>Border or shadow, not both, for a given surface’s edge.</strong> A card that
+both borders and floats looks like a sticker.</li>
+  <li><strong>Never animate a shadow’s blur.</strong> If a floated element needs to arrive,
+animate its <code>opacity</code>, or do not animate it at all.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/foundations/motion.html b/design-bundle/foundations/motion.html
new file mode 100644
index 0000000..059eb4b
--- /dev/null
+++ b/design-bundle/foundations/motion.html
@@ -0,0 +1,1843 @@
+<!-- @dsCard group="Foundations" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Motion</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Foundations</span>
+  <h1>Motion</h1>
+</header>
+<p class="ad-lead">Two durations, one easing curve, and one rule that overrides both: if the reader asked for less motion, they get none. This is an interface, not a title sequence.</p>
+<h2 id="durations">Durations</h2>
+
+<p>Short ease transitions on hover and focus only — no bounce, no springy
+easing, no page-transition choreography.</p>
+
+<table>
+    <thead><tr><th scope="col">Token</th><th scope="col">Value</th><th scope="col">Use for</th></tr></thead>
+    <tbody>
+      <tr>
+        <td><code>--ad-dur-fast</code></td>
+        <td><code>0.12s</code></td>
+        <td>Hover and focus color/border transitions — the default.</td>
+      </tr>
+      <tr>
+        <td><code>--ad-dur-base</code></td>
+        <td><code>0.16s</code></td>
+        <td>Switch track and thumb — the one moving part in the system.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<h2 id="one-easing">One easing</h2>
+
+<p>There is exactly one curve in the system. Hover the tile below to run it.</p>
+
+<ul class="ad-motion-grid">
+  <li>
+    <div class="ad-motion-demo" tabindex="0">
+      <span class="ad-motion-demo__dot"></span>
+    </div>
+    <div class="ad-specimen__meta"><code>--ad-ease</code></div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">The only easing curve in the system. Fast out, settles gently, applied to every transition.</p>
+  </li>
+</ul>
+
+<h2 id="reduced-motion-is-not-a-downgrade">Reduced motion is not a downgrade</h2>
+
+<p><code>tokens.css</code> includes a <code>prefers-reduced-motion: reduce</code> block that sets
+every duration token to <code>0ms</code>, and the base stylesheet clamps any remaining
+transition or animation to a hundredth of a millisecond. Components do not
+have to opt in, and cannot opt out.</p>
+
+<pre><code class="language-css">@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+</code></pre>
+
+<p>The state change still happens. The Switch still moves. It simply arrives
+instead of traveling.</p>
+
+<figure class="example">
+<figcaption>Motion in practice</figcaption>
+<div>
+<label class="switch">
+  <input type="checkbox" role="switch" checked="" />
+  <span></span>
+  Dark mode
+</label>
+<label class="switch">
+  <input type="checkbox" role="switch" />
+  <span></span>
+  Weekly digest
+</label>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;label class="switch"&gt;
+  &lt;input type="checkbox" role="switch" checked&gt;
+  &lt;span&gt;&lt;/span&gt;
+  Dark mode
+&lt;/label&gt;
+&lt;label class="switch"&gt;
+  &lt;input type="checkbox" role="switch"&gt;
+  &lt;span&gt;&lt;/span&gt;
+  Weekly digest
+&lt;/label&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>Transition named properties, never <code>all</code>.</strong> <code>transition: all</code> animates
+things you did not think about, including layout.</li>
+  <li><strong>Hover states shift a background one step deeper, never a color or
+opacity trick.</strong> Surface → fill is the whole vocabulary.</li>
+  <li><strong>Press is not animated.</strong> Rely on the hover-darken plus native <code>:active</code>,
+if anything at all.</li>
+  <li><strong>Motion is for hover and focus only.</strong> No page-transition choreography.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/foundations/space.html b/design-bundle/foundations/space.html
new file mode 100644
index 0000000..3e4bd50
--- /dev/null
+++ b/design-bundle/foundations/space.html
@@ -0,0 +1,1941 @@
+<!-- @dsCard group="Foundations" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Space</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Foundations</span>
+  <h1>Space</h1>
+</header>
+<p class="ad-lead">Nine fluid Utopia steps, 3xs through 3xl — the same clamp() config as type, because there is no fixed base unit here to count multiples of.</p>
+<h2 id="the-scale">The scale</h2>
+
+<div class="ad-ruler">
+  <div class="ad-ruler__row">
+    <code>space-3xs</code>
+    <span class="ad-ruler__num">5px</span>
+    <span class="ad-ruler__bar" style="width: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-2xs</code>
+    <span class="ad-ruler__num">9 → 10px</span>
+    <span class="ad-ruler__bar" style="width: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-xs</code>
+    <span class="ad-ruler__num">14 → 15px</span>
+    <span class="ad-ruler__bar" style="width: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-s</code>
+    <span class="ad-ruler__num">18 → 20px</span>
+    <span class="ad-ruler__bar" style="width: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-m</code>
+    <span class="ad-ruler__num">27 → 30px</span>
+    <span class="ad-ruler__bar" style="width: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-l</code>
+    <span class="ad-ruler__num">36 → 40px</span>
+    <span class="ad-ruler__bar" style="width: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-xl</code>
+    <span class="ad-ruler__num">54 → 60px</span>
+    <span class="ad-ruler__bar" style="width: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-2xl</code>
+    <span class="ad-ruler__num">72 → 80px</span>
+    <span class="ad-ruler__bar" style="width: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem); min-width: 1px;"></span>
+  </div>
+  <div class="ad-ruler__row">
+    <code>space-3xl</code>
+    <span class="ad-ruler__num">108 → 120px</span>
+    <span class="ad-ruler__bar" style="width: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem); min-width: 1px;"></span>
+  </div>
+</div>
+
+<h2 id="how-to-pick-one">How to pick one</h2>
+
+<table>
+  <thead>
+    <tr>
+      <th>Distance between</th>
+      <th>Reach for</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>An icon and its own label</td>
+      <td><code>--ad-space-3xs</code> / <code>--ad-space-2xs</code></td>
+    </tr>
+    <tr>
+      <td>A field’s label and its control</td>
+      <td><code>--ad-space-2xs</code></td>
+    </tr>
+    <tr>
+      <td>Two controls in a row, CardRow padding</td>
+      <td><code>--ad-space-xs</code></td>
+    </tr>
+    <tr>
+      <td>Two fields in a form, a Dialog’s title/footer padding</td>
+      <td><code>--ad-space-s</code></td>
+    </tr>
+    <tr>
+      <td>Card body padding, a Dialog’s body padding</td>
+      <td><code>--ad-space-m</code></td>
+    </tr>
+    <tr>
+      <td>Two sections of a page</td>
+      <td><code>--ad-space-l</code></td>
+    </tr>
+    <tr>
+      <td>Major section spacing</td>
+      <td><code>--ad-space-xl</code> / <code>--ad-space-2xl</code></td>
+    </tr>
+    <tr>
+      <td>Hero and empty-state breathing room</td>
+      <td><code>--ad-space-3xl</code></td>
+    </tr>
+  </tbody>
+</table>
+
+<figure class="example">
+<figcaption>The same card at three densities</figcaption>
+<div data-layout="grid">
+<article class="card">
+  <div class="card-body" style="gap: var(--ad-space-3xs); padding: var(--ad-space-xs);">
+    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Compact</h3>
+    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">space-xs padding, space-3xs gap. For dense lists.</p>
+  </div>
+</article>
+<article class="card">
+  <div class="card-body">
+    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Default</h3>
+    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">space-m padding, space-2xs gap. What Card ships with.</p>
+  </div>
+</article>
+<article class="card">
+  <div class="card-body" style="gap: var(--ad-space-s); padding: var(--ad-space-l);">
+    <h3 style="margin:0; font: 600 var(--ad-step--1)/1.3 var(--ad-font-sans);">Roomy</h3>
+    <p style="margin:0; color: var(--ad-color-text-secondary); font-size: var(--ad-step--1);">space-l padding, space-s gap. For a card that is the whole screen.</p>
+  </div>
+</article>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;article class="card"&gt;
+  &lt;div class="card-body" style="gap: var(--ad-space-3xs); padding: var(--ad-space-xs);"&gt;
+    &lt;h3&gt;Compact&lt;/h3&gt;
+    &lt;p&gt;space-xs padding, space-3xs gap. For dense lists.&lt;/p&gt;
+  &lt;/div&gt;
+&lt;/article&gt;
+&lt;article class="card"&gt;
+  &lt;div class="card-body"&gt;
+    &lt;h3&gt;Default&lt;/h3&gt;
+    &lt;p&gt;space-m padding, space-2xs gap. What Card ships with.&lt;/p&gt;
+  &lt;/div&gt;
+&lt;/article&gt;
+&lt;article class="card"&gt;
+  &lt;div class="card-body" style="gap: var(--ad-space-s); padding: var(--ad-space-l);"&gt;
+    &lt;h3&gt;Roomy&lt;/h3&gt;
+    &lt;p&gt;space-l padding, space-s gap. For a card that is the whole screen.&lt;/p&gt;
+  &lt;/div&gt;
+&lt;/article&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="radius">Radius</h2>
+
+<p>4/6/10px — small and quiet, kept modest so it reads as a neutral default
+rather than any one source project’s specific softness. Nothing pill-shaped
+except true pills.</p>
+
+<ul class="ad-radius-grid">
+  <li>
+    <div class="ad-radius-demo" style="border-radius: 4px;"></div>
+    <div class="ad-specimen__meta">
+      <code>radius-sm</code>
+      <span>4px</span>
+    </div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Buttons, inputs, badges, tags.</p>
+  </li>
+  <li>
+    <div class="ad-radius-demo" style="border-radius: 6px;"></div>
+    <div class="ad-specimen__meta">
+      <code>radius-md</code>
+      <span>6px</span>
+    </div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">IconButton, the segmented-tabs track, avatar chips.</p>
+  </li>
+  <li>
+    <div class="ad-radius-demo" style="border-radius: 10px;"></div>
+    <div class="ad-specimen__meta">
+      <code>radius-lg</code>
+      <span>10px</span>
+    </div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">Cards, dialogs, toasts, photo slots — the system's "surface" radius.</p>
+  </li>
+  <li>
+    <div class="ad-radius-demo" style="border-radius: 999px;"></div>
+    <div class="ad-specimen__meta">
+      <code>radius-full</code>
+      <span>999px</span>
+    </div>
+    <p class="ad-muted" style="font-size: var(--ad-step--2); margin: var(--ad-space-3xs) 0 0;">True pills only — Badge, Tag, Switch, round avatars.</p>
+  </li>
+</ul>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>Space comes from the parent.</strong> A component sets its own internal padding
+and never its external margin; the layout that contains it owns the gap.</li>
+  <li><strong>Use <code>gap</code>.</strong> Flex and grid gaps do not collapse and do not need a
+<code>:last-child</code> reset.</li>
+  <li><strong>A value not on the scale is a bug</strong>, not a nudge. If a gap looks wrong,
+the scale is wrong and should change for everybody.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/foundations/typography.html b/design-bundle/foundations/typography.html
new file mode 100644
index 0000000..cfa620b
--- /dev/null
+++ b/design-bundle/foundations/typography.html
@@ -0,0 +1,1987 @@
+<!-- @dsCard group="Foundations" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Typography</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Foundations</span>
+  <h1>Typography</h1>
+</header>
+<p class="ad-lead">Three families, eight fluid steps, eight compound styles. Sans for interface, mono for every label and technical value, serif as an opt-in reading variant.</p>
+<h2 id="families">Families</h2>
+
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-font-sans</code>
+    <span>Interface text — every component, every screen. Web-safe; nothing is loaded for it.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-family: var(--ad-font-sans); font-size: 1.5rem;">
+    Arbitrary Definitions — 0123456789
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-font-mono</code>
+    <span>Every label, meta value, technical/catalog value, and code sample. The system's one loaded webfont.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-family: var(--ad-font-mono); font-size: 1.5rem;">
+    Arbitrary Definitions — 0123456789
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-font-serif</code>
+    <span>Opt-in reading variant for a project that wants an editorial, archival feel (domus-style). Not loaded by default; web-safe only.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-family: var(--ad-font-serif); font-size: 1.5rem;">
+    Arbitrary Definitions — 0123456789
+  </div>
+</div>
+
+<p>Only one webfont is loaded — IBM Plex Mono, at 400/500/600:</p>
+
+<pre><code class="language-css">@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&amp;display=swap');
+</code></pre>
+
+<p>Sans is a web-safe system stack; serif is Georgia-based and opt-in, for a
+project that wants an editorial or archival feel. Neither is fetched.</p>
+
+<h2 id="fluid-scale">Fluid scale</h2>
+
+<p>Eight steps, <code>clamp()</code>-based (Utopia, 320→1240px viewport). The body sits at
+<code>--ad-step-0</code> — 18px on a phone, 20px on a wide screen — with no fixed
+breakpoint in between.</p>
+
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step--2</code>
+    <span>12.5 → 12.8px</span>
+    <span>type-label — eyebrows, catalog labels, meta.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step--2);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step--1</code>
+    <span>15 → 16px</span>
+    <span>type-body-sm and type-mono — secondary copy, technical values.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step--1);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step-0</code>
+    <span>18 → 20px</span>
+    <span>type-body — the base size, and the body element's own size.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step-0);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step-1</code>
+    <span>22 → 25px</span>
+    <span>type-h3 — card and subsection headings.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step-1);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step-2</code>
+    <span>26 → 31px</span>
+    <span>type-h2 — section headings.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step-2);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step-3</code>
+    <span>31 → 39px</span>
+    <span>type-h1 — screen titles.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step-3);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step-4</code>
+    <span>37 → 49px</span>
+    <span>type-display — one hero title per screen, at most.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step-4);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+<div class="ad-specimen">
+  <div class="ad-specimen__meta">
+    <code>--ad-step-5</code>
+    <span>45 → 61px</span>
+    <span>Reserved headroom. No compound style claims it yet.</span>
+  </div>
+  <div class="ad-specimen__sample" style="font-size: var(--ad-step-5);">
+    The quick brown fox jumps over the lazy dog
+  </div>
+</div>
+
+<h2 id="the-eight-compound-styles">The eight compound styles</h2>
+
+<p>Real, specific numbers from the source — not a generic ramp compressed to
+fit. Each class sets family, size, weight, line-height, and (where the
+source specifies one) letter-spacing in a single declaration.</p>
+
+<table>
+    <thead><tr><th scope="col">Class</th><th scope="col">Weight</th><th scope="col">Size</th><th scope="col">Line-height</th><th scope="col">Tracking</th><th scope="col">Use for</th></tr></thead>
+    <tbody>
+      <tr>
+        <td><code>.type-display</code></td>
+        <td>600</td>
+        <td><code>--ad-step-4</code></td>
+        <td>1.08</td>
+        <td>-0.015em</td>
+        <td>Page-level hero title, once per screen.</td>
+      </tr>
+      <tr>
+        <td><code>.type-h1</code></td>
+        <td>600</td>
+        <td><code>--ad-step-3</code></td>
+        <td>1.12</td>
+        <td>-0.012em</td>
+        <td>Screen title.</td>
+      </tr>
+      <tr>
+        <td><code>.type-h2</code></td>
+        <td>600</td>
+        <td><code>--ad-step-2</code></td>
+        <td>1.16</td>
+        <td>-0.01em</td>
+        <td>Section heading.</td>
+      </tr>
+      <tr>
+        <td><code>.type-h3</code></td>
+        <td>600</td>
+        <td><code>--ad-step-1</code></td>
+        <td>1.25</td>
+        <td>normal</td>
+        <td>Card / subsection heading.</td>
+      </tr>
+      <tr>
+        <td><code>.type-body</code></td>
+        <td>400</td>
+        <td><code>--ad-step-0</code></td>
+        <td>1.55</td>
+        <td>normal</td>
+        <td>Body copy.</td>
+      </tr>
+      <tr>
+        <td><code>.type-body-sm</code></td>
+        <td>400</td>
+        <td><code>--ad-step--1</code></td>
+        <td>1.5</td>
+        <td>normal</td>
+        <td>Secondary copy, hints.</td>
+      </tr>
+      <tr>
+        <td><code>.type-label</code></td>
+        <td>500</td>
+        <td><code>--ad-step--2</code></td>
+        <td>1</td>
+        <td>0.08em</td>
+        <td>Eyebrows, catalog labels, meta — SAVED, RECOMMENDED, OVERDUE.</td>
+      </tr>
+      <tr>
+        <td><code>.type-mono</code></td>
+        <td>400</td>
+        <td><code>--ad-step--1</code></td>
+        <td>1.5</td>
+        <td>normal</td>
+        <td>Technical values, IDs, dates, code.</td>
+      </tr>
+    </tbody>
+  </table>
+
+<figure class="example">
+<figcaption>All eight, in order</figcaption>
+<div data-layout="stack">
+<div class="type-display">Display</div>
+<h1 class="type-h1">Heading one</h1>
+<h2 class="type-h2">Heading two</h2>
+<h3 class="type-h3">Heading three</h3>
+<p class="type-body">Body copy at the base size, 1.55 line-height.</p>
+<p class="type-body-sm">Secondary copy, one step down.</p>
+<span class="type-label">Catalog label</span>
+<span class="type-mono">technical.value / 2026-08-21 / #3a6a63</span>
+</div>
+<details><summary>Markup</summary>
+<pre><code>&lt;div class="type-display"&gt;Display&lt;/div&gt;
+&lt;h1 class="type-h1"&gt;Heading one&lt;/h1&gt;
+&lt;h2 class="type-h2"&gt;Heading two&lt;/h2&gt;
+&lt;h3 class="type-h3"&gt;Heading three&lt;/h3&gt;
+&lt;p class="type-body"&gt;Body copy at the base size, 1.55 line-height.&lt;/p&gt;
+&lt;p class="type-body-sm"&gt;Secondary copy, one step down.&lt;/p&gt;
+&lt;span class="type-label"&gt;Catalog label&lt;/span&gt;
+&lt;span class="type-mono"&gt;technical.value / 2026-08-21 / #3a6a63&lt;/span&gt;</code></pre>
+</details>
+</figure>
+
+<h2 id="rules">Rules</h2>
+
+<ul>
+  <li><strong>Three families, and no fourth.</strong> A new typeface needs a reason a weight
+or a size cannot supply.</li>
+  <li><strong>Mono is not decoration.</strong> Every label, meta value, ID, date, and code
+sample is mono — it is the one thread present in all three source projects.</li>
+  <li><strong><code>type-label</code> is always uppercase, mono, and tracked.</strong> It is the one
+place uppercase belongs in this system.</li>
+  <li><strong>Never set a size in <code>px</code>.</strong> The eight steps are fluid on purpose.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/patterns/archive.html b/design-bundle/patterns/archive.html
new file mode 100644
index 0000000..3ce15b8
--- /dev/null
+++ b/design-bundle/patterns/archive.html
@@ -0,0 +1,1860 @@
+<!-- @dsCard group="Patterns" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Archive</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Patterns</span>
+  <h1>Archive — capture app</h1>
+</header>
+<p class="ad-lead">A capture/document mobile app. Card list, bottom capture dock, photo slots with the diagonal-grain empty state. A generic demonstration of the system, not a recreation of any one source project's actual screens.</p>
+<p>Archive is not a real product — it is the system’s own reference layout for a
+mobile capture flow: the shape <code>kejadlen/domus</code> (a household inventory and
+document archive) would take if it were rebuilt on this token set, at its
+390×760 frame. Three screens, abbreviated to what each one adds.</p>
+
+<figure class="example">
+<figcaption>Home — recent captures</figcaption>
+<div>
+<div style="width: 300px; height: 560px; background: var(--ad-color-surface-page); border-radius: var(--ad-radius-lg); box-shadow: var(--ad-shadow-float); overflow:hidden; display:flex; flex-direction:column; position:relative;">
+  <header style="padding: 16px var(--ad-space-m) var(--ad-space-2xs);">
+    <span style="font-weight:600; font-size: var(--ad-step-1); letter-spacing:-0.01em;">Archive</span>
+  </header>
+  <div style="flex:1; overflow:hidden; padding: 0 var(--ad-space-m);">
+    <div style="display:flex; align-items:baseline; gap:8px; margin: var(--ad-space-s) 0 var(--ad-space-xs);">
+      <span style="font-weight:700; font-size: var(--ad-step-0);">Recent</span>
+      <span class="type-label" style="margin-left:auto;">3 tracked</span>
+    </div>
+    <ul class="card">
+      <li>
+        <span class="avatar" data-square=""><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
+        <div style="flex:1; min-width:0;">
+          <div style="font-weight:550; font-size: var(--ad-step--1); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;">Dishwasher manual</div>
+          <div class="type-label" style="margin-top:2px;">PDF · 2.1MB</div>
+        </div>
+        <span class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">2h</span>
+      </li>
+      <li>
+        <span class="avatar" data-square=""><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
+        <div style="flex:1; min-width:0;">
+          <div style="font-weight:550; font-size: var(--ad-step--1);">Sofa receipt</div>
+          <div class="type-label" style="margin-top:2px;">JPG · 640KB</div>
+        </div>
+        <span class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">1d</span>
+      </li>
+      <li>
+        <span class="avatar" data-square=""><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
+        <div style="flex:1; min-width:0;">
+          <div style="font-weight:550; font-size: var(--ad-step--1);">Passport scan</div>
+          <div class="type-label" style="margin-top:2px;">PDF · 890KB</div>
+        </div>
+        <span class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">4d</span>
+      </li>
+    </ul>
+  </div>
+  <div style="position:absolute; left:0; right:0; bottom:0; display:flex; justify-content:center; padding: 14px 20px 22px; background: linear-gradient(to top, var(--ad-color-surface-page) 65%, transparent);">
+    <button data-variant="primary" data-size="lg" data-block="">
+      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8a2 2 0 0 1 2-2h1.5l1-1.5h9l1 1.5H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8Z" /><circle cx="12" cy="13" r="3.5" /></svg>
+      Take a photo
+    </button>
+  </div>
+</div>
+<div style="width: 300px; height: 560px; background: var(--ad-color-surface-page); border-radius: var(--ad-radius-lg); box-shadow: var(--ad-shadow-float); overflow:hidden; display:flex; flex-direction:column;">
+  <header style="display:flex; align-items:center; gap:8px; padding: 16px var(--ad-space-m) var(--ad-space-2xs);">
+    <button class="icon-button" data-size="sm" aria-label="Back"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
+    <span style="font-weight:600; font-size: var(--ad-step-0);">Save</span>
+  </header>
+  <div style="flex:1; padding: 0 var(--ad-space-m);">
+    <div style="height: 180px; border-radius: var(--ad-radius-lg); border: 1px solid var(--ad-color-border-default); background: repeating-linear-gradient(45deg, transparent 0 8px, var(--ad-color-surface-fill-2) 8px 9px), var(--ad-color-surface-fill); display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px; margin-top: var(--ad-space-s);">
+      <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg>
+      <span class="type-label">Photo preview</span>
+    </div>
+    <label class="field" style="margin-top: var(--ad-space-m);">
+      Name
+      <input placeholder="Dishwasher manual" />
+    </label>
+  </div>
+  <div style="padding: var(--ad-space-m); display:flex; gap: var(--ad-space-2xs);">
+    <button style="flex:1;">Retake</button>
+    <button data-variant="primary" style="flex:1;">Save</button>
+  </div>
+</div>
+<div style="width: 300px; height: 560px; background: var(--ad-color-surface-page); border-radius: var(--ad-radius-lg); box-shadow: var(--ad-shadow-float); overflow:hidden; display:flex; flex-direction:column;">
+  <header style="display:flex; align-items:center; gap:8px; padding: 16px var(--ad-space-m) var(--ad-space-2xs);">
+    <button class="icon-button" data-size="sm" aria-label="Back"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
+    <span class="type-label">Archive</span>
+  </header>
+  <div style="flex:1; overflow:hidden; padding: 0 var(--ad-space-m) var(--ad-space-l);">
+    <h1 style="font-weight:700; font-size: var(--ad-step-2); letter-spacing:-0.01em; margin: var(--ad-space-xs) 0 var(--ad-space-2xs);">Dishwasher manual</h1>
+    <div style="display:flex; gap:6px; flex-wrap:wrap; margin-bottom: var(--ad-space-m);">
+      <span class="tag">location:kitchen</span>
+      <span class="tag" data-dashed="">+ add tag</span>
+    </div>
+    <div class="type-label" style="margin-bottom: var(--ad-space-2xs);">File</div>
+    <ul class="card">
+      <li>
+        <span class="avatar" data-square=""><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 8 12 3 3 8v8l9 5 9-5V8Z" /><path d="M3 8l9 5 9-5M12 13v8" /></svg></span>
+        <div style="flex:1; font-size: var(--ad-step--1);">PDF · 2.1MB</div>
+      </li>
+    </ul>
+    <div class="type-label" style="margin: var(--ad-space-m) 0 var(--ad-space-2xs);">Notes</div>
+    <p style="font-size: var(--ad-step--1); color: var(--ad-color-text-secondary); line-height:1.55; margin:0;">No notes yet.</p>
+  </div>
+</div>
+</div>
+</figure>
+
+<h2 id="what-this-screen-is-testing">What this screen is testing</h2>
+
+<ul>
+  <li><strong>The diagonal-grain empty state.</strong> The only patterned background this
+system permits, used only inside an empty photo slot.</li>
+  <li><strong>CardRow as a file row, twice.</strong> The same component holds a scannable
+list on Home and a single, focused row on Detail — no special “detail row”
+variant needed.</li>
+  <li><strong>Tag alongside its own dashed “add” affordance.</strong> The two live in one row,
+reading as one continuous, extendable list.</li>
+  <li><strong><code>type-label</code> as the workhorse.</strong> File size, tag count, and the back-button
+screen name all reach for the same mono catalog-label convention as Badge.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/design-bundle/patterns/loop.html b/design-bundle/patterns/loop.html
new file mode 100644
index 0000000..c5f4150
--- /dev/null
+++ b/design-bundle/patterns/loop.html
@@ -0,0 +1,1932 @@
+<!-- @dsCard group="Patterns" -->
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Loop</title>
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
+<style>
+/* Arbitrary Definitions — design tokens. Hand-maintained; edit values directly. */
+
+:root {
+  /* Palette ramps — reference only. Components use the aliases below. */
+  --ad-neutral-0: #faf9f7;
+  --ad-neutral-50: #fdfdfb;
+  --ad-neutral-100: #f1f0ed;
+  --ad-neutral-150: #e8e6e2;
+  --ad-neutral-200: #dcdad7;
+  --ad-neutral-300: #c0bdb9;
+  --ad-neutral-500: #888681;
+  --ad-neutral-600: #5f5d59;
+  --ad-neutral-800: #2a2926;
+  --ad-neutral-900: #100f0d;
+  --ad-neutral-dark-0: #0e0d0b;
+  --ad-neutral-dark-50: #151412;
+  --ad-neutral-dark-100: #1e1d1a;
+  --ad-neutral-dark-150: #252421;
+  --ad-neutral-dark-200: #2c2b29;
+  --ad-neutral-dark-300: #44423f;
+  --ad-neutral-dark-500: #7c7a76;
+  --ad-neutral-dark-600: #a09e9a;
+  --ad-neutral-dark-800: #d9d7d4;
+  --ad-neutral-dark-900: #e9e8e6;
+  --ad-accent-teal: #3a6a63;
+  --ad-accent-clay: #9a5a3c;
+  --ad-accent-ink-blue: #2b4a78;
+  --ad-accent-ochre: #93701f;
+  --ad-accent-plum: #6a3a5c;
+
+  /* Surfaces */
+  --ad-color-surface-page: #faf9f7;
+  --ad-color-surface-card: #fdfdfb;
+  --ad-color-surface-fill: #f1f0ed;
+  --ad-color-surface-fill-2: #e8e6e2;
+
+  /* Borders */
+  --ad-color-border-hairline: #dcdad7;
+  --ad-color-border-default: #c0bdb9;
+
+  /* Text */
+  --ad-color-text-primary: #100f0d;
+  --ad-color-text-secondary: #5f5d59;
+  --ad-color-text-tertiary: #888681;
+
+  /* Accent */
+  --ad-color-accent: #3a6a63;
+  --ad-color-accent-fg: #ffffff;
+  --ad-color-accent-ink: color-mix(in oklch, var(--ad-color-accent) 78%, black);
+  --ad-color-accent-soft: color-mix(in oklch, var(--ad-color-accent) 12%, white);
+
+  /* Status (fixed — never swapped like the accent) */
+  --ad-color-success: #3f7a4a;
+  --ad-color-success-bg: color-mix(in oklch, var(--ad-color-success) 12%, white);
+  --ad-color-danger: #ad3a2c;
+  --ad-color-danger-bg: color-mix(in oklch, var(--ad-color-danger) 10%, white);
+
+  /* Type families */
+  --ad-font-sans: -apple-system, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
+  --ad-font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Courier New", monospace;
+  --ad-font-serif: Georgia, "Times New Roman", "Iowan Old Style", serif;
+
+  /* Type steps — fluid (Utopia scale), the design system's own body-text size */
+  --ad-step--2: clamp(0.7813rem, 0.7736rem + 0.0341vw, 0.8rem);
+  --ad-step--1: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem);
+  --ad-step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-step-1: clamp(1.35rem, 1.2631rem + 0.3864vw, 1.5625rem);
+  --ad-step-2: clamp(1.62rem, 1.4837rem + 0.6057vw, 1.9531rem);
+  --ad-step-3: clamp(1.944rem, 1.7405rem + 0.9044vw, 2.4414rem);
+  --ad-step-4: clamp(2.3328rem, 2.0387rem + 1.3072vw, 3.0518rem);
+  --ad-step-5: clamp(2.7994rem, 2.384rem + 1.8461vw, 3.8147rem);
+
+  /* Space */
+  --ad-space-3xs: clamp(0.3125rem, 0.3125rem + 0vw, 0.3125rem);
+  --ad-space-2xs: clamp(0.5625rem, 0.5369rem + 0.1136vw, 0.625rem);
+  --ad-space-xs: clamp(0.875rem, 0.8494rem + 0.1136vw, 0.9375rem);
+  --ad-space-s: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
+  --ad-space-m: clamp(1.6875rem, 1.6108rem + 0.3409vw, 1.875rem);
+  --ad-space-l: clamp(2.25rem, 2.1477rem + 0.4545vw, 2.5rem);
+  --ad-space-xl: clamp(3.375rem, 3.2216rem + 0.6818vw, 3.75rem);
+  --ad-space-2xl: clamp(4.5rem, 4.2955rem + 0.9091vw, 5rem);
+  --ad-space-3xl: clamp(6.75rem, 6.4432rem + 1.3636vw, 7.5rem);
+
+  /* Radius */
+  --ad-radius-sm: 4px;
+  --ad-radius-md: 6px;
+  --ad-radius-lg: 10px;
+  --ad-radius-full: 999px;
+  --ad-border-w: 1px;
+
+  /* Elevation */
+  --ad-shadow-sm: 0 1px 2px rgba(20, 18, 14, 0.05);
+  --ad-shadow-float: 0 2px 6px rgba(20, 18, 14, 0.06), 0 10px 24px -12px rgba(20, 18, 14, 0.18);
+
+  /* Motion */
+  --ad-dur-fast: 0.12s;
+  --ad-dur-base: 0.16s;
+  --ad-ease: cubic-bezier(0.2, 0, 0, 1);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    color-scheme: dark;
+    --ad-color-surface-page: #0e0d0b;
+    --ad-color-surface-card: #151412;
+    --ad-color-surface-fill: #1e1d1a;
+    --ad-color-surface-fill-2: #252421;
+    --ad-color-border-hairline: #2c2b29;
+    --ad-color-border-default: #44423f;
+    --ad-color-text-primary: #e9e8e6;
+    --ad-color-text-secondary: #a09e9a;
+    --ad-color-text-tertiary: #7c7a76;
+  }
+}
+
+:root[data-theme="dark"] {
+  color-scheme: dark;
+  --ad-color-surface-page: #0e0d0b;
+  --ad-color-surface-card: #151412;
+  --ad-color-surface-fill: #1e1d1a;
+  --ad-color-surface-fill-2: #252421;
+  --ad-color-border-hairline: #2c2b29;
+  --ad-color-border-default: #44423f;
+  --ad-color-text-primary: #e9e8e6;
+  --ad-color-text-secondary: #a09e9a;
+  --ad-color-text-tertiary: #7c7a76;
+}
+
+@media (prefers-reduced-motion: reduce) {
+  :root {
+    --ad-dur-fast: 0ms;
+    --ad-dur-base: 0ms;
+  }
+}
+
+/* A short reset. Everything it sets is something the system would otherwise
+   have to override in every component.
+
+   The rem values used for this documentation site's own chrome (measure,
+   content width, sidebar width, header height) belong to this site, not to
+   the design system it documents — the source design system defines no
+   container-width tokens at all, so there is nothing under `--ad-*` to reach
+   for here. See the header comment in site/shell.css. */
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+
+html {
+  -webkit-text-size-adjust: 100%;
+  scroll-behavior: smooth;
+  scroll-padding-top: calc(3.5rem + var(--ad-space-s));
+}
+
+@media (prefers-reduced-motion: reduce) {
+  html { scroll-behavior: auto; }
+  *,
+  *::before,
+  *::after {
+    animation-duration: 0.01ms !important;
+    animation-iteration-count: 1 !important;
+    transition-duration: 0.01ms !important;
+  }
+}
+
+body {
+  margin: 0;
+  background: var(--ad-color-surface-page);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  line-height: 1.55;
+  font-synthesis-weight: none;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+}
+
+::selection {
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+}
+
+h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
+ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }
+
+img, svg, video { display: block; max-width: 100%; height: auto; }
+
+button, input, select, textarea {
+  font: inherit;
+  color: inherit;
+}
+
+hr {
+  height: 1px;
+  margin: var(--ad-space-l) 0;
+  border: 0;
+  background: var(--ad-color-border-hairline);
+}
+
+/* One focus ring, defined once. No component is allowed its own. */
+:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+  border-radius: var(--ad-radius-sm);
+}
+:focus:not(:focus-visible) { outline: none; }
+
+[hidden] { display: none !important; }
+
+.ad-visually-hidden {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  margin: -1px;
+  overflow: hidden;
+  clip-path: inset(50%);
+  white-space: nowrap;
+  border: 0;
+}
+
+/* Every rule here reads a type token for family and size. Weight, line-height,
+   and letter-spacing are hardcoded to the exact numbers the source ships —
+   there is no `--ad-weight-*` / `--ad-leading-*` / `--ad-tracking-*` scale in
+   the real system, only eight fixed compound styles (see the Typography
+   foundation page, which this file implements verbatim). */
+
+.type-display { font: 600 var(--ad-step-4)/1.08 var(--ad-font-sans); letter-spacing: -0.015em; }
+.type-h1, h1 { font: 600 var(--ad-step-3)/1.12 var(--ad-font-sans); letter-spacing: -0.012em; }
+.type-h2, h2 { font: 600 var(--ad-step-2)/1.16 var(--ad-font-sans); letter-spacing: -0.01em; }
+.type-h3, h3 { font: 600 var(--ad-step-1)/1.25 var(--ad-font-sans); }
+.type-body    { font: 400 var(--ad-step-0)/1.55 var(--ad-font-sans); }
+.type-body-sm { font: 400 var(--ad-step--1)/1.5 var(--ad-font-sans); }
+.type-label {
+  font: 500 var(--ad-step--2)/1 var(--ad-font-mono);
+  text-transform: uppercase;
+  letter-spacing: 0.08em;
+  color: var(--ad-color-text-secondary);
+}
+.type-mono { font: 400 var(--ad-step--1)/1.5 var(--ad-font-mono); }
+
+/* Prose defaults for the documentation body copy. These read the same
+   tokens the compound classes above do; they are not a second scale. */
+h1, h2, h3, h4 { font-weight: 600; text-wrap: balance; }
+
+h4 { font: 600 var(--ad-step-0)/1.3 var(--ad-font-sans); }
+
+p, ul, ol { margin: 0 0 var(--ad-space-s); }
+li + li { margin-top: var(--ad-space-3xs); }
+
+a {
+  color: var(--ad-color-accent);
+  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
+  text-underline-offset: 0.18em;
+  text-decoration-thickness: 1px;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              text-decoration-color var(--ad-dur-fast) var(--ad-ease);
+}
+a:hover {
+  color: var(--ad-color-accent-ink);
+  text-decoration-color: currentColor;
+}
+
+strong, b { font-weight: 600; }
+
+small { font-size: var(--ad-step--1); }
+
+.ad-lead {
+  font-size: var(--ad-step-1);
+  line-height: 1.5;
+  color: var(--ad-color-text-secondary);
+  max-width: 68ch;
+  text-wrap: pretty;
+}
+
+.ad-muted { color: var(--ad-color-text-secondary); }
+.ad-subtle { color: var(--ad-color-text-tertiary); }
+
+code, kbd, samp, pre {
+  font-family: var(--ad-font-mono);
+  font-feature-settings: "liga" 0;
+}
+
+:not(pre) > code {
+  padding: 0.15em 0.4em;
+  font-size: 0.875em;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-sm);
+  white-space: nowrap;
+}
+
+kbd {
+  display: inline-block;
+  padding: 0.1em 0.45em;
+  font-size: var(--ad-step--2);
+  line-height: 1.6;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-bottom-width: 2px;
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-secondary);
+}
+
+blockquote {
+  margin-block: var(--ad-space-s);
+  padding-left: var(--ad-space-s);
+  border-left: 2px solid var(--ad-color-accent);
+  color: var(--ad-color-text-secondary);
+}
+
+/* Button
+   A flat, quiet button that recedes rather than performs — no gradients, no
+   shine. Variants: default, primary, dark, ghost, danger. Sizes: sm, md
+   (default), lg — padding and font step only, weight and radius stay put.
+
+   The contract is the element itself: a bare <button> is styled directly, no
+   class required. An <a> that acts like a button (navigates rather than
+   changes something — see the Button page's "Links that act like buttons")
+   opts in with a single `.btn` class, since a bare `a` selector would catch
+   every ordinary prose link on the site. `:not(.icon-button)` keeps this
+   block from leaking onto IconButton, which shares the <button> tag but is
+   an entirely different shape. */
+
+button:not(.icon-button),
+a.btn {
+  --_bg: var(--ad-color-surface-card);
+  --_fg: var(--ad-color-text-primary);
+  --_border: var(--ad-color-border-default);
+  --_pad: var(--ad-space-xs) var(--ad-space-s);
+  --_font: var(--ad-step--1);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  gap: var(--ad-space-2xs);
+  padding: var(--_pad);
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-sans);
+  font-size: var(--_font);
+  font-weight: 550;
+  letter-spacing: -0.01em;
+  line-height: 1.2;
+  text-align: center;
+  text-decoration: none;
+  white-space: nowrap;
+  cursor: pointer;
+  transition: filter var(--ad-dur-fast) var(--ad-ease),
+              border-color var(--ad-dur-fast) var(--ad-ease);
+}
+
+:is(button:not(.icon-button), a.btn):hover:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.96); }
+:is(button:not(.icon-button), a.btn):active:not(:disabled):not([aria-disabled="true"]) { filter: brightness(0.92); }
+
+button:not(.icon-button):disabled,
+:is(button:not(.icon-button), a.btn)[aria-disabled="true"] {
+  opacity: 0.5;
+  cursor: default;
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="primary"] {
+  --_bg: var(--ad-color-accent);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-accent);
+}
+
+/* Reserved for the single most-committing action in a view — a final Save,
+   never a whole row of them. */
+:is(button:not(.icon-button), a.btn)[data-variant="dark"] {
+  --_bg: var(--ad-color-text-primary);
+  --_fg: var(--ad-color-surface-page);
+  --_border: var(--ad-color-text-primary);
+}
+
+:is(button:not(.icon-button), a.btn)[data-variant="ghost"] {
+  --_bg: transparent;
+  --_fg: var(--ad-color-text-primary);
+  --_border: transparent;
+}
+
+/* The source hardcodes this label white rather than deriving it — danger
+   is not "on a filled accent surface", so --ad-color-accent-fg is reused
+   here only because its resolved value is the same literal white, not
+   because the two roles are the same thing. */
+:is(button:not(.icon-button), a.btn)[data-variant="danger"] {
+  --_bg: var(--ad-color-danger);
+  --_fg: var(--ad-color-accent-fg);
+  --_border: var(--ad-color-danger);
+}
+
+:is(button:not(.icon-button), a.btn)[data-size="sm"] { --_pad: 0.375rem 0.75rem; --_font: 0.8125rem; }
+:is(button:not(.icon-button), a.btn)[data-size="lg"] { --_pad: 0.75rem 1.375rem; --_font: var(--ad-step-0); }
+
+:is(button:not(.icon-button), a.btn)[data-block] { width: 100%; }
+
+/* Button group — [role="group"] is already the correct ARIA role for a
+   toolbar of related buttons, so it doubles as the styling hook for free. */
+[role="group"] {
+  display: inline-flex;
+  isolation: isolate;
+}
+[role="group"] > button { border-radius: 0; }
+[role="group"] > button:first-child { border-start-start-radius: var(--ad-radius-md); border-end-start-radius: var(--ad-radius-md); }
+[role="group"] > button:last-child { border-start-end-radius: var(--ad-radius-md); border-end-end-radius: var(--ad-radius-md); }
+[role="group"] > button + button { margin-inline-start: -1px; }
+[role="group"] > button:hover,
+[role="group"] > button:focus-visible { z-index: 1; }
+
+/* IconButton — a square icon-only button. Always needs an aria-label; it
+   becomes both the accessible name and the native tooltip. There is no
+   attribute that distinguishes "a button that is only an icon" from a plain
+   Button, so this is the one sanctioned class in this file. */
+.icon-button {
+  --_size: 2.125rem;
+  --_bg: transparent;
+  --_border: transparent;
+  --_fg: var(--ad-color-text-secondary);
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  padding: 0;
+  flex: none;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-md);
+  background: var(--_bg);
+  color: var(--_fg);
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease),
+              color var(--ad-dur-fast) var(--ad-ease);
+}
+.icon-button:hover:not(:disabled) { background: var(--ad-color-surface-fill-2); }
+.icon-button:disabled { opacity: 0.5; cursor: default; }
+
+.icon-button[data-size="sm"] { --_size: 1.75rem; }
+.icon-button[data-size="lg"] { --_size: 2.5rem; }
+
+.icon-button[data-variant="outline"] { --_bg: var(--ad-color-surface-card); --_border: var(--ad-color-border-default); --_fg: var(--ad-color-text-primary); }
+.icon-button[data-variant="accent"]  { --_bg: var(--ad-color-accent-soft); --_fg: var(--ad-color-accent-ink); }
+
+/* Field
+   The labeled field wrapper — a <label> that wraps its own caption text
+   together with the control, so the association is native and needs no
+   `for`/`id` pair. The caption is mono, uppercase, tracked — the same
+   catalog-label convention as Badge and type-label.
+
+   A <label> is reused for three different shapes across this system (this
+   wrapper, Checkbox/Radio's row, Switch's row), so it cannot be styled bare
+   without one shape leaking into another. Field is the one of the three with
+   no distinguishing attribute of its own, so it gets the sanctioned class;
+   Checkbox/Radio tell themselves apart structurally instead (see below). */
+.field {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  min-width: 0;
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Hint and error read the native fine-print element. `role="alert"` is a
+   real live-region role for validation text, so it doubles as the selector
+   that turns a hint red. */
+.field > small {
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+.field > small[role="alert"] { color: var(--ad-color-danger); }
+
+/* Input / Select — bordered, matched to each other exactly. Both tags ARE
+   the component, so they are styled bare; nothing else on this site uses a
+   text input or a select. */
+input:not([type="checkbox"]):not([type="radio"]),
+select {
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  text-transform: none;
+  letter-spacing: normal;
+  font-weight: 400;
+  outline: none;
+  transition: border-color var(--ad-dur-fast) var(--ad-ease),
+              box-shadow var(--ad-dur-fast) var(--ad-ease);
+}
+input::placeholder { color: var(--ad-color-text-tertiary); }
+
+input:not([type="checkbox"]):not([type="radio"]):focus,
+select:focus {
+  border-color: var(--ad-color-accent);
+  box-shadow: 0 0 0 2px var(--ad-color-accent-soft);
+}
+
+input:not([type="checkbox"]):not([type="radio"]):disabled,
+select:disabled {
+  opacity: 0.5;
+  cursor: default;
+}
+
+/* The chevron is the one flagged color exception in this component set:
+   CSS cannot point a data-URI background-image at a custom property, so its
+   stroke is a literal hex rather than a var(--ad-*) reference. It is picked
+   to match --ad-color-text-secondary and commented here so it is not
+   mistaken for a stray color. */
+select {
+  appearance: none;
+  padding-inline-end: var(--ad-space-l);
+  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235f5d59' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
+  background-repeat: no-repeat;
+  background-position: right var(--ad-space-xs) center;
+}
+
+input[aria-invalid="true"],
+select[aria-invalid="true"] {
+  border-color: var(--ad-color-danger);
+  background-color: var(--ad-color-danger-bg);
+}
+
+/* Checkbox / Radio — the real native controls, tinted with accent-color
+   instead of a hand-drawn box. This is not just a rename: it deletes the
+   custom SVG-checkmark markup entirely and lets the browser draw its own
+   (platform-appropriate) check and dot. `role="switch"` is excluded here so
+   Switch — a checkbox playing a different role — can style itself below
+   without this rule fighting it. A <label> wrapping a checkbox/radio is told
+   apart from Field's <label> structurally: it :has() one as a direct child,
+   no class required. */
+input[type="checkbox"]:not([role="switch"]),
+input[type="radio"] {
+  width: 1.125rem;
+  height: 1.125rem;
+  margin: 0;
+  accent-color: var(--ad-color-accent);
+  cursor: pointer;
+}
+input[type="checkbox"]:not([role="switch"]):focus-visible,
+input[type="radio"]:focus-visible {
+  outline: 2px solid var(--ad-color-accent);
+  outline-offset: 2px;
+}
+
+label:has(> input[type="checkbox"]:not([role="switch"])),
+label:has(> input[type="radio"]) {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 400;
+  text-transform: none;
+  letter-spacing: normal;
+  color: var(--ad-color-text-primary);
+}
+label:has(> input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Switch — for on/off settings only, never a substitute for Checkbox.
+   `input[type="checkbox"][role="switch"]` is real ARIA (the correct role for
+   a toggle), not an invented hook, but the visual track+thumb needs a second
+   element for the thumb's independent position and transition — more than
+   `appearance: none` plus pseudo-elements on the input itself can cleanly
+   carry — so `.switch` is a deliberate, documented fallback class rather
+   than a first choice. */
+.switch {
+  display: inline-flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+  cursor: pointer;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  color: var(--ad-color-text-primary);
+}
+.switch input[role="switch"] { position: absolute; opacity: 0; width: 2.25rem; height: 1.25rem; margin: 0; }
+
+.switch span {
+  position: relative;
+  flex: none;
+  width: 2.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-border-default);
+  transition: background-color var(--ad-dur-base) var(--ad-ease);
+}
+.switch span::after {
+  content: "";
+  position: absolute;
+  inset-block-start: 2px;
+  inset-inline-start: 2px;
+  width: 1rem;
+  height: 1rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-fg);
+  box-shadow: var(--ad-shadow-sm);
+  transition: translate var(--ad-dur-base) var(--ad-ease);
+}
+.switch input[role="switch"]:checked + span { background: var(--ad-color-accent); }
+.switch input[role="switch"]:checked + span::after { translate: 1rem 0; }
+.switch input[role="switch"]:focus-visible + span { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+.switch:has(input:disabled) { cursor: default; opacity: 0.5; }
+
+/* Rows of fields — used by the settings-form pattern. `<form>`/`<fieldset>`
+   are the elements that already mean this, so they are styled bare. A row
+   grouping two fields side by side has no element of its own, so it keeps
+   one plain class. */
+form {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-s);
+  max-width: 28rem;
+}
+.form-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
+  gap: var(--ad-space-xs);
+}
+fieldset {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  margin: 0;
+  padding: 0;
+  border: 0;
+}
+fieldset > legend {
+  padding: 0 0 var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  color: var(--ad-color-text-secondary);
+}
+
+/* Badge
+   Mono, uppercase, tracked — the catalog-label convention for status and
+   meta values (SAVED, OVERDUE, RECOMMENDED). A label, never a button.
+
+   A <span> is too generic to style globally — it is used all over running
+   prose for unrelated reasons — so Badge gets the one sanctioned class this
+   shape needs. Tone is an attribute, not a modifier class. */
+
+.badge {
+  --_bg: var(--ad-color-surface-fill);
+  --_fg: var(--ad-color-text-secondary);
+  --_border: var(--ad-color-border-hairline);
+
+  display: inline-flex;
+  align-items: center;
+  gap: 0.25rem;
+  padding: 0.1875rem 0.5rem;
+  border: 1px solid var(--_border);
+  border-radius: var(--ad-radius-sm);
+  background: var(--_bg);
+  color: var(--_fg);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  text-transform: uppercase;
+  letter-spacing: 0.06em;
+  line-height: 1;
+  white-space: nowrap;
+}
+
+.badge[data-tone="accent"]  { --_bg: var(--ad-color-accent-soft);  --_fg: var(--ad-color-accent-ink);  --_border: transparent; }
+.badge[data-tone="success"] { --_bg: var(--ad-color-success-bg);   --_fg: var(--ad-color-success);      --_border: transparent; }
+.badge[data-tone="danger"]  { --_bg: var(--ad-color-danger-bg);    --_fg: var(--ad-color-danger);       --_border: transparent; }
+
+.badge-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-2xs);
+}
+
+/* Tag
+   A removable mono chip for freeform tags — locations, categories.
+   `[data-dashed]` renders an "add tag" affordance instead of a value. Same
+   reasoning as Badge: <span> is too generic to select bare, so Tag gets one
+   class. The remove control is a real <button>, styled through the
+   descendant selector rather than a class of its own. */
+
+.tag {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.375rem;
+  padding: 0.25rem 0.625rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-default);
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  line-height: 1;
+}
+
+.tag[data-dashed] {
+  background: transparent;
+  border-style: dashed;
+  color: var(--ad-color-text-tertiary);
+  cursor: pointer;
+}
+
+.tag button {
+  all: unset;
+  cursor: pointer;
+  color: var(--ad-color-text-tertiary);
+  line-height: 1;
+  font-size: 0.75rem;
+}
+.tag button:hover { color: var(--ad-color-text-primary); }
+
+.tag-set {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.375rem;
+}
+
+/* Card
+   Flat surface, hairline border, radius-lg. `[data-elevated]` is opt-in and
+   reserved for the one focused/primary card in a view — a dialog, the
+   primary capture card — flat is the default everywhere else.
+
+   A <div>/<article> is too generic to select bare, so Card keeps one
+   sanctioned class. When Card's job is holding a list of rows — the common
+   case, entry lists, task lists, settings rows — it is a real <ul class="
+   card">, and CardRow is a bare <li> underneath it: no second class needed,
+   the row look comes from the `.card > li` descendant selector alone. The
+   first row's top border is removed automatically so callers never have to
+   override it by hand. */
+
+.card {
+  display: flex;
+  flex-direction: column;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: none;
+  overflow: hidden;
+}
+
+.card[data-elevated] { box-shadow: var(--ad-shadow-float); }
+
+.card > li {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+}
+.card > li:first-child { border-top: none; }
+
+/* A row whose ENTIRE content is wrapped in a real <button> or <a> — the
+   accessible way to make a row clickable — fills the row edge-to-edge and
+   picks up a hover fill and pointer cursor. `:only-child` is what tells this
+   apart from a row that merely contains a small button among other content
+   (a leading checkbox next to a title and a trailing value, say): only a
+   button/anchor that IS the row's one and only child means "the whole row
+   is the control." */
+.card > li:has(> button:only-child),
+.card > li:has(> a:only-child) {
+  padding: 0;
+}
+.card > li > button:only-child,
+.card > li > a:only-child {
+  all: unset;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  width: 100%;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  box-sizing: border-box;
+  color: inherit;
+  font: inherit;
+  cursor: pointer;
+  transition: background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.card > li > button:only-child:hover,
+.card > li > a:only-child:hover { background: var(--ad-color-surface-fill); }
+
+/* Documentation-only extras: a body/footer pair and a responsive grid, used
+   by the prose pages (rationale.md, index.md) to show a Card as a plain
+   content tile rather than a data row. Neither is part of Card's props —
+   they exist because a content tile's inner layout has no element of its
+   own to hang a selector on. */
+.card-body {
+  display: flex;
+  flex-direction: column;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-m);
+}
+.card-footer {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  margin-top: auto;
+  padding: var(--ad-space-xs) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+
+.card[data-link] { transition: border-color var(--ad-dur-fast) var(--ad-ease), box-shadow var(--ad-dur-fast) var(--ad-ease); }
+.card[data-link]:hover { border-color: var(--ad-color-border-default); box-shadow: var(--ad-shadow-sm); }
+.card[data-link]:focus-within { outline: 2px solid var(--ad-color-accent); outline-offset: 2px; }
+
+.card-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
+  gap: var(--ad-space-s);
+}
+
+/* Avatar — lives here because it almost never appears outside a card or a
+   row (the Loop dashboard's initials chip, Archive's file-type chip). A
+   <span> is too generic for a bare selector, so it keeps one class. */
+.avatar {
+  --_size: 1.875rem;
+
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: var(--_size);
+  height: var(--_size);
+  flex: none;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent-soft);
+  color: var(--ad-color-accent-ink);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--2);
+  font-weight: 600;
+  overflow: hidden;
+}
+.avatar[data-square] { border-radius: var(--ad-radius-md); background: var(--ad-color-surface-fill); color: var(--ad-color-text-secondary); border: 1px solid var(--ad-color-border-hairline); }
+.avatar[data-size="sm"] { --_size: 1.5rem; }
+.avatar[data-size="lg"] { --_size: 2.25rem; }
+
+/* Tooltip — a dark mono label on hover, positioned above the child. Pure CSS:
+   the trigger and bubble are siblings inside one relatively-positioned span,
+   shown on :hover/:focus-within so it works from the keyboard too.
+
+   `[role="tooltip"]` is the correct ARIA role for the bubble itself, so it
+   doubles as the styling hook — zero classes there. The wrapping span has no
+   attribute of its own, but it does not need one: `:has()` picks out "a span
+   that contains a [role=tooltip] bubble" precisely, without reaching for a
+   class on an otherwise-generic element. */
+span:has(> [role="tooltip"]) {
+  position: relative;
+  display: inline-flex;
+}
+
+[role="tooltip"] {
+  position: absolute;
+  bottom: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  margin-bottom: 0.375rem;
+  padding: 0.25rem 0.5rem;
+  border-radius: var(--ad-radius-sm);
+  background: var(--ad-color-text-primary);
+  color: var(--ad-color-surface-page);
+  font-family: var(--ad-font-mono);
+  /* 11px is the source's own literal choice — smaller than --ad-step--2, the
+     smallest step on the scale, because a tooltip is meant to read as a
+     glance-only aside rather than body text. */
+  font-size: 11px;
+  white-space: nowrap;
+  line-height: 1.4;
+  z-index: 20;
+  opacity: 0;
+  visibility: hidden;
+  pointer-events: none;
+  transition: opacity var(--ad-dur-fast) var(--ad-ease);
+}
+span:has(> [role="tooltip"]):hover > [role="tooltip"],
+span:has(> [role="tooltip"]):focus-within > [role="tooltip"] {
+  opacity: 1;
+  visibility: visible;
+}
+
+/* Toast — the real pattern used for delete confirmations: a flat bar with an
+   optional destructive action and a dismiss. `[data-fixed]` pins it
+   bottom-right for real use; without it the toast stays in document flow for
+   documentation. `role="status"` is the correct live-region role for a
+   transient status message, so it is both the accessibility hook and the
+   style selector — no base class needed. The action and dismiss buttons are
+   plain <button>s told apart by `aria-label="Dismiss"`, an attribute they
+   need anyway for the icon-only close control. */
+[role="status"] {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  min-width: 20rem;
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--2);
+}
+[role="status"][data-fixed] {
+  position: fixed;
+  inset-block-end: var(--ad-space-s);
+  inset-inline-end: var(--ad-space-s);
+  z-index: 60;
+}
+[role="status"] > span { flex: 1; }
+[role="status"] button {
+  all: unset;
+  cursor: pointer;
+  font-weight: 600;
+  color: var(--ad-color-danger);
+}
+[role="status"] button[aria-label="Dismiss"] {
+  color: var(--ad-color-text-tertiary);
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1;
+}
+[role="status"] button[aria-label="Dismiss"]:hover { color: var(--ad-color-text-primary); }
+
+/* Dialog — the native <dialog> element: a centered modal, flat surface, no
+   colored header, hairline dividers between title/body/footer. A <header>
+   holds the title and a <footer> holds the actions, matching the elements
+   the tag already wants; everything else in between is the body, styled by
+   excluding those two rather than by a class of its own.
+
+   `.dialog-demo` scopes a static, always-open example to its own preview
+   container instead of the viewport, so it can sit safely inside a
+   documentation page — this is a doc-only affordance, not part of Dialog's
+   contract. It relies on the browser's own dialog centering: the UA
+   stylesheet already gives an open <dialog> `position: absolute; inset: 0;
+   margin: auto`, which centers it inside the nearest positioned ancestor —
+   here, `.dialog-demo` itself. A real `.showModal()` call gets the genuine
+   viewport-fixed overlay and `::backdrop` for free; a plain `open` attribute
+   (used here so the demo renders without JavaScript) does not paint a
+   backdrop at all, since `::backdrop` only exists for a dialog shown
+   modally — wire the real open/close state and call `.showModal()` in the
+   consuming app. */
+.dialog-demo {
+  position: relative;
+  min-height: 20rem;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-lg);
+}
+
+dialog {
+  width: 26rem;
+  max-width: calc(100% - (2 * var(--ad-space-s)));
+  height: fit-content;
+  padding: 0;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  box-shadow: var(--ad-shadow-float);
+  color: var(--ad-color-text-primary);
+  overflow: hidden;
+}
+dialog::backdrop {
+  background: rgba(20, 18, 14, 0.35);
+}
+dialog > header {
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-sans);
+  font-weight: 600;
+  font-size: var(--ad-step-0);
+  color: var(--ad-color-text-primary);
+}
+dialog > footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: var(--ad-space-2xs);
+  padding: var(--ad-space-s) var(--ad-space-m);
+  border-top: 1px solid var(--ad-color-border-hairline);
+}
+dialog > *:not(header):not(footer) {
+  padding: var(--ad-space-m);
+  margin: 0;
+  color: var(--ad-color-text-primary);
+  font-size: var(--ad-step--1);
+}
+
+/* Tabs
+   Follows the real WAI-ARIA tabs pattern: a `[role="tablist"]` of
+   `[role="tab"]` buttons controlling `[role="tabpanel"]`s. Those roles are
+   required for the pattern to be accessible in the first place, so they
+   double as the entire styling contract — no classes at all for the base
+   shape. The keyboard wiring lives in assets/js/system.js and is
+   variant-agnostic — it only cares about `[data-tabs]` / `[role=tab]`.
+
+   Two real variants: `underline` (mono, accent underline — primary section
+   nav, the default) and `segmented` (pill track, active segment lifts to the
+   surface — filters like All · Overdue · Upcoming, never primary
+   navigation), chosen with `data-variant="segmented"` on the tablist since
+   neither has a natural attribute of its own. */
+
+/* Every rule below the list container pairs [role="tablist"] with
+   [role="tab"] rather than styling [role="tab"] alone — Tab buttons are
+   still literal <button> elements, so the compound selector's extra
+   specificity is what keeps Button's base styling (button.css) from
+   winning the cascade on shared properties like padding and background. */
+
+[role="tablist"] {
+  display: flex;
+  gap: var(--ad-space-m);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+[role="tablist"] [role="tab"] {
+  padding: 0.5rem 0;
+  margin-bottom: -1px;
+  background: none;
+  border: 0;
+  border-bottom: 2px solid transparent;
+  color: var(--ad-color-text-secondary);
+  font-family: var(--ad-font-mono);
+  font-size: var(--ad-step--1);
+  letter-spacing: 0.02em;
+  cursor: pointer;
+  transition: color var(--ad-dur-fast) var(--ad-ease), border-color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"] [role="tab"]:hover { color: var(--ad-color-text-primary); }
+[role="tablist"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  border-bottom-color: var(--ad-color-accent);
+}
+
+[role="tablist"][data-variant="segmented"] {
+  display: inline-flex;
+  gap: 0.125rem;
+  padding: 0.1875rem;
+  border-bottom: 0;
+  background: var(--ad-color-surface-fill);
+  border-radius: var(--ad-radius-md);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"] {
+  all: unset;
+  cursor: pointer;
+  padding: 0.375rem 0.875rem;
+  border-radius: var(--ad-radius-sm);
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step--1);
+  font-weight: 550;
+  color: var(--ad-color-text-secondary);
+  transition: background-color var(--ad-dur-fast) var(--ad-ease), color var(--ad-dur-fast) var(--ad-ease);
+}
+[role="tablist"][data-variant="segmented"] [role="tab"][aria-selected="true"] {
+  color: var(--ad-color-text-primary);
+  background: var(--ad-color-surface-card);
+  box-shadow: var(--ad-shadow-sm);
+}
+
+[role="tabpanel"] { padding-top: var(--ad-space-s); }
+[role="tabpanel"][hidden] { display: none; }
+[role="tabpanel"]:focus-visible { outline-offset: 4px; }
+
+/* Documentation site chrome. Everything below the `.ad-doc-` prefix belongs
+   to this site rather than to the design system it documents — including the
+   width/height constants used directly below. The source design system
+   defines no container-width tokens at all, so there is nothing under
+   `--ad-*` for a doc shell to reach for; the Space foundation page's own
+   notes say to omit that group entirely rather than invent one. */
+
+.ad-doc-skip {
+  position: absolute;
+  inset-inline-start: var(--ad-space-xs);
+  inset-block-start: -4rem;
+  z-index: 40;
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  box-shadow: var(--ad-shadow-float);
+  transition: inset-block-start var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-skip:focus { inset-block-start: var(--ad-space-2xs); }
+
+.ad-doc-header {
+  position: sticky;
+  inset-block-start: 0;
+  z-index: 30;
+  height: 3.5rem;
+  background: color-mix(in srgb, var(--ad-color-surface-page) 92%, transparent);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-header__inner {
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  height: 100%;
+  max-width: 72rem;
+  margin-inline: auto;
+  padding-inline: var(--ad-space-xs);
+}
+
+.ad-doc-wordmark {
+  display: flex;
+  align-items: baseline;
+  gap: var(--ad-space-2xs);
+  color: var(--ad-color-text-primary);
+  text-decoration: none;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-0);
+  font-weight: 600;
+  letter-spacing: -0.01em;
+  white-space: nowrap;
+}
+.ad-doc-wordmark:hover { color: var(--ad-color-text-primary); }
+.ad-doc-wordmark__mark {
+  width: 1.375rem;
+  height: 1.375rem;
+  flex: none;
+  align-self: center;
+  color: var(--ad-color-accent);
+}
+.ad-doc-wordmark__version {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 400;
+  color: var(--ad-color-text-tertiary);
+}
+
+.ad-doc-header__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--ad-space-2xs); }
+
+.ad-doc-layout {
+  display: grid;
+  grid-template-columns: 16rem minmax(0, 1fr);
+  gap: var(--ad-space-l);
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-m) var(--ad-space-xs) var(--ad-space-2xl);
+}
+
+.ad-doc-sidebar {
+  position: sticky;
+  inset-block-start: calc(3.5rem + var(--ad-space-m));
+  align-self: start;
+  max-height: calc(100vh - 3.5rem - var(--ad-space-l));
+  overflow-y: auto;
+  padding-inline-end: var(--ad-space-2xs);
+}
+.ad-doc-nav__group + .ad-doc-nav__group { margin-top: var(--ad-space-s); }
+.ad-doc-nav__heading {
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-doc-nav__link {
+  display: block;
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  margin-inline-start: calc(var(--ad-space-xs) * -1);
+  border-inline-start: 2px solid transparent;
+  border-radius: 0 var(--ad-radius-sm) var(--ad-radius-sm) 0;
+  color: var(--ad-color-text-secondary);
+  font-size: var(--ad-step--1);
+  text-decoration: none;
+  transition: color var(--ad-dur-fast) var(--ad-ease),
+              background-color var(--ad-dur-fast) var(--ad-ease);
+}
+.ad-doc-nav__link:hover { color: var(--ad-color-text-primary); background: var(--ad-color-surface-fill); }
+.ad-doc-nav__link[aria-current="page"] {
+  color: var(--ad-color-accent-ink);
+  border-inline-start-color: var(--ad-color-accent);
+  background: var(--ad-color-accent-soft);
+  font-weight: 500;
+}
+
+.ad-doc-main {
+  min-width: 0;
+  /* The design system's own body-text token (--ad-step-0, 18–20px) is right
+     for a product screen but too large for long-form documentation prose.
+     This site's own copy gets a plain, fixed 16px instead — the token above
+     is unchanged, and specimen tables/demos below still show its real
+     value. */
+  font-size: 1rem;
+}
+.ad-doc-main > * { max-width: 50rem; }
+
+.ad-doc-title { margin-bottom: var(--ad-space-xs); }
+.ad-doc-title__section {
+  display: block;
+  margin-bottom: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.08em;
+  text-transform: uppercase;
+  color: var(--ad-color-accent);
+}
+
+.ad-doc-main h2 {
+  margin-block: var(--ad-space-2xl) var(--ad-space-xs);
+  padding-bottom: var(--ad-space-2xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-doc-main h3 { margin-block: var(--ad-space-l) var(--ad-space-2xs); }
+.ad-doc-main h4 { margin-block: var(--ad-space-s) var(--ad-space-2xs); }
+.ad-doc-main p,
+.ad-doc-main ul,
+.ad-doc-main ol { max-width: 68ch; }
+.ad-doc-main ul:not([class]),
+.ad-doc-main ol:not([class]) { padding-inline-start: var(--ad-space-s); }
+
+.ad-doc-footer {
+  max-width: 72rem;
+  margin-inline: auto;
+  padding: var(--ad-space-s) var(--ad-space-xs) var(--ad-space-l);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  color: var(--ad-color-text-tertiary);
+  font-size: var(--ad-step--1);
+}
+.ad-doc-footer__inner { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); justify-content: space-between; }
+
+/* `button.ad-doc-nav-toggle` (element + class) rather than a bare class:
+   button.css's own base rule is `button:not(.icon-button)`, which is also
+   one element + one class in specificity and sets `display: inline-flex` —
+   a bare `.ad-doc-nav-toggle { display: none }` loses that fight and the
+   toggle stays visible at every width. Matching its specificity here (and
+   coming later in the concatenated stylesheet) settles it in source order. */
+button.ad-doc-nav-toggle { display: none; }
+
+@media (max-width: 60rem) {
+  .ad-doc-layout { grid-template-columns: minmax(0, 1fr); gap: var(--ad-space-s); }
+  .ad-doc-sidebar {
+    position: static;
+    max-height: none;
+  }
+  /* The toggle is a normal Button; the panel it opens gets its own card
+     treatment. Putting the same card styling on the <aside> wrapper too
+     nested a button-shaped box inside an outer box for no reason. */
+  .ad-doc-nav {
+    margin-top: var(--ad-space-xs);
+    padding: var(--ad-space-xs);
+    background: var(--ad-color-surface-card);
+    border: 1px solid var(--ad-color-border-default);
+    border-radius: var(--ad-radius-md);
+  }
+  .ad-doc-sidebar[data-collapsed="true"] > .ad-doc-nav { display: none; }
+  button.ad-doc-nav-toggle {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+  }
+}
+
+@media (max-width: 34rem) {
+  .ad-doc-wordmark__version { display: none; }
+  .ad-doc-layout { padding-inline: var(--ad-space-2xs); }
+}
+
+/* The live-example figure used throughout the docs — see the "How the
+   example demos work" section on the Using the CSS page. One class on the
+   outer <figure>; everything inside is styled by plain element selectors,
+   since figcaption/div/details/summary/pre already say what they are.
+   `data-layout` and `data-surface` on the preview <div> distinguish the
+   handful of demos that need a non-default arrangement. */
+
+.example {
+  margin: var(--ad-space-s) 0 var(--ad-space-l);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+  background: var(--ad-color-surface-card);
+  overflow: hidden;
+}
+
+.example figcaption {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-secondary);
+}
+
+.example > div {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  gap: var(--ad-space-xs);
+  padding: var(--ad-space-s);
+}
+/* nowrap is load-bearing: a column-direction flex container with wrap enabled
+   sizes its single line against the container rather than the content, which
+   left every stacked example with a few hundred pixels of dead space. */
+.example > div[data-layout="stack"] { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
+.example > div[data-layout="grid"] {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
+  align-items: start;
+}
+.example > div[data-surface="sunken"] { background: var(--ad-color-surface-fill); }
+.example > div > * { min-width: 0; }
+
+.example details {
+  border-top: 1px solid var(--ad-color-border-hairline);
+  background: var(--ad-color-surface-fill);
+}
+.example summary {
+  padding: var(--ad-space-2xs) var(--ad-space-xs);
+  font-size: var(--ad-step--2);
+  font-weight: 500;
+  color: var(--ad-color-text-secondary);
+  cursor: pointer;
+  list-style: none;
+  user-select: none;
+  display: flex;
+  align-items: center;
+  gap: var(--ad-space-2xs);
+}
+.example summary::-webkit-details-marker { display: none; }
+.example summary::before {
+  content: "";
+  width: 0.5rem;
+  height: 0.5rem;
+  border-inline-end: 1.5px solid currentColor;
+  border-block-end: 1.5px solid currentColor;
+  rotate: -45deg;
+  transition: rotate var(--ad-dur-fast) var(--ad-ease);
+}
+.example details[open] > summary::before { rotate: 45deg; }
+.example summary:hover { color: var(--ad-color-text-primary); }
+
+.example pre {
+  margin: 0;
+  padding: var(--ad-space-xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+  tab-size: 2;
+}
+.example pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Standalone fenced code blocks in the prose (unhighlighted — there is no
+   syntax highlighter in this build any more, just Kramdown's plain
+   <pre><code class="language-*">). */
+.ad-doc-main > pre {
+  margin-block: var(--ad-space-xs);
+  padding: var(--ad-space-xs);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+  overflow-x: auto;
+  font-size: var(--ad-step--2);
+  line-height: 1.5;
+}
+.ad-doc-main > pre code { background: none; border: 0; padding: 0; white-space: pre; }
+
+/* Presentation for the token reference tables and swatch grids, plus a
+   generic data-table utility. All of this is documentation chrome — the
+   design system itself has no Table component (see the note on the removed
+   `table`/`progress`/`callout` pages in git history). */
+
+.ad-swatch-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs) var(--ad-space-s);
+  padding: 0;
+  list-style: none;
+}
+.ad-swatch {
+  display: flex;
+  flex-direction: column;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+  overflow: hidden;
+  background: var(--ad-color-surface-card);
+}
+.ad-swatch__chip {
+  display: flex;
+  align-items: flex-end;
+  justify-content: flex-end;
+  height: 4rem;
+  padding: var(--ad-space-2xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  font-weight: 600;
+}
+.ad-swatch__meta {
+  display: flex;
+  flex-direction: column;
+  gap: 0.1rem;
+  padding: var(--ad-space-2xs);
+  border-top: 1px solid var(--ad-color-border-hairline);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+}
+.ad-swatch__hex { color: var(--ad-color-text-primary); text-transform: uppercase; }
+.ad-swatch__ratio { color: var(--ad-color-text-tertiary); }
+
+.ad-alias-row { display: flex; align-items: center; gap: var(--ad-space-2xs); }
+.ad-alias-chip {
+  width: 1.5rem;
+  height: 1.5rem;
+  flex: none;
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-sm);
+}
+.ad-alias-chip--pair { display: flex; }
+.ad-alias-chip--pair > span { flex: 1; }
+
+/* Type specimen rows. */
+.ad-specimen {
+  display: grid;
+  grid-template-columns: minmax(0, 1fr);
+  gap: var(--ad-space-3xs);
+  padding-block: var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+}
+.ad-specimen__meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: var(--ad-space-xs);
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  color: var(--ad-color-text-tertiary);
+}
+.ad-specimen__sample {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  color: var(--ad-color-text-primary);
+}
+
+/* Space and radius rulers. */
+.ad-ruler { display: flex; flex-direction: column; gap: var(--ad-space-2xs); }
+.ad-ruler__row { display: grid; grid-template-columns: 6.5rem 4.5rem 1fr; align-items: center; gap: var(--ad-space-xs); font-family: var(--ad-font-mono); font-size: 11px; }
+.ad-ruler__bar { height: 0.75rem; background: var(--ad-color-accent); border-radius: var(--ad-radius-sm); }
+.ad-ruler__num { color: var(--ad-color-text-tertiary); text-align: right; }
+
+.ad-radius-grid, .ad-elevation-grid, .ad-motion-grid, .ad-accent-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-xs);
+  padding: 0;
+  list-style: none;
+}
+.ad-radius-demo {
+  height: 4.5rem;
+  background: var(--ad-color-accent-soft);
+  border: 1px solid var(--ad-color-accent);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-elevation-demo {
+  height: 4.5rem;
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-lg);
+  margin-bottom: var(--ad-space-2xs);
+}
+.ad-motion-demo {
+  height: 4.5rem;
+  display: grid;
+  place-items: center;
+  background: var(--ad-color-surface-fill);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-radius: var(--ad-radius-md);
+  margin-bottom: var(--ad-space-2xs);
+  cursor: pointer;
+  overflow: hidden;
+}
+.ad-motion-demo__dot {
+  width: 1.25rem;
+  height: 1.25rem;
+  border-radius: var(--ad-radius-full);
+  background: var(--ad-color-accent);
+  translate: -3rem 0;
+  transition-property: translate;
+  transition-duration: var(--ad-dur-base);
+  transition-timing-function: var(--ad-ease);
+}
+.ad-motion-demo:hover .ad-motion-demo__dot,
+.ad-motion-demo:focus-visible .ad-motion-demo__dot { translate: 3rem 0; }
+
+.ad-accent-demo {
+  height: 4.5rem;
+  display: flex;
+  align-items: flex-end;
+  padding: var(--ad-space-2xs);
+  border-radius: var(--ad-radius-md);
+  color: #fff;
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  margin-bottom: var(--ad-space-2xs);
+}
+
+/* Token names read `<code>` sitewide, which already carries a mono chip
+   look for running prose (see :not(pre) > code in base/typography.css).
+   Inside these specimen/swatch/ruler rows the old `.ad-token-name` class was
+   plain mono text with no chip, so `<code>` is flattened back to that look
+   here the same way table cells are. */
+.ad-swatch code, .ad-specimen code, .ad-ruler code, .ad-alias-row code {
+  background: none;
+  border: 0;
+  padding: 0;
+  font-size: var(--ad-step--2);
+  color: var(--ad-color-text-primary);
+  white-space: nowrap;
+}
+
+/* A documentation aside. Like `<table>`, this is site chrome for the prose
+   itself, not a system component — the real system has no Callout. */
+.ad-callout {
+  margin-block: var(--ad-space-s);
+  padding: var(--ad-space-xs) var(--ad-space-s);
+  border: 1px solid var(--ad-color-border-hairline);
+  border-left: 3px solid var(--ad-color-accent);
+  border-radius: var(--ad-radius-md);
+  background: var(--ad-color-surface-fill);
+}
+/* Generic reference tables (component APIs, alias tables, the contrast
+   contract). `<table>` IS a table — no class needed to say so. Every table
+   on this site uses the one compact density, so there is no separate
+   modifier for it. `display: block` plus `overflow-x: auto` gives the table
+   its own horizontal scrollbar on narrow viewports without a wrapper div;
+   the anonymous table box the browser generates around `<thead>`/`<tbody>`
+   still does the row/column layout. `<code>` replaces the old
+   `.ad-token-name` / `.ad-table__code` cells — it is already styled
+   sitewide, just re-flattened here to a plain mono run instead of the
+   chip-with-border look prose code gets, to match this table's original
+   look. `.num` is the one sanctioned class left, for right-aligned numeric
+   columns — there is no attribute that means "this column is a number". */
+table { width: 100%; border-collapse: collapse; font-size: var(--ad-step--1); display: block; overflow-x: auto; }
+table th, table td {
+  padding: var(--ad-space-3xs) var(--ad-space-xs);
+  border-bottom: 1px solid var(--ad-color-border-hairline);
+  text-align: left;
+  vertical-align: top;
+}
+table th { font-family: var(--ad-font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ad-color-text-secondary); font-weight: 500; }
+table code { background: none; border: 0; padding: 0; font-size: var(--ad-step--2); white-space: nowrap; }
+.num { text-align: right; font-variant-numeric: tabular-nums; }
+
+/* Home page. */
+.ad-hero { padding-block: var(--ad-space-m) var(--ad-space-l); }
+.ad-hero__title {
+  font-size: var(--ad-step-4);
+  margin-bottom: var(--ad-space-xs);
+}
+.ad-hero__actions { display: flex; flex-wrap: wrap; gap: var(--ad-space-xs); margin-top: var(--ad-space-s); }
+.ad-stat-row {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
+  gap: var(--ad-space-xs);
+  margin-block: var(--ad-space-l);
+  padding: var(--ad-space-xs);
+  background: var(--ad-color-surface-card);
+  border: 1px solid var(--ad-color-border-default);
+  border-radius: var(--ad-radius-lg);
+}
+.ad-stat__value {
+  display: block;
+  font-family: var(--ad-font-sans);
+  font-size: var(--ad-step-2);
+  font-weight: 600;
+  line-height: 1.16;
+  font-variant-numeric: tabular-nums;
+}
+.ad-stat__label {
+  font-family: var(--ad-font-mono);
+  font-size: 11px;
+  letter-spacing: 0.06em;
+  text-transform: uppercase;
+  color: var(--ad-color-text-tertiary);
+}
+
+/* Card chrome. The pane supplies the frame; this just insets the page. */
+body { padding: var(--ad-space-l) var(--ad-space-m); }
+.ad-doc-main { max-width: 50rem; margin-inline: auto; }
+.ad-doc-main > * { max-width: none; }
+</style>
+</head>
+<body>
+<main class="ad-doc-main">
+<header class="ad-doc-title"><span class="ad-doc-title__section">Patterns</span>
+  <h1>Loop — task dashboard</h1>
+</header>
+<p class="ad-lead">A recurring-task web dashboard. Dense rows, mono meta columns, overdue in danger red, one primary action. A generic demonstration of the system, not a recreation of any one source project's actual screens.</p>
+<p>Loop is not a real product — it is the system’s own reference layout for a
+dense, table-ish list screen: the shape <code>kejadlen/ketchup</code> (a recurring-task
+tracker) would take if it were rebuilt on this token set. Every visible value
+below is a component from this system; nothing here is page-specific CSS
+beyond a couple of inline widths.</p>
+
+<figure class="example">
+<figcaption>Loop</figcaption>
+<div data-layout="stack">
+<div style="border: 1px solid var(--ad-color-border-hairline); border-radius: var(--ad-radius-lg); overflow: hidden; background: var(--ad-color-surface-page);">
+  <header style="display:flex; align-items:center; gap: var(--ad-space-s); padding: var(--ad-space-s) var(--ad-space-l); border-bottom: 1px solid var(--ad-color-border-hairline);">
+    <span style="font-family: var(--ad-font-mono); font-weight:600; letter-spacing:0.02em; font-size: var(--ad-step-0);">Loop</span>
+    <div style="flex:1;"></div>
+    <button data-variant="primary" data-size="sm">
+      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M5 12h14" /></svg>
+      New
+    </button>
+    <span class="avatar">km</span>
+  </header>
+  <div style="display:flex;">
+    <div style="flex:1; min-width:0; max-width: 34rem; padding: var(--ad-space-l);">
+      <section style="margin-bottom: var(--ad-space-l);">
+        <div style="display:flex; align-items:baseline; gap: var(--ad-space-2xs); margin-bottom: var(--ad-space-s);">
+          <span class="type-label" style="color: var(--ad-color-danger);">Overdue</span>
+          <span class="badge" data-tone="danger">2</span>
+        </div>
+        <ul class="card" style="border:none; border-radius:0; background:none;">
+          <li style="border-top: 1px solid var(--ad-color-border-hairline);">
+            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-danger);"></button>
+            <div style="flex:1; min-width:0;">
+              <div style="font-weight:500; color: var(--ad-color-danger);">Call Mom</div>
+              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 2 weeks</div>
+            </div>
+            <span class="type-mono" style="color: var(--ad-color-danger); font-size: var(--ad-step--2); white-space:nowrap;">3d overdue</span>
+          </li>
+          <li>
+            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-danger);"></button>
+            <div style="flex:1; min-width:0;">
+              <div style="font-weight:500; color: var(--ad-color-danger);">Water the ferns</div>
+              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 5 days</div>
+            </div>
+            <span class="type-mono" style="color: var(--ad-color-danger); font-size: var(--ad-step--2); white-space:nowrap;">1d overdue</span>
+          </li>
+        </ul>
+      </section>
+      <section>
+        <div class="type-label" style="margin-bottom: var(--ad-space-s);">Upcoming</div>
+        <ul class="card" style="border:none; border-radius:0; background:none;">
+          <li style="border-top: 1px solid var(--ad-color-border-hairline);">
+            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-text-secondary);"></button>
+            <div style="flex:1; min-width:0;">
+              <div style="font-weight:500;">Renew passport</div>
+              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 10 years</div>
+            </div>
+            <span class="type-mono" style="color: var(--ad-color-text-secondary); font-size: var(--ad-step--2); white-space:nowrap;">in 3 months</span>
+          </li>
+          <li>
+            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-text-secondary);"></button>
+            <div style="flex:1; min-width:0;">
+              <div style="font-weight:500;">Dentist checkup</div>
+              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 6 months</div>
+            </div>
+            <span class="type-mono" style="color: var(--ad-color-text-secondary); font-size: var(--ad-step--2); white-space:nowrap;">in 2 weeks</span>
+          </li>
+          <li>
+            <button aria-label="Complete" style="all:unset; width:18px; height:18px; border-radius:4px; flex-shrink:0; cursor:pointer; border: 1.5px solid var(--ad-color-text-secondary);"></button>
+            <div style="flex:1; min-width:0;">
+              <div style="font-weight:500;">Rotate mattress</div>
+              <div class="type-mono" style="color: var(--ad-color-text-tertiary); font-size: var(--ad-step--2);">every 6 months</div>
+            </div>
+            <span class="type-mono" style="color: var(--ad-color-text-secondary); font-size: var(--ad-step--2); white-space:nowrap;">in 5 weeks</span>
+          </li>
+        </ul>
+      </section>
+    </div>
+    <aside style="width: 15rem; flex-shrink:0; background: var(--ad-color-surface-fill); border-left: 1px solid var(--ad-color-border-hairline); padding: var(--ad-space-l);">
+      <div class="type-label" style="margin-bottom: var(--ad-space-s);">This week</div>
+      <div style="display:flex; background: var(--ad-color-surface-card); border: 1px solid var(--ad-color-border-hairline); border-radius: var(--ad-radius-md); overflow:hidden; margin-bottom: var(--ad-space-l);">
+                                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">S</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        </div>
+                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">M</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">1</span>
+        </div>
+                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">T</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        </div>
+                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0; background: var(--ad-color-accent-soft); border-right: 1px solid var(--ad-color-border-hairline);">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">W</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-accent-ink);">2</span>
+        </div>
+                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">T</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        </div>
+                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  border-right: 1px solid var(--ad-color-border-hairline);">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">F</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">1</span>
+        </div>
+                <div style="flex:1; display:flex; flex-direction:column; align-items:center; gap:4px; padding: 8px 0;  ">
+          <span class="type-mono" style="font-size:9px; color: var(--ad-color-text-tertiary); text-transform:uppercase;">S</span>
+          <span style="font-size:13px; font-weight:600; color: var(--ad-color-text-primary);">0</span>
+        </div>
+              </div>
+      <div class="type-label" style="margin-bottom: var(--ad-space-2xs);">Series</div>
+      <div>
+        <div style="padding: var(--ad-space-2xs) 0; font-size: var(--ad-step--1); color: var(--ad-color-text-secondary);">Call Mom</div>
+        <div style="padding: var(--ad-space-2xs) 0; border-top: 1px solid var(--ad-color-border-hairline); font-size: var(--ad-step--1); color: var(--ad-color-text-secondary);">Water the ferns</div>
+        <div style="padding: var(--ad-space-2xs) 0; border-top: 1px solid var(--ad-color-border-hairline); font-size: var(--ad-step--1); color: var(--ad-color-text-secondary);">Renew passport</div>
+      </div>
+    </aside>
+  </div>
+</div>
+</div>
+</figure>
+
+<h2 id="the-new-series-dialog">The New series dialog</h2>
+
+<figure class="example">
+<figcaption>New series</figcaption>
+<div data-layout="stack">
+<div class="dialog-demo" style="min-height: 36rem;">
+  <dialog open="" style="width: 22rem;">
+    <header>New series</header>
+    <div>
+      <div style="display:flex; flex-direction:column; gap: var(--ad-space-s);">
+        <label class="field">
+          Note
+          <input placeholder="Call Mom" />
+          <small>First line becomes the display name.</small>
+        </label>
+        <div class="form-row">
+          <label class="field">
+            Every
+            <input type="number" placeholder="2" />
+          </label>
+          <label class="field">
+            Unit
+            <select><option>Day</option><option selected="">Week</option><option>Month</option><option>Year</option></select>
+          </label>
+        </div>
+      </div>
+    </div>
+    <footer>
+      <button>Cancel</button>
+      <button data-variant="primary">Create</button>
+    </footer>
+  </dialog>
+</div>
+</div>
+</figure>
+
+<h2 id="after-completing-a-task">After completing a task</h2>
+
+<figure class="example">
+<figcaption>Toast</figcaption>
+<div>
+<div role="status">
+  <span>Completed "Call Mom"</span>
+  <button aria-label="Dismiss">×</button>
+</div>
+</div>
+</figure>
+
+<h2 id="what-this-screen-is-testing">What this screen is testing</h2>
+
+<ul>
+  <li><strong>Dense rows next to a mono meta column.</strong> A recurring-task list is
+fundamentally tabular even though it never touches an actual <code>&lt;table&gt;</code>.</li>
+  <li><strong>Overdue in <code>--ad-color-danger</code>, everywhere at once.</strong> Row text, the
+complete-button border, and the trailing meta all pick it up from the same
+<code>overdue</code> state — color never drifts row to row.</li>
+  <li><strong>One primary action.</strong> <code>New</code> is the only accent-filled control on screen;
+everything else is neutral or bordered.</li>
+  <li><strong>Accent used exactly once, decoratively.</strong> The “km” avatar and the
+highlighted day both use <code>--ad-color-accent-soft</code> / <code>-ink</code> — never the raw
+accent fill outside of <code>New</code>.</li>
+</ul>
+</main>
+<script>
+// Behavior for the pieces of the system that need it. Everything else is
+// CSS and semantic HTML on purpose — a design system that only works with
+// JavaScript running is a component library with extra steps.
+(function () {
+  "use strict";
+
+  var STORAGE_KEY = "ad-theme";
+
+  function readStored() {
+    try {
+      return localStorage.getItem(STORAGE_KEY);
+    } catch (error) {
+      return null;
+    }
+  }
+
+  function writeStored(value) {
+    try {
+      localStorage.setItem(STORAGE_KEY, value);
+    } catch (error) {
+      /* Nothing to do — the media query still gives a sensible default. */
+    }
+  }
+
+  function systemPrefersDark() {
+    return window.matchMedia("(prefers-color-scheme: dark)").matches;
+  }
+
+  function currentTheme() {
+    var explicit = document.documentElement.getAttribute("data-theme");
+    if (explicit) return explicit;
+    return systemPrefersDark() ? "dark" : "light";
+  }
+
+  function paintToggle(theme) {
+    document.querySelectorAll("[data-theme-toggle]").forEach(function (toggle) {
+      var next = theme === "dark" ? "light" : "dark";
+      toggle.querySelectorAll("[data-theme-icon]").forEach(function (icon) {
+        icon.hidden = icon.dataset.themeIcon !== theme;
+      });
+      toggle.setAttribute("aria-label", "Switch to the " + next + " theme");
+      toggle.setAttribute("title", "Switch to the " + next + " theme");
+      var label = toggle.querySelector("[data-theme-label]");
+      if (label) label.textContent = "Switch to the " + next + " theme";
+    });
+  }
+
+  function setUpTheme() {
+    paintToggle(currentTheme());
+
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-theme-toggle]");
+      if (!toggle) return;
+
+      var next = currentTheme() === "dark" ? "light" : "dark";
+      document.documentElement.setAttribute("data-theme", next);
+      writeStored(next);
+      paintToggle(next);
+    });
+
+    // Follow the OS while the reader has not made an explicit choice.
+    window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function () {
+      if (!readStored()) paintToggle(currentTheme());
+    });
+  }
+
+  // Tabs, wired to the WAI-ARIA authoring practices: arrows move, Home/End
+  // jump, and only the selected tab stays in the tab order.
+  function setUpTabs() {
+    document.querySelectorAll("[data-tabs]").forEach(function (root) {
+      var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
+      if (!tabs.length) return;
+
+      function select(tab, focus) {
+        tabs.forEach(function (candidate) {
+          var selected = candidate === tab;
+          candidate.setAttribute("aria-selected", String(selected));
+          candidate.tabIndex = selected ? 0 : -1;
+          var panel = document.getElementById(candidate.getAttribute("aria-controls"));
+          if (panel) panel.hidden = !selected;
+        });
+        if (focus) tab.focus();
+      }
+
+      root.addEventListener("click", function (event) {
+        var tab = event.target.closest('[role="tab"]');
+        if (tab) select(tab, false);
+      });
+
+      root.addEventListener("keydown", function (event) {
+        var index = tabs.indexOf(document.activeElement);
+        if (index === -1) return;
+
+        var next = null;
+        if (event.key === "ArrowRight") next = tabs[(index + 1) % tabs.length];
+        else if (event.key === "ArrowLeft") next = tabs[(index - 1 + tabs.length) % tabs.length];
+        else if (event.key === "Home") next = tabs[0];
+        else if (event.key === "End") next = tabs[tabs.length - 1];
+
+        if (next) {
+          event.preventDefault();
+          select(next, true);
+        }
+      });
+
+      select(tabs.filter(function (tab) {
+        return tab.getAttribute("aria-selected") === "true";
+      })[0] || tabs[0], false);
+    });
+  }
+
+  function setUpNavToggle() {
+    document.addEventListener("click", function (event) {
+      var toggle = event.target.closest("[data-nav-toggle]");
+      if (!toggle) return;
+
+      var sidebar = toggle.closest("[data-sidebar]");
+      var collapsed = sidebar.dataset.collapsed !== "false";
+      sidebar.dataset.collapsed = String(!collapsed);
+      toggle.setAttribute("aria-expanded", String(collapsed));
+    });
+  }
+
+  setUpTheme();
+  setUpTabs();
+  setUpNavToggle();
+})();
+
+</script>
+</body>
+</html>
diff --git a/script/build_design_bundle.rb b/script/build_design_bundle.rb
deleted file mode 100644
index 38ff581..0000000
--- a/script/build_design_bundle.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/env ruby
-# frozen_string_literal: true
-
-# Builds the Claude Design upload bundle from the already-built _site.
-#
-# One card per documentation page: the page's <main> lifted out of the site
-# chrome and dropped into a standalone HTML file with the compiled tokens and
-# component CSS inlined. Cards are generated rather than hand-written for the
-# same reason the docs are — a second, hand-maintained copy of the system would
-# start disagreeing with the first one immediately.
-#
-#   bundle exec rake build && ruby script/build_design_bundle.rb
-#
-# Output lands in design-bundle/, which is gitignored: it is a build artifact.
-
-require "fileutils"
-
-# The site is UTF-8 regardless of the locale the build happens to run under,
-# and a runner with LANG unset would otherwise read it as US-ASCII.
-Encoding.default_external = Encoding::UTF_8
-Encoding.default_internal = Encoding::UTF_8
-
-ROOT   = File.expand_path("..", __dir__)
-SITE   = File.join(ROOT, "_site")
-OUT    = File.join(ROOT, "design-bundle")
-BASE   = "/arbitrary-definitions-design-system"
-CANON  = "https://kejadlen.github.io#{BASE}"
-
-# page path in _site => [bundle path, Design System pane group, card title]
-CARDS = [
-  ["foundations/color",       "foundations/color.html",       "Foundations", "Color"],
-  ["foundations/typography",  "foundations/typography.html",  "Foundations", "Typography"],
-  ["foundations/space",       "foundations/space.html",       "Foundations", "Space"],
-  ["foundations/elevation",   "foundations/elevation.html",   "Foundations", "Elevation"],
-  ["foundations/motion",      "foundations/motion.html",      "Foundations", "Motion"],
-  ["components/button",       "components/button.html",       "Core",        "Button"],
-  ["components/icon-button",  "components/icon-button.html",  "Core",        "IconButton"],
-  ["components/badge",        "components/badge.html",        "Core",        "Badge"],
-  ["components/tag",          "components/tag.html",          "Core",        "Tag"],
-  ["components/card",         "components/card.html",         "Core",        "Card"],
-  ["components/card-row",     "components/card-row.html",     "Core",        "CardRow"],
-  ["components/field",        "components/field.html",        "Forms",       "Field"],
-  ["components/input",        "components/input.html",        "Forms",       "Input"],
-  ["components/select",       "components/select.html",       "Forms",       "Select"],
-  ["components/checkbox",     "components/checkbox.html",     "Forms",       "Checkbox"],
-  ["components/radio",        "components/radio.html",        "Forms",       "Radio"],
-  ["components/switch",       "components/switch.html",       "Forms",       "Switch"],
-  ["components/tooltip",      "components/tooltip.html",      "Feedback",    "Tooltip"],
-  ["components/toast",        "components/toast.html",        "Feedback",    "Toast"],
-  ["components/dialog",       "components/dialog.html",       "Feedback",    "Dialog"],
-  ["components/tabs",         "components/tabs.html",         "Navigation",  "Tabs"],
-  ["patterns/loop",           "patterns/loop.html",           "Patterns",    "Loop"],
-  ["patterns/archive",        "patterns/archive.html",        "Patterns",    "Archive"],
-].freeze
-
-def read_site(path)
-  full = File.join(SITE, path)
-  abort "missing #{full} — run `bundle exec rake build` first" unless File.file?(full)
-  File.read(full, encoding: "UTF-8")
-end
-
-# The site emits exactly one <main>, with no nesting, so this is unambiguous.
-def extract_main(html, page)
-  body = html[%r{<main[^>]*id="main"[^>]*>(.*?)</main>}m, 1]
-  abort "no <main> found in #{page}" unless body
-
-  body
-    # Site-relative links would dead-end inside the Design System pane.
-    .gsub(%r{(href|src)="#{Regexp.escape(BASE)}/}, "\\1=\"#{CANON}/")
-    .strip
-end
-
-def card_html(group:, title:, body:, tokens:, styles:, script:)
-  <<~HTML
-    <!-- @dsCard group="#{group}" -->
-    <!doctype html>
-    <html lang="en">
-    <head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <title>#{title}</title>
-    <link rel="preconnect" href="https://fonts.googleapis.com">
-    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
-    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap">
-    <style>
-    #{tokens}
-    #{styles}
-    /* Card chrome. The pane supplies the frame; this just insets the page. */
-    body { padding: var(--ad-space-l) var(--ad-space-m); }
-    .ad-doc-main { max-width: 50rem; margin-inline: auto; }
-    .ad-doc-main > * { max-width: none; }
-    </style>
-    </head>
-    <body>
-    <main class="ad-doc-main">
-    #{body}
-    </main>
-    <script>
-    #{script}
-    </script>
-    </body>
-    </html>
-  HTML
-end
-
-FileUtils.rm_rf(OUT)
-FileUtils.mkdir_p(OUT)
-
-tokens = read_site("assets/css/tokens.css")
-styles = read_site("assets/css/style.css")
-script = read_site("assets/js/system.js")
-
-# The compiled CSS goes in as-is too, so the project carries the artifact a
-# consumer would actually link, not only the rendered previews.
-FileUtils.mkdir_p(File.join(OUT, "css"))
-File.write(File.join(OUT, "css", "tokens.css"), tokens)
-File.write(File.join(OUT, "css", "style.css"), styles)
-
-CARDS.each do |page, out_path, group, title|
-  body = extract_main(read_site(File.join(page, "index.html")), page)
-  target = File.join(OUT, out_path)
-  FileUtils.mkdir_p(File.dirname(target))
-  File.write(target, card_html(group: group, title: title, body: body,
-                               tokens: tokens, styles: styles, script: script))
-end
-
-total = Dir.glob(File.join(OUT, "**", "*")).count { |f| File.file?(f) }
-bytes = Dir.glob(File.join(OUT, "**", "*")).sum { |f| File.file?(f) ? File.size(f) : 0 }
-puts "design-bundle: #{CARDS.size} cards, #{total} files, #{(bytes / 1024.0).round} KiB"