/* WebGL stage for /counterfactual (stage.mjs). Every rule is scoped to a staged
   hero or a mounted stage, so without WebGL the page keeps its 2D story card
   and map unchanged. Labels are positioned from script through CSSOM
   transforms; nothing here relies on inline styles, which the page's CSP forbids. */

/* ---- Hero stage: the stage is the first screen ----
   Where WebGL exists, app.mjs reserves the stage's slot (.stage-pending) before
   three.js loads, so the first screen keeps its geometry when the scene arrives.
   The stage sets .has-stage only after shader preparation. The story card
   and the 2D map then leave the screen but stay in the accessibility tree; the
   card's live region still announces every change of view. */
.hero:is(.has-stage,.stage-pending){--stage-h:clamp(540px,calc(100vh - 132px),760px);grid-template-columns:minmax(0,1fr);gap:0;padding-top:0;padding-bottom:20px;background:none}
.hero:is(.has-stage,.stage-pending)>.hero-copy{grid-area:1/1;position:relative;z-index:2;align-self:start;width:min(470px,42%);padding-top:clamp(34px,4.4vw,62px)}
.hero:is(.has-stage,.stage-pending)>.ripple{grid-area:1/1;display:block;position:relative;min-height:var(--stage-h);padding:0;border:0}
.hero.has-stage>.story-panel,.hero:is(.has-stage,.stage-pending) .ripple-record{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0;padding:0;border:0}
.hero:is(.has-stage,.stage-pending)>.record-note{grid-area:2/1;margin-top:14px}
/* While the scene prepares, the readable story card holds its slot. It shows
   only when preparation takes long enough to notice, so fast loads never flash
   it; if the stage cannot mount, or nothing renders within 12 s, the class goes
   and the 2D layout returns. Only the paint waits: the card stays in the
   accessibility tree, its live region keeps announcing, and keyboard focus
   inside it shows it at once. */
.hero.stage-pending>.story-panel{grid-area:1/1;z-index:2;justify-self:end;align-self:center;width:min(560px,48%);animation:cf-story-wait .35s ease .9s both}
.hero.stage-pending>.story-panel:focus-within{animation:none}
@keyframes cf-story-wait{from{opacity:0;pointer-events:none}to{opacity:1;pointer-events:auto}}
.hero.has-stage .ripple-heading{position:absolute;right:0;bottom:20px;z-index:3;display:grid;justify-items:end;gap:6px;text-align:right;pointer-events:none}
.hero:is(.has-stage,.stage-pending) .ripple-heading .eyebrow{margin:0}
.hero.has-stage .cf-stage{height:var(--stage-h)}
/* A soft shade under the headline keeps it legible over the scene. */
.hero.has-stage .cf-stage::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(90deg,rgba(5,4,5,.74),rgba(5,4,5,.4) 30%,rgba(5,4,5,0) 54%)}
.hero.has-stage .cf-hint{right:auto;left:var(--stage-pad)}

