/* ── The Round Robin — Homepage ────────────────────────────────────────────
   Companion to assets/js/home.js, linked by index.html and nothing else.
   Assumes assets/css/tokens.css is already loaded (it defines --bg, --orange,
   --card, --fh/--fd/--fb/--fm, --max, --pad and the --studio/--projection/
   --guide pillar triads).

   This file used to say it duplicated a handful of rules from join.css on
   purpose. join.css was deleted with the /join/ page, so as of 2026-09-09
   these are the sole definitions of the OPEN BETA badge, the proof strip, the seed table, the HoF class list and the Oscars bar
   chart — not copies of anything. Nothing needs reconciling with a twin.

   The --seed-* ramp used to live here too, which meant it resolved to black on
   every page that wasn't index.html. It now lives in tokens.css.
   ──────────────────────────────────────────────────────────────────────── */

/* ── Shared primitives (section frame, buttons, labels) ─────────────────── */
.home-wrap{max-width:var(--max);margin:0 auto;padding-inline:var(--pad)}
.mono{font-family:var(--fm);font-variant-numeric:tabular-nums}
.tnum{font-variant-numeric:tabular-nums}

.home-sec{margin-top:clamp(56px,7vw,96px)}
.home-sec h2{
  margin:0 0 24px;font-family:var(--fb);font-weight:700;line-height:1.08;
  font-size:clamp(28px,3.4vw,40px);color:var(--text);text-wrap:balance;
}
.home-sec__lede{margin:0 0 28px;font-size:15.5px;line-height:1.65;color:var(--sub);max-width:56em}

.home-btn{
  display:inline-flex;align-items:center;gap:.6em;
  /* Geometry realigned to .btn-primary/.btn-ghost in main.css (2026-09-09): this
     was a parallel button system at 15px/.06em/--r-sm/14px 22px. Its hover lift is
     kept -- that gesture is the homepage's, not a divergence. */
  font-family:var(--fd);font-size:var(--t-ui);font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;padding:14px var(--s-5);border-radius: var(--r-md);text-decoration:none;
  border:1px solid var(--border);background:var(--card);color:var(--text);
  cursor:pointer;transition:filter .18s ease,border-color .18s ease,transform .18s ease;
}
.home-btn:hover{filter:brightness(1.12);border-color:var(--studio-border);transform:translateY(-1px)}
.home-btn--primary{background:var(--orange);border-color:var(--orange);color:#01172B}
/* Label colour restated for hover/focus: the sitewide `a:hover, a:focus-visible`
   (0,1,1) outranks .home-btn--primary (0,1,0) and turned the label orange on
   the amber fill. */
.home-btn--primary:hover,.home-btn--primary:focus-visible{border-color:var(--orange);color:#01172B}
.home-btn--ghost{background:transparent}



/* ── Hero: the ring ─────────────────────────────────────────────────────
   Replaced the three rotating line-art scenes (bracket, ballot, stage) on
   2026-09-24. DESIGN_DIRECTION.md §7 rules out decorative brackets, ballots,
   curtains and spotlights, and §9 wants motion that shows a state change; the
   scenes were both. The ring is one set of marks that narrows through each
   decision in turn -- drawn on .hero-ring by home.js ("Hero ring"), which also
   positions the hub counter and the foot, because both sit on the ring's
   centre and the ring's geometry is measured off the copy column at runtime.

   Three layouts, one breakpoint pair shared with home.js's matchMedia calls:
     >=1100  the whole ring sits right of the copy; nothing overlaps the text.
     701-1099  the ring slides part-way off the right edge, behind a scrim.
     <=700  the ring rises from the bottom of the hero below the buttons;
            home.js sets --ring-pad to reserve that room.
   The hub and foot stay display:none until home.js adds .is-ring, so a
   no-JS or failed-script render is the copy alone, never an empty frame. */
.home-hero{background:var(--surface);border-bottom:1px solid var(--border);position:relative;overflow:hidden}
.home-hero__visual{position:relative;min-height:clamp(500px,40vw,580px);display:flex;align-items:center}
/* The scroll-told hero (2026-10-19; replaced the 300vh pinned track of 2026-10-15). With JS and motion allowed,
   home.js adds .is-beats and moves the canvas and hub onto .hero-ring-stage, a sticky layer at the top of the
   hero, with the copy pulled up over it, so the copy and the beats scroll up past it. The
   browser pins it and releases it when the hero ends, so the ring leaves with the hero. overflow:clip, not
   hidden: hidden would make the hero a scroll container and the pin would never hold. 100lvh, not vh/svh,
   so a phone's URL bar showing and hiding never resizes the stage and resets the ring. --nav-h is the
   sticky nav's measured height, set by home.js. */
.home-hero.is-beats{overflow:clip;--stage-h:calc(100vh - var(--nav-h,66px));--stage-h:calc(100lvh - var(--nav-h,66px))}
.hero-ring-stage{position:sticky;top:var(--nav-h,66px);z-index:0;height:var(--stage-h);overflow:hidden;pointer-events:none}
.hero-ring-stage .hero-ring{position:absolute;inset:0;width:100%;height:100%}
/* The copy is pulled up over the stage, rather than the stage given a negative bottom margin: sticky keeps an
   element's margin box inside its container, so a negative margin would hold the ring pinned (and clipped)
   until the hero's bottom edge reached the top of the screen. */
.home-hero.is-beats .home-hero__visual{min-height:calc(100svh - var(--nav-h,66px));margin-top:calc(-1 * var(--stage-h))}
.home-hero.is-ring.is-beats .home-hero__visual::after{display:none}
.home-hero.is-ring.is-beats .hero-ring__foot{display:none}
/* Until the first scroll, say that the ring answers to it. */
.home-hero.is-beats .home-hero__visual::before{
  content:"Scroll to run it \2193";position:absolute;z-index:3;left:0;right:0;bottom:var(--s-5);
  max-width:var(--max);margin:0 auto;padding-inline:var(--pad);transition:opacity .3s ease;
  font-family:var(--fm);font-size:var(--t-label);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
}
.home-hero.is-beats.is-moved .home-hero__visual::before{opacity:0}
@media(max-width:700px){.home-hero.is-beats .home-hero__visual::before{text-align:center}}
.hero-ring{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;z-index:0}
.home-hero__in{max-width:var(--max);width:100%;margin:0 auto;padding:clamp(56px,6vw,88px) var(--pad) clamp(96px,8vw,120px);position:relative;z-index:3}
.home-hero__in > *{max-width:540px}
.home-hero h1{
  font-family:var(--fe);font-weight:600;font-size:clamp(30px,3.6vw,46px);line-height:.98;
  max-width:20ch;margin:0 0 16px;text-wrap:balance;
}
.home-hero h1 em{font-style:italic;color:var(--orange)}
.home-hero__lede{font-size:var(--t-lede);line-height:1.6;color:var(--sub);max-width:36em;margin:0 0 26px}
.home-hero__ctas{display:flex;gap:var(--s-3);flex-wrap:wrap}
.home-hero .home-btn--primary{background:var(--amber);border-color:var(--amber)}
.home-hero .home-btn--ghost{border-color:rgba(240,244,248,.3)}
.home-hero .home-btn--ghost:hover{border-color:var(--amber)}
/* The quiet route past the beats to the forecast stage. Text, not a third button, so How It Works stays the
   one primary action. */
.home-hero__skip{
  display:inline-flex;align-items:center;min-height:44px;margin-top:var(--s-2);
  font-family:var(--fd);font-size:var(--t-ui);font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--sub);text-decoration:underline;text-decoration-color:var(--border);text-underline-offset:5px;
}
.home-hero__skip:hover,.home-hero__skip:focus-visible{color:var(--text);text-decoration-color:var(--orange)}

.hero-ring__hub,.hero-ring__foot{display:none}
.home-hero.is-ring .hero-ring__hub{display:block}
.home-hero.is-ring .hero-ring__foot{display:grid}

/* The counter in the ring's centre. The soft disc behind it keeps the numeral
   legible where the bracket's inner rounds pass underneath. */
.hero-ring__hub{position:absolute;z-index:2;transform:translate(-50%,-50%);width:12em;text-align:center;pointer-events:none}
.hero-ring__hub::before{
  content:"";position:absolute;left:50%;top:50%;width:var(--disc,120px);height:var(--disc,120px);
  transform:translate(-50%,-50%);border-radius:var(--r-circle);z-index:-1;
  background:radial-gradient(closest-side,rgba(6,30,58,.92) 55%,rgba(6,30,58,0) 100%);
}
.hero-ring__hub b{display:block;font-family:var(--fe);font-weight:500;line-height:1;color:var(--text);font-size:var(--hub-size,44px);font-variant-numeric:lining-nums tabular-nums;transition:opacity .3s ease}
.hero-ring__hub span{display:block;margin-top:6px;font-family:var(--fm);font-size:var(--t-label);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);transition:opacity .3s ease}

