/* ============================================================
   THE PAGE — base styles, the WebGL canvas and scroll track, the UI layer, the loader.
   Tokens: css/tokens.css · the instrument's chrome: css/chrome.css · the reveal: css/reveal.css
   ============================================================ */
*{box-sizing:border-box}
html{background:var(--bg);-webkit-text-size-adjust:100%;scroll-behavior:auto}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font-family:var(--f-ui);font-weight:400;line-height:1.45;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;touch-action:pan-y;
}
body.loading{overflow:hidden}
a{color:var(--accent);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--accent) 40%,transparent)}
a:hover{border-bottom-color:var(--accent)}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
.mono{font-family:var(--f-mono)}
::selection{background:rgba(244,183,40,.35)}

/* ---------- canvas + scroll track ---------- */
#gl{position:fixed;inset:0;width:100%;height:100%;display:block;z-index:0;outline:none;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
/* touch screens: the stage is as tall as the large viewport (toolbars retracted), set by stage.js as --stage-h, so the
   browser's toolbars sliding in and out as the reader scrolls never resize or reframe the scene. Everything drawn over
   the scene in its coordinates (the callouts, the loupe) takes the same height. */
@media (pointer:coarse){
  #gl,#callouts,.rv-lens{bottom:auto;height:var(--stage-h,100%)}
}
#track{position:relative;z-index:1;pointer-events:none}
#track section{width:100%}
#endnote{position:absolute;left:0;right:0;bottom:0}

/* ---------- the UI layer: everything over the scene (chrome.css places what's inside) ---------- */
#ui{position:fixed;inset:0;z-index:2;pointer-events:none;transition:opacity .5s var(--e-out)}
#ui > *{pointer-events:none}
body.dd-open #ui{opacity:0}
#capwrap{opacity:0;will-change:opacity,transform}
#slate,#titlecard{opacity:0}

/* the end card: what was verified, where to go further, and a way back to the beginning */
/* it takes no room until the end (the caption block is anchored at the bottom, so anything in it lifts the caption);
   then it opens, and the caption rises smoothly to make room */
#endcard{max-height:0;margin-top:0;padding:2px;overflow:hidden;opacity:0;pointer-events:none;transition:max-height .9s var(--e-out),margin .9s var(--e-out),opacity .9s var(--e-out)}
#endcard.on{max-height:320px;margin-top:24px;opacity:1;pointer-events:auto}
#endcard .acts{display:flex;flex-wrap:wrap;gap:10px}
#endcard .acts button{
  display:inline-flex;align-items:center;gap:9px;min-height:40px;padding:0 16px;
  border:1px solid var(--rule-2);background:var(--panel);color:var(--ink);cursor:pointer;--b:5px;
  transition:background-color var(--d-2),border-color var(--d-2);
}
#endcard .acts #replay{border-color:color-mix(in srgb,var(--zec) 45%,transparent);background:var(--zec-dim)}
#replay span{font-size:14px;letter-spacing:0;color:var(--zec)}
#endcard .acts button:hover{border-color:var(--accent);background:var(--accent-dim)}
#endcard .acts button:focus-visible{outline:1px solid var(--accent);outline-offset:3px}
#endcard .end-credit{display:none;margin-top:16px}   /* phones only: elsewhere the credit is in the top bar (chrome.css) */
/* the way on to the ecosystem page: a third action beside Replay and Share on a wide screen; on a phone, where those two
   already fill their row, a small link at the end of the credit's row (which keeps the end card exactly as tall) */
