/* ============================================================
   Motion Design System — showcase styles.
   Shared by index.html (motion) and tokens.html (token overview).
   Skinned entirely from tokens/tokens.css; BEM naming. The pages
   own layout, the tokens own the look.
   ============================================================ */
[x-cloak] { display: none !important; }
* { box-sizing: border-box; }
body { margin: 0; }

.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: var(--sp-4);
  z-index: 10;
  padding: var(--sp-2) var(--sp-4);
  background: var(--accent);
  color: var(--accent-on);
  border-radius: var(--r-pill);
  transform: translateY(-200%);
  transition: transform var(--motion-base-functional-entrance);
}
.skip-link:focus-visible { transform: translateY(0); }

/* ---------- Site header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--gutter);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border-1);
}

/* Splash header — minimal cover chrome: brand + theme switch, no nav, not sticky (the in-page
   section rail owns the sticky behaviour). Shares the wrap gutter so it lines up with content. */
.splash-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;  /* the labelled view toggle is wide — let it drop below the brand on narrow screens */
  gap: var(--sp-4);
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--sp-5) var(--gutter);
}
/* Under 768px the header toggle is redundant — the same read/explore switch lives in the doc rail,
   which is reachable on mobile — so drop the header copy to keep the splash chrome to brand only. */
@media (max-width: 767.98px) {
  .splash-header .view-switch { display: none; }
}

/* Brand lockup — lime mark + wordmark, links to the home route. */
.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-4); /* 16px */
  text-decoration: none;
  color: inherit;
  border-radius: var(--r-md);
}
.brand:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.brand__name {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg3);
}

/* Primary navigation — Motion / Articles / About. */
.site-nav__list {
  display: flex;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-nav__link {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg3);
  text-decoration: none;
  text-transform: lowercase;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-pill);
  transition: color var(--motion-use-hover), background var(--motion-use-hover);
}
.site-nav__link:hover { color: var(--fg1); background: var(--bg-elev); }
.site-nav__link[aria-current="page"] { color: var(--accent-text); }
.site-nav__link:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Mobile-first: below 1024px the inline nav is hidden and a hamburger opens the drawer.
   At the breakpoint the inline nav returns and the hamburger hides. */
.site-nav { display: none; }
.site-nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-1);
  color: var(--fg1);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color var(--motion-use-hover);
}
.site-nav__toggle:hover { color: var(--accent-text); }
.site-nav__toggle:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }
.site-nav__toggle svg { display: block; width: 1.5rem; height: 1.5rem; }

@media (min-width: 1024px) {
  .site-nav { display: block; }
  .site-nav__toggle { display: none; }
}

/* Motion disclosure dropdown — a button (shares .site-nav__link) toggling a submenu that
   pops on the nav-popover choreography. The submenu is absolutely positioned off its item. */
.site-nav__item { position: relative; }
.site-nav__disclosure {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  border: 0;
  background: none;
  cursor: pointer;
}
.site-nav__disclosure.is-current { color: var(--accent-text); }
.site-nav__caret { width: 0.9em; height: 0.9em; transition: transform var(--motion-use-hover); }
.site-nav__disclosure[aria-expanded="true"] .site-nav__caret { transform: rotate(180deg); }

.site-subnav {
  position: absolute;
  top: calc(100% + var(--sp-2));
  inset-inline-start: 0;
  transform-origin: top left;
  min-width: 12rem;
  margin: 0;
  padding: var(--sp-2);
  list-style: none;
  display: grid;
  gap: 2px;
  background: var(--bg);
  border: 1px solid var(--border-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  z-index: 6;
}
.site-subnav__link {
  display: block;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  text-transform: lowercase;
  color: var(--fg2);
  text-decoration: none;
  transition: color var(--motion-use-hover), background var(--motion-use-hover);
}
.site-subnav__link:hover { color: var(--fg1); background: var(--bg-elev); }
.site-subnav__link[aria-current="page"] { color: var(--accent-text); }
.site-subnav__link:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Home link (legacy topbar — used by the old header / principals page). */
.topbar__home {
  display: inline-flex;
  border-radius: var(--r-md);
  transition: opacity var(--motion-use-hover);
}
.topbar__home:hover { opacity: 0.85; }
.topbar__home:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg1);
  background: var(--bg-elev);
  border: 1px solid var(--border-1);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: border-color var(--motion-use-hover), background var(--motion-use-hover);
}
.theme-toggle:hover { border-color: var(--border-2); background: var(--bg-inset); }
.theme-toggle:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* ---------- Logo — the rs_ mark + blinking lime caret ----------
   The caret is a mono underscore that blinks 1s stepped, like a terminal
   cursor. It's the system's one signature motion. */
.logo-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  user-select: none;
}
.logo-tile--brand { width: 84px; height: 84px; border-radius: var(--r-lg); font-size: 44px; }
.logo-tile--light { background: var(--bone-50); color: var(--ink-900); border: 1px solid var(--border-1); }
.logo-tile--dark  { background: var(--ink-900); color: var(--bone-50); }
.logo-tile--lime  { background: var(--accent);  color: var(--ink-900); }

.logo__caret {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--accent);
  animation: caret-blink 1s steps(1) infinite;
}
.logo-tile--lime .logo__caret { color: var(--ink-900); }
@keyframes caret-blink {
  0%, 50%     { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* Brand mark — always the lime variant (both light and dark themes). */
.brand__mark {
  width: 34px;
  height: 34px;
  border-radius: var(--r-md);
  font-size: 18px;
}

/* Brand section layout */
.logo-grid { display: flex; gap: var(--sp-5); flex-wrap: wrap; }
.logo-cell { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); margin: 0; }
.logo-cell__cap {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg3);
}
.wordmark-row { margin-top: var(--sp-7); }
.wordmark {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-h1);
  letter-spacing: var(--tracking-tight);
  color: var(--fg1);
  line-height: 1;
}

/* ---------- Layout ---------- */
.wrap {
  max-width: var(--container);
  margin-inline: auto;
  padding: var(--sp-9) var(--gutter) var(--sp-10);
}
/* Individual article is full-bleed and shares the header's gutter, so the
   breadcrumb, divider, and body all sit on the header's left edge. The tight
   top padding tucks the breadcrumb close under the sticky header. */
.wrap--article {
  max-width: none;
  padding: var(--sp-4) var(--gutter) var(--sp-10);
}

.hero { max-width: var(--container-narrow); margin-bottom: var(--sp-10); }
.hero__title {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  margin: var(--sp-4) 0 var(--sp-5);
  text-wrap: balance;
}
.hero__title em { color: var(--accent-text); font-style: normal; }
.hero__lede { font-size: var(--fs-h4); color: var(--fg2); max-width: 60ch; text-wrap: balance; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); margin-top: var(--sp-6); }

.divider { border: 0; border-top: 1px solid var(--border-1); margin: 0; }

/* Placeholder — a "coming soon" panel for stub pages (Examples, Generator). */
.placeholder {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-8);
  border: 1px dashed var(--border-2);
  border-radius: var(--r-lg);
  background: var(--bg-elev);
}
.placeholder__tag {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--accent-text);
}
.placeholder__text { margin: 0; color: var(--fg2); max-width: 60ch; }

.section { margin-top: var(--sp-9); scroll-margin-top: 80px; }
/* Anchor targets clear the sticky mobile rail and leave breathing room when jumped to. */
.subsection[id] { scroll-margin-top: var(--sp-8); }

/* Smooth in-page jumps from the section rail (motion-safe only). */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* ---------- Doc layout — content + on-page section rail (overview) ----------
   Mobile: a sticky glassy dropdown above the content. Desktop: a sticky, elevated surface card
   beside it (View controls + Quicklinks, split by a hairline). Scroll-spy (docNav) toggles
   .is-active → an accent chip on the exact section/subsection; it eases in on the hover token. */
.doc { margin-top: var(--sp-7); }
/* First section's heading aligns with the top of the side rail (drop the inter-section top margin). */
.doc-body > .section:first-child { margin-top: 0; }
.doc-rail__list { list-style: none; margin: 0; padding: 0; }
.doc-rail__link {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg3);
  text-decoration: none;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  transition: color var(--motion-use-hover), background-color var(--motion-use-hover);
}
.doc-rail__link:not(.is-active):hover { color: var(--fg1); }
/* Active = the exact section/subsection you're in, as an accent chip — the same language as the
   Example/Token and View toggles. accent + accent-on is a fixed high-contrast pair, so it stays
   vivid in light mode too (unlike the old muddy lime-on-light text). */
.doc-rail__link.is-active { background-color: var(--accent); color: var(--accent-on); }

/* Mobile: a sticky, glassy dropdown. The trigger shows the current section; the list drops beneath
   it as a floating panel (keeps the sticky + glassmorphism; replaces the old scrolling pill row). */
.doc-rail {
  position: sticky;
  top: 0;
  z-index: 4;
  margin-inline: calc(-1 * var(--gutter));
  padding: var(--sp-3) var(--gutter);
  margin-bottom: var(--sp-6);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-1);
}
/* Mobile: the dropdown trigger and the view switch share one row; the trigger takes the slack. */
.doc-rail__bar { display: flex; align-items: center; gap: var(--sp-3); }
.doc-rail__view-label,
.doc-rail__heading { display: none; }   /* eyebrows — desktop only (the mobile rail is a dropdown) */
.doc-rail__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex: 1 1 auto;
  padding: var(--sp-2) var(--sp-4);
  background: var(--bg-elev);
  border: 1px solid var(--border-1);
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg1);
  cursor: pointer;
}
.doc-rail__toggle:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.doc-rail__toggle-icon { color: var(--fg3); transition: transform var(--motion-use-disclosure-in); }
.doc-rail__toggle[aria-expanded="true"] .doc-rail__toggle-icon { transform: rotate(180deg); }