/* The foot: which decision is playing, how far along, and where to read it. */
.hero-ring__foot{position:absolute;z-index:3;bottom:var(--s-4);transform:translateX(-50%);justify-items:center;gap:var(--s-1);width:max-content;max-width:calc(100% - 32px)}
.hero-ring__pips{display:flex;gap:var(--s-1)}
.hero-ring__pip{
  position:relative;min-height:40px;padding:10px 10px 12px;background:none;border:0;cursor:pointer;
  font-family:var(--fd);font-weight:500;font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
}
.hero-ring__pip:hover{color:var(--sub)}
.hero-ring__pip[aria-current="true"]{color:var(--text)}
.hero-ring__pip:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.hero-ring__pip i{position:absolute;left:10px;right:10px;bottom:4px;height:1px;background:var(--border);overflow:hidden}
.hero-ring__pip i::after{content:"";position:absolute;inset:0;background:var(--orange);transform-origin:left;transform:scaleX(var(--p,0))}
.hero-ring__cap{
  margin:0;display:flex;gap:var(--s-2);flex-wrap:wrap;justify-content:center;transition:opacity .3s ease;
  font-family:var(--fm);font-size:var(--t-label);letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
}
.hero-ring__cap a{color:var(--orange);text-decoration:none;white-space:nowrap}
.hero-ring__cap a:hover{text-decoration:underline}
.hero-ring__hub b.is-fading,.hero-ring__hub span.is-fading,.hero-ring__cap.is-fading{opacity:0}
/* The round seal (2026-10-20): the name set around a circle at the centre of the finished bracket the page
   opens on, with the champion's lit path ending at its orange dot. home.js builds the SVG to the ring's size
   (buildSeal) and sets .is-seal for that opening keyframe only; the counter takes over as the bracket
   rewinds. The backing is a ring, not a disc, so the bracket's last rounds and the champion's path stay
   visible inside it. Hidden in the reduced-motion hero. */
.hero-ring__seal{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);opacity:0;transition:opacity .35s ease;pointer-events:none;line-height:0}
.hero-ring__seal svg{display:block;overflow:visible}
.hero-ring__seal text{font-family:var(--fm);letter-spacing:.3em;text-transform:uppercase;fill:var(--sub)}
.hero-ring__seal-dot{fill:var(--orange)}
.hero-ring__seal-glow{fill:var(--orange);opacity:.18}
.hero-ring__seal-halo{fill:none;stroke:var(--orange);stroke-opacity:.5;stroke-width:1}
.hero-ring__hub.is-seal::before{
  width:var(--seal-d);height:var(--seal-d);
  background:radial-gradient(closest-side,rgba(6,30,58,0) var(--seal-in0),rgba(6,30,58,.92) var(--seal-in),rgba(6,30,58,.92) 86%,rgba(6,30,58,0) 100%);
}
.hero-ring__hub.is-seal .hero-ring__seal{opacity:1}
.hero-ring__hub.is-seal b,.hero-ring__hub.is-seal span{opacity:0}

@media(min-width:701px) and (max-width:1099px){
  .home-hero__in > *{max-width:500px}
  .home-hero.is-ring .home-hero__visual::after{
    content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(100deg,rgba(6,30,58,.95) 0%,rgba(6,30,58,.88) 42%,rgba(6,30,58,.35) 62%,rgba(6,30,58,.1) 80%);
  }
}