#endcard .acts{contain:inline-size}   /* (its buttons never widen the caption block: that sizes to the caption alone, as before) */
#endcard .acts #end-eco{
  display:inline-flex;align-items:center;gap:9px;min-height:40px;padding:0 14px;text-decoration:none;
  border:1px solid color-mix(in srgb,var(--zec) 45%,transparent);background:var(--panel);color:var(--ink);--b:5px;
  transition:background-color var(--d-2),border-color var(--d-2);
}
#end-eco i{font-style:normal;color:var(--zec);letter-spacing:0;transition:transform var(--d-3) var(--e-out)}
#end-eco .w{white-space:pre}
#endcard .acts #end-eco:hover{border-color:var(--accent);background:var(--accent-dim)}
#endcard .acts #end-eco:hover i{transform:translateX(3px)}
@media (max-width:1099px){#end-eco .w{display:none}}   /* (narrower: "Ecosystem →", so the three keep one row) */
#endcard .acts #end-eco:focus-visible{outline:1px solid var(--accent);outline-offset:3px}
#end-eco-m{display:none}

/* ---------- loader ---------- */
#loader{position:fixed;inset:0;z-index:20;background:var(--bg);display:grid;place-items:center;transition:opacity .9s var(--e-out),visibility 0s linear .9s}
#loader.off{opacity:0;visibility:hidden}
#loader .in{display:flex;flex-direction:column;align-items:center;gap:18px}
#loader .lg{width:48px;height:48px;border-radius:50%;display:grid;place-items:center;box-shadow:0 0 36px rgba(244,183,40,.28);animation:pulse 1.8s ease-in-out infinite}
#loader .lg svg{display:block;width:48px;height:48px}
@keyframes pulse{50%{transform:scale(1.05);box-shadow:0 0 56px rgba(244,183,40,.42)}}
#loader .bar{width:180px;height:1px;background:var(--rule-2);overflow:hidden}
#loader .bar i{display:block;height:100%;width:0;background:var(--zec);transition:width .4s var(--e-out)}
#loader .msg{font:500 var(--t-micro)/1 var(--f-mono);letter-spacing:var(--track-micro);text-transform:uppercase;color:var(--ink-2)}
#nogl{display:none;max-width:420px;text-align:center;padding:24px;color:var(--ink-2);font-size:14px;line-height:1.6}

@media (max-width:900px),(orientation:portrait) and (max-width:1024px){
  /* phones: the two actions share one row (stacked, they pushed the caption up into the finale's coin) */
  #endcard.on{margin-top:14px}
  #endcard .acts{gap:8px}
  #endcard .acts button{gap:7px;min-height:38px;padding:0 12px;font-size:10px;letter-spacing:.08em}
  #endcard .end-credit{display:flex}
  #endcard .acts #end-eco{display:none}
  #endcard .end-credit #end-eco-m{
    position:relative;display:inline-flex;align-items:center;gap:6px;margin-left:auto;padding:5px 0;
    color:var(--accent);border-bottom:0;text-decoration:none;
  }
  #end-eco-m svg{display:none;width:15px;height:15px;fill:currentColor}
  #end-eco-m i{font-style:normal;letter-spacing:0}
  #end-eco-m::after{content:"";position:absolute;inset:-7px -6px}   /* (a finger's target, taking no room) */
  #end-eco-m:focus-visible{outline:1px solid var(--accent);outline-offset:3px}
}
/* the end card on small phones (approved fix): on a short screen the line under the caption folds away as the end card
   opens — it has been read by then — so the caption doesn't rise into the finale's coin; on the narrowest, the two
   actions keep one row, their words wrapping inside them, and the ecosystem link keeps only its mark */
@media (orientation:portrait) and (max-height:700px){
  /* (10em: above the tallest sub-caption on the narrowest phone, 126 px — measured over the whole story) */
  #subcap{max-height:10em;transition:max-height .9s var(--e-out),margin .9s var(--e-out),opacity .6s var(--e-out)}
  #capwrap:has(#endcard.on) #subcap{max-height:0;margin-top:0;opacity:0;overflow:hidden}
}
@media (max-width:353px){
  #endcard .acts{flex-wrap:nowrap}
  #endcard .acts button{flex:1 1 0;min-width:0;white-space:normal;line-height:1.25;padding:5px 10px;text-align:left}
}
@media (max-width:369px){
  #end-eco-m span{display:none}
  #end-eco-m svg{display:block}
}
@media (prefers-reduced-motion:reduce){
  #loader .lg{animation:none}
  #endcard{transition-duration:.15s}
}