.doc-rail__list {
  position: absolute;
  inset-inline: var(--gutter);
  margin-top: var(--sp-2);
  padding: var(--sp-2);
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  background: color-mix(in srgb, var(--bg-elev) 92%, transparent);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border-1);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition:
    opacity var(--motion-use-disclosure-out),
    transform var(--motion-use-disclosure-out),
    visibility 0s linear var(--motion-duration-short);
}
.doc-rail__list.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity var(--motion-use-disclosure-in), transform var(--motion-use-disclosure-in), visibility 0s;
}
.doc-rail__link { white-space: nowrap; }

@media (min-width: 960px) {
  .doc { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: var(--sp-6); align-items: start; }
  /* The rail becomes one elevated surface card, so the View controls and the Quicklinks read as a
     single cohesive group lifted off the page (vs. the old bare, un-grouped column). */
  .doc-rail {
    position: sticky; top: var(--sp-7); align-self: start; z-index: auto;
    margin: 0; padding: var(--sp-4);
    background: var(--bg-elev); backdrop-filter: none;
    border: 1px solid var(--border-1); border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
  }
  .doc-rail__toggle { display: none; }
  /* View controls group, split from the Quicklinks group by a hairline for clear grouping. */
  .doc-rail__bar {
    flex-direction: column; align-items: flex-start; gap: var(--sp-3);
    padding-bottom: var(--sp-4); margin-bottom: var(--sp-4);
    border-bottom: 1px solid var(--border-1);
  }
  .doc-rail__view-label,
  .doc-rail__heading {
    display: block;
    font-family: var(--font-mono); font-size: var(--fs-micro);
    text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--fg3);
  }
  /* "Quicklinks" labels the section list below the view switch. */
  .doc-rail__heading { margin: 0 0 var(--sp-3); }
  .doc-rail__list {
    position: static; inset-inline: auto; margin: 0; padding: 0; z-index: auto;
    background: none; backdrop-filter: none; border: 0; border-radius: 0; box-shadow: none;
    opacity: 1; visibility: visible; transform: none; transition: none;
    gap: var(--sp-1);
  }
}
.section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding-bottom: var(--sp-4);
  margin-bottom: var(--sp-7);
  border-bottom: 1px solid var(--border-1);
}
.section__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  letter-spacing: var(--tracking-snug);
}
.section__note { font-size: var(--fs-small); color: var(--fg3); max-width: 42ch; }
/* Stacked variant: an authoritative tier opener — a large heading with a lede beneath it, sized at
   --fs-lead (one step down from h4, above body) so the description reads as support, not a headline. */
.section__head--stacked { flex-direction: column; align-items: flex-start; gap: var(--sp-4); }
.section__head--stacked .section__title { font-size: var(--fs-h2); line-height: var(--lh-snug); }
.section__head--stacked .section__note { margin: 0; max-width: 64ch; font-size: var(--fs-lead); line-height: var(--lh-normal); color: var(--fg2); }
/* Inline links in prose notes — mode-specific accent, underlined, two-tone focus. */
.section__note a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.2em; transition: color var(--motion-use-hover); }
.section__note a:hover { color: var(--fg1); }
.section__note a:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }
/* Contact email — mail icon + address on its own line (8px gap), accent-colored like the note links. */
.summary-email { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-lead); color: var(--accent-text); text-decoration: none; transition: color var(--motion-use-hover); }
.summary-email:hover { color: var(--fg1); }
.summary-email:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }
.summary-email span { text-decoration: underline; text-underline-offset: 0.2em; }
.summary-email__icon { flex: none; width: 1.2em; height: 1.2em; }

.grid { display: grid; gap: var(--sp-4); }
.grid--swatches { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.grid--cards { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

/* ---------- Buttons ----------
   .btn works as either a <button> (trigger) or an <a> (link); the flex + no-underline
   rules keep an anchor visually identical to a button. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: 500;
  padding: var(--sp-3) var(--sp-6);
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--motion-use-hover), border-color var(--motion-use-hover);
}
.btn--primary { background: var(--accent); color: var(--accent-on); }
.btn--primary:hover { background: var(--accent-hover); }
.btn--primary:active { background: var(--accent-press); }
/* Secondary — the outlined treatment (btn--ghost kept as an alias). */
.btn--secondary, .btn--ghost { background: transparent; color: var(--fg1); border-color: var(--border-2); }
.btn--secondary:hover, .btn--ghost:hover { border-color: var(--fg1); }
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.btn--sm { padding: var(--sp-2) var(--sp-4); font-size: var(--fs-small); }

/* ---------- Route transition — the "Explore" wipe ----------
   A cross-document View Transition: a lime scrim irises out from the click point
   to cover the page (driven by assets/route-transition.js), then the browser
   crossfades the covered snapshot away to reveal the destination. This is a
   native/CSS effect on purpose — the best tool for the job, not a Tier-3 JSON
   token — but its timing still reads from the --motion-* tokens, so it collapses
   under reduced motion with the rest of the system. */
@view-transition { navigation: auto; }

.route-scrim {
  position: fixed;
  inset: 0;
  z-index: 100; /* above the sticky header, skip-link, and overlays */
  background: var(--accent);
  pointer-events: none;
  visibility: hidden; /* armed by JS only for the duration of the wipe */
  clip-path: circle(0 at 50% 50%);
}

/* Every other navigation stays instant/unchanged: neutralize the default root
   cross-fade that `navigation: auto` would otherwise apply site-wide. */
::view-transition-group(root),
::view-transition-old(root),
::view-transition-new(root) { animation: none; }

/* The wipe navigation (tagged `route-wipe` in pagereveal) holds the lime cover for
   a beat as the page changes over, then crossfades it away — a `short` hold
   (animation-delay) + a `long`, gentle fade. The delay's backwards fill keeps the
   lime opaque and the destination hidden during the hold; both collapse to 0 under
   reduced motion with the tokens. */
html:active-view-transition-type(route-wipe)::view-transition-old(root) {
  animation: route-reveal-out var(--motion-duration-long) var(--motion-easing-gentle) var(--motion-duration-short) both;
}
html:active-view-transition-type(route-wipe)::view-transition-new(root) {
  animation: route-reveal-in var(--motion-duration-long) var(--motion-easing-gentle) var(--motion-duration-short) both;
}
@keyframes route-reveal-out { to { opacity: 0; } }
@keyframes route-reveal-in { from { opacity: 0; } }

/* Safety net: force any root view transition instant under reduced motion (the
   JS already declines to arm the wipe, this covers the CSS side regardless). */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}

/* ---------- Motion showcase — tiers ---------- */
.tier { display: grid; gap: var(--sp-7); }
/* Overview Tier 1: double the breathing room between the duration and easing subsections. */
.tier:has(.subsection--split) { gap: var(--sp-9); }
.tier__sub { display: grid; gap: var(--sp-3); }
.tier__caption { font-family: var(--font-mono); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--fg3); margin: 0; }
.tier__eyebrow { font-family: var(--font-mono); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--accent-text); margin: 0 0 var(--sp-2); }

.motion__controls { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }

/* ---------- Tier 1 — accordions (duration / easing) ---------- */
.accordion { border: 1px solid var(--border-1); border-radius: var(--r-md); overflow: hidden; }
.accordion + .accordion { margin-top: var(--sp-4); }
.accordion__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--bg-elev);
  border: 0;
  color: var(--fg1);
  cursor: pointer;
  text-align: left;
  transition: background var(--motion-use-hover);
}
.accordion__trigger:hover { background: var(--bg-inset); }
.accordion__trigger:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.accordion__name { font-family: var(--font-display); font-size: var(--fs-h4); font-weight: 600; }
.accordion__meta { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); margin-inline-start: var(--sp-3); }
.accordion__spacer { flex: 1; }
.accordion__icon { font-family: var(--font-mono); font-size: var(--fs-h4); color: var(--fg3); line-height: 1; }
.accordion__body { }
.accordion__inner { padding: var(--sp-3) var(--sp-5) var(--sp-5); display: grid; gap: var(--sp-2); }

/* Primitive tracks — one row per token, with a per-row play button. */
.motion-track {
  display: grid;
  grid-template-columns: minmax(64px, 110px) 1fr max-content max-content;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--border-1);
}
.motion-track:last-child { border-bottom: 0; }
.motion-track__label { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--fg1); }
.motion-track__label small { display: block; color: var(--fg3); font-size: var(--fs-micro); }
.motion-track__rail {
  position: relative;
  height: 40px;
  border-radius: var(--r-sm);
  background: var(--bg-elev);
  border: 1px solid var(--border-1);
  overflow: hidden;
  container-type: inline-size;
}
.motion-track__dot {
  position: absolute;
  top: 50%;
  left: 6px;
  width: 28px;
  height: 28px;
  margin-top: -14px;
  border-radius: var(--r-sm);
  /* The playhead is lime-as-ink on the light --bg-elev rail, so it uses the mode-aware
     --accent-text (olive lime-600 in light, bright lime-300 in dark) — matching the easing
     curve, rather than the raw fill lime that sat ~1.1:1 on the light rail. */
  background: var(--accent-text);
  transform: translateX(0);
}
/* Travel = rail inline size minus the dot (28px) and its two 6px insets. */
.motion-track__rail.is-go .motion-track__dot { transform: translateX(calc(100cqw - 40px)); }
.motion-track__val {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--fg3);
  text-align: right;
  white-space: nowrap;
}
.motion-track__play { justify-self: end; min-width: 68px; }