/* ── The path: Learn -> Model -> Build ──────────────────────────────────
   One rule with three round stops, not three cards (2026-09-24). The rule's
   gradient runs through the three pillar colours in order, and it draws left
   to right when the section reveals; each stop's node fills as the line
   reaches it. Stacks vertically under 700px, with the rule running down the
   left edge. Without JS (no .js-reveals) everything renders drawn and filled. */
.home-path{
  --node:17px;position:relative;list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-6);
}
.home-path::before{
  content:"";position:absolute;left:0;right:0;top:calc(var(--node) / 2);height:1px;
  background:linear-gradient(90deg,var(--guide),var(--projection) 50%,var(--studio));
  transform-origin:left center;
}
.home-path__stop{position:relative;padding-top:calc(var(--node) + var(--s-5));display:flex;flex-direction:column;min-width:0}
.home-path__stop--guides{--k:var(--guide)}
.home-path__stop--forecasts{--k:var(--projection)}
.home-path__stop--studios{--k:var(--studio)}
.home-path__node{
  position:absolute;top:0;left:0;width:var(--node);height:var(--node);border-radius:var(--r-circle);
  border:2px solid var(--k);background:var(--k);box-sizing:border-box;
}
.home-path__name{margin:0;font-family:var(--fe);font-weight:600;font-size:clamp(24px,2.4vw,30px);line-height:1.08;color:var(--text)}
.home-path__sub{margin:var(--s-2) 0 var(--s-3);font-family:var(--fb);font-size:var(--t-strong);font-weight:500;line-height:1.4;color:var(--text)}
.home-path__stop > p:not(.home-path__sub){margin:0;font-size:var(--t-body);line-height:1.65;color:var(--sub);flex:1;max-width:36ch}
.home-path__cta{
  margin-top:var(--s-4);align-self:flex-start;display:inline-flex;align-items:center;gap:5px;
  font-family:var(--fd);font-size:var(--t-ui);font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--orange);text-decoration:none; /* one link colour; --k stays on the path's rule and nodes */
}
.home-path__cta:hover{filter:var(--hover-lift)}
.home-path__cta:focus-visible{outline:2px solid var(--k);outline-offset:3px}
/* The one link off the path to the long-form explainer (/how-it-works/). */
.home-path__more{margin:var(--s-6) 0 0;font-size:var(--t-body)}
.home-path__more a{display:inline-flex;align-items:center;gap:5px;color:var(--sub);text-decoration:none;border-bottom:1px solid var(--border)}
.home-path__more a:hover,.home-path__more a:focus-visible{color:var(--text);border-bottom-color:var(--orange)}

/* The draw: armed only when home.js has confirmed it will reveal the section. */
.js-reveals .home-path-sec[data-reveal] .home-path::before{transform:scaleX(0);transition:transform 1.3s cubic-bezier(.3,.7,.2,1) .15s}
.js-reveals .home-path-sec[data-reveal] .home-path__node{background:var(--bg);transition:background .35s ease}
.js-reveals .home-path-sec[data-reveal] .home-path__stop--guides .home-path__node{transition-delay:.2s}
.js-reveals .home-path-sec[data-reveal] .home-path__stop--forecasts .home-path__node{transition-delay:.8s}
.js-reveals .home-path-sec[data-reveal] .home-path__stop--studios .home-path__node{transition-delay:1.35s}
.js-reveals .home-path-sec[data-reveal].is-revealed .home-path::before{transform:none}
.js-reveals .home-path-sec[data-reveal].is-revealed .home-path__node{background:var(--k)}

@media(max-width:700px){
  .home-path{grid-template-columns:minmax(0,1fr);gap:var(--s-6)}
  /* Stacked, the rule runs node to node in two segments, so it ends at the
     last stop instead of running on past its text. */
  .home-path::before{display:none}
  .home-path__stop{padding-top:0;padding-left:calc(var(--node) + var(--s-4))}
  .home-path__node{top:2px}
  .home-path__stop:not(:last-child)::after{
    content:"";position:absolute;left:calc(var(--node) / 2);width:1px;
    top:calc(2px + var(--node) / 2);bottom:calc(-1 * var(--s-6) - 2px - var(--node) / 2);
    transform-origin:center top;
  }
  .home-path__stop--guides::after{background:linear-gradient(180deg,var(--guide),var(--projection))}
  .home-path__stop--forecasts::after{background:linear-gradient(180deg,var(--projection),var(--studio))}
  .js-reveals .home-path-sec[data-reveal] .home-path__stop::after{transform:scaleY(0);transition:transform .7s cubic-bezier(.3,.7,.2,1) .2s}
  .js-reveals .home-path-sec[data-reveal] .home-path__stop--forecasts::after{transition-delay:.85s}
  .js-reveals .home-path-sec[data-reveal].is-revealed .home-path__stop::after{transform:none}
}
@media(prefers-reduced-motion:reduce){
  .js-reveals .home-path-sec[data-reveal] .home-path::before,
  .js-reveals .home-path-sec[data-reveal] .home-path__stop::after,
  .js-reveals .home-path-sec[data-reveal] .home-path__node{transition:none}
}

/* ── Mobile hero ───────────────────────────────────────────────────────── */
.home-hero__lede--short{display:none}
@media(max-width:700px){
  .home-hero__visual{min-height:0;align-items:flex-start}
  /* Trimmed 2026-09-14 (TickTick: "Recompose the homepage from premise into
     the next live decision") so a real forecast signal below shows up
     sooner. Every cut here is spacing, not content. */
  .home-hero__in{padding:28px var(--pad) 20px}
  /* Room for the ring to rise from the bottom edge; home.js sizes it. */
  .home-hero.is-ring .home-hero__in{padding-bottom:var(--ring-pad,300px)}
  .home-hero.is-ring .home-hero__visual::after{
    content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(180deg,rgba(6,30,58,.9) 0%,rgba(6,30,58,.72) 48%,rgba(6,30,58,.2) 72%,rgba(6,30,58,0) 100%);
  }
  .home-hero h1{font-size:clamp(30px,7.4vw,46px)}
  /* Full lede reads to 6 lines here and used to be line-clamped to 3, which
     cut it off mid-word. A lede authored to land on a sentence boundary at 3
     lines beats clamping the long one; the full copy stays in the DOM. */
  .home-hero__lede--full{display:none}
  .home-hero__lede--short{
    display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;
    font-size:var(--t-read);line-height:1.5;margin-bottom:18px;-webkit-line-clamp:3;
  }
  .home-hero__ctas{gap:var(--s-3)}
  .hero-ring__pip{padding:10px 7px 12px;font-size:var(--t-label)}
}
/* Two auto-width buttons wrap to a ragged second row well before this, so
   stack them full-width and centre the labels instead. */
