/* ============================================================
   Cadent — marketing site
   Palette and geometry inherit from the app's renderer (theme.ts,
   Umbra accent). Type, spacing and motion follow the website plan,
   Part VI. The site is achromatic by design: do not introduce a hue
   that is not defined here.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body, h1, h2, h3, p, ul, ol, li, figure, figcaption, dl, dt, dd {
  margin: 0; padding: 0;
}
ul, ol { list-style: none; }
img, svg { display: block; max-width: 100%; }
html { scroll-behavior: smooth; }

/* ─────────────  TOKENS  ───────────── */

:root {
  color-scheme: light;

  /* Palette — the app's light mode, from theme.ts modeTokens.light and
     accentTokens.umbra.light. Verbatim; do not adjust. */
  --app-background: #ECEDEF;
  --surface-primary: #FFFFFF;
  --surface-secondary: #F5F6F7;
  --text-primary: #17181A;
  --text-secondary: #565C64;

  --accent-start: #15171A;
  --accent-middle: #565C64;
  --accent-end: #8E959D;
  --focus-ring: #3A3F46;
  --interactive-foreground: #22262B;
  --interactive-fill: #22262B;
  --on-accent: #FFFFFF;

  /* Deadline states — the app's own warning pair. */
  --warning: #8A5700;
  --warning-tint: #FFF4DD;

  /* Lines, fills and shadow derive from the ink, as in the app. */
  --border-subtle: color-mix(in srgb, var(--text-primary) 10%, transparent);
  --border-strong: color-mix(in srgb, var(--text-primary) 18%, transparent);
  --fill-subtle: color-mix(in srgb, var(--text-primary) 5%, transparent);
  --shadow-color: color-mix(in srgb, var(--text-primary) 12%, transparent);
  --panel-shadow: 0 30px 80px -32px var(--shadow-color);

  /* Liquid Glass, light recipe — from the app's renderer stylesheet. */
  --surface-glass: color-mix(in srgb, #FFFFFF 70%, transparent);
  --surface-glass-strong: color-mix(in srgb, #FFFFFF 84%, transparent);
  --glass-rim: rgb(255 255 255 / 62%);
  --glass-rim-top: rgb(255 255 255 / 88%);
  --glass-blur: 30px;
  --glass-saturate: 135%;

  /* Ambient pools — achromatic silver in Umbra. */
  --ambient-a: rgba(86, 92, 100, 0.10);
  --ambient-b: rgba(142, 149, 157, 0.08);

  /* Geometry — the app's radius ladder, squircle throughout. */
  --r-sheet: 34px;
  --r-major: 30px;
  --r-panel: 26px;
  --r-row: 17px;
  --r-control: 12px;
  --r-xs: 7px;
  --r-2xs: 5px;

  /* Type — the app's face and its optical tracking tiers. */
  --font-body: 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --track-display: -0.022em;
  --track-large: -0.014em;
  --track-title: -0.008em;
  --track-body: -0.002em;
  --track-micro: 0.06em;

  /* Rhythm */
  --shell: 1160px;
  --gutter: clamp(20px, 5vw, 48px);
  --section-y: clamp(92px, 13vw, 190px);

  /* Motion — the app's tokens. --ease is unchanged from before. */
  --motion-fast: 140ms;
  --motion-standard: 200ms;
  --motion-panel: 280ms;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
}

/* ─────────────  BASE  ───────────── */

body {
  background: var(--app-background);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 19px;
  line-height: 1.6;
  letter-spacing: var(--track-body);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute; left: 16px; top: -60px; z-index: 100;
  padding: 10px 16px;
  background: var(--surface-primary); color: var(--text-primary);
  border-radius: var(--r-control);
  transition: top 0.16s var(--ease);
}
.skip-link:focus { top: 16px; }

/* ─────────────  AMBIENT  ───────────── */

/* Carries only the gradient definition the marks reference. The stops ship
   literal Umbra-light values because var() in an SVG presentation attribute
   is not portable; CSS then overrides them, so the mark stays token-driven
   and still paints correctly wherever that support is missing. */
.markdefs { position: absolute; width: 0; height: 0; overflow: hidden; }
.mk-a { stop-color: var(--accent-start); }
.mk-b { stop-color: var(--accent-middle); }
.mk-c { stop-color: var(--accent-end); }

/* The ground. Achromatic by rule: light gathers toward the top, the floor
   settles a shade deeper, and two silver pools drift behind it. Umbra takes
   its colour from the accent and the ambient, never from the substrate.
   Inset past every edge so the blur never reveals a seam, and fixed so the
   wash belongs to the window rather than stretching over a very tall page. */
.ambient {
  position: fixed; inset: -25%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(58% 42% at 50% 22%,
      color-mix(in srgb, #FFFFFF 70%, var(--app-background)), transparent 72%),
    radial-gradient(46% 40% at 20% 34%, var(--ambient-a), transparent 68%),
    radial-gradient(42% 40% at 84% 62%, var(--ambient-b), transparent 66%),
    linear-gradient(178deg,
      var(--app-background) 42%,
      color-mix(in srgb, var(--text-primary) 4%, var(--app-background)) 78%);
  filter: blur(30px);
  animation: ambient-drift 22s var(--ease) infinite alternate;
}

@keyframes ambient-drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(3%, -2.5%, 0) scale(1.1); }
}

/* ─────────────  TYPE  (Part VI §6.2)  ───────────── */

/* Display scale. The old cap of 2.95rem dated from a two-column hero and had
   been holding the headline at roughly a third of its intended size ever since
   the hero went centred. Leading goes below 1 because at this size the lines
   need to read as one block, not as a list. */
.display {
  font-size: clamp(2.5rem, 4.6vw, 4.3rem);
  font-weight: 750;
  letter-spacing: var(--track-display);
  line-height: 1.02;
}
/* The closing CTA and the sub-page titles. */
.display--sm {
  font-size: clamp(2.1rem, 4vw, 3.4rem);
  line-height: 1.05;
  letter-spacing: var(--track-display);
}

.h2 {
  text-wrap: balance;
  font-size: clamp(1.85rem, 3.2vw, 2.8rem);
  font-weight: 700;
  letter-spacing: var(--track-large);
  line-height: 1.08;
}

.h3 {
  text-wrap: balance;
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  font-weight: 700;
  letter-spacing: var(--track-title);
  line-height: 1.18;
}

/* Proper nouns that carry their own casing — "macOS", never "MACOS". */
.nocaps { text-transform: none; }

.lead {
  font-size: clamp(1.06rem, 1.35vw, 1.18rem);
  color: var(--text-secondary);
  max-width: 46ch;
  margin-top: 28px;
}

/* Measure capped at 68 characters, per §6.2. */
.body {
  color: var(--text-secondary);
  max-width: 68ch;
  margin-top: 22px;
  text-wrap: pretty;
}
.h2 + .body, .h3 + .body { margin-top: 26px; }

.detail {
  font-size: 0.895rem;
  color: var(--text-secondary);
  max-width: 62ch;
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--border-subtle);
}

/* The line a section is remembered by. */
.statement {
  text-wrap: balance;
  font-size: clamp(1.2rem, 1.9vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.35;
  color: var(--text-primary);
  max-width: 34ch;
  margin-top: 38px;
}

.fineprint { font-size: 0.85rem; color: var(--text-secondary); }


.textlink {
  display: inline-block;
  margin-top: 34px;
  font-size: 0.925rem; font-weight: 500;
  color: var(--text-secondary);
  transition: color 0.14s var(--ease);
}
.textlink:hover { color: var(--text-primary); }

/* One gradient element per view. Umbra's ramp runs near-white -> grey in
   dark and near-black -> silver in light; the end stop is large display
   text only — it is 3.03:1 on white and must never carry body copy. */
.grad {
  background: linear-gradient(102deg, var(--accent-start) 4%, var(--accent-middle) 54%, var(--accent-end) 96%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* ─────────────  LAYOUT  ───────────── */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* The shell keeps its full width so every section shares one left edge with
   the nav and the hero — the app is left-aligned against its rail and the
   site holds the same line. Only the measure is narrowed. */
.shell.narrow { max-width: var(--shell); }
.shell.narrow > * { max-width: 820px; }

.section { padding-block: var(--section-y); }
/* The closing call to action is the page's one dark moment: an inset panel
   in the app's dark-Umbra palette, scoped to .night. On a light page the
   classic emphasis device is a dark panel — and Cadent's dark mode is a
   palette we own rather than a style to invent. */
.night {
  --n-bg: #0B0C0E;
  --n-surface: #17181B;
  --n-text: #F4F5F7;
  --n-text-2: #B4B7BE;
  --n-fill: #E7E9ED;
}
.section--download {
  padding-block: clamp(72px, 10vw, 130px);
  padding-inline: var(--gutter);
}
.section--download > .shell {
  padding-inline: clamp(28px, 5vw, 72px);
  padding-block: clamp(56px, 9vw, 104px);
  background: var(--n-bg);
  color: var(--n-text);
  border-radius: var(--r-sheet);
  corner-shape: squircle;
  text-align: center;
}
.section--download .shell > * { margin-inline: auto; }
.section--download .display--sm { max-width: 26ch; }
.section--download .hero__cta { margin-top: 40px; justify-content: center; }
.section--download .fineprint {
  margin-top: 22px;
  color: var(--n-text-2);
}
/* The gradient ramp is dark-on-light; on the night panel the name inverts to
   the dark mode's own ramp. */
.section--download .grad {
  background: linear-gradient(102deg, #F2F3F5 4%, #AEB3BA 54%, #767C85 96%);
  -webkit-background-clip: text;
  background-clip: text;
}
/* The app's dark-mode interactive: near-white fill, dark label. */
.section--download .btn {
  background: var(--n-fill);
  color: var(--n-bg);
}
.section--download .btn--soon {
  background: none;
  color: var(--n-text-2);
  border-color: rgb(255 255 255 / 24%);
}
.section--download .textlink { color: var(--n-text-2); }
.section--download .textlink:hover { color: var(--n-text); }
/* The light focus ring vanishes on the night panel. */
.section--download :focus-visible { outline-color: var(--n-fill); }

/* Follows the hero directly, so it opens tighter than a standalone section. */
.section--tight { padding-block: clamp(48px, 6vw, 84px) var(--section-y); }

/* Section openings centre; everything below them keeps the shared left edge
   that ties the page to the app's rail.

   .intro is applied two ways — on the shell itself where a section has a
   separate shell for its content, and as a wrapper inside the shell where it
   does not. In the second case .intro is itself the child that .shell.narrow
   caps at 820px and anchors left, which would sit its centred contents well
   off page centre. The second rule makes both modes land on the same axis. */
.intro { text-align: center; }
.intro > * { margin-inline: auto; }
.intro > .body { max-width: 60ch; }
.shell.narrow > .intro { max-width: none; margin-inline: auto; }

/* ─────────────  MASTHEAD  ───────────── */

/* A floating pill, detached from the top edge, rather than a full-width bar.
   The page scrolls underneath it and the ambient shows around its edges. */
.masthead {
  position: sticky; top: 14px; z-index: 50;
  padding-inline: var(--gutter);
  margin-bottom: -66px;
}
.masthead__inner {
  display: flex; align-items: center; gap: 22px;
  width: 100%; max-width: 1080px;
  margin-inline: auto;
  height: 62px;
  padding-inline: 10px 10px;
  padding-left: 20px;
  border-radius: var(--r-row);
  corner-shape: squircle;
  /* The app's light glass: heavy veil, bright rim, real blur. */
  background: var(--surface-glass-strong);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  box-shadow:
    inset 0 1px 0 var(--glass-rim-top),
    inset 0 0 0 1px var(--glass-rim),
    0 12px 34px -22px var(--shadow-color);
}
.masthead.is-stuck .masthead__inner {
  box-shadow:
    inset 0 1px 0 var(--glass-rim-top),
    inset 0 0 0 1px var(--glass-rim),
    0 16px 40px -20px var(--shadow-color);
}

/* On the home page the hero's own sheets carry the nav, so the masthead
   holds back until the reader scrolls past them. .has-hero is set by JS
   when a .hero exists — the generated pages have none and keep the bar,
   and so does anyone browsing without JS. */
.masthead.has-hero {
  opacity: 0;
  pointer-events: none;
  transform: translateY(-8px);
  transition: opacity var(--motion-standard) var(--ease),
              transform var(--motion-standard) var(--ease);
}
.masthead.has-hero.is-stuck {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}

.brand { display: flex; align-items: center; gap: 11px; margin-right: auto; }

/* The mark stands on its own: no tile, no container. It is painted by the
   shared #cadentMark sweep rather than a flat currentColor, so the three
   beats are slices of one gradient exactly as the app draws them. */
.brand__mark { display: grid; place-items: center; }
.brand__mark svg { width: 23px; height: 23px; }

.brand__word { font-size: 1rem; font-weight: 700; letter-spacing: -0.022em; }

.brand--sm .brand__mark svg { width: 20px; height: 20px; }
.brand--sm .brand__word { font-size: 0.9rem; }

.masthead__actions { display: flex; align-items: center; gap: 12px; margin-left: auto; }

/* Tabbed nav. The pill marks where you are: on the home page it follows the
   section you are reading; on a subpage it marks the page. */
.tabs {
  display: flex; align-items: center; gap: 4px;
  margin-inline: auto;
}
.tabs a {
  padding: 7px 14px;
  border-radius: 8px;
  corner-shape: squircle;
  font-size: 0.82rem; font-weight: 550;
  color: var(--text-secondary);
  white-space: nowrap;
  transition: color 0.14s var(--ease), background 0.14s var(--ease);
}
.tabs a:hover { color: var(--text-primary); }
.tabs a.is-current {
  background: var(--surface-secondary);
  color: var(--text-primary);
}

/* In-page tabs for the long setup guide, sitting under the masthead. */
.subnav {
  position: sticky; top: 64px; z-index: 40;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  background: color-mix(in srgb, var(--app-background) 82%, transparent);
  border-bottom: 1px solid var(--border-subtle);
}
.subnav__inner {
  display: flex; gap: 24px;
  height: 50px; align-items: center;
  overflow-x: auto;
  scrollbar-width: none;
}
.subnav__inner::-webkit-scrollbar { display: none; }
.subnav a {
  font-size: 0.82rem; font-weight: 550;
  color: var(--text-secondary);
  white-space: nowrap;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  transition: color 0.14s var(--ease), border-color 0.14s var(--ease);
}
.subnav a:hover { color: var(--text-primary); }
.subnav a.is-current {
  color: var(--text-primary);
  border-bottom-color: var(--interactive-fill);
}

/* ─────────────  CHIPS, SECTION HEADS, CARDS  ───────────── */

/* Section labels. A solid capsule rather than an outlined one — the smallest
   instance of the inversion device, so the badge, the closing panel and the
   open FAQ row all read as the same idea at three sizes.
   0.6315rem / 0.12em / uppercase is the site's existing micro-label setting,
   shared with .card__label, .reqs__head, .checksum__label and .footer__head;
   this joins that convention rather than inventing a fifth. */
.chip {
  display: inline-flex; align-items: center;
  padding: 6px 12px;
  margin-bottom: 22px;
  border-radius: var(--r-control);
  corner-shape: squircle;
  background: var(--interactive-fill);
  color: var(--on-accent);
  font-size: 0.6315rem; font-weight: 700;
  letter-spacing: var(--track-micro);
  text-transform: uppercase;
}

/* ─────────────  ICON BUTTON  ─────────────
   A circle is the one shape where corner-shape has nothing to say, which is
   why .dot and the .reqs bullet are already the documented exceptions. */

.iconbtn {
  width: 40px; height: 40px;
  flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: none;
  color: var(--text-secondary);
  transition: background 0.14s var(--ease), color 0.14s var(--ease),
              border-color 0.14s var(--ease);
}


/* Three-up card grid. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
  margin-top: clamp(38px, 5vw, 56px);
}
.card {
  padding: clamp(24px, 2.8vw, 32px);
  border-radius: var(--r-major);
  corner-shape: squircle;
  background: var(--surface-primary);
  border: 1px solid var(--border-subtle);
}
.card__label {
  font-size: 0.6315rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 14px;
}
.card__title {
  font-size: 1.12rem; font-weight: 650;
  letter-spacing: -0.018em; line-height: 1.25;
}
.card__body { text-wrap: pretty; font-size: 0.92rem; color: var(--text-secondary); margin-top: 10px; line-height: 1.55; }

/* ─────────────  BUTTON  ───────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 50px; padding-inline: 28px;
  border-radius: var(--r-row);
  corner-shape: squircle;
  background: var(--interactive-fill);
  color: var(--on-accent);
  font-size: 0.95rem; font-weight: 600; letter-spacing: -0.008em;
  transition: transform 0.14s var(--ease), opacity 0.14s var(--ease);
}
.btn:hover { transform: translateY(-1.5px); opacity: 0.92; }
.btn:active { transform: translateY(0); }

.btn--small { height: 36px; padding-inline: 16px; font-size: 0.83rem; }

/* Ghost — the secondary action beside a filled primary. Declared after .btn
   so its transparent background is not overridden by the base rule. */
.btn--ghost {
  background: none;
  color: var(--text-primary);
  border: 1px solid var(--border-strong);
}
.btn--ghost:hover { background: var(--fill-subtle); opacity: 1; }

/* Waiting — the primary action's shape, held open for a build that is not out
   yet. Not an <a>, so there is nothing to click and nothing to 404; the muted
   fill and default cursor say so before anyone tries. */
.btn--soon {
  background: none;
  color: var(--text-secondary);
  border: 1px dashed var(--border-strong);
  cursor: default;
}
.btn--soon:hover { transform: none; opacity: 1; }

/* ─────────────  HERO — split sheets (from the reference recording)  ───────────── */

/* Two rounded sheets inside the page gutter. The reference is 50/50 with a
   portrait panel; Cadent's app is landscape, so the app sheet takes the
   width. */
.hero { padding: clamp(10px, 1.2vw, 16px) clamp(10px, 1.2vw, 16px) 0; }
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 0.58fr);
  gap: clamp(8px, 1vw, 12px);
  min-height: min(88vh, 920px);
}

.sheet {
  border-radius: var(--r-sheet);
  corner-shape: squircle;
  overflow: hidden;
  position: relative;
}

/* ── Left: the copy sheet ── */
.sheet--copy {
  background: var(--surface-primary);
  display: flex; flex-direction: column;
  padding: clamp(20px, 2.4vw, 34px) clamp(22px, 2.6vw, 40px);
}
.sheet__top { display: flex; align-items: center; justify-content: space-between; }
.chip--quiet {
  background: var(--surface-secondary);
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
}
.sheet__center {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  padding-block: clamp(28px, 4vw, 56px);
}
.medallion {
  width: 74px; height: 74px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--surface-secondary);
  box-shadow: inset 0 1px 0 var(--glass-rim-top), 0 10px 24px -14px var(--shadow-color);
  margin-bottom: clamp(22px, 3vw, 40px);
}
.medallion svg { width: 34px; height: 34px; color: var(--accent-middle); }
.hero .lead { margin-top: 24px; max-width: 40ch; margin-inline: auto; text-wrap: balance; }
/* The action row everywhere: pricing, the download page, the closing
   panel. The hero centres it; everyone gets the same breathing room. */
.hero__cta {
  display: flex; flex-wrap: wrap;
  gap: 12px; align-items: center;
  margin-top: 36px;
}
.hero__cta + .fineprint { margin-top: 14px; }
.hero .hero__cta { justify-content: center; margin-top: 34px; }
.avail { margin-top: 16px; font-size: 0.8rem; color: var(--text-secondary); opacity: 0.8; }

/* Headline reveal: a soft mask sweeps each line open left to right — the
   vanish effect in reverse. A mask, not per-character opacity, because the
   gradient word paints via background-clip: text on its parent: the clip
   mask is built from glyph geometry, and a child span's opacity cannot hide
   the parent's clipped background — which is exactly how "start" used to
   sit visible before the animation. The mask composites the line's finished
   paint, gradient included. Hidden from first frame because the inline head
   script sets .js before render; no-JS renders the headline whole. */
.display__line { display: block; }
.js .display .display__line {
  -webkit-mask-image: linear-gradient(90deg, #000 45%, transparent 62%);
  mask-image: linear-gradient(90deg, #000 45%, transparent 62%);
  -webkit-mask-size: 250% 100%;
  mask-size: 250% 100%;
  -webkit-mask-position: 100% 0;
  mask-position: 100% 0;
  transition: -webkit-mask-position 0.9s var(--ease), mask-position 0.9s var(--ease);
}
.js .display.is-typed .display__line {
  -webkit-mask-position: 0 0;
  mask-position: 0 0;
}
.js .display.is-typed .display__line:nth-child(2) { transition-delay: 0.28s; }
.js .display.is-typed .display__line:nth-child(3) { transition-delay: 0.56s; }

/* ── Right: the app sheet ── */
.sheet--app {
  background:
    radial-gradient(88% 70% at 6% 0%, var(--ambient-a), transparent 64%),
    radial-gradient(82% 66% at 100% 100%, var(--ambient-b), transparent 68%),
    var(--surface-secondary);
  background-size: 132% 132%, 132% 132%, auto;
  animation: sheet-drift 20s ease-in-out infinite alternate;
  display: flex; flex-direction: column;
  padding: clamp(16px, 1.8vw, 24px);
}
/* The reference's halftone shader, in Umbra silver. */
.sheet--app::before {
  content: '';
  position: absolute; inset: 0;
  background-image: radial-gradient(circle, rgba(142, 149, 157, 0.28) 1.2px, transparent 1.3px);
  background-size: 13px 13px;
  mask-image: radial-gradient(120% 90% at 70% 40%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 90% at 70% 40%, #000 30%, transparent 78%);
  pointer-events: none;
}
@keyframes sheet-drift {
  from { background-position: 0% 0%, 100% 100%, 0 0; }
  to   { background-position: 10% 8%, 90% 92%, 0 0; }
}

.sheet__nav {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chips a {
  display: inline-flex; align-items: center;
  height: 38px; padding-inline: 16px;
  border-radius: var(--r-control);
  corner-shape: squircle;
  background: var(--surface-glass);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  box-shadow: inset 0 1px 0 var(--glass-rim-top), inset 0 0 0 1px var(--glass-rim);
  font-size: 0.85rem; font-weight: 600;
  color: var(--text-primary);
  transition: background var(--motion-fast) var(--ease);
}
.chips a:hover { background: var(--surface-glass-strong); }
.btn--onglass { background: var(--surface-primary); color: var(--text-primary); box-shadow: 0 10px 24px -14px var(--shadow-color); }

/* ── The staged app ── */
.appshot {
  position: relative; z-index: 1;
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
  padding-block: clamp(14px, 2vw, 26px);
}
.appshot__frame {
  width: min(860px, 100%);
  border-radius: var(--r-panel);
  corner-shape: squircle;
  background: var(--surface-glass-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  box-shadow:
    inset 0 1px 0 var(--glass-rim-top),
    inset 0 0 0 1px var(--glass-rim),
    var(--panel-shadow);
  overflow: hidden;
}
.appshot__chrome { display: flex; gap: 7px; padding: 12px 14px 8px; }
.appshot__body {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr) 0px;
  transition: grid-template-columns var(--motion-panel) var(--ease);
  min-height: 380px;
  text-align: left;
}
.appshot[data-step="5"] .appshot__body,
.appshot[data-step="6"] .appshot__body,
.appshot[data-step="7"] .appshot__body,
.appshot[data-step="8"] .appshot__body { grid-template-columns: 132px minmax(0, 1fr) 236px; }

/* Each pane is pinned to its track: hiding a sibling must never let
   auto-placement drop the main pane into the collapsed first column. */
.appshot__rail { grid-column: 1; }
.appshot__main { grid-column: 2; }
.appshot__panel { grid-column: 3; }

/* Rail — the app's own left rail, reduced. */
.appshot__rail {
  padding: 8px 10px 12px;
  border-right: 1px solid var(--border-subtle);
  background:
    radial-gradient(88% 70% at 6% 0%, var(--ambient-a), transparent 64%),
    var(--surface-glass);
  display: flex; flex-direction: column; gap: 4px;
  font-size: 0.62rem;
}
.rail__brand { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 0.7rem; padding: 4px 6px 8px; }
.rail__brand svg { width: 12px; height: 12px; }
.rail__nav { display: flex; flex-direction: column; gap: 2px; }
.rail__row {
  display: block;
  padding: 6px 8px; border-radius: 7px; corner-shape: squircle;
  font-weight: 600; color: var(--text-primary);
}
.rail__row--on { background: color-mix(in srgb, var(--text-primary) 8%, transparent); }
.rail__row--soon { display: flex; align-items: center; gap: 5px; color: var(--text-secondary); }
.rail__row--soon { display: flex; }
.rail__row--soon i {
  font-style: normal; font-size: 0.48rem; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase;
  white-space: nowrap;
  padding: 2px 5px; border-radius: 5px;
  background: color-mix(in srgb, var(--text-primary) 7%, transparent);
}
.rail__label {
  margin-top: 10px; padding-inline: 8px;
  font-size: 0.52rem; font-weight: 700;
  letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--text-secondary);
}
.rail__recent {
  margin-top: 2px; padding: 5px 8px; border-radius: 6px;
  color: var(--text-secondary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  opacity: 0;
  transition: opacity var(--motion-standard) var(--ease);
}
.appshot[data-step="5"] .rail__recent,
.appshot[data-step="6"] .rail__recent,
.appshot[data-step="7"] .rail__recent,
.appshot[data-step="8"] .rail__recent { opacity: 1; background: color-mix(in srgb, var(--text-primary) 6%, transparent); }
.rail__spring { flex: 1; }
.rail__user {
  display: flex; align-items: center; gap: 6px;
  background: var(--surface-primary);
  border-radius: 8px; corner-shape: squircle;
  padding: 5px 7px;
  box-shadow: 0 4px 10px -6px var(--shadow-color);
}
.rail__user b {
  width: 16px; height: 16px; display: grid; place-items: center;
  background: var(--interactive-fill); color: var(--on-accent);
  border-radius: 5px; corner-shape: squircle;
  font-size: 0.5rem;
}
.rail__user span { line-height: 1.15; font-weight: 700; font-size: 0.56rem; }
.rail__user i { font-style: normal; font-weight: 500; color: var(--text-secondary); }

/* Main pane */
.appshot__main { padding: 16px 20px 18px; display: flex; flex-direction: column; min-width: 0; }
.appshot__greet {
  font-size: clamp(1.1rem, 1.6vw, 1.45rem);
  font-weight: 750; letter-spacing: var(--track-large);
}
.appshot__date { font-size: 0.68rem; color: var(--text-secondary); margin-top: 2px; }
.appshot__dayhead {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-top: 18px; padding-bottom: 8px;
  border-bottom: 1px solid var(--border-subtle);
  font-size: 0.72rem; font-weight: 700;
}
.appshot__total { font-variant-numeric: tabular-nums; }
.appshot__tasks { flex: 1; }
.atask {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-subtle);
  transition: opacity var(--motion-standard) var(--ease),
              transform var(--motion-standard) var(--ease),
              max-height var(--motion-panel) var(--ease);
}
.atask__box {
  flex: none; width: 13px; height: 13px; margin-top: 2px;
  border: 1.4px solid var(--border-strong);
  border-radius: 4px; corner-shape: squircle;
}
.atask__text { min-width: 0; }
.atask__text b { display: block; font-size: 0.74rem; font-weight: 600; letter-spacing: var(--track-title); }
.atask__text i { font-style: normal; font-size: 0.62rem; color: var(--text-secondary); }
.atask__meta {
  margin-left: auto; flex: none;
  display: flex; align-items: center; gap: 8px;
  font-size: 0.65rem; color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.duepill {
  font-style: normal; font-size: 0.56rem; font-weight: 700;
  color: var(--warning); background: var(--warning-tint);
  border: 1px solid color-mix(in srgb, var(--warning) 25%, transparent);
  padding: 3px 7px; border-radius: 6px; corner-shape: squircle;
}

/* Task build (steps 1–3) and clearing (step 6). */
.atask { opacity: 0; transform: translateY(8px); }
.appshot[data-step="1"] .atask--1,
.appshot[data-step="2"] .atask--1, .appshot[data-step="2"] .atask--2,
.appshot[data-step="3"] .atask--1, .appshot[data-step="3"] .atask--2, .appshot[data-step="3"] .atask--3,
.appshot[data-step="4"] .atask,
.appshot[data-step="5"] .atask,
.appshot[data-step="6"] .atask,
.appshot[data-step="7"] .atask { opacity: 1; transform: none; }
.appshot[data-step="8"] .atask--2 { opacity: 1; transform: none; }
.appshot[data-step="8"] .atask--clears { opacity: 0; transform: translateX(14px); max-height: 0; padding-block: 0; border-bottom-width: 0; overflow: hidden; }
.atask--clears { max-height: 60px; }

/* Ask bar */
.appshot__askbar {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-control); corner-shape: squircle;
  background: var(--surface-primary);
  padding: 9px 12px;
  font-size: 0.7rem;
  box-shadow: 0 8px 20px -14px var(--shadow-color);
}
.askbar__q { position: relative; flex: 1; min-width: 0; }
.askbar__ph { color: var(--text-secondary); }
.askbar__typed {
  position: absolute; inset: 0;
  color: var(--text-primary);
  white-space: nowrap; overflow: hidden;
  width: 0;
}
.appshot[data-step="4"] .askbar__ph { opacity: 0; }
.appshot[data-step="4"] .askbar__typed { width: 100%; transition: width 1.4s steps(30, end); }
.askbar__send {
  flex: none; width: 20px; height: 20px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--interactive-fill); color: var(--on-accent);
  font-size: 0.62rem;
}

/* ─── Beats — the app's loading mark, read from its source ───
   Three skewed bars sharing one gradient (each shows its own slice), each
   on a 1.35s linear loop rising from dim to full in a left-to-right wave.
   Geometry and keyframe offsets are the app's own. */
.beats {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 13%;
  width: 14px; height: 14px;
  flex: none;
}
.beats i {
  display: block;
  width: 19.5%;
  border-radius: 1.5px;
  corner-shape: squircle;
  transform: skewY(-18.4deg);
  transform-origin: center;
  background-image: linear-gradient(160deg, var(--accent-start), var(--accent-middle) 52%, var(--accent-end));
  background-repeat: no-repeat;
}
.beats i:nth-child(1) { height: 49%;  background-position: 9.63% 50%;  background-size: 512.8% 204.1%; }
.beats i:nth-child(2) { height: 75%;  background-position: 50% 50%;    background-size: 512.8% 133.3%; }
.beats i:nth-child(3) { height: 100%; background-position: 90.37% 50%; background-size: 512.8% 100%; }
.beats.is-live i {
  animation-duration: 1.35s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.beats.is-live i:nth-child(1) { animation-name: beat-one; }
.beats.is-live i:nth-child(2) { animation-name: beat-two; }
.beats.is-live i:nth-child(3) { animation-name: beat-three; }
@keyframes beat-one {
  0%, 7%   { opacity: 0.42; transform: skewY(-18.4deg) translateY(1px) scaleY(0.62); }
  15%, 92% { opacity: 1;    transform: skewY(-18.4deg) translateY(0)   scaleY(1); }
  100%     { opacity: 0.42; transform: skewY(-18.4deg) translateY(1px) scaleY(0.62); }
}
@keyframes beat-two {
  0%, 22%  { opacity: 0.42; transform: skewY(-18.4deg) translateY(1px) scaleY(0.62); }
  30%, 92% { opacity: 1;    transform: skewY(-18.4deg) translateY(0)   scaleY(1); }
  100%     { opacity: 0.42; transform: skewY(-18.4deg) translateY(1px) scaleY(0.62); }
}
@keyframes beat-three {
  0%, 37%  { opacity: 0.42; transform: skewY(-18.4deg) translateY(1px) scaleY(0.62); }
  45%, 92% { opacity: 1;    transform: skewY(-18.4deg) translateY(0)   scaleY(1); }
  100%     { opacity: 0.42; transform: skewY(-18.4deg) translateY(1px) scaleY(0.62); }
}
/* Live only while its searching step is on stage. */
.appshot[data-step="5"] .panel__searching--1 .beats i,
.appshot[data-step="7"] .panel__searching--2 .beats i {
  animation-duration: 1.35s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.appshot[data-step="5"] .panel__searching--1 .beats i:nth-child(1),
.appshot[data-step="7"] .panel__searching--2 .beats i:nth-child(1) { animation-name: beat-one; }
.appshot[data-step="5"] .panel__searching--1 .beats i:nth-child(2),
.appshot[data-step="7"] .panel__searching--2 .beats i:nth-child(2) { animation-name: beat-two; }
.appshot[data-step="5"] .panel__searching--1 .beats i:nth-child(3),
.appshot[data-step="7"] .panel__searching--2 .beats i:nth-child(3) { animation-name: beat-three; }

/* Ask panel — slides in with the grid column (steps 5–6). */
.appshot__panel {
  border-left: 1px solid var(--border-subtle);
  background: var(--surface-primary);
  min-width: 236px;
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 10px;
  font-size: 0.62rem;
  opacity: 0;
  transition: opacity var(--motion-panel) var(--ease);
}
.appshot[data-step="5"] .appshot__panel,
.appshot[data-step="6"] .appshot__panel,
.appshot[data-step="7"] .appshot__panel,
.appshot[data-step="8"] .appshot__panel { opacity: 1; }
.panel__head { display: flex; justify-content: space-between; align-items: center; font-size: 0.72rem; }
.panel__head span { color: var(--text-secondary); letter-spacing: 2px; }
.panel__bubble {
  align-self: flex-end;
  background: var(--surface-secondary);
  border-radius: 9px; corner-shape: squircle;
  padding: 7px 10px;
  max-width: 90%;
}
.panel__searching {
  display: flex; align-items: center; gap: 6px;
  color: var(--text-secondary);
  transition: opacity var(--motion-standard) var(--ease);
}
.panel__searching svg { width: 10px; height: 10px; }
/* Conversation ladder. Everything hidden until its step arrives; the
   searching rows yield to their answers. Parked markup (step 8) shows the
   whole conversation. */
.panel__bubble, .panel__searching, .panel__answer { display: none; }
.appshot[data-step="5"] .panel__bubble--1,
.appshot[data-step="6"] .panel__bubble--1,
.appshot[data-step="7"] .panel__bubble--1,
.appshot[data-step="8"] .panel__bubble--1 { display: block; }
.appshot[data-step="5"] .panel__searching--1 { display: flex; }
.appshot[data-step="6"] .panel__answer--1,
.appshot[data-step="7"] .panel__answer--1,
.appshot[data-step="8"] .panel__answer--1 { display: block; }
.appshot[data-step="7"] .panel__bubble--2,
.appshot[data-step="8"] .panel__bubble--2 { display: block; }
.appshot[data-step="7"] .panel__searching--2 { display: flex; }
.appshot[data-step="8"] .panel__answer--2 { display: block; }

.panel__answer p { margin-bottom: 6px; line-height: 1.45; }
.panel__undo {
  display: block; text-align: center;
  margin-top: 8px; padding: 7px 0;
  border: 1px solid var(--border-strong);
  border-radius: 8px; corner-shape: squircle;
  font-weight: 600;
}
.panel__input {
  margin-top: auto;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border: 1px solid var(--border-subtle);
  border-radius: 9px; corner-shape: squircle;
  padding: 7px 10px;
  color: var(--text-secondary);
}
.panel__input b {
  width: 16px; height: 16px; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--border-strong);
  font-weight: 600; font-size: 0.55rem;
}

.appshot__cap { text-align: center; font-size: 0.9rem; color: var(--text-secondary); max-width: 46ch; }
.appshot__cap b { display: block; color: var(--text-primary); font-size: 1.02rem; letter-spacing: var(--track-title); margin-bottom: 3px; }

/* Loop reset breath. */
.appshot.is-resetting .appshot__frame { opacity: 0.35; transition: opacity var(--motion-panel) var(--ease); }

/* ── Stacking ── */
@media (max-width: 940px) {
  .hero__grid { grid-template-columns: 1fr; min-height: 0; }
  .sheet--copy { min-height: 72vh; }
  .sheet__nav { display: none; }             /* the masthead serves mobile */
  .appshot__body { grid-template-columns: 0px minmax(0, 1fr) 0px; }
  .appshot[data-step="5"] .appshot__body,
  .appshot[data-step="6"] .appshot__body,
  .appshot[data-step="7"] .appshot__body,
  .appshot[data-step="8"] .appshot__body { grid-template-columns: 0px minmax(0, 1fr) 200px; }
  .appshot__rail { display: none; }
}

/* A phone hasn't the width for the split, so the panel does what the app's
   own panel does: slides in from the side, over the workspace. The
   conversation stays visible; the list peeks out on the left. */
@media (max-width: 620px) {
  .appshot[data-step="5"] .appshot__body,
  .appshot[data-step="6"] .appshot__body,
  .appshot[data-step="7"] .appshot__body,
  .appshot[data-step="8"] .appshot__body { grid-template-columns: 0px minmax(0, 1fr) 0px; }
  .appshot__frame { position: relative; }
  .appshot__panel {
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: min(300px, 84%);
    min-width: 0;
    border-left: 1px solid var(--border-subtle);
    box-shadow: -18px 0 40px -28px var(--shadow-color);
    transform: translateX(105%);
    transition: transform var(--motion-panel) var(--ease),
                opacity var(--motion-panel) var(--ease);
  }
  .appshot[data-step="5"] .appshot__panel,
  .appshot[data-step="6"] .appshot__panel,
  .appshot[data-step="7"] .appshot__panel,
  .appshot[data-step="8"] .appshot__panel { transform: translateX(0); }
}


/* ─────────────  LEDGER  ─────────────
   label left / value right, hairline separated — carried from the app. */

.ledger { margin-top: clamp(38px, 5vw, 56px); border-top: 1px solid var(--border-subtle); }

.ledger__row {
  display: grid;
  grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
  gap: 10px 36px;
  padding: 24px 0;
  border-bottom: 1px solid var(--border-subtle);
}
.ledger__row dt { font-weight: 600; letter-spacing: -0.014em; }
.ledger__row dd { color: var(--text-secondary); }

/* ─────────────  PLAIN LIST  ───────────── */

.plainlist { margin-top: 40px; }
.plainlist li {
  color: var(--text-secondary);
  max-width: 68ch;
  padding: 16px 0 16px 22px;
  position: relative;
  border-bottom: 1px solid var(--border-subtle);
}
.plainlist li:first-child { border-top: 1px solid var(--border-subtle); }
.plainlist li::before {
  content: ''; position: absolute; left: 2px; top: 28px;
  width: 5px; height: 1px; background: var(--border-strong);
}

/* ─────────────  PRICING  ───────────── */

.price { display: flex; align-items: baseline; gap: 12px; margin-top: 46px; }
.price__figure {
  font-family: var(--font-body);
  font-size: clamp(3.8rem, 8vw, 6rem);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.price__unit { color: var(--text-secondary); font-size: 1rem; }

/* ─────────────  FAQ  ───────────── */

.faq { margin-top: clamp(38px, 5vw, 56px); border-top: 1px solid var(--border-subtle); }

/* Closed rows are a bare hairline; the open row lifts into a filled card and
   its marker inverts — outlined with the arrow pointing down-right, filled
   with it pointing up-right. A CSS border-corner cannot carry the arrow's
   shaft and renders as a bracket, so the mark is a real SVG in an .iconbtn. */

.faq__item {
  border-bottom: 1px solid var(--border-subtle);
  border-radius: var(--r-major);
  corner-shape: squircle;
  padding-inline: 0;
  transition: background 0.2s var(--ease), padding-inline 0.2s var(--ease);
}
.faq__item[open] {
  background: var(--surface-primary);
  border-bottom-color: transparent;
  padding-inline: clamp(20px, 2.6vw, 30px);
  box-shadow: 0 18px 44px -28px var(--shadow-color);
}

.faq__item summary {
  display: flex; align-items: center; gap: 16px;
  padding: 20px 0;
  cursor: pointer;
  font-weight: 600; letter-spacing: -0.014em;
  list-style: none;
  transition: color 0.14s var(--ease);
}
.faq__item summary::-webkit-details-marker { display: none; }

.faq__item summary .iconbtn { margin-left: auto; }
.faq__item summary svg {
  width: 16px; height: 16px;
  transition: transform 0.16s var(--ease);
}
.faq__item[open] summary .iconbtn {
  background: var(--interactive-fill);
  border-color: var(--interactive-fill);
  color: var(--on-accent);
}
.faq__item[open] summary svg { transform: rotate(-90deg); }

.faq__item summary:hover { color: var(--text-primary); }
.faq__item summary:hover .iconbtn { border-color: var(--text-secondary); color: var(--text-primary); }
.faq__item .body { margin-top: 0; padding-bottom: 26px; }

/* ─────────────  SECONDARY PAGES  ─────────────
   Prose pages sit under a short head rather than a hero: they are read,
   not scrolled past, so the first screen is the first paragraph. */

.section--head { padding-block: clamp(56px, 8vw, 104px) clamp(24px, 3vw, 40px); }

/* A page title, not a closing CTA — the display scale that suits a final
   full-width call to action is too loud at the top of something to read. */
.section--head .display--sm { font-size: clamp(2rem, 3.6vw, 3.1rem); }

.section--head .body--lead { margin-top: 26px; }

.section--sub { padding-block: clamp(48px, 6vw, 84px); }

/* Blockers, above the fold. A student who misses one of these installs an app
   they cannot run, so this is the one place on the site that raises its voice
   — a bordered panel rather than another paragraph. */
.reqs {
  margin-top: 36px;
  padding: clamp(20px, 2.6vw, 28px);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-row);
  corner-shape: squircle;
  background: var(--surface-secondary);
}
.reqs__head {
  font-size: 0.6315rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 16px;
}
.reqs li {
  color: var(--text-secondary);
  padding: 9px 0 9px 20px;
  position: relative;
  line-height: 1.55;
}
.reqs li::before {
  content: ''; position: absolute; left: 2px; top: 0.95em;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-secondary);
}
.reqs b { color: var(--text-primary); font-weight: 600; }

/* The checksum has to be selectable and must not wrap mid-character-run in a
   way that makes comparison unreliable. */
.whatsnew {
  max-width: 62ch;
  margin-top: 20px;
  line-height: 1.6;
}
.whatsnew .textlink { margin-top: 0; }
.whatsnew b { color: var(--text-primary); }

.checksum { margin-top: 34px; padding-top: 22px; border-top: 1px solid var(--border-subtle); }
.checksum__label {
  font-size: 0.6315rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 10px;
}
.checksum__value {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
  line-height: 1.6;
  word-break: break-all;
  user-select: all;
  color: var(--text-primary);
}
.checksum__note { font-size: 0.8rem; color: var(--text-secondary); margin-top: 8px; }

/* A heading that opens a subsection inside a longer page, rather than sitting
   directly above its own paragraph. */
.h3--section { margin-top: clamp(40px, 5vw, 60px); margin-bottom: 4px; }
.shell.narrow > .h3--section:first-of-type { margin-top: 34px; }

.textlink--inline { margin-top: 0; }

/* Headings inside a running prose page need air above them that a first
   heading in a section does not. */
.shell.narrow > .h2 + .h2,
.shell.narrow > .body + .h2,
.shell.narrow > .plainlist + .h2,
.shell.narrow > .statement + .h2,
.shell.narrow > .detail + .h2,
.shell.narrow > ol + .h2,
.shell.narrow > .ledger + .h2 { margin-top: clamp(48px, 6vw, 76px); }

/* The install steps read as a list, not a row of columns. Self-contained:
   the home page's old numbered grid went away with the demos rewrite, so
   this must not depend on it. */
.steps--plain { display: block; margin-top: 40px; }

.steps--plain .step {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 26px 0;
  border-bottom: 1px solid var(--border-subtle);
}
.steps--plain .step:first-child { border-top: 1px solid var(--border-subtle); }

.steps--plain .step__num {
  flex: none;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  margin-top: 2px;
  border-radius: 8px;
  corner-shape: squircle;
  border: 1px solid var(--border-strong);
  font-size: 0.78rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.steps--plain .h3 { font-size: 1.12rem; margin-bottom: 0; }
.steps--plain .body { margin-top: 6px; }

/* ─────────────  GUIDE STEPS  ─────────────
   Install and setup instructions, each paired with a diagram. The diagrams
   are schematic on purpose: they are drawn in the site's own palette rather
   than imitating macOS pixel-for-pixel, so nothing on the page pretends to
   be a screenshot it is not. They show the shape of a dialog and which
   control to press, which is the part a stuck student needs. */

.guide { margin-top: clamp(36px, 5vw, 52px); }

.guide__step {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
  padding: clamp(28px, 3.4vw, 40px) 0;
  border-top: 1px solid var(--border-subtle);
}
.guide__step:last-child { border-bottom: 1px solid var(--border-subtle); }

.guide__num {
  display: grid; place-items: center;
  width: 26px; height: 26px;
  margin-bottom: 14px;
  border-radius: 8px;
  corner-shape: squircle;
  border: 1px solid var(--border-strong);
  font-size: 0.78rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.guide__text .h3 { font-size: 1.12rem; margin-bottom: 8px; }
.guide__text .body { margin-top: 8px; max-width: 46ch; }
/* Inline in a step, so it sits close to the copy it answers. */
.guide__text .textlink { margin-top: 12px; font-size: 0.875rem; }

.guide__shot { min-width: 0; }

/* Shared frame for every diagram. */
.shot {
  border-radius: var(--r-row);
  corner-shape: squircle;
  border: 1px solid var(--border-subtle);
  background: var(--surface-secondary);
  padding: 20px;
  overflow: hidden;
}
.shot__cap {
  margin-top: 10px;
  font-size: 0.72rem;
  color: var(--text-secondary);
}

/* macOS-style alert, drawn schematically. */
.dlg {
  max-width: 320px; margin-inline: auto;
  padding: 20px 18px 16px;
  border-radius: 12px;
  corner-shape: squircle;
  background: var(--surface-primary);
  border: 1px solid var(--border-subtle);
  text-align: center;
  box-shadow: 0 18px 40px -22px rgba(0,0,0,0.55);
}
.dlg__icon {
  width: 34px; height: 34px; margin: 0 auto 12px;
  display: grid; place-items: center;
  border-radius: 9px;
  corner-shape: squircle;
  border: 1px solid var(--border-strong);
  color: var(--text-secondary);
  font-size: 1rem; font-weight: 700;
}
.dlg__icon svg { width: 18px; height: 18px; }
.dlg__title { font-size: 0.9rem; font-weight: 650; letter-spacing: -0.01em; }
.dlg__body { font-size: 0.78rem; color: var(--text-secondary); margin-top: 6px; line-height: 1.45; }
.dlg__row { display: flex; gap: 8px; margin-top: 16px; }

.dlg__btn {
  flex: 1 1 0;
  padding: 7px 10px;
  border-radius: 8px;
  corner-shape: squircle;
  font-size: 0.78rem; font-weight: 600;
  border: 1px solid var(--border-strong);
  color: var(--text-secondary);
  background: none;
  white-space: nowrap;
}
/* The one to press. */
.dlg__btn--go {
  background: var(--interactive-fill);
  border-color: var(--interactive-fill);
  color: var(--on-accent);
}
/* The one that deletes the app. Dimmed and labelled rather than coloured —
   the palette is achromatic, so emphasis comes from weight, not hue. */
.dlg__btn--avoid { opacity: 0.4; text-decoration: line-through; }

.dlg__legend {
  display: flex; gap: 8px; margin-top: 8px;
  font-size: 0.66rem; color: var(--text-secondary);
}
.dlg__legend span { flex: 1 1 0; text-align: center; }

/* A System Settings row. */
.pane { background: var(--surface-primary); border: 1px solid var(--border-subtle); border-radius: 10px; corner-shape: squircle; overflow: hidden; }
.pane__head {
  padding: 10px 14px;
  font-size: 0.75rem; font-weight: 650;
  border-bottom: 1px solid var(--border-subtle);
}
.pane__row {
  display: flex; align-items: center; gap: 12px;
  padding: 14px;
}
.pane__row + .pane__row { border-top: 1px solid var(--border-subtle); }
.pane__label { font-size: 0.78rem; color: var(--text-secondary); line-height: 1.45; }
.pane__label b { color: var(--text-primary); font-weight: 600; }
.pane__btn {
  flex: none; margin-left: auto;
  padding: 6px 12px;
  border-radius: 8px;
  corner-shape: squircle;
  font-size: 0.75rem; font-weight: 600;
  background: var(--interactive-fill);
  color: var(--on-accent);
  white-space: nowrap;
}
.pane__field {
  flex: 1 1 auto; min-width: 0;
  padding: 6px 10px;
  border-radius: var(--r-xs);
  corner-shape: squircle;
  border: 1px solid var(--border-strong);
  font-size: 0.75rem;
  color: var(--text-primary);
  background: var(--surface-secondary);
}
.pane__field--empty { color: var(--text-secondary); opacity: 0.6; }
.pane__key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.7rem;
  color: var(--text-secondary);
  word-break: break-all;
}

/* Drag-to-Applications illustration. */
.drag { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 8px 0; }
.drag__item { text-align: center; }
.drag__tile {
  width: 54px; height: 54px; margin: 0 auto 8px;
  display: grid; place-items: center;
  border-radius: 13px;
  corner-shape: squircle;
  border: 1px solid var(--border-strong);
  background: var(--surface-primary);
  color: var(--interactive-foreground);
}
.drag__tile svg { width: 26px; height: 26px; }
.drag__name { font-size: 0.7rem; color: var(--text-secondary); }
.drag__arrow { color: var(--text-secondary); font-size: 1.1rem; padding-bottom: 20px; }

/* A breadcrumb through nested menus: Account → Settings. */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.crumb {
  padding: 6px 11px;
  border-radius: 8px;
  corner-shape: squircle;
  border: 1px solid var(--border-strong);
  font-size: 0.76rem; font-weight: 600;
  color: var(--text-secondary);
}
.crumb--now { background: var(--interactive-fill); border-color: var(--interactive-fill); color: var(--on-accent); }
.crumbs__sep { color: var(--text-secondary); font-size: 0.8rem; }

/* ─────────────  FOOTER  ───────────── */

.footer { border-top: 1px solid var(--border-subtle); padding-block: 48px; }

.footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 30px;
  padding-bottom: 40px;
  margin-bottom: 34px;
  border-bottom: 1px solid var(--border-subtle);
}
.footer__col { display: flex; flex-direction: column; gap: 11px; align-items: flex-start; }
/* The brand column leads, as it does in the reference: mark, wordmark, then
   the one line that says what this is. Wider than a link column. */
.footer__col--brand { gap: 16px; grid-column: span 2; max-width: 34ch; }
.footer__head {
  font-size: 0.6315rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 3px;
}
.footer__col a {
  font-size: 0.875rem; color: var(--text-secondary);
  transition: color 0.14s var(--ease);
}
.footer__col a:hover { color: var(--text-primary); }

.footer__inner { display: flex; flex-wrap: wrap; align-items: center; gap: 18px 32px; }
.footer__note { color: var(--text-secondary); font-size: 0.88rem; line-height: 1.5; }
.footer__legal { color: var(--text-secondary); font-size: 0.8rem; }

/* ─────────────  REVEAL  (§6.4: 240–320ms, once)  ───────────── */

/* Hidden only when JS is present to reveal it again — without this the
   whole page renders at opacity 0 for anyone with scripts off. */
.js .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.js .reveal.is-visible { opacity: 1; transform: none; }

/* ─────────────  RESPONSIVE  ───────────── */

@media (max-width: 940px) {
  /* Guide steps stack — instruction first, then its diagram. */
  .guide__step { grid-template-columns: 1fr; gap: 22px; }

  /* Tabs drop to their own scrollable row rather than being hidden — a phone
     needs the navigation more than a desktop does, not less. */
  .masthead { margin-bottom: -78px; }
  .masthead__inner {
    flex-wrap: wrap;
    height: auto;
    border-radius: 22px;
    padding-block: 11px;
    row-gap: 10px;
    column-gap: 12px;
  }
  .tabs {
    order: 3;
    width: 100%;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { padding: 6px 11px; font-size: 0.78rem; }

  /* The masthead is no longer a fixed 64px, so a sticky sub-nav can't be
     offset against it. Two stacked sticky bars is too much chrome on a phone
     anyway — the sub-nav scrolls away with the content. */
  .subnav { position: static; }
}

@media (max-width: 620px) {
  body { font-size: 17px; }
  .ledger__row { grid-template-columns: 1fr; gap: 6px; }
}

/* ─────────────  ACCESSIBILITY FLOORS  ─────────────
   Reduced motion kills drift, reveals and transforms while keeping every
   state legible through colour and opacity — the app's own rule, and
   non-negotiable per §6.4. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .ambient { animation: none; }
  .js .reveal { opacity: 1; transform: none; }
  .btn:hover { transform: none; }

  /* The hero load sequence holds its finished state rather than running. */
  /* The hero holds its finished story rather than animating toward it. */
  .ticker__track { animation: none; }
  .sheet--app { animation: none; }
  .js .display .display__line { -webkit-mask-image: none; mask-image: none; }
}

@media (forced-colors: active) {
  .grad {
    -webkit-text-fill-color: CanvasText;
    color: CanvasText;
    background: none;
  }
  .appshot__frame, .appshot__askbar { border: 1px solid CanvasText; }
}


/* ─────────────  ASK CADENT — a real exchange, restaged  ─────────────
   The recordings are behavioural reference, not footage: the exchange is
   rebuilt in HTML, in the app's own Ask-panel look, so it stays crisp at any
   size and honest about being a staging. The words, the ordering logic and
   the minutes are the app's own. */

.exchange { margin-top: clamp(36px, 5vw, 56px); max-width: 720px; margin-inline: auto; }
.askdemo__cap { margin-top: 14px; font-size: 0.8rem; color: var(--text-secondary); text-align: center; }

.exchange__frame {
  border-radius: var(--r-panel);
  corner-shape: squircle;
  background: var(--surface-primary);
  box-shadow:
    inset 0 1px 0 var(--glass-rim-top),
    inset 0 0 0 1px var(--glass-rim),
    var(--panel-shadow);
  padding: clamp(20px, 3vw, 34px);
  display: flex; flex-direction: column; gap: 18px;
  text-align: left;
}
.exchange__bubble {
  align-self: flex-end;
  max-width: 75%;
  background: var(--surface-secondary);
  border-radius: var(--r-control);
  corner-shape: squircle;
  padding: 12px 16px;
  font-size: 0.92rem; font-weight: 600;
}
.exchange__answer { max-width: 58ch; }
.exchange__answer p {
  font-size: 0.95rem; line-height: 1.6;
  color: var(--text-primary);
}
.exchange__answer p + p { margin-top: 12px; }
.exchange__searching {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.9rem;
  color: var(--text-secondary);
}
.exchange__searching .beats { width: 16px; height: 16px; }
.exchange__receipt { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
/* The citation chip, as the app draws it under an answer. */
.exchange__cite {
  display: inline-block;
  font-size: 0.78rem; font-weight: 600;
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-xs);
  corner-shape: squircle;
  color: var(--text-primary);
}
.exchange__actions {
  display: flex; gap: 18px;
  font-size: 0.78rem; font-weight: 600;
  color: var(--text-secondary);
}

/* ── The exchange plays the recording's sequence once, on reveal ──
   data-phase: 0 bubble · 1 searching · 2 answer · 3 receipt. Ships parked
   at 3 so no-JS and reduced motion see the finished exchange. */
.exchange__bubble, .exchange__searching, .exchange__answer, .exchange__receipt {
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
}
.js .exchange.is-playing[data-phase="0"] .exchange__searching,
.js .exchange.is-playing[data-phase="0"] .exchange__answer,
.js .exchange.is-playing[data-phase="0"] .exchange__receipt { opacity: 0; }
.js .exchange.is-playing[data-phase="0"] .exchange__answer,
.js .exchange.is-playing[data-phase="0"] .exchange__receipt { display: none; }
.js .exchange.is-playing[data-phase="1"] .exchange__answer,
.js .exchange.is-playing[data-phase="1"] .exchange__receipt { opacity: 0; display: none; }
.js .exchange.is-playing[data-phase="1"] .exchange__searching { opacity: 1; }
.js .exchange.is-playing[data-phase="2"] .exchange__searching { display: none; }
.js .exchange.is-playing[data-phase="2"] .exchange__receipt { opacity: 0; }
.js .exchange[data-phase="3"] .exchange__searching { display: none; }
.js .exchange.is-playing[data-phase="1"] .beats i {
  animation-duration: 1.35s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.js .exchange.is-playing[data-phase="1"] .beats i:nth-child(1) { animation-name: beat-one; }
.js .exchange.is-playing[data-phase="1"] .beats i:nth-child(2) { animation-name: beat-two; }
.js .exchange.is-playing[data-phase="1"] .beats i:nth-child(3) { animation-name: beat-three; }
/* Parked (no-JS, reduced motion, after play): searching row gone. */
.exchange[data-phase="3"] .exchange__searching { display: none; }

/* ─────────────  CANVAS INTELLIGENCE  ─────────────
   What Cadent reads, and the diagram of announcements becoming plan
   changes. A process drawing in the site's language, not an app shot. */

.sources {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 10px;
  margin-top: 30px;
}
.sources li {
  padding: 9px 16px;
  background: var(--surface-primary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-control);
  corner-shape: squircle;
  font-size: 0.85rem; font-weight: 600;
  box-shadow: 0 8px 20px -16px var(--shadow-color);
}

.flow { margin-top: clamp(36px, 5vw, 56px); max-width: 880px; margin-inline: auto; }
.flowrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 88px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}
.flowrow--2 { margin-top: clamp(22px, 3vw, 34px); }

.flow__ann {
  background: var(--surface-primary);
  border-radius: var(--r-row);
  corner-shape: squircle;
  border: 1px solid var(--border-subtle);
  padding: 16px 18px;
  box-shadow: 0 12px 30px -22px var(--shadow-color);
}
.flow__annhead {
  font-size: 0.68rem; font-weight: 700;
  letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: 8px;
}
.flow__anntext { font-size: 0.92rem; line-height: 1.5; }

.flow__link svg { display: block; width: 100%; height: 20px; overflow: visible; }
.flow__wire, .flow__tip {
  fill: none;
  stroke: var(--border-strong);
  stroke-width: 1.6;
  vector-effect: non-scaling-stroke;
  stroke-linecap: round; stroke-linejoin: round;
}

.flow__out {
  background: var(--surface-secondary);
  border-radius: var(--r-row);
  corner-shape: squircle;
  border: 1px solid var(--border-subtle);
  padding: 16px 18px;
}
.flow__outhead { font-size: 0.72rem; font-weight: 700; margin-bottom: 10px; }
.flow__list { display: flex; flex-direction: column; gap: 8px; }
.flow__event, .flow__task {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--surface-primary);
  border-radius: 9px; corner-shape: squircle;
  padding: 8px 12px;
  font-size: 0.78rem; font-weight: 600;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease),
              text-decoration-color 0.5s var(--ease);
}
.flow__event--goes {
  text-decoration: line-through;
  text-decoration-color: var(--text-secondary);
  opacity: 0.45;
}
.flow__task b { font-weight: 600; }
.flow__task i { font-style: normal; font-size: 0.68rem; color: var(--text-secondary); flex: none; }
.flow__verdict {
  margin-top: 12px;
  font-size: 0.74rem; color: var(--text-secondary);
}

/* ── The two scenarios play once, on reveal ──
   Phases: 0 announcement 1 · 1 its outcome · 2 announcement 2 · 3 its
   outcome · 4 done. Ships parked at 4. */
.flow__ann, .flow__out, .flow__verdict {
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.js .flow.is-playing .flow__wire { stroke-dasharray: 130; }
.js .flow.is-playing .flow__tip { transition: opacity 0.3s var(--ease); }

.js .flow.is-playing[data-phase="0"] .flowrow .flow__out,
.js .flow.is-playing[data-phase="0"] .flowrow--2 { opacity: 0; }
.js .flow.is-playing[data-phase="0"] .flow__wire { stroke-dashoffset: 130; }
.js .flow.is-playing[data-phase="0"] .flow__tip { opacity: 0; }

.js .flow.is-playing[data-phase="1"] .flowrow--2 { opacity: 0; }
.js .flow.is-playing[data-phase="1"] .flowrow:not(.flowrow--2) .flow__wire { stroke-dashoffset: 0; transition: stroke-dashoffset 0.6s var(--ease); }
.js .flow.is-playing[data-phase="1"] .flowrow--2 .flow__wire { stroke-dashoffset: 130; }
.js .flow.is-playing[data-phase="1"] .flowrow--2 .flow__tip { opacity: 0; }
.js .flow.is-playing[data-phase="2"] .flowrow--2 .flow__out { opacity: 0; }
.js .flow.is-playing[data-phase="2"] .flowrow--2 .flow__wire { stroke-dashoffset: 130; }
.js .flow.is-playing[data-phase="2"] .flowrow--2 .flow__tip { opacity: 0; }
.js .flow.is-playing[data-phase="3"] .flowrow--2 .flow__wire { stroke-dashoffset: 0; transition: stroke-dashoffset 0.6s var(--ease); }
/* new tasks pop in with the second outcome */
.js .flow.is-playing[data-phase="2"] .flow__task { opacity: 0; transform: translateY(8px); }
.js .flow.is-playing[data-phase="3"] .flow__task--a { transition-delay: 0.15s; }
.js .flow.is-playing[data-phase="3"] .flow__task--b { transition-delay: 0.3s; }

@media (max-width: 700px) {
  .flowrow { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .flow__link { justify-self: center; width: 20px; }
  .flow__link svg { transform: rotate(90deg); height: 20px; width: 36px; }
}

/* ─────────────  SOURCE GRID  ─────────────
   Every place coursework arrives from, each stating what it brings. The
   two unreleased ones are quieter and carry their own label, so the grid
   never implies more than it does. */

.srcgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
  margin-top: clamp(30px, 4vw, 44px);
}
.src {
  background: var(--surface-primary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-row);
  corner-shape: squircle;
  padding: 18px 20px;
  box-shadow: 0 12px 30px -24px var(--shadow-color);
}
.src__name {
  display: flex; align-items: center; gap: 10px;
  font-size: 0.98rem; font-weight: 700;
  letter-spacing: var(--track-title);
}
.src__what {
  margin-top: 8px;
  font-size: 0.85rem; line-height: 1.55;
  color: var(--text-secondary);
  text-wrap: pretty;
}
/* Not here yet, and said so. */
.src--soon {
  background: none;
  box-shadow: none;
  border-style: dashed;
  display: flex; align-items: center;
}
.src--soon .src__name { color: var(--text-secondary); font-weight: 600; }
.src__name em {
  font-style: normal;
  font-size: 0.6rem; font-weight: 700;
  letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-2xs);
  corner-shape: squircle;
  padding: 3px 7px;
}
.srcnote { margin-inline: auto; text-align: center; max-width: 60ch; }

/* ─────────────  BREAKDOWN TREE  ─────────────
   A process diagram in the site's own language — the app has no tree view,
   and this does not pretend to be a screenshot. One assignment at the root,
   timed steps as leaves, and the days they land on. */

.tree { margin-top: clamp(36px, 5vw, 56px); max-width: 760px; margin-inline: auto; }
.tree__root {
  width: max-content; max-width: 100%;
  margin-inline: auto;
  display: flex; align-items: center; gap: 12px;
  background: var(--surface-primary);
  border-radius: var(--r-row);
  corner-shape: squircle;
  padding: 14px 20px;
  box-shadow: inset 0 1px 0 var(--glass-rim-top), inset 0 0 0 1px var(--glass-rim), var(--panel-shadow);
}
.tree__roottitle { font-weight: 700; font-size: 0.98rem; letter-spacing: var(--track-title); }

/* The connectors overlap the cards by a few pixels at both ends, and the
   cards sit above them, so every line visibly meets what it joins instead
   of stopping at the row boundary. */
.tree__branches, .tree__drops {
  display: block; width: 100%; overflow: visible;
  position: relative; z-index: 0;
}
.tree__branches { height: 64px; margin-top: -7px; margin-bottom: -7px; }
.tree__drops { height: 40px; margin-top: -7px; margin-bottom: -7px; }
.tree__root, .leaf, .tree__day { position: relative; z-index: 1; }
.tree__branches path, .tree__drops path {
  fill: none;
  stroke: var(--border-strong);
  stroke-width: 1.6;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.tree__leaves {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}
.leaf {
  background: var(--surface-primary);
  border-radius: var(--r-row);
  corner-shape: squircle;
  border: 1px solid var(--border-subtle);
  padding: 12px 12px 11px;
  text-align: center;
  box-shadow: 0 10px 26px -20px var(--shadow-color);
}
.leaf b { display: block; font-size: 0.8rem; font-weight: 700; letter-spacing: var(--track-title); text-wrap: balance; }
.leaf span { display: block; margin-top: 4px; font-size: 0.72rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.leaf__day { display: none; }

.tree__days {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
}
.tree__day {
  text-align: center;
  font-size: 0.68rem; font-weight: 700;
  letter-spacing: var(--track-micro); text-transform: uppercase;
  color: var(--text-secondary);
  border-top: 2px solid var(--border-subtle);
  padding-top: 8px;
  background: var(--app-background);
}
.tree__day.is-filled { color: var(--text-primary); border-top-color: var(--accent-middle); }

/* Draw-on-reveal. Phases: 0 root · 1 branches · 2 leaves · 3 drops + days.
   Ships parked at 3. */
.tree__root, .leaf, .tree__day { transition: opacity 0.45s var(--ease), transform 0.45s var(--ease); }
/* Dashes exist only while the reveal is playing. At rest the paths are
   plain strokes; a resting dash pattern shorter than the path renders the
   connectors broken, which is exactly the bug this replaces. */
.js .tree.is-playing .tree__branches path,
.js .tree.is-playing .tree__drops path {
  stroke-dasharray: 460;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.7s var(--ease);
}
.js .tree.is-playing[data-phase="0"] .tree__branches path,
.js .tree.is-playing[data-phase="0"] .tree__drops path { stroke-dashoffset: 460; }
.js .tree.is-playing[data-phase="0"] .leaf,
.js .tree.is-playing[data-phase="0"] .tree__day { opacity: 0; transform: translateY(8px); }
.js .tree.is-playing[data-phase="1"] .tree__drops path { stroke-dashoffset: 460; }
.js .tree.is-playing[data-phase="1"] .leaf,
.js .tree.is-playing[data-phase="1"] .tree__day { opacity: 0; transform: translateY(8px); }
.js .tree.is-playing[data-phase="2"] .leaf { opacity: 1; transform: none; }
.js .tree.is-playing[data-phase="2"] .tree__drops path { stroke-dashoffset: 460; }
.js .tree.is-playing[data-phase="2"] .tree__day { opacity: 0; transform: translateY(8px); }
.js .tree.is-playing .leaf--1 { transition-delay: 0.00s; }
.js .tree.is-playing .leaf--2 { transition-delay: 0.09s; }
.js .tree.is-playing .leaf--3 { transition-delay: 0.18s; }
.js .tree.is-playing .leaf--4 { transition-delay: 0.27s; }
.js .tree.is-playing .leaf--5 { transition-delay: 0.36s; }

@media (max-width: 620px) {
  /* On a phone the tree becomes a vertical process: a spine drops from the
     root and branches into each step, and every card carries its own day,
     so the separation still reads as separation. The horizontal SVGs and
     the day strip go with the geometry they described. */
  .tree__branches, .tree__drops, .tree__days { display: none; }

  .tree__root { width: 100%; justify-content: space-between; }

  .tree__leaves {
    position: relative;
    grid-template-columns: 1fr;
    gap: 12px;
    margin-top: 10px;
    padding-top: 6px;
  }
  /* The spine: from under the root down through the last branch point. */
  .tree__leaves::before {
    content: '';
    position: absolute;
    left: 22px; top: -10px; bottom: 34px;
    width: 1.6px;
    background: var(--border-strong);
  }
  .leaf {
    position: relative;
    margin-left: 48px;
    display: flex; align-items: center;
    gap: 10px;
    text-align: left;
  }
  /* Title takes the room; the duration and the day sit together on the
     right, in that order, every row aligned. */
  .leaf b { text-wrap: wrap; flex: 1; }
  .leaf span { margin-top: 0; flex: none; }
  /* The branch: elbow out of the spine, arrowhead into the card. */
  .leaf::before {
    content: '';
    position: absolute;
    left: -26px; top: 50%;
    width: 21px; height: 1.6px;
    background: var(--border-strong);
  }
  .leaf::after {
    content: '';
    position: absolute;
    left: -7px; top: 50%;
    margin-top: -3.5px;
    border-left: 5px solid var(--border-strong);
    border-top: 3.5px solid transparent;
    border-bottom: 3.5px solid transparent;
  }
  /* Each step carries its day. */
  .leaf__day {
    display: inline-block;
    flex: none;
    font-size: 0.6rem; font-weight: 700;
    letter-spacing: var(--track-micro); text-transform: uppercase;
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-2xs);
    corner-shape: squircle;
    text-decoration: none;
    padding: 2px 7px;
  }
}
.exchange__input {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-control);
  corner-shape: squircle;
  padding: 11px 14px;
  font-size: 0.85rem;
  color: var(--text-secondary);
}
.exchange__input b {
  flex: none;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  font-size: 0.7rem;
}

/* ─────────────  EMPTY MEDIA SLOT  ─────────────
   A feature section whose capture has not landed yet renders nothing at all
   rather than a recreation that no longer matches the app. */
.slot:empty { display: none; }
/* script.js injects this element when a media slot's flag is turned on; it
   exists in no HTML file. Pinned to 16:10 so the slot reserves its space
   before the file decodes — a <video preload="none"> otherwise reports a
   300x150 intrinsic size and the page reflows the moment the poster lands. */
.demo__video {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  background: var(--surface-secondary);
}
.slot .demo__video { border-radius: var(--r-major); corner-shape: squircle; }
.slot.has-media {
  margin-top: clamp(30px, 4vw, 48px);
  border-radius: var(--r-major);
  corner-shape: squircle;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  box-shadow: var(--panel-shadow);
}

/* The flagship keeps its prominence without going full-bleed. */
.askdemo { max-width: 860px; margin-inline: auto; }

/* A cited figure carries more weight than the prose around it. */
.stat { font-size: 1.06rem; }
.stat b { color: var(--text-primary); font-weight: 650; }


/* ─────────────  LEGAL DOCUMENTS  ─────────────
   Policy text is read, not scanned. Marketing heading scale is far too loud
   here, and the numbered sections need to sit closer to the prose they own. */
.legal { padding-block: clamp(28px, 3.5vw, 44px) clamp(60px, 8vw, 110px); }
.legal .h2 {
  font-family: var(--font-body);
  font-size: clamp(1.15rem, 1.7vw, 1.35rem);
  font-weight: 650;
  letter-spacing: -0.012em;
  margin-top: clamp(34px, 4vw, 50px);
  margin-bottom: 2px;
}
.legal .shell.narrow > .h2:first-child { margin-top: 0; }
.legal .h3--section { font-family: var(--font-body); font-size: 1rem; margin-top: 26px; }
.legal .body { margin-top: 14px; font-size: 0.97rem; }
.legal .plainlist { margin-top: 14px; }
.legal .plainlist li { padding: 9px 0 9px 20px; font-size: 0.97rem; }
.legal .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; }