/* ---------- Tier 1 — subsections (duration table + easing grid) ----------
   Each primitive subsection: an icon + title head, the live token display, then a
   paragraph on the vocabulary. Skinned from the brand tokens; BEM naming. */
.subsection { display: grid; gap: var(--sp-5); }
.subsection__head { display: flex; align-items: center; gap: var(--sp-3); }
.subsection__icon { display: inline-flex; color: var(--accent-text); }
.subsection__icon svg { display: block; width: 1.5rem; height: 1.5rem; }
.subsection__title { font-family: var(--font-display); font-size: var(--fs-h4); font-weight: 600; letter-spacing: var(--tracking-snug); color: var(--fg1); }
.subsection__note { font-size: var(--fs-small); line-height: var(--lh-relaxed); color: var(--fg2); max-width: 70ch; margin: 0; }
.subsection__note code { font-family: var(--font-mono); font-size: 0.9em; background: var(--bg-elev); border: 1px solid var(--border-1); padding: 0.15em 0.4em; border-radius: var(--r-sm); color: var(--fg1); }
.subsection__note strong { color: var(--accent-text); font-weight: 600; }
/* Overview Tier-1 intros: "ladder" is a defined term — emphasised by weight only, in primary ink,
   not the lime system-term accent. Scoped to .subsection__intro (overview-only). */
.subsection__intro strong { color: var(--fg1); }
.subsection__note em { font-style: italic; color: var(--fg1); }

/* Split subsections (overview Tier 1) — a bigger head, then the compressed demos below.
   Scoped to --split so the plain .subsection (tokens page) is untouched. */
.subsection--split { display: block; }
.subsection--split .subsection__title { font-size: var(--fs-h3); }
.subsection--split .subsection__icon svg { width: 1.75rem; height: 1.75rem; }
.subsection--split .subsection__note { font-size: var(--fs-body); }
.subsection--split .subsection__intro { margin-top: var(--sp-3); }   /* 12px: head → intro */
.subsection--split .table-scroll,
.subsection--split .curve-gallery { margin-top: var(--sp-7); }       /* 48px: intro → demos */
.subsection--split + .use-grid { margin-top: var(--sp-7); }          /* 48px: recipe lead → examples */

/* Skim lead — a bold phrase that gives each blurb a scannable anchor, in fg1 so it reads as a
   plain bold (distinct from the lime <strong> reserved for system terms like "ladder"). */
.lead { color: var(--fg1); font-weight: 600; }

/* Duration — one banded table: a single header, then each rung group introduced by a full-width
   band row (label + blurb) so the three groups read as sections of one comparable ladder. */
.token-table--banded .band__cell {
  padding: var(--sp-6) var(--sp-4) var(--sp-4);
  border-bottom: 0;
  font-weight: 400;
  text-align: left;
  vertical-align: baseline;
}
.token-table--banded tbody:first-of-type .band__cell { padding-top: var(--sp-2); }
.token-table--banded tbody + tbody .band__cell { border-top: 1px solid var(--border-1); padding-top: var(--sp-8); }
/* The Name / Value / Example header is redundant under the banded group labels, so it's hidden in
   the default context view; it only appears in examples-only, where the bands are gone and the
   merged table needs its columns labelled. */
.doc:not(.doc--examples-only) .token-table--banded thead { display: none; }
.band__title {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: 600;
  letter-spacing: var(--tracking-snug);
  color: var(--fg1);
}
.band__note {
  display: block;
  margin-top: var(--sp-2);
  max-width: 70ch;
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  color: var(--fg2);
  white-space: normal;
}
.band__note code { font-family: var(--font-mono); font-size: 0.9em; background: var(--bg-elev); border: 1px solid var(--border-1); padding: 0.15em 0.4em; border-radius: var(--r-sm); color: var(--fg1); }

/* Easing — a two-up gallery of curve groups: label + blurb + the curve card(s). */
/* Subsections go 2-up only on wide viewports (>=1200px); below that they stack vertically so each
   group gets the full content width for its two-up cards. */
.curve-gallery { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 1200px) { .curve-gallery { grid-template-columns: repeat(2, 1fr); gap: var(--sp-7) var(--sp-6); } }
.curve-group { display: flex; flex-direction: column; gap: var(--sp-3); }
.curve-group__title { font-family: var(--font-display); font-size: var(--fs-h4); font-weight: 600; letter-spacing: var(--tracking-snug); color: var(--fg1); }
.curve-group__note { margin: 0; max-width: 60ch; font-size: var(--fs-body); line-height: var(--lh-relaxed); color: var(--fg2); }
.curve-group__note code { font-family: var(--font-mono); font-size: 0.9em; background: var(--bg-elev); border: 1px solid var(--border-1); padding: 0.15em 0.4em; border-radius: var(--r-sm); color: var(--fg1); }
.curve-group__note em { font-style: italic; color: var(--fg1); }
.curve-group .easing-grid { margin-top: var(--sp-5); }

/* Duration ladder — a play-the-token table. The Example cell reuses the primitive rail + dot;
   the rail grows to fill while the Play button stays fixed. The wrapper scrolls on narrow screens. */
.table-scroll { overflow-x: auto; }
.token-table { width: 100%; border-collapse: collapse; }
.token-table thead th {
  text-align: left;
  padding: 0 var(--sp-4) var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg3);
  white-space: nowrap;
  border-bottom: 1px solid var(--border-1);
}
.token-table tbody th,
.token-table tbody td {
  padding: var(--sp-3) var(--sp-4);
  vertical-align: middle;
  border-bottom: 1px solid var(--border-1);
}
.token-table tbody tr:last-child th,
.token-table tbody tr:last-child td { border-bottom: 0; }
.token-table__name { text-align: left; font-family: var(--font-mono); font-size: var(--fs-small); font-weight: 500; color: var(--fg1); white-space: nowrap; }
.token-table__value { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); white-space: nowrap; }
.token-table__example { width: 60%; }

.dur-demo { display: flex; align-items: center; gap: var(--sp-4); }
.dur-demo .motion-track__rail { flex: 1; min-width: 120px; }
.dur-demo__play { flex: none; min-width: 72px; }

/* Under 600px: the three-column row (name · value · example) can't breathe, so each rung becomes a
   stack — name + value on the first line, the track + Play button drop to a full-width line below. */
@media (max-width: 599.98px) {
  .token-table--banded,
  .token-table--banded tbody,
  .token-table--banded tr,
  .token-table--banded th,
  .token-table--banded td { display: block; }
  .token-table--banded thead { display: none; }   /* stacked rows make the column header meaningless */

  .token-table--banded tbody tr:not(.band) {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: var(--sp-3);
    row-gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--border-1);
  }
  .token-table--banded tbody:last-of-type tr:not(.band):last-child { border-bottom: 0; }

  .token-table--banded tbody tr:not(.band) .token-table__name,
  .token-table--banded tbody tr:not(.band) .token-table__value { padding: 0; border: 0; }
  .token-table--banded tbody tr:not(.band) .token-table__example {
    flex: 1 0 100%;   /* full-width line under name + value */
    width: auto;
    padding: 0;
    border: 0;
  }
}

/* Easing set — one card per curve: name, a drawn cubic-bezier graph, value. The dashed diagonal is
   the linear reference; thin handles mark the two control points; the lime path is the curve. */
/* Cards stay two-up from 768px (including the stacked-subsection range below 1200px); under 768px
   they stack vertically. */
.easing-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-4); }
@media (min-width: 768px) { .easing-grid { grid-template-columns: repeat(2, 1fr); } }
.easing-card { display: grid; gap: var(--sp-3); padding: var(--sp-5); border: 1px solid var(--border-1); border-radius: var(--r-lg); background: var(--bg-elev); }
.easing-card__name { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--fg1); }
.easing-card__graph { display: block; width: 100%; aspect-ratio: 1 / 1; background: var(--bg-inset); border: 1px solid var(--border-1); border-radius: var(--r-md); }
.easing-card__value { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); word-break: break-word; }
.easing-card__graph .ec-guide { stroke: var(--border-2); stroke-dasharray: 3 4; vector-effect: non-scaling-stroke; }
.easing-card__graph .ec-handle { stroke: var(--border-2); vector-effect: non-scaling-stroke; }
.easing-card__graph .ec-handle-dot { fill: var(--fg-muted); }
/* The curve + endpoint nodes are lime-as-ink on the near-white inset well, so they use the
   mode-aware --accent-text (olive lime-600 in light ≈3.4:1, bright lime-300 in dark) rather than
   the raw fill lime (--accent), which washes out to ~1.4:1 on white. Matches the system rule:
   lime fills use --accent + --accent-on; lime strokes/text use --accent-text. */