@media(max-width:560px){
  .home-hero__ctas{flex-direction:column;align-items:stretch;gap:var(--s-2)}
  .home-hero .home-btn{justify-content:center}
  .home-hero__skip{display:flex;justify-content:center}
}

/* ── Decision beats ─────────────────────────────────────────────────────
   Static (no JS, reduced motion): a three-column strip under the hero. With .is-beats each beat takes most
   of a screen in the copy column and scrolls up past the fixed ring, which plays that decision as it goes.
   No box around them: the ring's hub carries the number and the text sits on the page (DESIGN_DIRECTION §7). */
.home-beats{
  list-style:none;margin:0 auto;padding:var(--s-6) var(--pad);max-width:var(--max);
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-6);
}
.home-beat__h{margin:0 0 var(--s-3);font-family:var(--fe);font-weight:600;font-size:clamp(24px,2.4vw,30px);line-height:1.08;color:var(--text);text-wrap:balance}
.home-beat p{margin:0;font-size:var(--t-body);line-height:1.65;color:var(--sub);max-width:40ch}
.home-beat__cta{
  margin-top:var(--s-4);display:inline-flex;align-items:center;gap:5px;min-height:44px;
  font-family:var(--fd);font-size:var(--t-ui);font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--orange);text-decoration:none;
}
.home-beat__cta:hover{filter:var(--hover-lift)}
@media(max-width:700px){.home-beats{grid-template-columns:minmax(0,1fr)}}

/* The bottom padding is the rest after Best Picture: the winner lands, then the hero ends and the ring leaves. */
.home-hero.is-beats .home-beats{display:block;padding-block:0 55vh}
.home-hero.is-beats .home-beat{min-height:90vh;display:flex;align-items:center}
.home-hero.is-beats .home-beat__in{max-width:440px;position:relative;z-index:3}
.home-hero.is-beats .home-beat__h{font-size:clamp(30px,3.4vw,44px);line-height:1}
.home-hero.is-beats .home-beat p{font-size:var(--t-lede);line-height:1.6;color:var(--text);opacity:.86}
@media(min-width:701px) and (max-width:1099px){.home-hero.is-beats .home-beat__in{max-width:380px}}
/* Phones: the ring holds in the top half, so the beats pass under it on a band of page colour. */
@media(max-width:700px){
  .home-hero.is-beats .home-beat{min-height:80vh}
  .home-hero.is-beats .home-beat__in{
    max-width:none;margin-inline:calc(-1 * var(--pad));padding:var(--s-6) var(--pad);
    background:linear-gradient(180deg,rgba(1,23,43,0),rgba(1,23,43,.9) 18%,rgba(1,23,43,.9) 82%,rgba(1,23,43,0));
  }
}

/* ── "Who's behind it" ───────────────────────────────────────────────────
   Reuses join.css's .join-about component verbatim (this is the same kind
   of content — the site's one-person, AI-assisted origin story — so there's
   no reason to invent a second version of this card). Only the rules this
   page actually uses are duplicated here (no .join-about-logo or
   .join-about-callout, since this page's markup doesn't call for either). */