/* Outside the hero (a mounted stage without the hero layout): the old band. */
.ripple.has-stage{grid-template-columns:1fr;gap:14px;align-items:stretch}
.ripple.has-stage .ripple-heading{display:flex;align-items:baseline;justify-content:space-between;gap:24px}
.ripple.has-stage .ripple-heading .eyebrow{margin:0}
.ripple.has-stage .ripple-record{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ---- Stage ---- */
.cf-stage{--stage-pad:clamp(22px,4.2vw,70px);position:relative;height:clamp(420px,36vw,520px);margin-inline:calc(-1 * var(--stage-pad));overflow:hidden;background:#050405;isolation:isolate;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;opacity:0;transition:opacity .9s ease}
.cf-stage:not([data-ready="1"]){position:absolute;top:0;left:0;right:0;visibility:hidden;pointer-events:none}
.cf-stage[data-ready="1"]{opacity:1}
#ripple{position:relative}
/* The site's film grain over the scene, under the labels: text stays sharp. */
.cf-stage::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:url('/assets/film/grain-v2.png') repeat;opacity:.05}
.cf-canvas{display:block;width:100%;height:100%;touch-action:pan-y;cursor:grab}
.cf-stage.is-pointing .cf-canvas{cursor:pointer}
.cf-stage.is-dragging .cf-canvas{cursor:grabbing}
.cf-overlay{position:absolute;inset:0;z-index:2;pointer-events:none;font-family:var(--mono);color:var(--text)}
.cf-anchor{position:absolute;left:0;top:0;will-change:transform,opacity}
.cf-anchor.is-hidden{visibility:hidden}

.cf-honesty{position:absolute;right:var(--stage-pad);top:22px;margin:0;display:flex;align-items:center;gap:9px;font-size:9px;letter-spacing:.14em;color:var(--muted)}
.cf-honesty i{width:6px;height:6px;border-radius:50%;background:var(--muted);opacity:.8}

/* 01 / 02: the page story card's plain words, inside the scene. */
.cf-step{display:flex;align-items:center;gap:8px;font-size:9px;letter-spacing:.12em;line-height:1;color:var(--text);white-space:nowrap}
.cf-step b{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:18px;padding:0 4px;border:1px solid rgba(242,238,233,.34);font-size:8px;font-weight:500;letter-spacing:.04em;color:var(--text)}
.cf-step .cf-loc{color:var(--muted)}

.cf-input{display:grid;justify-items:center;gap:7px;padding-bottom:14px;pointer-events:auto}
.cf-input-head{margin:0;display:flex;gap:10px;font-size:9px;letter-spacing:.12em;color:var(--muted);white-space:nowrap}
.cf-loc{color:var(--text)}
.cf-switch{display:flex;border:1px solid rgba(242,238,233,.3);background:rgba(8,7,9,.74)}
.cf-switch button{font:inherit;font-size:12px;letter-spacing:.02em;line-height:1;color:var(--muted);background:transparent;border:0;border-radius:0;margin:0;padding:11px 13px;min-height:38px;cursor:pointer;transition:background-color 180ms ease,color 180ms ease}
.cf-switch button+button{border-left:1px solid rgba(242,238,233,.3);min-width:46px}
.cf-switch button[aria-pressed=true]{color:var(--bg);background:var(--text)}
.cf-switch button[data-input=BRANCH][aria-pressed=true]{background:var(--accent)}
.cf-switch button:focus-visible,.cf-result:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
@media(hover:hover) and (pointer:fine){.cf-switch button[aria-pressed=false]:hover{color:var(--text)}}
/* Both notes share one grid cell, so the label keeps one measured size. */
.cf-input-note{display:grid;justify-items:center;margin:0;font-size:9px;letter-spacing:.03em;line-height:1.4;color:var(--muted);white-space:nowrap}
.cf-stage[data-short="1"] .cf-input{padding-bottom:6px}
.cf-stage[data-short="1"] .cf-input-head{display:none}
.cf-input-note span{grid-area:1/1;transition:opacity .3s ease}
.cf-stage[data-world=BRANCH] .cf-input-note .is-actual,.cf-stage:not([data-world=BRANCH]) .cf-input-note .is-branch{opacity:0}
.cf-stage[data-world=BRANCH] .cf-input-note .is-branch{color:#e0d6dc}

.cf-row{font-size:8px;letter-spacing:.16em;color:rgba(180,169,175,.72);padding-right:12px;white-space:nowrap}
.cf-lane{margin:0;font-size:9px;letter-spacing:.15em;color:var(--text);white-space:nowrap}
.cf-lane.is-lower{color:var(--accent)}
.cf-lane.is-shared{color:var(--muted)}

.cf-result{pointer-events:auto;display:flex;align-items:baseline;gap:10px;font:inherit;color:var(--text);background:transparent;border:0;border-radius:0;margin:0;padding:6px 8px;cursor:pointer;white-space:nowrap}
.cf-result.is-upper{flex-direction:column;align-items:flex-start;gap:8px}
.cf-result-line,.cf-result-head{display:flex;align-items:baseline;gap:10px}
.cf-result strong{font-family:Archivo,'Helvetica Neue',Arial,sans-serif;font-size:22px;font-weight:760;font-stretch:88%;letter-spacing:-.02em;line-height:1}
.cf-result.is-lower{flex-direction:column;align-items:center;gap:5px}
.cf-result.is-lower strong{color:var(--accent)}
.cf-world{font-size:9px;letter-spacing:.14em;color:var(--muted)}
.cf-result .cf-loc{font-size:9px;letter-spacing:.12em;color:var(--muted)}
.cf-agree{display:flex;align-items:center;font-size:9px;letter-spacing:.08em;color:var(--muted)}
.cf-check{display:inline-block;width:4px;height:8px;margin:0 9px 3px 6px;border:solid currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(40deg)}

.cf-legend{position:absolute;left:var(--stage-pad);bottom:20px;margin:0;display:flex;flex-wrap:wrap;gap:8px 22px;font-size:9px;letter-spacing:.1em;color:var(--muted)}
.cf-legend span{display:flex;align-items:center;gap:8px;white-space:nowrap}
.cf-key{display:inline-block;width:2px;height:13px;background:#d6d2db}
.cf-key.is-broken{background:linear-gradient(var(--accent) 0 36%,transparent 36% 64%,var(--accent) 64%)}
.cf-key.is-crack{width:13px;height:2px;background:#9d8b87;transform:rotate(-28deg)}
.cf-hint{position:absolute;right:var(--stage-pad);bottom:20px;margin:0;font-size:9px;letter-spacing:.1em;color:var(--muted)}

.cf-tip{width:max-content;min-width:180px;max-width:228px;padding:10px 12px;background:rgba(10,8,11,.94);border:1px solid rgba(242,238,233,.2);font-size:10px;line-height:1.5}
.cf-tip-head{margin:0 0 6px;font-size:11px;letter-spacing:.06em}
.cf-tip dl{margin:0 0 6px;display:grid;gap:2px}
.cf-tip dl div{display:flex;justify-content:space-between;gap:14px}
.cf-tip dt{color:var(--muted)}
.cf-tip dd{margin:0}
.cf-tip .is-changed dd{color:var(--accent)}
.cf-tip-note{margin:0;color:var(--muted)}
.cf-tip-action{margin:7px 0 0}

/* ---- Tablet and small laptops: headline above the stage. Below 1200 px the
   overlay leaves too little room: the input would run into the honesty label. ---- */
@media(max-width:1199px){
  .hero:is(.has-stage,.stage-pending){--stage-h:480px;padding-top:42px}
  .hero:is(.has-stage,.stage-pending)>.hero-copy,.hero:is(.has-stage,.stage-pending)>.ripple,.hero:is(.has-stage,.stage-pending)>.record-note{grid-area:auto}
  .hero:is(.has-stage,.stage-pending)>.hero-copy{width:auto;max-width:620px;padding:0 0 26px}
  /* Stacked layouts: the card itself stands in the stage's place. */
  .hero.stage-pending>.story-panel{grid-area:auto;justify-self:stretch;align-self:auto;width:auto}
  .hero.stage-pending>.ripple{min-height:0}
  .hero:is(.has-stage,.stage-pending) .ripple-heading{position:static;display:flex;align-items:baseline;justify-content:space-between;gap:20px;text-align:left;margin:0 0 12px}
  .hero.has-stage .cf-stage::before{display:none}
  .hero.has-stage .cf-hint{left:auto;right:var(--stage-pad)}
  .cf-input{gap:5px;padding-bottom:6px}
  .cf-input-head{display:none}
  .cf-stage{height:440px}
}
/* Above phone width the stacked heading sits over the stage, so while the card
   stands in for the stage it has nothing to label yet. */
@media(min-width:768px){.hero.stage-pending .ripple-heading{display:none}}
/* ---- Phone: headline, then the stage, then the rest of the copy ---- */
@media(max-width:767px){
  .cf-stage{--stage-pad:22px;height:440px}
  .hero:is(.has-stage,.stage-pending){--stage-h:440px;padding-top:32px}
  .hero:is(.has-stage,.stage-pending)>.hero-copy{display:contents}
  .hero:is(.has-stage,.stage-pending)>.hero-copy>*{order:4}
  .hero:is(.has-stage,.stage-pending)>.hero-copy>.eyebrow{order:1}
  .hero:is(.has-stage,.stage-pending)>.hero-copy>h1{order:2;margin-bottom:20px}
  .hero:is(.has-stage,.stage-pending)>.ripple{order:3;display:flex;flex-direction:column;align-items:stretch}
  .hero:is(.has-stage,.stage-pending)>.record-note{order:5}
  .hero.has-stage .cf-stage{order:1}
  .hero:is(.has-stage,.stage-pending) .ripple-heading{order:2;margin:12px 0 0}
  .hero:is(.has-stage,.stage-pending) .story-why-link{justify-self:start}
  /* The heading sits under the slot in both states; the card reserves the stage's
     height and leaves its count to that heading, so the copy below does not move. */
  .hero.stage-pending>.story-panel{order:3;min-height:var(--stage-h)}
  .hero.stage-pending .story-caption{display:none}
  /* Stands in for the stage inside the ripple column, so the column's gap above
     the heading is the same in both states. */
  .hero.stage-pending>.ripple::before{content:'';order:1}
  .cf-honesty{top:14px;font-size:8px}
  .cf-lane,.cf-result .cf-loc,.cf-input .cf-loc{display:none}
  .cf-input{gap:5px;padding-bottom:6px}
  .cf-input-head{display:none}
  .cf-input-note{font-size:8px;letter-spacing:0}
  .cf-legend{right:var(--stage-pad);bottom:12px;gap:6px 14px;font-size:8px}
  .cf-hint,.cf-row{display:none}
  .cf-switch button{font-size:11px;padding:12px 10px;min-height:42px}
  .cf-result strong{font-size:17px}
  .cf-step{font-size:8px}
}
@media(prefers-reduced-motion:reduce){.cf-stage,.cf-switch button,.cf-input-note span{transition:none}.hero.stage-pending>.story-panel{animation:none}}