.easing-card__graph .ec-curve { stroke: var(--accent-text); stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.easing-card__graph .ec-node { fill: var(--accent-text); }

/* Tier 2 — semantic reference rows (composites — currently hidden) */
.mtoken { display: grid; grid-template-columns: minmax(160px, 220px) 1fr; gap: var(--sp-4); align-items: baseline; padding: var(--sp-2) 0; border-bottom: 1px solid var(--border-1); }
.mtoken__name { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--fg1); }
.mtoken__val { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }

/* ---------- Tier 2 — semantic use cases (overview) ----------
   Each card runs a live demo whose transition is driven by a single --motion-use-* composite,
   with a recipe line mapping that token back to the Tier 1 rung + curve it pairs. */
.use-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); }
@media (min-width: 1200px) { .use-grid { grid-template-columns: repeat(3, 1fr); gap: var(--sp-6); } }

.use-card { display: grid; grid-template-rows: auto 1fr; gap: var(--sp-5); padding: var(--sp-4); border: 1px solid var(--border-1); border-radius: var(--r-lg); background: var(--bg-elev); }
/* 768-1199px: the cards are stacked one-up (see .use-grid), so each one goes horizontal — square
   stage on the left, copy + toggle on the right (mirrors the Tier 3 / reduced-motion panels). Above
   1200px they are 3-up and vertical; under 768px they return to the original vertical stack. */
@media (min-width: 768px) and (max-width: 1199.98px) {
  .use-card {
    grid-template-columns: minmax(0, 280px) minmax(0, 1fr);
    grid-template-rows: auto;
    gap: var(--sp-6);
    align-items: center;
  }
}
.use-card__stage { position: relative; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-4); aspect-ratio: 1 / 1; min-height: 132px; padding: var(--sp-5); border: 1px solid var(--border-1); border-radius: var(--r-md); background: var(--bg-inset); }
.use-card__stage > .accordion--demo { width: 100%; }
.use-card__body { display: flex; flex-direction: column; gap: var(--sp-5); }
.use-card__text { display: flex; flex-direction: column; gap: var(--sp-3); }   /* heading + desc stay grouped */
.use-card__title { font-family: var(--font-display); font-size: var(--fs-h4); font-weight: 600; letter-spacing: var(--tracking-snug); color: var(--fg1); }
.use-card__desc { font-size: var(--fs-body); line-height: var(--lh-relaxed); color: var(--fg2); margin: 0; }
.use-card__desc code { font-family: var(--font-mono); font-size: 0.9em; background: var(--bg-inset); padding: 0.15em 0.4em; border-radius: var(--r-sm); color: var(--fg1); }

/* Recipe — the semantic token mapped to the rungs/curves it composes (the vocabulary payoff). */
/* Reads like the CSS custom property it documents — "--motion-use-hover: quick standard":
   dim property name, a colon, then the space-separated primitive values in accent. One declaration
   per row; disclosure's two tokens stack as two lines. */
.recipe { margin: 0; display: grid; gap: var(--sp-1); font-family: var(--font-mono); font-size: var(--fs-micro); line-height: var(--lh-normal); }
.recipe__row { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 1ch; }
.recipe code { font: inherit; }
.recipe__token { margin: 0; color: var(--fg2); }
.recipe__token::after { content: ":"; }
.recipe__value { margin: 0; color: var(--accent-text); }

/* Example / Token toggle — pinned to the card foot so it lines up across the row, left-aligned so
   the pill keeps its natural width rather than stretching. */
.use-card__body .seg-toggle { align-self: flex-start; }

/* Tier 2 — "Token" accent wash. Mirrors the Tier 3 reveal (see .choreo-wash), sized for the square
   card stage: flipping to Token adds .is-token, the accent sweeps across (clip-path), then the recipe
   panel fades in a beat behind it. Same Tier-2 motion tokens as Tier 3, so it collapses to an instant
   swap under reduced motion. */
.use-wash {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--accent);
  clip-path: inset(0 100% 0 0);
  pointer-events: none;
  transition: clip-path var(--motion-use-overlay-out) var(--motion-duration-short);
}
.use-card__stage.is-token .use-wash {
  clip-path: inset(0 0 0 0);
  pointer-events: auto;
  transition: clip-path var(--motion-use-page-transition);
}
.use-wash__panel {
  position: absolute;
  inset: var(--sp-3);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--sp-4);
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--bg-inset);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(8px) scale(0.98);
  transform-origin: center;
  transition: opacity var(--motion-use-overlay-out), transform var(--motion-use-overlay-out);
}
.use-card__stage.is-token .use-wash__panel {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--motion-use-overlay-in) var(--motion-duration-medium),
    transform var(--motion-use-overlay-in) var(--motion-duration-medium);
}

/* Hover demo — the lift joins the button's existing transition, still timed by --motion-use-hover. */
.use-hover { transition: background var(--motion-use-hover), border-color var(--motion-use-hover), transform var(--motion-use-hover), box-shadow var(--motion-use-hover); }
.use-hover:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }

/* Focus demo — border + ring ease in on --motion-use-focus (quick + entrance). */
.use-field { width: 100%; max-width: 200px; padding: var(--sp-3) var(--sp-4); font-family: var(--font-sans); font-size: var(--fs-body); color: var(--fg1); background: var(--bg-elev); border: 1px solid var(--border-2); border-radius: var(--r-md); transition: border-color var(--motion-use-focus), box-shadow var(--motion-use-focus); }
.use-field::placeholder { color: var(--fg-muted); }
.use-field:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--shadow-focus); }

/* Disclosure demo — a click-toggled tip. The .is-open rule carries the "in" transition
   (short + entrance); the base rule carries the "out" transition (quick + exit), so each
   direction animates on its own token. */
.use-tip { position: relative; display: inline-flex; }
.use-tip__bubble {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  width: max-content;
  max-width: 180px;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-elev);
  border: 1px solid var(--border-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-small);
  line-height: var(--lh-normal);
  color: var(--fg1);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(4px) scale(0.96);
  transform-origin: bottom center;
  transition: opacity var(--motion-use-disclosure-out), transform var(--motion-use-disclosure-out);
}
.use-tip__bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--bg-elev);
}
.use-tip__bubble.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0) scale(1);
  transition: opacity var(--motion-use-disclosure-in), transform var(--motion-use-disclosure-in);
}

/* Intent example — one real token printed from the source, with a caption. Reuses .choreo-spec
   for the code block; the figure just handles spacing and the caption. */
.intent-example { margin: var(--sp-6) 0 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
@media (min-width: 1200px) { .intent-example { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; } }
.intent-example__item { margin: 0; min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); align-content: start; }
/* Framed like the Tier 2/3 token views (.choreo-wash__panel): an accent frame around the dark spec.
   min-width:0 + minmax(0,1fr) tracks let the frame shrink so the pre's overflow-x scrolls the long
   choreography lines inside the panel instead of blowing out the whole page width. */
.intent-example__frame { min-width: 0; background: var(--accent); padding: var(--sp-5); border-radius: var(--r-lg); }
.intent-example__frame .choreo-spec { margin: 0; min-width: 0; border: 0; border-radius: var(--r-md); background: var(--bg-inset); box-shadow: var(--shadow-lg); overflow-x: auto; }
.intent-example .choreo-spec { font-size: 12px; }
.intent-example__caption { margin: 0; font-size: var(--fs-small); line-height: var(--lh-relaxed); color: var(--fg3); }
.intent-example + .subsection--split { margin-top: var(--sp-9); }   /* 96px: examples → closing subsection */
.intent-example__caption code { font-family: var(--font-mono); font-size: 0.9em; background: var(--bg-elev); border: 1px solid var(--border-1); padding: 0.15em 0.4em; border-radius: var(--r-sm); color: var(--fg1); }

/* Tier 3 toast — a transient notification that springs in (choreography-spring-in) and auto-dismisses.
   Centred at the top without a transform so the spring's own transform animates cleanly. Teleported
   to <body>, so it floats above the page chrome. */
/* Toast stack — pinned bottom-right. The container is a passthrough; each toast re-enables pointer
   events. New toasts push onto the end (nearest the corner); dismissing one collapses its box so the
   others slide down to fill the gap (see dismissToast). */
.toast-stack {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  z-index: 90;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  width: max-content;
  max-width: min(90vw, 360px);
  pointer-events: none;
}
.use-toast {
  margin-top: var(--sp-3);
  width: 100%;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  background: var(--bg-elev);
  border: 1px solid var(--border-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  font-size: var(--fs-small);
  color: var(--fg1);
  opacity: 0;   /* spring-in brings it in (x-init on each toast element) */
}
.use-toast:first-child { margin-top: 0; }
.use-toast__dot { flex: none; width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--accent); }
.use-toast__close { flex: none; margin-inline-start: var(--sp-2); color: var(--fg3); font-size: var(--fs-h4); line-height: 1; }
.use-toast__close:hover { color: var(--fg1); }
.use-toast__close:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }

/* Tier 2 — interactive feedback */
.feedback-row { display: flex; gap: var(--sp-5); flex-wrap: wrap; }
.feedback { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); }
.feedback__box {
  width: 92px; height: 92px; border-radius: var(--r-md);
  background: var(--bg-elev); border: 1px solid var(--border-1);
  display: grid; place-items: center; cursor: pointer;
  color: var(--fg3); font-family: var(--font-mono); font-size: var(--fs-micro);
}
.feedback__box--hover { transition: transform var(--motion-use-hover), box-shadow var(--motion-use-hover); }
.feedback__box--hover:hover { transform: translateY(calc(-1 * var(--motion-transform-enter))); box-shadow: var(--shadow-lg); }
.feedback__box--press { transition: transform var(--motion-use-press); }
.feedback__box--press:active { transform: scale(var(--motion-transform-shrink)); }
.feedback__box--focus:focus-visible { outline: none; box-shadow: var(--shadow-focus); transition: box-shadow var(--motion-use-focus); }
.feedback__cap { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }

/* Tier 2 — disclosure (x-disclose) */
.disclosure { border: 1px solid var(--border-1); border-radius: var(--r-md); overflow: hidden; max-width: 560px; }
.disclosure__trigger { width: 100%; text-align: left; padding: var(--sp-4); background: var(--bg-elev); border: 0; color: var(--fg1); font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 500; cursor: pointer; display: flex; justify-content: space-between; gap: var(--sp-4); }
.disclosure__trigger:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.disclosure__body { padding: 0 var(--sp-4); }
.disclosure__body > p { margin: var(--sp-4) 0; color: var(--fg2); }

/* ---------- Tier 3 — full-width choreography sections ----------
   Each token gets a full-width split: live stage on one side, name /
   controls / spec on the other. Alternate sides on wide screens; stack
   on mobile (mobile-first single column). */
.choreo {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-6);
  align-items: center;
  padding: var(--sp-8) 0;
  border-bottom: 1px solid var(--border-1);
}
@media (min-width: 880px) {
  .choreo { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
  .choreo--flip .choreo__stage { order: 2; }
}
.choreo__stage {
  position: relative;
  min-height: 300px;
  display: grid;
  place-items: center;
  padding: var(--sp-8);
  border-radius: var(--r-lg);
  background: var(--bg-inset);
  border: 1px solid var(--border-1);
  overflow: hidden;
  container-type: inline-size;
}
.choreo__info { display: grid; gap: var(--sp-4); align-content: center; }
.choreo__name { font-family: var(--font-mono); font-size: var(--fs-h4); letter-spacing: var(--tracking-snug); color: var(--fg1); margin: 0; }
.choreo__desc { color: var(--fg2); margin: 0; max-width: 46ch; }
.choreo__controls { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.choreo__pair { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); margin: 0; }
.choreo__pair code { color: var(--fg2); }

.choreo__spec-wrap { border-top: 1px solid var(--border-1); padding-top: var(--sp-3); }
.choreo__spec-wrap > summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg3);
  list-style: none;
}
.choreo__spec-wrap > summary::-webkit-details-marker { display: none; }
.choreo__spec-wrap > summary::before { content: '+ '; }
.choreo__spec-wrap[open] > summary::before { content: '− '; }
.choreo__spec-wrap[open] > summary { color: var(--fg1); margin-bottom: var(--sp-3); }
.choreo__spec-wrap:hover > summary { color: var(--fg1); }

.choreo-spec { margin: 0; padding: var(--sp-4); background: var(--bg-inset); border: 1px solid var(--border-1); border-radius: var(--r-sm); font-family: var(--font-mono); font-size: 11px; line-height: 1.55; color: var(--fg2); overflow-x: auto; }

/* Stage props */
.demo-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); width: 100%; max-width: 320px; }
.demo-list li { padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sm); background: var(--bg-elev); color: var(--fg1); border: 1px solid var(--border-1); border-inline-start: 3px solid var(--accent); font-family: var(--font-mono); font-size: var(--fs-small); }

/* Multi-phase gallery — a chip that scales / travels; the dashed ring (drawn on top at resting size)
   makes a compress read as "inside the ring" and an overshoot as "past it". */
.pop-gauge { position: relative; width: 120px; height: 120px; }
.pop-chip {
  position: absolute; inset: 0;
  border-radius: var(--r-lg);
  background: var(--bg-elev);
  border: 1px solid var(--border-2);
  box-shadow: var(--shadow-md);
  display: grid; place-items: center;
  will-change: transform;
}
.pop-chip__glyph { font-size: 48px; line-height: 1; color: var(--accent-text); }
.pop-gauge__rest {
  position: absolute; inset: 0;
  border: 1px dashed var(--border-2);
  border-radius: var(--r-lg);
  z-index: 2;
  pointer-events: none;
}

/* Path-based — the component owns the geometry (offset-path); the token owns the traversal.
   Fixed 280x160 so the drawn SVG path and the traveler's offset-path share one coordinate space. */
.arc-demo { position: relative; width: 280px; height: 160px; }
.arc-demo__track { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.arc-demo__traveler {
  position: absolute; top: 0; left: 0;
  offset-path: path("M18,132 C84,16 196,16 262,132");
  offset-rotate: auto;
  color: var(--accent-text);
  font-size: 22px; line-height: 1;
  will-change: offset-distance;
}

.demo-popover-wrap { position: relative; }
.demo-popover { position: absolute; top: calc(100% + 8px); left: 50%; translate: -50% 0; transform-origin: top center; min-width: 190px; padding: var(--sp-2); border-radius: var(--r-md); background: var(--bg); border: 1px solid var(--border-2); box-shadow: var(--shadow-lg); display: grid; gap: 2px; z-index: 2; }
.demo-popover a { display: block; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); text-decoration: none; color: var(--fg1); font-size: var(--fs-small); }
.demo-popover a:hover { background: var(--bg-elev); }

.modal-root { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; background: rgba(0,0,0,0.34); padding: var(--sp-5); }
.modal-card { width: min(440px, 100%); background: var(--bg); border: 1px solid var(--border-1); border-radius: var(--r-xl); box-shadow: var(--shadow-lg); padding: var(--sp-7); transform-origin: center; }
.modal-card h3 { margin: 0 0 var(--sp-3); font-size: var(--fs-h4); }
.modal-card p { margin: 0 0 var(--sp-5); color: var(--fg2); }

/* Overlay scrims — arm them hidden at rest. A scrim is full-viewport, so the one frame where it
   would otherwise paint at resting opacity before the fade-in commits reads as a hard black flash
   (the runtime's from-frame pin runs in $nextTick, which doesn't reliably beat that first paint
   after x-show flips display). Making the resting state hidden removes the flash independent of JS
   timing. Guarded for reduced motion — where the scrim just appears (the modal's reduced collapse
   doesn't animate .modal-root, so an unguarded opacity:0 would leave it invisible). Mirrors the
   .motion-text-reveal--armed pattern. */
@media (prefers-reduced-motion: no-preference) {
  .modal-root, .drawer-scrim { opacity: 0; }
}
[data-motion-mode="reduced"] .modal-root,
[data-motion-mode="reduced"] .drawer-scrim { opacity: 1; }

/* Reduced-motion demo (#reduced-motion) — mirrors the Tier-3 panel: stage on the left with the
   reveal/dismiss corner buttons, description + preference toggle on the right. The segmented control
   sets [data-motion-mode] on the stage only; the runtime reads it via closest() and the CSS duration
   collapse inherits onto the subtree, so the same trigger plays the full staggered rise or the
   collapsed single fade. (An OS reduced-motion setting still wins — then both states show the fade.) */
.rm-demo { margin-top: var(--sp-6); }
.rm-demo__panel { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); align-items: center; }
@media (min-width: 880px) { .rm-demo__panel { grid-template-columns: 1fr 1fr; gap: var(--sp-8); } }
.rm-demo__info { display: grid; gap: var(--sp-5); align-content: center; justify-items: start; }
.rm-demo__stage {
  position: relative;
  min-height: 18rem;
  display: grid;
  place-items: center;
  padding: var(--sp-5);
  background: var(--bg-elev);
  border: 1px solid var(--border-1);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.rm-demo__hint { margin: 0; max-width: 44ch; font-size: var(--fs-small); line-height: var(--lh-relaxed); color: var(--fg2); }

/* Drawer — scrim + panel are independent elements so drawer-enter/exit can animate
   them on separate coordinated tracks (scrim fades, panel slides). The interior nav
   then cascades in with list-reveal. */
.drawer-root { position: fixed; inset: 0; z-index: 50; }
.drawer-scrim { position: absolute; inset: 0; background: rgba(0,0,0,0.34); }
.drawer-panel {
  position: absolute; inset-block: 0; inset-inline-end: 0;
  width: min(360px, 86vw);
  background: var(--bg);
  border-inline-start: 1px solid var(--border-1);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-7) var(--sp-6);
  display: grid; gap: var(--sp-5); align-content: start;
  will-change: transform;
}
.drawer-panel__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }
.drawer-panel__title { font-family: var(--font-display); font-size: var(--fs-h4); font-weight: 600; }
.drawer-panel__close { background: none; border: 0; color: var(--fg3); font-family: var(--font-mono); font-size: var(--fs-h4); line-height: 1; cursor: pointer; padding: var(--sp-1); }
.drawer-panel__close:hover { color: var(--fg1); }
.drawer-panel__close:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }
.drawer-panel__close svg { display: block; width: 1.25rem; height: 1.25rem; }
.drawer-nav { display: grid; gap: var(--sp-2); }
/* The interior is revealed by list-reveal ~a beat AFTER the panel lands, so its animation is
   created too late for the runtime's from-frame pin to cover the gap. Keep the rows hidden until
   then, otherwise they paint in their resting (visible) state during the enter + beat and only
   vanish once the reveal's first frame commits (the first-open flash). Opacity-only, so the
   reduced-motion fade collapse is unaffected; the reveal's fill:both holds them visible after. */