.join-about{
  margin-top:clamp(56px,7vw,96px);padding:clamp(32px,4vw,48px) 0 clamp(56px,7vw,96px);
  border-top:1px solid var(--border);
}
.join-about-grid{display:flex;flex-wrap:wrap;gap:clamp(24px,4vw,64px);align-items:flex-start}
.join-about-copy{flex:1 1 320px;min-width:min(100%,300px)}
.join-about-copy h2{margin:0 0 16px;font-family:var(--fb);font-size:clamp(26px,3vw,36px);font-weight:700;line-height:1.1;color:var(--text)}
.join-about-copy>p{margin:0 0 14px;font-size:14.5px;line-height:1.75;color:var(--sub);max-width:560px}
.join-about-email{font-family:var(--fd);font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--orange);text-decoration:none;display:inline-flex;align-items:center;gap:5px}
.join-about-stats{flex:0 1 300px;min-width:min(100%,260px);display:flex;flex-direction:column}
.join-about-stat{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:14px 0;border-bottom:1px solid var(--border)}
.join-about-stat:last-child{border-bottom:none}
.join-about-stat span:first-child{font-family:var(--fd);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.join-about-stat span:last-child{font-family:var(--fm);font-size:18px;font-weight:700;color:var(--text)}
@media(max-width:900px){.join-about-grid{gap:24px}}


/* ── Live decision stage ───────────────────────────────────────────────── */
.call-cards-sec{padding:clamp(28px,3.4vw,44px) 0 clamp(40px,5vw,52px)}
/* The eyebrow/rule/headline stack these three sections used to share is gone —
   see the comments in _includes/home-call-band.html and index.html. What's left
   is one heading per section that has something to say, and no label over it. */
.call-h2{font-family:var(--fd);font-size:22px;font-weight:600;text-transform:uppercase;color:var(--text);margin:0 0 24px}

.call-card{
  display:flex;flex-direction:column;gap:18px;background:var(--card);
  border:1px solid var(--border);border-radius: var(--r-lg);padding: var(--s-5);height:100%;
  transition:border-color .15s ease;
}
.call-card:hover{border-color:rgba(255,119,4,.4)}

.call-card-head{display:flex;flex-direction:column;gap:12px}
.call-card-toprow{display:flex;align-items:center;justify-content:space-between;gap:10px}
.call-card-cat{font-family:var(--fb);font-size:22px;font-weight:700;line-height:1.15;color:var(--text)}
.call-badge{font-family:var(--fd);font-size:11px;font-weight:500;letter-spacing:.05em;color:var(--sub);
  background:var(--surface);border:1px solid var(--border);border-radius: var(--r-sm);padding:3px 9px;white-space:nowrap}
.call-badge--amber{color:var(--amber);background:rgba(232,135,43,.13);border-color:rgba(232,135,43,.3)}
.call-phase{font-family:var(--fm);font-size:11px;color:var(--orange);border:1px solid rgba(255,119,4,.35);
  border-radius: var(--r-sm);padding:4px 9px;align-self:flex-start;text-transform:uppercase;letter-spacing:.06em}

/* The bracket card's live-rendered body (the inline script writes the chart in). */
.call-rows{display:flex;flex-direction:column;justify-content:center;gap:20px;flex:1}
.call-loading{font-family:var(--fb);font-size:13px;color:var(--muted);padding:6px 0}

/* Required by TMDB's API terms wherever their art renders. */
.call-tmdb{font-size:var(--t-micro);color:var(--muted);padding-top:5px}
.call-tmdb a{color:var(--muted);text-decoration:underline}
.call-tmdb a:hover{color:var(--text)}
.call-footnote{font-family:var(--fm);font-size:var(--t-label);color:var(--muted);padding-top:9px}

.call-foot{margin-top:auto;border-top:1px solid var(--border);padding-top:15px;display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
.call-cta{display:inline-flex;align-items:center;min-height:32px;font-family:var(--fd);font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--orange);text-decoration:none;transition:color .15s ease}
.call-cta:hover{color:var(--amber)}
.call-foot-record{font-family:var(--fm);font-size:var(--t-label);color:var(--muted)}
/* The card's record and its data date share the foot's right side, date on top.
   Stacked rather than inline because the two are different kinds of claim — one
   is how the model has done, the other is when this card last moved. */
.call-foot-meta{display:flex;flex-direction:column;align-items:flex-end;gap:2px;text-align:right;white-space:nowrap}
.call-stamp{font-size:var(--t-label);color:var(--muted)}
.call-stamp:empty{display:none}
/* A stale card states it in words as well as colour (the script appends "· not
   refreshed since"), so this is reinforcement, never the only signal. */
.call-stamp.is-stale{color:var(--orange)}

/* The record sheet — the only accuracy content above the footer, and the page's
   one light surface (tokens --paper/--ink; DESIGN_DIRECTION.md §12). Square, no
   shadow: a printed sheet laid on the dark page, not a floating card. */
.call-record-sec{
  margin-top:clamp(28px,4vw,48px);padding:clamp(24px,3.4vw,40px);
  background:var(--paper);color:var(--ink);border-top:3px solid var(--ink);
  display:grid;grid-template-columns:minmax(0,260px) minmax(0,1fr);gap:var(--s-6);align-items:start;
}
.call-record-left{display:flex;flex-direction:column;gap:var(--s-2)}
.call-record-h2{font-family:var(--fe);font-weight:600;font-size:28px;line-height:1.05;letter-spacing:0;text-transform:none;color:var(--ink);margin:0}
.call-record-sub{margin:0;font-family:var(--fb);font-size:var(--t-body);line-height:1.5;color:var(--paper-sub)}
.call-record-cta{
  margin-top:var(--s-3);align-self:flex-start;font-family:var(--fd);font-size:var(--t-meta);font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink);text-decoration:none;border-bottom:1px solid var(--ink);
}
.call-record-cta:hover{color:var(--paper-sub);border-color:var(--paper-sub)}
.call-record-cta:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.call-record-stats{margin:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.call-record-stat{display:flex;flex-direction:column;gap:var(--s-1);padding:0 var(--s-4);border-left:1px solid var(--paper-rule)}
.call-record-stat dd{margin:0}
.call-record-label{order:2;font-family:var(--fd);font-size:var(--t-label);letter-spacing:.12em;text-transform:uppercase;color:var(--paper-sub)}
.call-record-value{order:1;font-size:30px;font-weight:600;line-height:1.1;color:var(--ink);font-variant-numeric:tabular-nums}
.call-record-scope{order:3;font-family:var(--fm);font-size:var(--t-label);line-height:1.45;color:var(--paper-sub)}
@media(max-width:1099px){
  .call-record-sec{grid-template-columns:minmax(0,1fr);gap:var(--s-5)}
}
@media(max-width:700px){
  .call-record-stats{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:var(--s-5)}
  .call-record-stat:nth-child(odd){border-left:0;padding-left:0}
}

/* ── Visual decision stage ───────────────────────────────────────────────
   The earlier .call-* rules remain the typography and data-row primitives.
   This layer sets the composition: one decision owns the stage, and the
   other two are text tabs above it. Opened up 2026-09-24 -- no box, fill or
   tab column any more; the tabs sit on a rule the way the hero's pips do,
   and the chart sits straight on the page. */
.call-stage{display:block}
/* Target of the hero's See the current forecasts link: clear the sticky nav (taller than 66px on phones),
   and take focus without a ring, since it is a landing region and not a control. */
#call-stage{scroll-margin-top:calc(var(--nav-h,66px) + 40px)}
#call-stage:focus{outline:none}
/* Arriving by that link, skip the band's entrance: the browser measures the jump while the reveal transform
   still offsets the band, and on phones the stage then slid up under the nav. */
.js-reveals .call-band[data-reveal]:has(#call-stage:target),
.js-reveals .call-band[data-reveal]:has(#call-stage:target) .call-stage{opacity:1;transform:none;transition:none}
/* Featured decision + two teasers (2026-10-20, replacing the text tabs). The
   teasers hang off a rule, not a box: DESIGN_DIRECTION.md §7, a boundary only
   where there is a real object. Stacked under the feature below 1000px. */
.call-stage{display:grid;grid-template-columns:minmax(0,1fr) 248px;gap:var(--s-6);align-items:start}
.call-teasers{display:flex;flex-direction:column;border-left:1px solid var(--border);padding:clamp(24px,3vw,40px) 0 0 var(--s-5)}
.call-teaser{
  display:flex;flex-direction:column;gap:var(--s-2);width:100%;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--border);padding:var(--s-4) 0;cursor:pointer;color:var(--sub);
}
.call-teaser:first-child{padding-top:0}
.call-teaser[hidden]{display:none}
.call-teaser-top{display:flex;justify-content:space-between;gap:var(--s-2);font-family:var(--fd);font-size:var(--t-label);
  letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.call-teaser-top strong{font-weight:500;color:var(--sub)}
.call-teaser-line{font-family:var(--fe);font-size:var(--t-lede);line-height:1.22;color:var(--sub);text-wrap:balance;transition:color .15s ease}
.call-teaser-stamp{font-size:var(--t-label);color:var(--muted)}
.call-teaser-stamp:empty{display:none}
.call-teaser-go{font-family:var(--fd);font-size:var(--t-label);font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--orange)}
.call-teaser:hover .call-teaser-line{color:var(--text)}
.call-teaser:focus-visible{outline:2px solid var(--orange);outline-offset:4px}
.call-switch-settings{
  align-self:flex-start;margin-top:var(--s-4);font-family:var(--fd);font-size:var(--t-label);font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;text-decoration:none;color:var(--muted);
}
.call-switch-settings:hover{color:var(--amber)}
.call-card h3:focus{outline:none}
.call-when{font-family:var(--fm);font-size:var(--t-label);color:var(--muted)}
@media(max-width:999px){
  .call-stage{grid-template-columns:minmax(0,1fr);gap:var(--s-5)}
  .call-teasers{border-left:0;border-top:1px solid var(--border);padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:var(--s-5)}
  .call-teaser,.call-teaser:first-child{padding:var(--s-4) 0}
  .call-switch-settings{grid-column:1/-1;margin-top:var(--s-2)}
}
/* Phones: the other two decisions sit ABOVE the featured card as a slim two-up
   row, so they aren't 1,300px down past the whole chart (Grant, 2026-10-20). */
@media(max-width:600px){
  .call-stage{gap:var(--s-4)}
  .call-teasers{order:-1;border-top:0;border-bottom:1px solid var(--border);column-gap:var(--s-4)}
  .call-teaser,.call-teaser:first-child{gap:var(--s-1);padding:var(--s-3) 0;border-bottom:0}
  .call-teaser-line{font-size:var(--t-strong);line-height:1.25}
  .call-teaser-top{flex-direction:column;gap:var(--s-1)}
  .call-switch-settings{grid-column:1/-1;margin:0 0 var(--s-3)}
}

.call-cards{display:block;min-width:0}
.call-card{
  display:none;min-height:560px;height:100%;padding:clamp(24px,3vw,40px) 0 0;
  gap:var(--s-5);background:transparent;border:0;border-radius:0;
}
.call-card[data-decision="bracket"]{min-height:520px}
.call-card[hidden]{display:none}
.call-card.is-active{display:flex;animation:call-stage-in .24s ease both}
@keyframes call-stage-in{from{opacity:.35;transform:translateX(8px)}to{opacity:1;transform:none}}
.call-card:hover{border-color:transparent}
.call-card-head{gap:var(--s-3)}
.call-card-head .call-phase{font-size:var(--t-label);letter-spacing:.06em}
.call-card-cat{margin:0;font-size:clamp(25px,2.4vw,34px);letter-spacing:-.02em}
.call-card-toprow{align-items:flex-start}
.call-badge{margin-top:2px}
.call-phase{border:0;padding:0;color:var(--muted)}
/* Men's / Women's: the two published bracket tracks share one card. */
.call-sport{display:inline-flex;align-self:flex-start;gap:var(--s-1);margin-top:var(--s-1);padding:2px;
  border:1px solid var(--border);border-radius:var(--r-pill)}
.call-sport[hidden]{display:none}
.call-sport-btn{font-family:var(--fd);font-size:var(--t-label);font-weight:500;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);background:none;border:0;border-radius:var(--r-pill);padding:6px 14px;min-height:32px;cursor:pointer}
.call-sport-btn:hover{color:var(--sub)}
.call-sport-btn[aria-pressed="true"]{color:var(--text);background:rgba(255,119,4,.14)}
.call-sport-btn:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.call-foot-record[hidden]{display:none}

/* ── The spread: the Hall of Fame view (direction B, 2026-10-20) ─────────
   A Cleveland dot plot on one honest axis. Square marks per CHART_STYLE.md §2;
   amber = inside a full class, steel = outside it; a translucent band carries
   the top group, and the gap under it is the claim. */
.call-kicker{display:flex;flex-wrap:wrap;justify-content:space-between;gap:var(--s-1) var(--s-4);
  font-family:var(--fd);font-size:var(--t-label);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.call-kicker strong{font-weight:500;color:var(--text)}
.call-kicker .call-when{font-family:var(--fd);letter-spacing:.08em;color:var(--sub)}
.call-finding{font-family:var(--fe);font-weight:500;font-size:clamp(27px,3vw,38px);line-height:1.08;letter-spacing:-.01em;
  color:var(--text);margin:0;max-width:24ch;text-wrap:balance}
.call-dek{margin:calc(var(--s-2) * -1) 0 0;max-width:62ch;font-size:var(--t-body);line-height:1.55;color:var(--sub)}
.call-dek[hidden]{display:none}
.call-spread{display:flex;flex-direction:column;margin-top:var(--s-2)}
.call-dot-row,.call-dot-axis,.call-gap,.call-dot-head{display:grid;grid-template-columns:150px minmax(0,1fr) 40px 44px;column-gap:var(--s-3);align-items:center}
.call-dot-head{padding-bottom:var(--s-2);font-family:var(--fd);font-size:var(--t-label);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.call-dot-head span:nth-child(n+3){text-align:right}
.call-dot-year{font-size:var(--t-meta);text-align:right;color:var(--muted)}
.call-dot-row:not(.is-out) .call-dot-year{color:var(--orange)}
/* HoFW 100 = the average Hall of Famer at the position: the model's own bar, drawn
   as a quiet dashed rule through every row. Never a vote threshold. */
.call-dot-ref{position:absolute;top:0;bottom:0;border-left:1px dashed var(--dv-comparison);opacity:.7}
.call-dot-ticks span.is-ref{color:var(--sub)}
.call-axis-key{display:inline-block;width:0;height:11px;border-left:1px dashed var(--dv-comparison);margin-right:var(--s-2);vertical-align:-1px}
.call-dot-row{min-height:34px;width:100%;padding:0;background:none;border:0;text-align:left;cursor:pointer;color:var(--sub)}
.call-dot-name{font-family:var(--fc);font-size:var(--t-body);font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.call-dot-track{position:relative;align-self:stretch;border-left:1px solid var(--border)}
.call-dot-track::after{content:"";position:absolute;left:0;right:0;top:50%;border-top:1px dotted var(--border)}
.call-dot{position:absolute;top:50%;width:10px;height:10px;margin:-5px 0 0 -5px;background:var(--amber);z-index:1}
.call-dot-val{font-size:var(--t-ui);text-align:right;color:var(--text)}
.call-dot-row.is-out .call-dot{background:var(--dv-comparison)}
.call-dot-row.is-out .call-dot-name,.call-dot-row.is-out .call-dot-val{color:var(--muted)}
.call-dot-row:hover .call-dot-name,.call-dot-row[aria-pressed="true"] .call-dot-name{color:var(--text)}
.call-dot-row[aria-pressed="true"] .call-dot{outline:2px solid var(--orange);outline-offset:2px}
.call-dot-row:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
/* The gap, drawn as the distance it names: a bracket from the first name out
   to the last seat in, label hung under its right end. */
.call-gap{min-height:34px}
.call-gap-name{font-family:var(--fd);font-size:var(--t-label);letter-spacing:.08em;text-transform:uppercase;color:var(--orange);white-space:nowrap}
.call-gap-track{grid-column:2;position:relative;align-self:stretch}
/* The class line itself, across the track; the gap bracket hangs from it. */
.call-gap-track::before{content:"";position:absolute;left:0;right:0;top:2px;border-top:1px solid var(--orange);opacity:.55}
.call-gap-span{position:absolute;top:2px;padding-top:11px;display:flex;justify-content:center;
  font-size:var(--t-label);line-height:1.2;color:var(--orange);white-space:nowrap}
.call-gap-span::before{content:"";position:absolute;left:0;right:0;top:0;height:6px;border:1px solid var(--orange);border-top:0}
.call-dot-ticks{grid-column:2;position:relative;height:22px;border-top:1px solid var(--border);
  font-family:var(--fm);font-size:var(--t-mini);color:var(--muted)}
.call-dot-ticks span{position:absolute;top:5px;transform:translateX(-50%)}
.call-dot-ticks span:first-child{transform:none}
.call-dot-ticks span:last-child{transform:translateX(-100%)}
/* The Oscars range strip: same rows, dots and draw-in, plus a poster thumb and
   the model's range drawn at the same weight as the point (its overlap is the
   finding). Steel, translucent, dotted edge: CHART_STYLE.md's low-confidence
   treatment, never red. */
.call-spread--osc .call-dot-row,.call-spread--osc .call-dot-axis,.call-spread--osc .call-gap,.call-spread--osc .call-dot-head{
  grid-template-columns:20px 170px minmax(0,1fr) 52px}
.call-spread--osc .call-dot-row{min-height:34px;padding-block:2px}
.call-spread--osc .call-dot-name{white-space:normal;line-height:1.15}
.call-spread--osc .call-dot-ticks,.call-spread--osc .call-gap-track{grid-column:3}
.call-spread--osc .call-gap-name{grid-column:2}
.call-osc-thumb{display:block;width:20px;height:30px;object-fit:cover;border-radius:2px;background:var(--surface)}
.call-osc-range,.call-osc-key{position:absolute;top:50%;height:10px;margin-top:-5px;
  background:rgba(92,122,158,.22);border:1px dotted var(--dv-comparison);border-radius:2px}
.call-osc-key{position:relative;display:inline-block;top:auto;margin:0 var(--s-2) 0 0;width:22px;height:8px;vertical-align:0}
.call-card.is-drawing .call-osc-range{animation:call-fade-in .5s ease both;animation-delay:calc(var(--i,0) * 45ms)}
/* The bracket seed-vs-rank chart: 16 seed-line rows plus an "out" row, each
   team a square at its rank (log scale). Squares wear the seed ramp (CHART_STYLE.md
   section 3: the seed and its colour never disagree); hollow = in on an automatic
   bid alone; orange ring = my last four in. Each row's shaded span is where that
   line would rank by the ranking alone. */
.call-bk{display:flex;flex-direction:column;margin-top:var(--s-2)}
.call-bk-row,.call-bk-axis,.call-bk-cut{display:grid;grid-template-columns:34px minmax(0,1fr);column-gap:var(--s-3);align-items:center}
.call-bk-row{min-height:42px}
.call-bk-row.is-bubble{background:linear-gradient(90deg,rgba(232,135,43,.10),transparent 80%)}
.call-bk-row.is-out{margin-top:var(--s-1)}
.call-bk-seed{font-size:var(--t-meta);text-align:center;color:var(--text);border-left:3px solid var(--seed);padding:1px 0}
.call-bk-row.is-out .call-bk-seed{border-left:1px dashed var(--dv-comparison);color:var(--muted)}
.call-bk-track{position:relative;align-self:stretch;border-left:1px solid var(--border)}
.call-bk-track::after{content:"";position:absolute;left:0;right:0;top:50%;border-top:1px dotted var(--border)}
.call-bk-span{position:absolute;top:4px;bottom:4px;background:rgba(92,122,158,.22);border-radius:2px}
.call-bk-pt{position:absolute;top:calc(50% + var(--dy,0px));width:20px;height:20px;margin:-10px 0 0 -10px;padding:2px;border:0;border-radius:50%;cursor:pointer;z-index:1;
  background:rgba(255,255,255,.92);box-sizing:border-box}
.call-bk-pt img{display:block;width:100%;height:100%;object-fit:contain}
/* No logo (or it failed to load): the plain amber square the chart used before. */
.call-bk-pt.is-noimg{width:10px;height:10px;margin:-5px 0 0 -5px;padding:0;border-radius:0;background:var(--amber)}
.call-bk-pt.is-bid{opacity:.6;outline:1.5px dashed var(--dv-comparison);outline-offset:1px}
.call-bk-pt.is-l4{outline:2px solid var(--orange);outline-offset:1px}
.call-bk-row.is-out .call-bk-pt{opacity:.75;outline:1.5px dashed var(--dv-comparison);outline-offset:1px}
.call-bk-pt:hover,.call-bk-pt[aria-pressed="true"]{outline:2px solid var(--text);outline-offset:2px}
.call-bk-pt:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.call-bk-cut{min-height:16px}
.call-bk-cut-line{position:relative;border-top:1px solid var(--orange);opacity:.8}
.call-bk-cut-line b{position:absolute;right:0;top:2px;font-family:var(--fd);font-weight:500;font-size:var(--t-label);letter-spacing:.08em;text-transform:uppercase;color:var(--orange)}
.call-bk-axis .call-dot-ticks{grid-column:2}
.call-bk-key{display:inline-block;width:10px;height:10px;margin:0 var(--s-1) 0 var(--s-2);vertical-align:-1px;border-radius:50%;background:rgba(255,255,255,.92)}
.call-bk-key.is-bid{opacity:.6;outline:1.5px dashed var(--dv-comparison);outline-offset:1px}
.call-bk-key.is-l4{outline:2px solid var(--orange);outline-offset:1px}
.js-reveals .call-stage:not(.is-drawn) .call-bk-pt{opacity:0}
.call-card.is-drawing .call-bk-pt{animation:call-dot-in .5s ease both;animation-delay:calc(var(--i,0) * 35ms + 100ms)}
.call-axis-note{margin:0;font-family:var(--fc);font-size:var(--t-label);color:var(--muted)}
.call-detail{margin:0;min-height:44px;padding-top:var(--s-3);border-top:1px solid var(--border);
  font-size:var(--t-ui);line-height:1.5;color:var(--sub)}
.call-detail strong{color:var(--text);font-weight:600}
.call-rule{margin:0;display:flex;gap:var(--s-3);align-items:baseline;font-size:var(--t-ui);line-height:1.5;color:var(--muted)}
.call-rule-label{flex:0 0 auto;font-family:var(--fd);font-size:var(--t-label);letter-spacing:.08em;text-transform:uppercase;color:var(--sub)}
.call-ctas{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-2) var(--s-5)}
.call-cta--primary{color:var(--ink);background:var(--amber);padding:0 var(--s-4);border-radius:var(--r-sm)}
.call-cta--primary:hover{color:var(--ink);filter:var(--hover-lift)}
@media(max-width:600px){
  .call-dot-row,.call-dot-axis,.call-gap,.call-dot-head{grid-template-columns:116px minmax(0,1fr) 26px 34px;column-gap:var(--s-2)}
  .call-gap-name{white-space:normal;line-height:1.15}
  .call-spread--osc .call-dot-row,.call-spread--osc .call-dot-axis,.call-spread--osc .call-gap,.call-spread--osc .call-dot-head{
    grid-template-columns:20px 112px minmax(0,1fr) 44px}
  .call-dot-name{font-size:var(--t-ui)}
  .call-dot-val{font-size:var(--t-meta)}

  .call-foot{flex-direction:column;align-items:flex-start}
  .call-foot-meta{align-items:flex-start;text-align:left;white-space:normal}
}

/* Draw-in: the dots travel in from the axis's left edge, staggered, once when
   the stage is first on screen and again when a teaser promotes a decision
   (home.js setupDecisionStage). .js-reveals holds them only until the first
   draw; reduced motion and no-IntersectionObserver render the finished chart. */
@keyframes call-dot-in{from{opacity:0;transform:translateX(-36px)}to{opacity:1;transform:none}}
@keyframes call-fade-in{from{opacity:0}to{opacity:1}}
.js-reveals .call-stage:not(.is-drawn) .call-dot,
.js-reveals .call-stage:not(.is-drawn) .call-gap-span{opacity:0}
.call-card.is-drawing .call-dot{animation:call-dot-in .55s ease both;animation-delay:calc(var(--i,0) * 45ms + 120ms)}
.call-card.is-drawing .call-gap-span{animation:call-fade-in .4s ease both .7s}


.call-footnote{padding-top:var(--s-3)}
.call-foot{padding-top:var(--s-4)}

@media(max-width:850px){
  /* Let the decision box itself make the entrance on small screens. The
     section wrapper stays put so the animation feels like a fitted object
     arriving in the viewport rather than the whole page shifting. */
  .js-reveals .call-band[data-reveal]{opacity:1;transform:none;transition:none}
  .js-reveals .call-band[data-reveal] .call-stage{
    opacity:0;transform:translateY(44px) scale(.975);transform-origin:50% 0;
    transition:opacity .28s ease,transform .42s cubic-bezier(.2,.8,.2,1);
    will-change:opacity,transform;
  }
  .js-reveals .call-band[data-reveal].is-revealed .call-stage{opacity:1;transform:none}
  .call-card{min-height:0;padding:var(--s-5) 0 0}
  .call-card[data-decision="bracket"]{min-height:0}
  .call-card[data-decision="bracket"]{gap:var(--s-4)}
}
@media(max-width:420px){
  .call-card-cat{font-size:var(--t-h2)}
  .call-card-toprow{flex-direction:column;gap:var(--s-2)}
  .call-badge{margin:0}
}
@media(prefers-reduced-motion:reduce){
  .call-card.is-active{animation:none}
  .js-reveals .call-stage:not(.is-drawn) .call-dot,
  .js-reveals .call-stage:not(.is-drawn) .call-gap-span{opacity:1}
  .call-card.is-drawing .call-dot,.call-card.is-drawing .call-gap-span,.call-card.is-drawing .call-osc-range,.call-card.is-drawing .call-bk-pt{animation:none}
  .js-reveals .call-stage:not(.is-drawn) .call-bk-pt{opacity:1}
  .js-reveals .call-band[data-reveal] .call-stage{opacity:1;transform:none;transition:none}
}

/* ── Section reveal (progressive enhancement) ────────────────────────────
   .js-reveals is only added to <html> by home.js once an
   IntersectionObserver is confirmed available — so a [data-reveal] section
   stays visible by default and only animates when the JS is actually going
   to reveal it. Same convention as join.css. */
.js-reveals [data-reveal]{opacity:0;transform:translateY(22px);transition:opacity .6s ease,transform .6s ease}
.js-reveals [data-reveal].is-revealed{opacity:1;transform:translateY(0)}

/* __CACHEBUST_20260820b -- see SESSION_LOG.md; a second jekyll-serve deploy race today poisoned this file's immutable hash again, this content-only edit forces a fresh URL */

/* Phone: text links that stand alone on a line get a 44px target (UX review 2026-10-15). */
@media (max-width:760px){.call-record-cta,.join-about-email,.call-cta{min-height:44px;display:inline-flex;align-items:center}}
