/*
 * Oatmeal — marketing theme (CUBE CSS).
 *
 * CUBE: Composition primitives live in composition.css; this file holds the
 * theme token scope, a few token-driven Utilities, and the Block cosmetics.
 * Variants are Exceptions expressed with [data-*] attributes. Everything is
 * scoped to `.theme-oatmeal` (token remap) and `.oatmeal-*` blocks.
 * Neutrals come from Tailwind Stone; the brand accent is syo-ro.
 */

/* ─────────────────────────── Theme token scope ─────────────────────────── */
@layer modules {
  /* Skip link — visible only once focused, then pinned over the masthead.
     Sits above --z-nav so it paints over the sticky nav rather than under it. */
  .oatmeal-skip {
    background: var(--canvas);
    border: 1px solid var(--line);
    color: var(--ink);
    inset-block-start: var(--space-2xs);
    inset-inline-start: var(--space-2xs);
    padding: var(--space-2xs) var(--space-sm);
    position: fixed;
    text-decoration: none;
    transform: translateY(-200%);
    z-index: var(--z-skip);
  }
  .oatmeal-skip:focus { transform: none; }

  .theme-oatmeal {
    /* --font-sans is set globally in tokens.css so the font cycler can switch it. */
    --font-display: "Solway", ui-serif, Georgia, serif;

    /* Neutral roles — warm sand; page gets a subtle NW→SE sandstone wash */
    --canvas: var(--color-sandstone-50);
    --canvas-gradient: linear-gradient(to bottom right, var(--color-sandstone-50), var(--color-sandstone-200));
    --surface: var(--color-stone-50);
    --ink: var(--color-sandstone-950);
    --ink-muted: var(--color-sandstone-700); /* 9.1:1 on cream — AAA */
    --ink-subtle: var(--color-sandstone-600); /* 6.8:1 — AA (placeholders) */

    /* Accent — Pine, via the --color-accent-* layer (tokens.css). Light CTA uses
       the 700 stop so white button text clears WCAG AA on Pine's lighter ramp. */
    --accent: var(--color-accent-700);
    --accent-hover: var(--color-accent-800);
    --accent-ink: var(--color-sandstone-50);

    /* Spot ink — Copper, the second accent from the Workbench/Plate direction:
       eyebrows, microcap labels, and the short plate rule. 700 clears AA on
       cream; the dark scopes lift it to 400. */
    --accent-spot: var(--color-copper-700);

    /* Derived tints — built from --ink so they auto-flip in dark mode. */
    --card: color-mix(in oklch, var(--ink) 3%, transparent);
    --card-hover: color-mix(in oklch, var(--ink) 6%, transparent);
    --line: color-mix(in oklch, var(--ink) 10%, transparent);
    --line-strong: color-mix(in oklch, var(--ink) 20%, transparent);

    /* Inverse bar — an overlay strip in the page's opposite colors, for text
       that has to sit legibly on top of a screenshot. Built from --ink and
       --canvas, so it flips with the theme on its own: a near-black bar with
       cream text in light mode, the same pair swapped in dark. Follows the
       page palette only; a slab-scoped section would need its own pair. */
    --inverse-bg: var(--ink);
    --inverse-ink: var(--canvas);
    --inverse-ink-muted: color-mix(in oklch, var(--canvas) 82%, var(--ink));

    --radius-pill: 999px;
    --radius-card: var(--radius-3);

    /* Screenshot "wallpaper" gradients (light) */
    --wallpaper-green: linear-gradient(to bottom, var(--color-accent-400), var(--color-accent-700));
    --wallpaper-blue: linear-gradient(to bottom, #637c86, #778599);
    --wallpaper-purple: linear-gradient(to bottom, #7b627d, #8f6976);
    --wallpaper-brown: linear-gradient(to bottom, #8d7359, #765959);

    /* Grayscale noise texture overlaid on wallpapers */
    --noise: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='250'%20height='250'%20viewBox='0%200%20100%20100'%3E%3Cfilter%20id='n'%3E%3CfeTurbulence%20type='turbulence'%20baseFrequency='1.4'%20numOctaves='1'%20seed='2'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='saturate'%20values='0'/%3E%3C/filter%3E%3Crect%20width='100%25'%20height='100%25'%20filter='url(%23n)'/%3E%3C/svg%3E");
  }

  /* Dark mode — explicit choice and system preference. */
  html[data-theme="dark"] .theme-oatmeal {
    --canvas: var(--color-sandstone-800);
    --canvas-gradient: none;
    --surface: var(--color-stone-900);
    --card: var(--color-sandstone-700);
    --ink: var(--color-sandstone-50); /* 14.5:1 canvas, 9.8:1 cards — AAA */
    --ink-muted: var(--color-sandstone-200); /* 12.1:1 canvas, 8.2:1 cards — AAA */
    --ink-subtle: var(--color-sandstone-300); /* 10.2:1 canvas (placeholders) */

    --accent: var(--color-accent-400);
    --accent-hover: var(--color-accent-300);
    --accent-ink: var(--color-sandstone-950);
    --accent-spot: var(--color-copper-400);

    --wallpaper-green: linear-gradient(to bottom, var(--color-accent-800), var(--color-accent-950));
    --wallpaper-blue: linear-gradient(to bottom, #243a42, #232f40);
    --wallpaper-purple: linear-gradient(to bottom, #412c42, #3c1a26);
    --wallpaper-brown: linear-gradient(to bottom, #382d23, #3d2323);
  }

  @media (prefers-color-scheme: dark) {
    html:not([data-theme]) .theme-oatmeal {
      --canvas: var(--color-sandstone-800);
      --canvas-gradient: none;
      --surface: var(--color-stone-900);
      --card: var(--color-sandstone-700);
      --ink: var(--color-sandstone-50);
      --ink-muted: var(--color-sandstone-200);
      --ink-subtle: var(--color-sandstone-300);

      --accent: var(--color-accent-400);
      --accent-hover: var(--color-accent-300);
      --accent-ink: var(--color-sandstone-950);
      --accent-spot: var(--color-copper-400);

      --wallpaper-green: linear-gradient(to bottom, var(--color-accent-800), var(--color-accent-950));
      --wallpaper-blue: linear-gradient(to bottom, #243a42, #232f40);
      --wallpaper-purple: linear-gradient(to bottom, #412c42, #3c1a26);
      --wallpaper-brown: linear-gradient(to bottom, #382d23, #3d2323);
    }
  }

  /* Slab — a dark "press slab" band (pricing, built-by, the hero's navbar),
     from the Workbench direction. A nested token scope: any block inside picks
     up the remapped roles. The color-mix tints are re-declared so they
     re-resolve against the slab ink (custom properties resolve where they're
     defined).

     `.theme-slab-auto` is the same slab, but only in dark mode: the home hero
     uses it so a light-mode visitor gets the light editor screenshot on a
     light ground instead of the dark shot on a permanent dark band. In light
     mode it declares nothing and the section inherits the page palette. */
  .theme-slab,
  html[data-theme="dark"] .theme-slab-auto {
    --canvas: var(--color-sandstone-900);
    --canvas-gradient: none;
    --surface: var(--color-sandstone-950);
    --ink: var(--color-sandstone-50);
    --ink-muted: var(--color-sandstone-200);
    --ink-subtle: var(--color-sandstone-300);

    --accent: var(--color-accent-400);
    --accent-hover: var(--color-accent-300);
    --accent-ink: var(--color-sandstone-950);
    --accent-spot: var(--color-copper-400);

    --card: color-mix(in oklch, var(--ink) 3%, transparent);
    --card-hover: color-mix(in oklch, var(--ink) 6%, transparent);
    --line: color-mix(in oklch, var(--ink) 10%, transparent);
    --line-strong: color-mix(in oklch, var(--ink) 20%, transparent);

    background-color: var(--canvas);
    color: var(--ink);
  }

  @media (prefers-color-scheme: dark) {
    html:not([data-theme]) .theme-slab-auto {
      --canvas: var(--color-sandstone-900);
      --canvas-gradient: none;
      --surface: var(--color-sandstone-950);
      --ink: var(--color-sandstone-50);
      --ink-muted: var(--color-sandstone-200);
      --ink-subtle: var(--color-sandstone-300);

      --accent: var(--color-accent-400);
      --accent-hover: var(--color-accent-300);
      --accent-ink: var(--color-sandstone-950);
      --accent-spot: var(--color-copper-400);

      --card: color-mix(in oklch, var(--ink) 3%, transparent);
      --card-hover: color-mix(in oklch, var(--ink) 6%, transparent);
      --line: color-mix(in oklch, var(--ink) 10%, transparent);
      --line-strong: color-mix(in oklch, var(--ink) 20%, transparent);

      background-color: var(--canvas);
      color: var(--ink);
    }
  }

  /* Page shell */
  .layout-oatmeal {
    background-color: var(--canvas);
    background-image: var(--canvas-gradient, none);
    color: var(--ink);
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  /* Tune composition primitives for this theme (max content width = 80rem). */
  .layout-oatmeal .wrapper { --wrapper-max: 80rem; }

  /* ───────────────────────────── Typography ──────────────────────────── */
  /* Max 4rem = the 72px title-page size from the Plate direction. */
  .oatmeal-headline {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: clamp(2.5rem, 1.6rem + 4.5vw, 4rem);
    font-weight: 400;
    letter-spacing: -0.02em;
    line-height: 1.04;
    text-wrap: balance;
  }
  /* Compact variant — the split slab hero, where the headline shares the
     row with the app screenshot (mockup runs it at ~60px, not full size). */
  .oatmeal-headline-compact { font-size: clamp(2.25rem, 1.4rem + 3vw, 3.4rem); }

  .oatmeal-title {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: clamp(2rem, 1.4rem + 3vw, 3rem);
    font-weight: 400;
    letter-spacing: -0.01em;
    line-height: 1.1;
    text-wrap: pretty;
  }

  .oatmeal-lede {
    color: var(--ink-muted);
    font-size: var(--text-medium);
    line-height: 1.7;
  }

  .oatmeal-eyebrow {
    color: var(--accent-spot);
    font-family: var(--font-mono);
    font-size: var(--text-x-small);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }

  /* ─────────────────────────────── Buttons ────────────────────────────── */
  .oatmeal-btn {
    --btn-bg: var(--accent);
    --btn-ink: var(--accent-ink);

    align-items: center;
    background: var(--btn-bg);
    border: 0;
    border-radius: var(--radius-pill);
    color: var(--btn-ink);
    cursor: pointer;
    display: inline-flex;
    font: inherit;
    font-size: var(--text-small);
    font-weight: 500;
    gap: var(--inline-space-half);
    justify-content: center;
    padding: 0.4rem 1rem;
    text-decoration: none;
    transition: background-color 150ms var(--ease-out-expo);
    white-space: nowrap;
  }
  .oatmeal-btn:hover { --btn-bg: var(--accent-hover); }
  .oatmeal-btn[data-size="lg"] { font-size: var(--text-normal); padding: 0.6rem 1.4rem; }
  .oatmeal-btn[aria-disabled="true"] { cursor: not-allowed; opacity: 0.5; }

  .oatmeal-btn[data-variant="soft"] {
    --btn-bg: color-mix(in oklch, var(--ink) 8%, transparent);
    --btn-ink: var(--ink);
  }
  .oatmeal-btn[data-variant="soft"]:hover { --btn-bg: color-mix(in oklch, var(--ink) 14%, transparent); }

  .oatmeal-btn[data-variant="plain"] {
    --btn-bg: transparent;
    --btn-ink: var(--ink);
  }
  .oatmeal-btn[data-variant="plain"]:hover { --btn-bg: color-mix(in oklch, var(--ink) 8%, transparent); }

  /* Inline text link with trailing icon */
  .oatmeal-link {
    align-items: center;
    color: var(--ink);
    display: inline-flex;
    font-size: var(--text-small);
    font-weight: 500;
    gap: var(--inline-space-half);
    text-decoration: none;
  }
  .oatmeal-link:hover { color: var(--accent); }
  /* Spot variant — the copper-underlined text link from the Workbench hero. */
  .oatmeal-link-spot {
    border-block-end: 1px solid var(--accent-spot);
    font-size: var(--text-normal);
    padding-block-end: 0.15rem;
  }

  /* Newsletter signup — pill input + button */
  .oatmeal-signup {
    align-items: center;
    background: var(--surface);
    border-radius: var(--radius-pill);
    box-shadow: inset 0 0 0 1px var(--line);
    display: flex;
    gap: 0.25rem;
    padding: 0.3rem;
  }
  .oatmeal-signup__input {
    background: transparent;
    border: 0;
    color: var(--ink);
    flex: 1;
    font: inherit;
    min-inline-size: 0;
    outline: none;
    padding-inline: 0.85rem;
  }
  .oatmeal-signup__input::placeholder { color: var(--ink-subtle); }

  /* ──────────────────────── Navbar (chrome) ─────────────────────────── */
  .oatmeal-nav {
    /* Match the page shell: same canvas wash, viewport-anchored so the
       gradient lines up with the page behind it (dark mode has no gradient
       and stays flat). */
    background-color: var(--canvas);
    background-image: var(--canvas-gradient, none);
    background-attachment: fixed;
    position: sticky;
    top: 0;
    z-index: var(--z-nav);
  }
  .oatmeal-nav__bar { min-block-size: 5.25rem; }
  .oatmeal-nav__link {
    color: var(--ink);
    font-size: var(--text-small);
    font-weight: 500;
    text-decoration: none;
  }
  .oatmeal-nav__link:hover { color: var(--accent); }
  .oatmeal-nav__logo { align-items: center; color: var(--ink); display: inline-flex; gap: 0.5rem; font-size: var(--text-large); text-decoration: none; }
  .oatmeal-nav__logo-mark { block-size: 1.5em; inline-size: 1.5em; color: var(--accent); flex: none; }
  .oatmeal-nav__logo-text { font-family: var(--font-brand); font-weight: 700; letter-spacing: -0.01em; }
  .oatmeal-nav__toggle {
    background: transparent; border: 0; border-radius: var(--radius-pill);
    color: var(--ink); cursor: pointer; display: none; padding: 0.375rem;
  }
  .oatmeal-nav__toggle:hover { background: var(--card-hover); }

  /* Light/dark toggle — shows the icon for the mode you'd switch TO. */
  .oatmeal-theme-toggle {
    background: transparent;
    border: 0;
    border-radius: var(--radius-pill);
    color: var(--ink);
    cursor: pointer;
    display: inline-flex;
    padding: 0.375rem;
  }
  .oatmeal-theme-toggle:hover { background: var(--card-hover); }
  .oatmeal-theme-toggle .theme-icon--sun { display: none; }
  html[data-theme="dark"] .oatmeal-theme-toggle .theme-icon--sun { display: inline-flex; }
  html[data-theme="dark"] .oatmeal-theme-toggle .theme-icon--moon { display: none; }

  /* Mobile menu — native popover, anchored to the upper-right corner. */
  .oatmeal-nav__menu {
    background: var(--canvas);
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    box-shadow: 0 12px 32px rgb(0 0 0 / 0.18);
    inset: auto;
    margin: 0;
    min-inline-size: 13rem;
    max-inline-size: min(17rem, calc(100vw - 2 * var(--main-padding)));
    padding: 0.5rem;
    position: fixed;
    right: var(--main-padding);
    top: 0.75rem;
  }
  .oatmeal-nav__menu::backdrop { background: rgb(0 0 0 / 0.25); }

  .oatmeal-nav__menu-close {
    background: transparent; border: 0; border-radius: var(--radius-pill);
    color: var(--ink); cursor: pointer; display: block;
    margin-inline-start: auto; padding: 0.375rem;
  }
  .oatmeal-nav__menu-close:hover { background: var(--card-hover); }

  .oatmeal-nav__menu-links { list-style: none; margin: 0; padding: 0; }
  .oatmeal-nav__menu-link {
    border-radius: var(--radius-2);
    color: var(--ink);
    display: block;
    font-size: var(--text-normal);
    font-weight: 500;
    padding: 0.5rem 0.625rem;
    text-decoration: none;
  }
  .oatmeal-nav__menu-link:hover { background: var(--card-hover); color: var(--accent); }

  .oatmeal-nav__menu-actions {
    border-block-start: 1px solid var(--line);
    display: grid;
    gap: 0.5rem;
    margin-block-start: 0.5rem;
    padding: 0.625rem 0.25rem 0.25rem;
  }
  .oatmeal-nav__menu-actions .oatmeal-btn { inline-size: 100%; }
  .oatmeal-nav__menu-foot {
    align-items: center;
    display: flex;
    justify-content: space-between;
  }

  @media (max-width: 899px) {
    .oatmeal-nav__links,
    .oatmeal-nav__cta { display: none; }
    .oatmeal-nav__toggle { display: inline-flex; }
  }

  /* ─────────────────────── Section header block ─────────────────────── */
  .oatmeal-heading { max-inline-size: 42rem; }

  /* ──────────────────────── Screenshot / wallpaper ────────────────────── */
  .oatmeal-shot {
    background-image: var(--wallpaper-green);
    border-radius: var(--radius-card);
    overflow: hidden;
    position: relative;
  }
  .oatmeal-shot[data-color="blue"]   { background-image: var(--wallpaper-blue); }
  .oatmeal-shot[data-color="purple"] { background-image: var(--wallpaper-purple); }
  .oatmeal-shot[data-color="brown"]  { background-image: var(--wallpaper-brown); }

  .oatmeal-shot::before {
    background-image: var(--noise);
    content: "";
    inset: 0;
    mix-blend-mode: overlay;
    opacity: 0.3;
    pointer-events: none;
    position: absolute;
  }

  .oatmeal-shot__inner {
    --pad: min(10%, 4rem);
    padding: var(--pad);
    position: relative;
  }
  .oatmeal-shot__inner > * {
    box-shadow: 0 0 0 1px rgb(0 0 0 / 0.1);
    display: block;
    inline-size: 100%;
    position: relative;
  }

  /* Caption tag — bottom-right corner of the screenshot. */
  .oatmeal-shot__tag {
    background: var(--surface);
    border-radius: var(--radius-pill);
    box-shadow: 0 1px 4px rgb(0 0 0 / 0.18);
    color: var(--ink);
    font-size: var(--text-x-small);
    font-weight: 600;
    inset-block-end: 1rem;
    inset-inline-end: 1rem;
    padding: 0.3rem 0.85rem;
    position: absolute;
    z-index: 2;
  }

  /* Placement: no padding on the bleed edge(s); round the exposed corner(s). */
  .oatmeal-shot[data-placement="bottom"] .oatmeal-shot__inner { padding-block-end: 0; }
  .oatmeal-shot[data-placement="bottom"] .oatmeal-shot__inner > * { border-radius: var(--radius-2) var(--radius-2) 0 0; }

  .oatmeal-shot[data-placement="bottom-right"] .oatmeal-shot__inner { padding-block-end: 0; padding-inline-end: 0; }
  .oatmeal-shot[data-placement="bottom-right"] .oatmeal-shot__inner > * { border-radius: var(--radius-2) 0 0 0; }

  .oatmeal-shot[data-placement="bottom-left"] .oatmeal-shot__inner { padding-block-end: 0; padding-inline-start: 0; }
  .oatmeal-shot[data-placement="bottom-left"] .oatmeal-shot__inner > * { border-radius: 0 var(--radius-2) 0 0; }

  /* ──────────────────────────── Carousel ───────────────────────────── */
  .oatmeal-carousel { position: relative; }
  .oatmeal-carousel__viewport { overflow: hidden; }
  .oatmeal-carousel__track { display: flex; transition: transform 350ms var(--ease-out-expo); }
  .oatmeal-carousel__slide { flex: 0 0 100%; min-inline-size: 0; }

  .oatmeal-carousel__arrow {
    align-items: center;
    background: var(--surface);
    border: 0;
    block-size: 2.5rem;
    border-radius: 50%;
    box-shadow: 0 1px 6px rgb(0 0 0 / 0.18);
    color: var(--ink);
    cursor: pointer;
    display: inline-flex;
    font-size: 1.15rem;
    inline-size: 2.5rem;
    inset-block-start: 50%;
    justify-content: center;
    position: absolute;
    transform: translateY(-50%);
    z-index: 2;
  }
  .oatmeal-carousel__arrow:hover { background: var(--canvas); }
  .oatmeal-carousel__arrow--prev { inset-inline-start: 0.75rem; }
  .oatmeal-carousel__arrow--next { inset-inline-end: 0.75rem; }

  .oatmeal-carousel__dots {
    display: flex;
    gap: 0.5rem;
    justify-content: center;
    margin-block-start: 1rem;
  }
  .oatmeal-carousel__dot {
    background: var(--line-strong);
    block-size: 0.5rem;
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    inline-size: 0.5rem;
    padding: 0;
    transition: background-color 150ms var(--ease-out-expo), inline-size 150ms var(--ease-out-expo);
  }
  .oatmeal-carousel__dot[data-active] { background: var(--accent); inline-size: 1.25rem; }

  /* Stage — wraps the viewport so the prev/next arrows can center themselves
     on the screenshot rather than halfway down the slide, caption included.
     Every shot is 2000x1100, so the image's middle sits at 27.5% of the
     stage's width however tall the caption under it runs. */
  .carousel-stage {
    container-type: inline-size;
    position: relative;
  }
  .carousel-stage > .oatmeal-carousel__arrow { inset-block-start: 27.5cqw; }

  .carousel-slide { padding-block-end: 0.5rem; }
  .carousel-caption { text-align: center; }

  /* Controls row — play/pause beside the dots, under the caption. */
  .carousel-controls {
    align-items: center;
    display: flex;
    gap: 1rem;
    justify-content: center;
  }
  .carousel-controls .oatmeal-carousel__dots { margin-block-start: 0; }

  .carousel-toggle {
    align-items: center;
    background: var(--surface);
    block-size: 2.25rem;
    border: 1px solid var(--line);
    border-radius: 50%;
    color: var(--ink);
    cursor: pointer;
    display: inline-flex;
    font-size: 0.9rem;
    inline-size: 2.25rem;
    justify-content: center;
    padding: 0;
  }
  .carousel-toggle:hover { background: var(--canvas); border-color: var(--line-strong); }
  /* One button, two glyphs — whichever action it will perform is the one shown. */
  .carousel-toggle .carousel-toggle-play { display: none; }
  .carousel-toggle.is-paused .carousel-toggle-pause { display: none; }
  .carousel-toggle.is-paused .carousel-toggle-play { display: inline-flex; }

  @media (prefers-reduced-motion: reduce) {
    .oatmeal-carousel__track { transition: none; }
  }

  /* ── Inverse bar — an overlay strip in the page's opposite colors so copy
     stays readable on top of a screenshot. Shared by the conference masthead
     and the fill carousel's captions; it re-points the theme's text blocks at
     the inverse ink rather than restating their type. ── */
  .inverse-bar {
    background: var(--inverse-bg);
    color: var(--inverse-ink);
  }
  .inverse-bar .oatmeal-headline,
  .inverse-bar .oatmeal-title { color: inherit; }
  .inverse-bar .oatmeal-eyebrow,
  .inverse-bar .oatmeal-lede { color: var(--inverse-ink-muted); }
  /* Note there is no `.inverse-bar .text-subtle` here: .text-subtle lives in
     @layer utilities and would beat it. Anything needing muted ink on an
     inverse bar sets --inverse-ink-muted itself, as .conference-price does. */

  /* ── Fill variant — the carousel IS the viewport. The shot is sized to the
     screen and every piece of text rides over it on an inverse bar. Set by
     passing `fill` to the partial; /conference/ is the only caller. ── */
  .oatmeal-carousel[data-fill] {
    block-size: 100dvh;
    position: relative;
  }
  .oatmeal-carousel[data-fill] .carousel-stage,
  .oatmeal-carousel[data-fill] .oatmeal-carousel__viewport,
  .oatmeal-carousel[data-fill] .oatmeal-carousel__track,
  .oatmeal-carousel[data-fill] .oatmeal-carousel__slide,
  .oatmeal-carousel[data-fill] .carousel-slide { block-size: 100%; }

  /* The stage is now exactly the picture, so the arrows can use their own
     default middle instead of the caption-aware offset below. */
  .oatmeal-carousel[data-fill] .carousel-stage > .oatmeal-carousel__arrow {
    inset-block-start: 50%;
  }

  /* The caption is lifted out of the flow, so the figure has one child left. */
  .oatmeal-carousel[data-fill] .carousel-slide {
    padding-block-end: 0;
    position: relative;
  }
  .oatmeal-carousel[data-fill] .carousel-slide > * + * { margin-block-start: 0; }

  /* Edge to edge: no frame, no corners, and `contain` so a shot taller or
     wider than the screen letterboxes rather than losing its edges. */
  /* No frame, no corners. The block padding is the space the masthead and the
     caption bar occupy, measured by kiosk.js: it keeps the whole shot in the
     clear rather than letting the bars cover its top and bottom edges, which
     is where the app's own title bar, menus and status line sit. The shot is
     scaled to the band that's left, so the letterboxing lands on the sides.
     Unset (no JS) the padding is 0 and it goes back to full bleed. */
  .oatmeal-carousel[data-fill] .panel {
    --panel-bg: transparent;
    --panel-border: 0;
    --panel-radius: 0;

    block-size: 100%;
    padding-block: var(--kiosk-top, 0px) var(--kiosk-bottom, 0px);
  }
  /* 100% of the panel's content box, which the padding above has already
     shrunk to the gap between the two bars. */
  .oatmeal-carousel[data-fill] .panel > img {
    block-size: 100%;
    inline-size: 100%;
    object-fit: contain;
  }

  /* Caption bar, pinned to the foot of the screen. Its block-end padding
     reserves the strip the controls are pinned into, just below. */
  .oatmeal-carousel[data-fill] .carousel-caption {
    inset-block-end: 0;
    inset-inline: 0;
    padding-block: calc(var(--block-space) * 0.75) calc(var(--block-space) * 2.5);
    padding-inline: var(--main-padding);
    position: absolute;
    z-index: 2;
  }
  /* Read from across a room, one line each: the bar is only worth the screen
     it costs if the text doesn't wrap, so it runs the full content width. */
  .oatmeal-carousel[data-fill] .carousel-caption .center { --center-max: var(--main-width); }
  .oatmeal-carousel[data-fill] .carousel-caption .oatmeal-title {
    font-size: var(--text-large);
  }
  .oatmeal-carousel[data-fill] .carousel-caption .oatmeal-lede {
    font-size: var(--text-normal);
    line-height: 1.4;
  }

  /* Controls ride on the caption bar, so they take its ink rather than the
     page's — the page's line tints are invisible against the inverse ground. */
  .oatmeal-carousel[data-fill] .carousel-controls {
    inset-block-end: calc(var(--block-space) * 0.75);
    inset-inline: 0;
    position: absolute;
    z-index: 3;
  }
  .oatmeal-carousel[data-fill] .oatmeal-carousel__dot {
    background: color-mix(in oklch, var(--inverse-ink) 40%, transparent);
  }
  .oatmeal-carousel[data-fill] .oatmeal-carousel__dot[data-active] {
    background: var(--inverse-ink);
  }
  .oatmeal-carousel[data-fill] .carousel-toggle {
    background: transparent;
    border-color: color-mix(in oklch, var(--inverse-ink) 40%, transparent);
    color: var(--inverse-ink);
  }
  .oatmeal-carousel[data-fill] .carousel-toggle:hover {
    background: color-mix(in oklch, var(--inverse-ink) 15%, transparent);
    border-color: var(--inverse-ink);
  }
  .oatmeal-carousel[data-fill] .oatmeal-carousel__arrow {
    background: color-mix(in oklch, var(--inverse-ink) 18%, transparent);
    box-shadow: none;
    color: var(--inverse-ink);
  }
  .oatmeal-carousel[data-fill] .oatmeal-carousel__arrow:hover {
    background: var(--inverse-ink);
    color: var(--inverse-bg);
  }

  /* ── Conference kiosk (/conference/) — the unlisted screen we run at the
     table. The carousel fills the viewport; the page's own pitch sits on a
     matching inverse bar across the top edge. ── */
  .conference-screen { position: relative; }
  .conference-masthead {
    inset-block-start: 0;
    inset-inline: 0;
    padding-block: calc(var(--block-space) * 0.75);
    padding-inline: var(--main-padding);
    position: absolute;
    text-align: center;
    z-index: 2;
  }
  /* Every line unwrapped, so the bar stays a band rather than a block —
     it is sitting on top of the picture it introduces. */
  .conference-masthead .center { --center-max: var(--main-width); }
  .conference-masthead .oatmeal-headline { font-size: var(--text-x-large); }
  .conference-masthead .oatmeal-lede { font-size: var(--text-small); line-height: 1.4; }
  .conference-price {
    color: var(--inverse-ink-muted);
    font-size: var(--text-x-small);
  }
  .conference-theme {
    inset-block-start: calc(var(--block-space) / 2);
    inset-inline-end: calc(var(--block-space) / 2);
    position: absolute;
    z-index: 3;
  }
  .conference-theme .oatmeal-theme-toggle { color: var(--inverse-ink); }
  .conference-theme .oatmeal-theme-toggle:hover {
    background: color-mix(in oklch, var(--inverse-ink) 15%, transparent);
  }

  /* ──────────────────────────── Cards / features ────────────────────── */
  .oatmeal-card {
    background: var(--card);
    border-radius: var(--radius-card);
    padding: 0.5rem;
  }
  .oatmeal-card__media { border-radius: var(--radius-2); display: block; overflow: hidden; }
  /* Aspect ratios come from each img's width/height attributes. */
  .oatmeal-card__media img { display: block; inline-size: 100%; object-fit: cover; }

  .oatmeal-card__body { padding: 1.5rem; }

  .oatmeal-feature__title { color: var(--ink); font-size: var(--text-medium); font-weight: 500; }
  .oatmeal-feature__text { color: var(--ink-muted); font-size: var(--text-small); line-height: 1.7; }
  .oatmeal-feature__icon { color: var(--accent); }

  /* Zoomable card media → native CSS popover lightbox (graceful: no popover
     support = the inline card still shows, just not clickable to enlarge). */
  .oatmeal-card__zoom {
    appearance: none;
    background: none;
    border: 0;
    cursor: zoom-in;
    display: block;
    inline-size: 100%;
    padding: 0;
    position: relative;
  }
  .oatmeal-card__zoom::after {
    background: var(--surface);
    border-radius: var(--radius-pill);
    box-shadow: 0 1px 4px rgb(0 0 0 / 0.2);
    color: var(--ink);
    content: "Enlarge";
    font-size: var(--text-x-small);
    font-weight: 600;
    inset-block-end: 0.6rem;
    inset-inline-end: 0.6rem;
    opacity: 0;
    padding: 0.2rem 0.65rem;
    position: absolute;
    transition: opacity 150ms var(--ease-out-expo);
  }
  .oatmeal-card__zoom:hover::after,
  .oatmeal-card__zoom:focus-visible::after { opacity: 1; }

  .oatmeal-lightbox {
    background: transparent;
    border: 0;
    inset: 0;
    /* Re-assert the popover's UA centering, which our `* { margin: 0 }` reset clobbers. */
    margin: auto;
    max-block-size: 94vh;
    max-inline-size: 94vw;
    overflow: visible;
    padding: 0;
    position: fixed;
  }
  .oatmeal-lightbox img {
    block-size: auto;
    border-radius: var(--radius-3);
    box-shadow: 0 12px 48px rgb(0 0 0 / 0.45);
    display: block;
    inline-size: auto;
    max-block-size: 94vh;
    max-inline-size: 94vw;
  }
  .oatmeal-lightbox::backdrop {
    backdrop-filter: blur(2px);
    background: rgb(0 0 0 / 0.6);
  }
  .oatmeal-lightbox__close {
    align-items: center;
    background: var(--surface);
    block-size: 2.25rem;
    border: 0;
    border-radius: 50%;
    box-shadow: 0 1px 6px rgb(0 0 0 / 0.3);
    color: var(--ink);
    cursor: pointer;
    display: inline-flex;
    font-size: 1.1rem;
    inline-size: 2.25rem;
    inset-block-start: 0.6rem;
    inset-inline-end: 0.6rem;
    justify-content: center;
    position: absolute;
    z-index: 1;
  }
  .oatmeal-lightbox__close:hover { background: var(--canvas); }

  /* Fade in/out where supported (allow-discrete + @starting-style). */
  .oatmeal-lightbox,
  .oatmeal-lightbox::backdrop {
    opacity: 0;
    transition: opacity 200ms var(--ease-out-expo), overlay 200ms allow-discrete, display 200ms allow-discrete;
  }
  .oatmeal-lightbox:popover-open,
  .oatmeal-lightbox:popover-open::backdrop { opacity: 1; }
  @starting-style {
    .oatmeal-lightbox:popover-open,
    .oatmeal-lightbox:popover-open::backdrop { opacity: 0; }
  }

  /* ──────── Feature detail page (standalone tour page: hero + prev/next) ──────── */
  .oatmeal-feature-hero {
    background: var(--card);
    border-radius: var(--radius-3);
    overflow: hidden;
    padding: 0.5rem;
    inline-size: 100%;
  }
  .oatmeal-feature-hero img {
    border-radius: var(--radius-2);
    display: block;
    inline-size: 100%;
    object-fit: cover;
  }
  .oatmeal-feature-hero__placeholder {
    display: grid;
    place-items: center;
    border-radius: var(--radius-2);
    border: 1px dashed var(--line-strong);
    color: var(--ink-subtle);
    font-size: var(--text-small);
    letter-spacing: 0.02em;
    aspect-ratio: 16 / 9;
  }
  .oatmeal-feature-pager {
    display: flex;
    justify-content: space-between;
    gap: 1.5rem;
    padding-block-start: 2.5rem;
    border-block-start: 1px solid var(--line);
  }
  .oatmeal-feature-pager__link {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    text-decoration: none;
    color: var(--ink-muted);
    max-inline-size: 20rem;
  }
  .oatmeal-feature-pager__link[data-dir="next"] { text-align: end; align-items: flex-end; }
  .oatmeal-feature-pager__dir {
    color: var(--ink-subtle);
    font-size: var(--text-small);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
  }
  .oatmeal-feature-pager__title {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: var(--text-large);
    line-height: 1.2;
  }
  .oatmeal-feature-pager__link:hover .oatmeal-feature-pager__title { color: var(--accent); }

  /* Pillar heading — used for feature-page "Common questions". */
  .oatmeal-feature-pillar__title {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: var(--text-large);
    font-weight: 400;
    letter-spacing: -0.01em;
    padding-block-end: 0.75rem;
    border-block-end: 1px solid var(--line);
  }

  /* Feature page body — H2 section headings, bullet lists, inline screenshots.
     Scoped to .oatmeal-feature-body so legal/about pages are untouched. */
  .oatmeal-feature-body h2 {
    color: var(--ink);
    font-family: var(--font-display);
    font-weight: 400;
    font-size: var(--text-large);
    letter-spacing: -0.01em;
    line-height: 1.2;
    margin-block-start: 2.75rem;
  }
  .oatmeal-feature-body ul { display: flex; flex-direction: column; gap: 0.4rem; padding-inline-start: 1.15rem; }
  .oatmeal-feature-body li { color: var(--ink-muted); }
  .oatmeal-feature-shot {
    background: var(--card);
    border-radius: var(--radius-3);
    overflow: hidden;
    padding: 0.5rem;
    margin-block: 1.25rem;
  }
  .oatmeal-feature-shot img { border-radius: var(--radius-2); display: block; inline-size: 100%; }

  /* Author-authority band (built-by.html) — first-hand experience, E-E-A-T,
     set on the press slab per the interior-pages direction. */
  .oatmeal-built-by { padding: clamp(2rem, 5vw, 3.5rem); }

  /* Feature page FAQ — answers shown open (no accordion). */
  .oatmeal-feature-faq { display: flex; flex-direction: column; gap: 1.5rem; }
  .oatmeal-feature-faq__q {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: var(--text-normal);
    font-weight: 500;
    margin-block-end: 0.35rem;
  }
  .oatmeal-feature-faq__a { color: var(--ink-muted); font-size: var(--text-normal); line-height: 1.7; margin-inline-start: 0; }

  /* ─────────────────────────────── Stats ────────────────────────────── */
  .oatmeal-stat { border-inline-start: 1px solid var(--line-strong); padding-inline-start: 1.5rem; }
  .oatmeal-stat > * + * { margin-block-start: 0.35rem; }
  .oatmeal-stat__value { color: var(--ink); font-size: var(--text-large); letter-spacing: -0.01em; }
  .oatmeal-stat__label { color: var(--ink-muted); font-size: var(--text-small); }

  /* ─────────────────── Tag pill (tour job links) ────────────────────── */
  .oatmeal-tag {
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    color: var(--ink-muted);
    display: inline-block;
    font-family: var(--font-mono);
    font-size: var(--text-x-small);
    font-weight: 500;
    letter-spacing: 0.03em;
    padding: 0.25rem 0.65rem;
    text-decoration: none;
    white-space: nowrap;
  }
  /* The mono face reserves far more descender than these labels use, so
     centring the line box leaves the glyphs sitting high in the pill. Trim to
     cap-height/baseline and centre the ink instead; padding grows to keep the
     pill the same height. Browsers without text-box keep the old rendering. */
  @supports (text-box: trim-both cap alphabetic) {
    .oatmeal-tag {
      line-height: 1;
      padding-block: 0.55rem;
      text-box: trim-both cap alphabetic;
    }
  }
  a.oatmeal-tag:hover { border-color: var(--line-strong); color: var(--ink); }

  /* Release flag on a tour feature — front matter `badge: "New in 1.5"`. */
  .oatmeal-tag--new {
    background: color-mix(in oklch, var(--accent-spot) 12%, transparent);
    border-color: color-mix(in oklch, var(--accent-spot) 40%, transparent);
    color: var(--accent-spot);
  }

  /* ─────────────── Pending-screenshot placeholder (tour) ────────────── */
  .oatmeal-pending {
    background: var(--card);
    border: 1px dashed var(--line-strong);
    display: grid;
    min-block-size: 14rem;
    padding: 1.5rem;
    place-items: center;
    text-align: center;
  }

  /* ──────────────────────── Comparison table (card) ─────────────────── */
  .oatmeal-compare-wrap {
    background: var(--card);
    border-radius: var(--radius-card);
    overflow-x: auto;
    padding: 0.5rem 1.25rem;
  }
  .oatmeal-compare {
    border-collapse: collapse;
    font-size: var(--text-small);
    inline-size: 100%;
    min-inline-size: 42rem;
  }
  .oatmeal-compare th,
  .oatmeal-compare td {
    border-block-end: 1px solid var(--line);
    padding: 0.85rem 1rem;
    text-align: center;
  }
  .oatmeal-compare tbody tr:last-child :is(th, td) { border-block-end: 0; }
  .oatmeal-compare thead th { color: var(--ink); font-weight: 600; }
  .oatmeal-compare thead th:first-child { text-align: start; }
  .oatmeal-compare tbody th { color: var(--ink); font-weight: 500; text-align: start; }
  .oatmeal-compare td { color: var(--ink-muted); }
  .oatmeal-compare__yes { color: var(--color-positive); font-size: 2em; }
  .oatmeal-compare__no { color: var(--color-negative); font-size: 2em; }
  .oatmeal-compare__brand,
  .oatmeal-compare__brand-h { background: color-mix(in oklch, var(--accent) 8%, transparent); }
  .oatmeal-compare__brand-h { border-radius: var(--radius-2) var(--radius-2) 0 0; color: var(--ink); }
  .oatmeal-compare tbody tr:last-child .oatmeal-compare__brand { border-radius: 0 0 var(--radius-2) var(--radius-2); }

  /* ──────────────────────────── Testimonials ────────────────────────── */
  .oatmeal-quote {
    background: var(--card);
    border-radius: var(--radius-card);
    color: var(--ink);
    display: flex;
    flex-direction: column;
    font-size: var(--text-small);
    justify-content: space-between;
    line-height: 1.7;
    padding: 1.5rem;
  }
  .oatmeal-quote__avatar { block-size: 3rem; border-radius: 50%; inline-size: 3rem; overflow: hidden; }
  .oatmeal-quote__avatar > img { block-size: 100%; inline-size: 100%; object-fit: cover; }
  .oatmeal-quote__name { color: var(--ink); display: block; font-weight: 600; }
  .oatmeal-quote__byline { color: var(--ink-muted); }

  /* ─────────────────────────────── FAQ ──────────────────────────────── */
  .oatmeal-faq { border-block: 1px solid var(--line); }
  .oatmeal-faq__item + .oatmeal-faq__item { border-block-start: 1px solid var(--line); }
  .oatmeal-faq__q {
    align-items: flex-start;
    color: var(--ink);
    cursor: pointer;
    display: flex;
    font-size: var(--text-normal);
    gap: 1.5rem;
    justify-content: space-between;
    list-style: none;
    padding-block: 1rem;
  }
  .oatmeal-faq__q::-webkit-details-marker { display: none; }
  .oatmeal-faq__icon { color: var(--ink-muted); flex-shrink: 0; transition: transform 150ms var(--ease-out-expo); }
  .oatmeal-faq__item[open] .oatmeal-faq__icon { transform: rotate(180deg); }
  .oatmeal-faq__a { color: var(--ink-muted); font-size: var(--text-small); line-height: 1.7; padding-block-end: 1rem; padding-inline-end: 3rem; }

  /* ───────────────────────────── Pricing ────────────────────────────── */
  .oatmeal-plan__check { color: var(--accent); flex-shrink: 0; }

  /* ───────────── Pricing — slab band, included-features panel ─────────── */
  .oatmeal-price-card__panel {
    background: var(--surface);
    border-radius: var(--radius-card);
    padding: 1.5rem;
  }
  @media (min-width: 40rem) {
    .oatmeal-price-card__panel { padding: 2.5rem; }
  }
  .oatmeal-price-row { align-items: baseline; display: flex; gap: 0.5rem; }
  .oatmeal-price {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: clamp(3.5rem, 2rem + 7vw, 6rem);
    font-weight: 400;
    letter-spacing: -0.02em;
    line-height: 1;
  }
  .oatmeal-price__period { color: var(--ink-muted); font-size: var(--text-medium); }
  /* Founders & Friends variant: the standard price, struck through beside
     the founding price. */
  .oatmeal-price--was {
    color: var(--ink-muted);
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 1rem + 3.5vw, 3rem);
    font-weight: 400;
    letter-spacing: -0.02em;
    line-height: 1;
    text-decoration: line-through;
    text-decoration-thickness: 0.09em;
  }
  .oatmeal-checklist {
    display: grid;
    gap: 0.75rem;
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .oatmeal-checklist li {
    align-items: center;
    color: var(--ink-muted);
    display: flex;
    font-size: var(--text-small);
    gap: 0.75rem;
  }

  /* ────────────────────────── Call to action ────────────────────────── */
  .oatmeal-cta__title { max-inline-size: 56rem; }

  /* ─────────────────────────────── Footer ───────────────────────────── */
  .oatmeal-footer { padding-block-start: 4rem; }
  .oatmeal-footer__inner { background: var(--card); color: var(--ink); }
  .oatmeal-footer__cat-title { color: var(--ink); font-size: var(--text-small); font-weight: 600; }
  .oatmeal-footer__link { color: var(--ink-muted); display: block; font-size: var(--text-small); text-decoration: none; }
  .oatmeal-footer__link:hover { color: var(--ink); }
  .oatmeal-footer__fine { color: var(--ink-subtle); font-size: var(--text-small); }
  /* The copyright line reuses __link inside the fine print — keep it inline
     there (block display is for the column link lists). */
  .oatmeal-footer__fine .oatmeal-footer__link { display: inline; }
  .oatmeal-footer__social { color: var(--ink); }

  .oatmeal-newsletter__field {
    align-items: center;
    border-block-end: 1px solid var(--line-strong);
    display: flex;
    gap: 0.5rem;
    padding-block: 0.5rem;
  }
  .oatmeal-newsletter__field:focus-within { border-color: var(--ink); }
  .oatmeal-newsletter__input {
    background: transparent; border: 0; color: var(--ink); flex: 1; font: inherit; outline: none;
  }
  .oatmeal-newsletter__submit {
    align-items: center; background: transparent; border: 0; border-radius: var(--radius-pill);
    color: var(--ink); cursor: pointer; display: inline-flex; justify-content: center; padding: 0.375rem;
  }
  .oatmeal-newsletter__submit:hover { background: var(--card-hover); }

  /* ──────────────────────────── Logo cloud ──────────────────────────── */
  .oatmeal-logos { align-items: center; color: var(--ink-muted); justify-items: center; }
  .oatmeal-logo { block-size: 2rem; opacity: 0.7; }

  /* ────────────── Document (content pages — privacy-policy-01) ─────────
     Centered legal/prose body: small muted text, medium ink headings,
     square-bullet lists, underlined ink links. */
  .oatmeal-document { color: var(--color-stone-800); font-size: var(--text-prose); line-height: 1.75; }
  html[data-theme="dark"] .oatmeal-document { color: var(--color-stone-200); }
  @media (prefers-color-scheme: dark) {
    html:not([data-theme]) .oatmeal-document { color: var(--color-stone-200); }
  }
  .oatmeal-document > * + * { margin-block-start: 1rem; }
  .oatmeal-document h2 {
    color: var(--ink);
    font-size: var(--text-large);
    font-weight: 500;
    line-height: 1.6;
  }
  .oatmeal-document h2:not(:first-child) { margin-block-start: 3.5rem; }
  .oatmeal-document h3 { color: var(--ink); font-size: var(--text-normal); font-weight: 600; margin-block-start: 2.5rem; }
  .oatmeal-document a {
    color: var(--ink);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 4px;
  }
  /* Button-styled links inside prose keep their button treatment — the rule
     above is more specific than .oatmeal-btn, so restore ink/weight/underline. */
  .oatmeal-document a.oatmeal-btn { color: var(--btn-ink); font-weight: 500; text-decoration: none; }
  .oatmeal-document strong { color: var(--ink); font-weight: 600; }
  .oatmeal-document ul { list-style: square; padding-inline-start: 1.5rem; }
  .oatmeal-document ol { list-style: decimal; padding-inline-start: 1.5rem; }
  .oatmeal-document li { padding-inline-start: 0.5rem; }
  .oatmeal-document li::marker { color: var(--ink-subtle); }

  /* ─────────────── Download page (platform panels, /download/) ───────────── */
  .dl-detected {
    color: var(--accent);
    font-size: var(--text-large);
    font-weight: 600;
    min-block-size: 1.75rem;
  }
  .dl-hero {
    /* Accent tint: Pine 100 (light), Pine 900 (dark). */
    --hero-fill: var(--color-pine-100);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1rem;
    padding: clamp(2rem, 5vw, 3rem) 1.75rem;
    border: 1px solid var(--accent);
    border-radius: var(--radius-3);
    background: var(--hero-fill);
    box-shadow: 0 0 0 1px var(--accent);
  }
  html[data-theme="dark"] .dl-hero { --hero-fill: var(--color-pine-900); }
  @media (prefers-color-scheme: dark) {
    html:not([data-theme]) .dl-hero { --hero-fill: var(--color-pine-900); }
  }
  /* When JS is available, show only the active platform panel; without JS all
     panels render stacked so every platform stays reachable. */
  .dl-js .dl-hero:not(.dl-hero--active) { display: none; }

  .dl-hero__icon {
    font-size: 2.75rem;
    color: var(--ink);
    line-height: 1;
  }
  .dl-hero__btn {
    font-size: var(--text-large);
    font-weight: 600;
    padding: 0.9rem 2rem;
  }
  /* Pre-launch placeholder: stays prominent (full-strength solid button), just
     non-interactive, with a "Coming soon" caption instead of a faded button. */
  .dl-hero__btn[data-soon] { cursor: default; }
  .dl-soon {
    font-size: var(--text-x-small);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent);
  }
  .dl-meta {
    color: var(--ink-muted);
    font-size: var(--text-small);
    font-variant-numeric: tabular-nums;
  }
  .dl-req {
    color: var(--ink-subtle);
    font-size: var(--text-x-small);
  }
  .dl-alts { margin-block-start: 1.25rem; }
  .dl-alts__title {
    font-size: var(--text-x-small);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-subtle);
  }
  .dl-alts__items {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    margin-block-start: 0.6rem;
    font-size: var(--text-small);
  }
  .dl-alts__item[aria-disabled="true"] { color: var(--ink-subtle); opacity: 0.7; }
  a.dl-alts__item { color: var(--accent); text-decoration: none; }
  a.dl-alts__item:hover { text-decoration: underline; }

  /* ─────────── Download cards page (/download-cards/) ─────────── */
  .download-card {
    /* Recommended-card fill: Pine 200 (light), Pine 900 (dark). */
    --rec-fill: var(--color-pine-200);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-3);
    display: flex;
    flex-direction: column;
    padding: 2rem 1.75rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
  }
  html[data-theme="dark"] .download-card { --rec-fill: var(--color-pine-900); }
  @media (prefers-color-scheme: dark) {
    html:not([data-theme]) .download-card { --rec-fill: var(--color-pine-900); }
  }
  .download-card[data-recommended] {
    background: var(--rec-fill);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
  }
  .download-card__head { align-items: center; display: flex; gap: 0.85rem; }
  .download-card__icon { color: var(--ink); font-size: 2rem; line-height: 1; }
  .download-card__name {
    font-family: var(--font-display);
    font-size: var(--text-large);
    font-weight: 500;
    line-height: 1.1;
  }
  .download-card__badge {
    color: var(--accent);
    display: inline-block;
    font-size: var(--text-x-small);
    font-weight: 500;
    letter-spacing: 0.04em;
    margin-block-start: 0.25rem;
    text-transform: uppercase;
  }
  .download-card__req { color: var(--ink-subtle); font-size: var(--text-small); line-height: 1.5; }
  .download-card__actions {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-block-start: auto;
  }
  .download-card__actions .oatmeal-btn { justify-content: center; }
  .download-card__note { color: var(--ink-subtle); font-size: var(--text-x-small); text-align: center; }

  /* ─────────── Reviewer walkthrough page (/demo/) ─────────── */
  .ls-stage {
    background: var(--color-sandstone-950);
    border: 1px solid var(--line);
    border-radius: var(--radius-3);
    box-shadow: 0 1px 3px color-mix(in oklch, var(--ink) 8%, transparent);
    overflow: hidden;
  }
  .ls-video {
    aspect-ratio: 16 / 9;
    border: 0;
    display: block;
    inline-size: 100%;
  }

  /* ─────────── Updates feed (/updates/) ─────────── */
  .updates-item + .updates-item {
    border-block-start: 1px solid var(--line);
    margin-block-start: 3.5rem;
    padding-block-start: 3.5rem;
  }
  .updates-item__date {
    color: var(--ink-subtle);
    font-size: var(--text-small);
    font-weight: 500;
    letter-spacing: 0.02em;
  }
  .updates-item__title {
    color: var(--ink);
    font-family: var(--font-display);
    font-size: var(--text-x-large);
    font-weight: 400;
    letter-spacing: -0.01em;
    line-height: 1.15;
    margin-block-start: 0.5rem;
    text-wrap: pretty;
  }
  .updates-item__title a { color: inherit; text-decoration: none; }
  .updates-item__title a:hover { color: var(--accent); }
  .updates-item__excerpt {
    color: var(--ink-muted);
    font-size: var(--text-prose);
    line-height: 1.75;
    margin-block-start: 1rem;
  }
  .updates-item__more { margin-block-start: 1.25rem; }
}

/* ──────────────────── Utilities (token-driven, single job) ─────────────── */
@layer utilities {
  .font-display { font-family: var(--font-display); font-weight: 400; }
  .text-muted { color: var(--ink-muted); }
  .text-subtle { color: var(--ink-subtle); }
  .text-accent { color: var(--accent); }
  .text-spot { color: var(--accent-spot); }
  .text-balance { text-wrap: balance; }
  .text-pretty { text-wrap: pretty; }
  .text-center { text-align: center; }
  .text-end { text-align: end; }
  .text-x-small { font-size: var(--text-x-small); }
  .text-small { font-size: var(--text-small); }
  .text-large { font-size: var(--text-large); }
  .text-x-large { font-size: var(--text-x-large); }

  /* Measures — line length named by intent; the stylesheet owns the value. */
  .measure-headline { max-inline-size: 20ch; }
  .measure-note { max-inline-size: 18rem; }
  .measure-narrow { max-inline-size: 34rem; }
  .measure-lede { max-inline-size: 40rem; }
  .measure-prose { max-inline-size: 42rem; }
  .measure-wide { max-inline-size: 60rem; }

  .grow { flex: 1; }

  /* Dark-mode screenshots: expose the [data-mode="dark"] image, hide the light
     one when dark is active (explicit toggle or system preference). Works in
     any image container (hero shot, cards, /features, lightbox). Lives in the
     utilities layer so no component's display rule (e.g. the lightbox's) can
     un-hide the inactive image. */
  [data-mode="dark"] { display: none; }
  html[data-theme="dark"] [data-mode="light"] { display: none; }
  html[data-theme="dark"] [data-mode="dark"] { display: block; }
  @media (prefers-color-scheme: dark) {
    html:not([data-theme]) [data-mode="light"] { display: none; }
    html:not([data-theme]) [data-mode="dark"] { display: block; }
  }

  /* Visually hidden — available to screen readers, off-screen for everyone
     else. Used by icon-only controls and the skip link before focus. */
  .visually-hidden {
    block-size: 1px;
    clip-path: inset(50%);
    inline-size: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
  }

  /* Sticky rail header — pins below the sticky masthead and rides along
     until its section ends, when the next section pushes it out. align-self
     keeps the grid item its natural height so it has room to travel. */
  .sticky-top {
    align-self: start;
    inset-block-start: 6.5rem; /* masthead (5.25rem) + breathing room */
    position: sticky;
  }
  @media (max-width: 48em) /* --breakpoint-md */ {
    .sticky-top { position: static; }
  }

  /* Microcaps — small letterspaced monospace caps (fact-strip labels,
     platform lines, window titles). */
  .microcaps {
    font-family: var(--font-mono);
    font-size: var(--text-x-small);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  /* Caption — monospace plate/figure caption, sentence case. */
  .caption {
    color: var(--ink-muted);
    font-family: var(--font-mono);
    font-size: var(--text-x-small);
    letter-spacing: 0.04em;
  }

  /* Spot rule — the short copper divider from the Plate direction. Tune with
     --rule-spot-length; set --rule-spot-inline: auto to center it. */
  .rule-spot {
    background: var(--accent-spot);
    block-size: var(--rule-spot-size, 0.1875rem);
    border: 0;
    inline-size: var(--rule-spot-length, 6rem);
    margin-inline: var(--rule-spot-inline, 0);
  }
  .rule-spot-center { --rule-spot-inline: auto; }

  /* Ruled bands — a hairline above/below a block, with breathing room. */
  .rule-above { border-block-start: 1px solid var(--line); padding-block-start: 1rem; }
  .rule-below { border-block-end: 1px solid var(--line); padding-block-end: 1rem; }

  /* Panel — hairline-framed media box that clips its contents. */
  /* Knobs, not declarations: this block sits in `utilities`, which beats
     `modules` no matter how specific the other selector is. A variant defined
     in an earlier layer has to reconfigure the panel through these custom
     properties (custom properties are not layered) rather than restating
     background/border/radius and silently losing. */
  .panel {
    background: var(--panel-bg, var(--surface));
    border: var(--panel-border, 1px solid var(--line-strong));
    border-radius: var(--panel-radius, var(--radius-2));
    overflow: hidden;
  }
  /* Width only — `display` stays with the reset/mode-swap rules so the
     utilities layer can't un-hide [data-mode] screenshots. */
  .panel > img { inline-size: 100%; }

  /* Titlebar — window-chrome strip across the top of a panel. */
  .titlebar {
    align-items: center;
    border-block-end: 1px solid var(--line-strong);
    display: flex;
    gap: 0.5rem;
    padding: 0.6rem 0.75rem;
  }

  /* Dot — a small round marker (window-chrome dots). */
  .dot {
    background: var(--line-strong);
    block-size: 0.5rem;
    border-radius: 50%;
    flex: none;
    inline-size: 0.5rem;
  }
}