.drawer-nav > * { opacity: 0; }
.drawer-link { display: block; padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md); text-decoration: none; color: var(--fg1); font-family: var(--font-sans); font-weight: 500; background: var(--bg-elev); transition: background var(--motion-use-hover); }
.drawer-link:hover { background: var(--bg-inset); }

/* Header drawer — Motion group label + indented child links (mobile nav). */
.drawer-nav__group {
  margin: 0;
  padding: var(--sp-2) var(--sp-3) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg3);
}
.drawer-nav__group.is-current { color: var(--accent-text); }
.site-nav__link--child { margin-inline-start: var(--sp-4); }

/* Tier 3 — text reveal: the "invisible wall" (overflow-hidden line wraps a mover) */
.motion-text-reveal { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h2); line-height: 1.08; letter-spacing: var(--tracking-tight); color: var(--fg1); text-align: center; }
.motion-text-reveal__line { display: block; overflow: hidden; padding-block: 0.08em; margin-block: -0.08em; }
.motion-text-reveal [data-text-line] { display: block; will-change: transform; }
@media (prefers-reduced-motion: no-preference) { .motion-text-reveal--armed [data-text-line] { transform: translateY(100%); } }
:root[data-motion-mode="reduced"] .motion-text-reveal--armed [data-text-line] { transform: none; }

/* ---------- Tier 3 — compact token index (all tokens, structure) ---------- */
.choreo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--sp-4); }
.choreo-card { border: 1px solid var(--border-1); border-radius: var(--r-lg); overflow: hidden; display: flex; flex-direction: column; background: var(--bg-elev); }
.choreo-card__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); }
.choreo-card__meta { display: grid; gap: 2px; }
.choreo-card__name { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--fg1); }
.choreo-card__pattern { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }
.choreo-spec-toggle { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); background: none; border: 0; cursor: pointer; padding: 0; }
.choreo-spec-toggle:hover { color: var(--fg1); }
.choreo-card .choreo-spec { border: 0; border-top: 1px solid var(--border-1); border-radius: 0; }

/* ---------- Tier 3 — choreography tab explorer (tokens page) ----------
   A segmented "fluid tab" bar drives one stage/info panel. The active-tab
   indicator is a pill that slides between segments on choreography-switch-
   toggle (JS-driven, WAAPI) — the chrome built from the system it presents.
   Equal-width segments keep the slide a pure translate, so the pill never
   needs to resize; narrow screens scroll the bar horizontally. */
/* The explicit minmax(0, 1fr) track is load-bearing: without it the implicit `auto` column grows to
   the bar's max-content (all seven pills), so the bar's max-width:100% never clamps to the viewport
   and the whole page scrolls sideways on narrow screens. Capping the track lets the bar scroll
   internally instead — matching the desktop behaviour. */
.choreo-tabs { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-7); }

.choreo-tabs__bar {
  position: relative;
  display: flex;
  gap: 12px;                              /* space between segments */
  width: fit-content;                     /* hug the tabs, not the full row */
  max-width: 100%;                        /* but scroll rather than overflow on narrow screens */
  padding: 4px;
  background: var(--bg-inset);
  border: 1px solid var(--border-1);
  border-radius: var(--r-pill);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;          /* gentle snap as the strip is swiped — never fights the user */
  /* Edge fades signal more tabs off-screen. The fade widths stay 0 until JS adds has-fade-* (see
     updateFades in choreoOverviewTabs), so the capsule keeps crisp ends when everything fits. */
  --fade-start: 0px;
  --fade-end: 0px;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--fade-start), #000 calc(100% - var(--fade-end)), transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 var(--fade-start), #000 calc(100% - var(--fade-end)), transparent 100%);
}
.choreo-tabs__bar.has-fade-start { --fade-start: 28px; }
.choreo-tabs__bar.has-fade-end { --fade-end: 28px; }
.choreo-tabs__bar::-webkit-scrollbar { display: none; }
.choreo-tabs__tab { scroll-snap-align: start; }

/* Resting side is pure CSS (translateX set inline on first paint); the slide is switch-toggle. */
.choreo-tabs__pill {
  position: absolute;
  inset-block: 4px;
  inset-inline-start: 0;
  width: 0;                               /* set by JS to the active segment's width */
  border-radius: var(--r-pill);
  background: var(--accent);
  box-shadow: var(--shadow-sm);
  z-index: 0;
  pointer-events: none;
  will-change: transform;
}

.choreo-tabs__tab {
  position: relative;                     /* sit above the pill */
  z-index: 1;
  flex: 0 0 auto;                         /* size to the label; the bar hugs them (fit-content) */
  padding: var(--sp-3) var(--sp-4);
  background: none;
  border: 0;
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg3);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--motion-use-color);
}
.choreo-tabs__tab:hover { color: var(--fg1); }
.choreo-tabs__tab.is-active { color: var(--accent-on); }
.choreo-tabs__tab:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Panel — stage on one side, name / controls / spec on the other (stacks on mobile). */
.choreo-panel {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-6);
  align-items: center;
}
@media (min-width: 880px) {
  .choreo-panel { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
}
.choreo-panel__stage {
  position: relative;
  min-height: 320px;
  display: grid;
  place-items: center;
  padding: var(--sp-8);
  border-radius: var(--r-lg);
  background: var(--bg-inset);
  border: 1px solid var(--border-1);
  overflow: hidden;
  container-type: inline-size;
}
.choreo-panel__info { display: grid; gap: var(--sp-4); align-content: center; justify-items: start; }
.choreo-panel__name { font-family: var(--font-mono); font-size: var(--fs-h4); letter-spacing: var(--tracking-snug); color: var(--fg1); margin: 0; }
.choreo-panel__desc { color: var(--fg2); margin: 0; max-width: 48ch; }
/* Token-view footnote — the explorer shows the compiled runtime spec; points to the raw example.
   Negative top margin counteracts the .choreo-tabs grid gap (--sp-7) to sit it ~12px under the panel. */
.choreo-note { margin-top: calc(var(--sp-3) - var(--sp-7)); font-size: var(--fs-small); line-height: var(--lh-relaxed); color: var(--fg3); }
.choreo-note a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 0.2em; transition: color var(--motion-use-hover); }
.choreo-note a:hover { color: var(--fg1); }
.choreo-note a:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }
.choreo-panel__controls { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
/* The variant whose spec is on show reads as pressed. */
.choreo-panel__controls .is-current { border-color: var(--accent); color: var(--accent-text); }
.choreo-panel__cta { margin-top: var(--sp-1); }
.choreo-panel__spec { width: 100%; }
.choreo-panel__spec .choreo-spec { margin: 0; }

/* Stage corner controls — the self-running demos (text replay, list reveal/dismiss) trigger from
   icon buttons pinned in the stage's lower-right. Hidden in Token view (the wash covers the stage),
   so they're gated out of the tab order there too. */
.choreo-stage-actions {
  position: absolute;
  right: var(--sp-4);
  bottom: var(--sp-4);
  z-index: 3;
  display: flex;
  gap: var(--sp-2);
}
.choreo-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  color: var(--fg3);
  background: color-mix(in srgb, var(--bg-elev) 80%, transparent);
  border: 1px solid var(--border-1);
  border-radius: var(--r-md);
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: color var(--motion-use-hover), border-color var(--motion-use-hover), background var(--motion-use-hover);
}
.choreo-icon-btn:hover { color: var(--fg1); border-color: var(--border-2); background: var(--bg-elev); }
.choreo-icon-btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.choreo-icon-btn svg { display: block; width: 1.2rem; height: 1.2rem; }

/* ---------- Segmented toggle (shared) ----------
   A compact pill switch. Used by the choreography "Example / Token" control.
   Active segment reads as the accent chip. */
.seg-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-elev);
  border: 1px solid var(--border-1);
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-sm);
}
.seg-toggle__btn {
  padding: 4px var(--sp-3);
  background-color: transparent;
  border: 0;
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--fg3);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--motion-use-hover), background-color var(--motion-use-hover);
}
.seg-toggle__btn:hover { color: var(--fg1); }
.seg-toggle__btn.is-active { background-color: var(--accent); color: var(--accent-on); }
.seg-toggle__btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* ---------- Tier 3 — "Token" accent wash (overview) ----------
   The overview reveals a token behind the Example/Token toggle in the info column. Flipping to
   Token sets .is-token on the stage: an accent panel wipes across (clip-path), then the spec panel
   fades in a beat behind it. Both transitions are timed on the Tier-2 motion tokens, so the whole
   reveal collapses to an instant swap under reduced motion — the right tool for a CSS-native wipe
   (vs. a Tier-3 JSON choreography). */

/* The accent wash — sweeps in left→right on the page-transition curve; retracts after the spec
   has faded on the way out (clip-path delayed by one short beat). Clipped-away = non-interactive. */
.choreo-wash {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--accent);
  clip-path: inset(0 100% 0 0);
  pointer-events: none;
  transition: clip-path var(--motion-use-overlay-out) var(--motion-duration-short);
}
.choreo-panel__stage.is-token .choreo-wash {
  clip-path: inset(0 0 0 0);
  pointer-events: auto;
  transition: clip-path var(--motion-use-page-transition);
}

/* Phase 2 — the spec surface that overlays the accent. Begins once the wipe has mostly landed
   (a medium beat in), leaving an accent frame around it. On exit it fades first, no delay. */
.choreo-wash__panel {
  position: absolute;
  inset: var(--sp-5);
  display: grid;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--bg-inset);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(10px) scale(0.98);
  transform-origin: center;
  transition: opacity var(--motion-use-overlay-out), transform var(--motion-use-overlay-out);
}
.choreo-panel__stage.is-token .choreo-wash__panel {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--motion-use-overlay-in) var(--motion-duration-medium),
    transform var(--motion-use-overlay-in) var(--motion-duration-medium);
}
.choreo-wash .choreo-spec {
  margin: 0;
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  overflow: auto;
}

/* ---------- Overview: "View" density switch (read / explore) ----------
   A real toggle living in the doc rail: a content icon and an examples icon flank a sliding thumb
   that crosses on the switch-toggle choreography (see viewSwitch(), mirrors the theme switch).
   Flipping it on adds .doc--examples-only, which (1) hides the descriptive prose (subsection intros,
   per-band + per-curve notes, Tier-2 card copy) and (2) collapses the narrative bookends and prose
   framing subsections via data-examples-hide (see that rule below), leaving the tier headings, their
   notes, and the live examples. Geometry mirrors the theme switch; resting side is pure CSS. */
.view-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}
.view-switch__control {
  --switch-w: 3.5rem;                                                  /* track width  */
  --switch-h: 1.75rem;                                                 /* track height */
  --switch-pad: 0.25rem;
  --switch-border: 1px;
  --switch-thumb: calc(var(--switch-h) - 2 * var(--switch-border) - 2 * var(--switch-pad));
  --switch-travel: calc(var(--switch-w) - 2 * var(--switch-border) - var(--switch-thumb) - 2 * var(--switch-pad));

  position: relative;
  display: inline-block;
  width: var(--switch-w);
  height: var(--switch-h);
  padding: var(--switch-pad);
  background: var(--bg-elev-2);  /* secondary elevation — raised a rung above the bg-elev rail, not the white/black inset well */
  border: var(--switch-border) solid var(--border-2);
  border-radius: var(--r-pill);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.view-switch__control:hover { border-color: var(--fg-muted); }
.view-switch__control:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Icons flank the track; the active side lights up, the other dims. Content (default/off) gets
   the ink highlight; examples (on) gets the accent — mirroring the theme switch's sun/moon. */
.view-switch__icon {
  position: relative;                 /* anchors the hover tooltip */
  display: inline-flex;
  align-items: center;
  color: var(--fg3);
  pointer-events: none;
  transition: color var(--motion-use-color);
}
.view-switch__icon svg { display: block; width: 1rem; height: 1rem; }
.view-switch:not(.is-examples) .view-switch__icon--content { color: var(--fg1); }
.view-switch.is-examples .view-switch__icon--examples { color: var(--accent-text); }

/* Hover tooltip — names the mode each icon selects ("Read" / "Explore"). The icons
   are decorative (aria-hidden; the switch itself is labelled), so this is a sighted-only nicety;
   it eases in/out on the disclosure tokens, so it collapses to an instant show under reduced motion. */
.view-switch__icon[data-tooltip] { pointer-events: auto; }
.view-switch__icon[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  top: calc(100% + var(--sp-2));
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  padding: var(--sp-1) var(--sp-2);
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--fg1);
  background: var(--bg-elev);
  border: 1px solid var(--border-1);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 10;
  transition:
    opacity var(--motion-use-disclosure-out),
    transform var(--motion-use-disclosure-out),
    visibility 0s linear var(--motion-duration-short);
}
.view-switch__icon[data-tooltip]:hover::after {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  transition: opacity var(--motion-use-disclosure-in), transform var(--motion-use-disclosure-in), visibility 0s;
}

.view-switch__thumb {
  position: absolute;
  top: var(--switch-pad);
  left: var(--switch-pad);
  z-index: 0;
  width: var(--switch-thumb);
  height: var(--switch-thumb);
  border-radius: 50%;
  background: var(--fg1);
  box-shadow: var(--shadow-sm);
  transform: translateX(0);
  will-change: transform;
  pointer-events: none;
}
.view-switch.is-examples .view-switch__thumb { transform: translateX(var(--switch-travel)); }

/* Labelled variant (splash header) — a text label flanks each icon, framing the switch: "Read
   {icon}" on the left, "{icon} Explore" on the right. The active side's text lights up alongside
   its icon (ink for context, accent for examples); the rail variant stays icon-only with tooltips. */
.view-switch--labeled { gap: var(--sp-3); }
.view-switch__side { display: inline-flex; align-items: center; gap: var(--sp-2); }
.view-switch__text {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  line-height: 1;   /* tighten off the inherited body leading so the caps center against the icon */
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg3);
  transition: color var(--motion-use-color);
}
.view-switch:not(.is-examples) .view-switch__side--content .view-switch__text { color: var(--fg1); }
.view-switch.is-examples .view-switch__side--examples .view-switch__text { color: var(--accent-text); }

.doc--examples-only .subsection__intro,
.doc--examples-only .band,
.doc--examples-only .curve-group__note,
.doc--examples-only .curve-group__title,
.doc--examples-only .use-card__desc { display: none; }

/* Whole-block collapse: the narrative bookends (Intro + Summary sections) and the three prose
   framing subsections (Tier 2 "The Recipe", Tier 3 "Key takeaway", Intent "Verified motion"), plus
   the now-dead Intro/Summary rail links, carry data-examples-hide so examples mode is purely tier
   headings + notes + live demos. */
.doc--examples-only [data-examples-hide] { display: none; }
/* Intro is the DOM-first section (margin-top:0); with it hidden, hand that top alignment to the
   next section so Primitives sits flush against the rail. */
.doc--examples-only .doc-body > .section:first-child + .section { margin-top: 0; }

/* Examples-only, duration: with the band rows hidden the three rung groups merge into one table,
   so restore a divider between every row and drop it only on the very last row. */
.doc--examples-only .token-table--banded tbody tr:last-child th,
.doc--examples-only .token-table--banded tbody tr:last-child td { border-bottom: 1px solid var(--border-1); }
.doc--examples-only .token-table--banded tbody:last-of-type tr:last-child th,
.doc--examples-only .token-table--banded tbody:last-of-type tr:last-child td { border-bottom: 0; }

/* Examples-only, easing: flatten the four titled curve groups into one gallery of all six curves,
   3-up on desktop / 2-up on tablet / 1-up on mobile. display:contents lets the cards flow straight
   into the gallery grid once their group wrappers and the inner sub-grids are dissolved. */
.doc--examples-only .curve-group,
.doc--examples-only .curve-gallery .easing-grid { display: contents; }
.doc--examples-only .curve-gallery { grid-template-columns: 1fr; gap: var(--sp-4); }
@media (min-width: 720px) {
  .doc--examples-only .curve-gallery { grid-template-columns: repeat(2, 1fr); gap: var(--sp-5); }
}
@media (min-width: 960px) {
  .doc--examples-only .curve-gallery { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- Swatches ---------- */
.swatch { display: flex; flex-direction: column; gap: var(--sp-2); }
.swatch__chip { aspect-ratio: 16 / 10; border-radius: var(--r-md); box-shadow: var(--shadow-inset); }
.swatch__meta { display: flex; justify-content: space-between; gap: var(--sp-2); }
.swatch__name { font-size: var(--fs-small); color: var(--fg1); }
.swatch__val { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }

/* ---------- Type scale ---------- */
.type-row { display: grid; grid-template-columns: 88px 1fr; gap: var(--sp-5); align-items: baseline; padding: var(--sp-3) 0; border-bottom: 1px solid var(--border-1); }
.type-row__label { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); text-transform: uppercase; letter-spacing: var(--tracking-wide); }
.type-row__sample { color: var(--fg1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Spacing ---------- */
.space-row { display: grid; grid-template-columns: 72px 1fr; align-items: center; gap: var(--sp-4); padding: var(--sp-2) 0; }
.space-row__label { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }
.space-row__bar { height: 16px; border-radius: var(--r-sm); background: var(--fg-muted); }

/* ---------- Radii ---------- */
.radius { display: flex; flex-direction: column; gap: var(--sp-2); align-items: flex-start; }
.radius__box { width: 100%; aspect-ratio: 16 / 9; background: var(--bg-elev); border: 1px solid var(--border-2); }
.radius__label { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }

/* ---------- Shadow cards ---------- */
.shadow-card { padding: var(--sp-6); border-radius: var(--r-md); background: var(--bg-inset); display: flex; flex-direction: column; gap: var(--sp-2); min-height: 120px; }
.shadow-card__name { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--fg1); }
.shadow-card__val { font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--fg3); }

/* ---------- Site footer ---------- */
.site-footer {
  margin-top: var(--sp-10);
  padding: var(--sp-6) var(--gutter);
  border-top: 1px solid var(--border-1);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  flex-wrap: wrap;
}
.site-footer__brand { display: flex; align-items: baseline; gap: var(--sp-4); flex-wrap: wrap; }
.site-footer .wordmark { font-size: var(--fs-h4); } /* smaller than the tokens-page hero wordmark */
.site-footer__copy {
  margin: 0;
  max-width: none;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--fg3);
}
.site-footer__meta { display: flex; align-items: center; gap: var(--sp-5); }
.site-footer__link {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg3);
  text-decoration: none;
  text-transform: lowercase;
  transition: color var(--motion-use-hover);
}
.site-footer__link:hover { color: var(--fg1); }
.site-footer__link:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }

/* Light/dark switch — a real toggle: sun + moon-stars flank a sliding thumb. The thumb's
   travel is the choreography-switch-toggle token (JS-driven, WAAPI); its RESTING side is pure
   CSS off [data-theme], so it's already correct on first paint with no animation. */

/* Typed so var(--switch-travel) resolves to a concrete length wherever the keyframes reference
   it — the runtime pins the thumb's from/to as translateX(var(--switch-*)) and a bare custom
   property could otherwise carry an unresolved calc() into the animation. */
@property --switch-travel {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

.theme-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.theme-switch__control {
  --switch-w: 3.5rem;                                                   /* track width  */
  --switch-h: 1.75rem;                                                  /* track height */
  --switch-pad: 0.25rem;
  --switch-border: 1px;
  /* border-box shrinks the inner box by the border on each side — subtract it so the thumb
     centres and the two ends sit an equal pad in from the border. */
  --switch-thumb: calc(var(--switch-h) - 2 * var(--switch-border) - 2 * var(--switch-pad));
  --switch-travel: calc(var(--switch-w) - 2 * var(--switch-border) - var(--switch-thumb) - 2 * var(--switch-pad));

  position: relative;
  display: inline-block;
  width: var(--switch-w);
  height: var(--switch-h);
  padding: var(--switch-pad);
  background: var(--bg-elev);
  border: var(--switch-border) solid var(--border-2);
  border-radius: var(--r-pill);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.theme-switch__control:hover { border-color: var(--fg-muted); }
.theme-switch__control:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* The icons flank the track; the side matching the current theme lights up, the other dims.
   Light-mode highlight is dark ink (lime reads muddy on bone); dark mode gets the lime accent. */
.theme-switch__icon {
  display: inline-flex;
  align-items: center;
  color: var(--fg3);
  pointer-events: none;
  transition: color var(--motion-use-color);
}
.theme-switch__icon svg { display: block; width: 1rem; height: 1rem; }
:root:not([data-theme="dark"]) .theme-switch__icon--sun { color: var(--fg1); }
[data-theme="dark"] .theme-switch__icon--moon { color: var(--accent-text); }

.theme-switch__thumb {
  position: absolute;
  top: var(--switch-pad);
  left: var(--switch-pad);
  z-index: 0;
  width: var(--switch-thumb);
  height: var(--switch-thumb);
  border-radius: 50%;
  background: var(--fg1);
  box-shadow: var(--shadow-sm);
  transform: translateX(0);
  will-change: transform;
  pointer-events: none;
}
[data-theme="dark"] .theme-switch__thumb { transform: translateX(var(--switch-travel)); }

/* Theme colour cross-fade, coordinated with the toggle. While a flip is in flight the themed
   colours transition on short × gentle, delayed by the switch's anticipation (quick) — so the
   colour change runs through the travel phase and finishes exactly as the thumb enters its settle
   (quick delay + short = 260ms = anticipation + travel). Tokenised, so it collapses to an instant
   swap under reduced motion with the rest of the system. Armed only during the toggle (JS sets
   data-theme-switching), so ordinary colour changes keep their own timing.

   No !important on purpose: the motion runtime resolves tokens by writing them onto a hidden probe
   span and reading its computed transition-* — an !important here would win over those inline reads
   and corrupt every animation running during the toggle. The (0,2,0) specificity already beats the
   element-level colour transitions this needs to override. */
:root[data-theme-switching],
:root[data-theme-switching] * {
  --theme-fade: var(--motion-duration-short) var(--motion-easing-gentle) var(--motion-duration-quick);
  transition:
    background-color var(--theme-fade),
    color var(--theme-fade),
    border-color var(--theme-fade),
    fill var(--theme-fade),
    stroke var(--theme-fade);
}
.footer__wordmark { font-size: var(--fs-h3); }
.footer__note { margin: 0; max-width: 54ch; }
.footer__note a {
  color: var(--fg2);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color var(--motion-use-hover);
}
.footer__note a:hover { color: var(--fg1); }
.footer__note a:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }

/* Reduced motion — the caret is decorative, so stop it. Every token-based transition
   and the WAAPI runtime already collapse to instant via motion/motion.css (on the OS
   setting OR the [data-motion-mode="reduced"] preview toggle), so nothing else is needed. */
@media (prefers-reduced-motion: reduce) { .logo__caret { animation: none; opacity: 1; } }
:root[data-motion-mode="reduced"] .logo__caret { animation: none; opacity: 1; }

/* ============================================================
   Articles — index listing + single-article layout + prose.
   The pages own layout; the tokens own the look. BEM naming.
   ============================================================ */

/* ---------- Articles index ---------- */
.article-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-6); }
.article-card { border-bottom: 1px solid var(--border-1); padding-bottom: var(--sp-6); }
.article-card:last-child { border-bottom: 0; }
.article-card__link {
  display: block;
  text-decoration: none;
  color: inherit;
  border-radius: var(--r-md);
}
.article-card__link:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.article-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  letter-spacing: var(--tracking-snug);
  line-height: var(--lh-snug);
  margin: var(--sp-3) 0 var(--sp-3);
  text-wrap: balance;
  transition: color var(--motion-use-hover);
}
.article-card__link:hover .article-card__title { color: var(--accent-text); }
.article-card__excerpt { font-size: var(--fs-body); color: var(--fg2); max-width: 60ch; margin: 0; }
.article-card__meta {
  margin: var(--sp-4) 0 0;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg3);
}

/* ---------- Single article ---------- */
.article { max-width: none; margin-inline: auto; padding: var(--sp-5) 80px 0; }
.article p { max-width: 100%; }
.article__head { margin-bottom: var(--sp-8); }
.breadcrumb { padding-block: var(--sp-5); }
.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
}
.breadcrumb__item { display: flex; align-items: center; gap: var(--sp-2); }
.breadcrumb__item + .breadcrumb__item::before {
  content: "";
  flex: none;
  width: 1.25em;
  height: 1.25em;
  background-color: var(--fg-muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 7l5 5l-5 5'/%3E%3Cpath d='M13 7l5 5l-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 7l5 5l-5 5'/%3E%3Cpath d='M13 7l5 5l-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.breadcrumb__link {
  color: var(--fg3);
  text-decoration: none;
  border-radius: var(--r-sm);
  transition: color var(--motion-use-hover);
}
.breadcrumb__link:hover { color: var(--accent-text); }
.breadcrumb__link:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.breadcrumb__current { color: var(--fg2); }
.article__title {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  margin: var(--sp-4) 0 var(--sp-5);
  text-wrap: balance;
}
.article__title em { color: var(--accent-text); font-style: normal; }
.article__lede {
  font-size: var(--fs-h4);
  color: var(--fg2);
  line-height: var(--lh-snug);
  text-wrap: balance;
  margin: 0 0 var(--sp-5);
}
.article__meta {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg3);
  margin: 0;
}
.article__dot { color: var(--fg-muted); margin-inline: var(--sp-1); }

/* ---------- Prose — long-form Markdown body ----------
   Low-specificity element rules via :where() so a page can override a single
   element without a specificity fight. `> * + *` sets the default flow rhythm. */
.prose { max-width: none; font-size: var(--fs-body); line-height: var(--lh-relaxed); color: var(--fg2); }
.prose > * + * { margin-block-start: var(--sp-5); }

.prose :where(h2) {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  letter-spacing: var(--tracking-snug);
  line-height: var(--lh-snug);
  color: var(--fg1);
  margin-block-start: var(--sp-8);
}
.prose :where(h3) {
  font-family: var(--font-sans);
  font-size: var(--fs-h4);
  letter-spacing: var(--tracking-snug);
  line-height: var(--lh-snug);
  color: var(--fg1);
  margin-block-start: var(--sp-7);
}
.prose :where(a) { color: var(--accent-text); text-underline-offset: 0.15em; }
.prose :where(a):focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--r-sm); }
.prose :where(strong) { color: var(--accent-text); font-weight: 600; }
.prose :where(ul, ol) { padding-inline-start: var(--sp-6); }
.prose :where(li) { margin-block-start: var(--sp-2); }
.prose :where(ul li)::marker { color: var(--accent-text); }
.prose :where(blockquote) {
  margin-inline: 0;
  padding-inline-start: var(--sp-5);
  border-inline-start: 2px solid var(--accent);
  color: var(--fg1);
  font-style: italic;
}
.prose :where(code) {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--bg-inset);
  padding: 0.15em 0.4em;
  border-radius: var(--r-sm);
}
.prose :where(pre) {
  background: var(--bg-inset);
  border: 1px solid var(--border-1);
  border-radius: var(--r-md);
  padding: var(--sp-5);
  overflow-x: auto;
  font-size: var(--fs-small);
  line-height: var(--lh-normal);
}
.prose :where(pre code) { background: none; padding: 0; font-size: inherit; }
.prose :where(img) { max-width: 100%; height: auto; border-radius: var(--r-md); }
.prose :where(hr) { border: 0; border-top: 1px solid var(--border-1); margin-block: var(--sp-7); }
