/* ═══════════════════════════════════════════════════════════════════════════
   NULL — design system
   ───────────────────────────────────────────────────────────────────────────
   Paper, not phosphor. dev.fun's palette and structure: cream ground with a
   faint graph-paper grid, near-black ink, one hairline weight, zero-radius
   corners, monospace throughout, and full-bleed bands that cut to black for
   contrast.

   Restraint is the rule. No glows, no drop shadows, no scanlines. Colour is
   reserved for one thing: something is live, or money moved.

   Everything visual is a token in :root. Re-skinning means editing that block
   and nothing else.

   Loaded by: index.html, play.html, archive.html.
   The claim page carries its own copy of these tokens inline. It stays a
   single self-contained file with no JavaScript dependencies, because it
   handles plaintext answers worth money and a player must be able to audit it
   in one read. Keep the two palettes in sync by hand. That is deliberate.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── ground ─────────────────────────────────────────────────────────────
     Taken from the reference site's own computed styles. */
  --paper:#fafaf7;
  --paper-2:#f2f2ed;     /* a half-step down, for inset panels   */
  --ink:#0a0a0a;
  --rule:#b9bcb3;
  --rule-soft:#dcdcd4;

  --mid:#4a4d46;         /* body text                            */
  --dim:#74786e;         /* labels, secondary                    */
  --faint:#a2a69b;       /* hints, axis text                     */

  /* ── inverted band ──────────────────────────────────────────────────────
     Matte, not pure black. A hair of warmth and lift keeps the dark bands
     from punching a hole in the paper, and stops hairlines disappearing. */
  --dark:#1b1b19;
  --dark-2:#232320;
  --dark-rule:#3a3a34;
  --dark-ink:#f4f4ef;      /* headings                       */
  --dark-body:#d2d3c8;     /* body copy. ~11:1 on the matte. */
  --dark-dim:#9fa096;      /* labels                         */

  /* ── accent. Used sparingly: live status, money in, the one lit bar. ──── */
  --acc:#3f7d3f;
  --acc-soft:#e4eede;
  --live:#4ea24e;
  --bad:#a8443c;
  --suit:#b03a30;        /* hearts and diamonds. Muted, not pillar-box red. */

  /* The primary button needs its own pair rather than borrowing --dark and
     --paper: those both go dark in dark mode, which leaves dark text on a
     dark button. These two always invert against each other. */
  --btn-bg:#1b1b19;
  --btn-fg:#fafaf7;
  --btn-bg-hover:#0a0a0a;

  /* ── type ─────────────────────────────────────────────────────────────── */
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  --dotm:"Doto","JetBrains Mono",ui-monospace,monospace;  /* wordmark only */

  --fs-micro:10px;
  --fs-tiny:11px;
  --fs-small:12px;
  --fs-base:13px;
  --fs-lede:16px;
  --fs-stat:20px;
  --fs-big:clamp(24px,3vw,40px);
  --fs-hero:clamp(30px,4.4vw,60px);

  --track:.12em;

  /* ── space ────────────────────────────────────────────────────────────── */
  --s-1:5px;  --s-2:9px;  --s-3:14px; --s-4:22px;
  --s-5:34px; --s-6:52px; --s-7:80px;

  --measure:56ch;
  --page:1140px;         /* the one content column */
  --gut:28px;
  --rhythm:76px;
}

/* ═══ dark mode ════════════════════════════════════════════════════════════
   Subtle, and only a re-point of the tokens above. No component knows this
   exists. Warm charcoal rather than black, so it reads as the paper's night
   shift instead of a different site.

   Three states: an explicit choice stamps data-theme on <html>; with nothing
   stamped, the system preference decides. Both directions are declared so the
   toggle wins either way. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#17181a;
    --paper-2:#1e1f21;
    --ink:#eceee9;
    --rule:#3a3d3e;
    --rule-soft:#2a2c2e;

    --mid:#b3b7b1;
    --dim:#8b908a;
    --faint:#646963;

    --dark:#0e0f10;
    --dark-2:#161719;
    --dark-rule:#2e3132;
    --dark-ink:#f2f3ef;
    --dark-body:#c9ccc5;
    --dark-dim:#8b908a;

    --acc:#7cc47c;
    --acc-soft:#22301f;
    --live:#7cc47c;
    --suit:#d4736a;

    /* inverted: a light button on the dark ground */
    --btn-bg:#eceee9;
    --btn-fg:#17181a;
    --btn-bg-hover:#ffffff;
  }
}
:root[data-theme="dark"]{
  --paper:#17181a;
  --paper-2:#1e1f21;
  --ink:#eceee9;
  --rule:#3a3d3e;
  --rule-soft:#2a2c2e;

  --mid:#b3b7b1;
  --dim:#8b908a;
  --faint:#646963;

  --dark:#0e0f10;
  --dark-2:#161719;
  --dark-rule:#2e3132;
  --dark-ink:#f2f3ef;
  --dark-body:#c9ccc5;
  --dark-dim:#8b908a;

  --acc:#7cc47c;
  --acc-soft:#22301f;
  --live:#7cc47c;
  --suit:#d4736a;

  /* inverted: a light button on the dark ground */
  --btn-bg:#eceee9;
  --btn-fg:#17181a;
  --btn-bg-hover:#ffffff;
}

/* Surfaces that were hardcoded against paper have to follow the tokens. */
:root[data-theme="dark"] .topbar,
:root:not([data-theme="light"]) .topbar{background:color-mix(in srgb, var(--paper) 88%, transparent)}
:root[data-theme="dark"] .pcard,
:root[data-theme="dark"] .card,
:root[data-theme="dark"] .riddlecard{box-shadow:none}
:root[data-theme="dark"] .pcard:hover,
:root[data-theme="dark"] .card:hover,
:root[data-theme="dark"] .riddlecard:hover{box-shadow:0 10px 24px rgba(0,0,0,.45)}
:root[data-theme="dark"] .band-paper{
  background-image:
    linear-gradient(rgba(255,255,255,.022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.022) 1px, transparent 1px);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .band-paper{
    background-image:
      linear-gradient(rgba(255,255,255,.022) 1px, transparent 1px),
      linear-gradient(90deg, rgba(255,255,255,.022) 1px, transparent 1px);
  }
  :root:not([data-theme="light"]) .pcard,
  :root:not([data-theme="light"]) .card,
  :root:not([data-theme="light"]) .riddlecard{box-shadow:none}
}

/* the toggle itself */
.themetoggle{
  background:none; border:1px solid var(--rule); color:var(--dim); cursor:pointer;
  font:inherit; font-size:var(--fs-micro); letter-spacing:var(--track);
  text-transform:uppercase; padding:5px var(--s-2); line-height:1.4;
}
.themetoggle:hover{color:var(--ink); border-color:var(--ink)}

/* ═══ reset ════════════════════════════════════════════════════════════════ */
*{box-sizing:border-box}
*,*::before,*::after{border-radius:0}     /* nothing is rounded, by default */

/* [hidden] only sets display:none at the lowest specificity, so any component
   rule that sets `display` silently beats it and the element stays visible.
   This makes the attribute mean what everyone assumes it means. */
[hidden]{display:none !important}
html{background:var(--paper)}
body{
  margin:0; color:var(--mid); font-family:var(--mono);
  font-size:var(--fs-base); line-height:1.65;
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
}
a{color:inherit}
/* height:auto matters — without it an intrinsic height attribute on the tag
   overrides the scaled width and the image renders stretched. */
img{max-width:100%; height:auto; display:block}

/* ═══ motion ═══════════════════════════════════════════════════════════════
   One easing curve and three durations for the whole site. Everything that
   moves borrows from here, which is what keeps it feeling like one object
   rather than a pile of separate effects. */
:root{
  --ease:cubic-bezier(.2,.8,.3,1);
  --t-fast:.16s;
  --t-mid:.28s;
  --t-slow:.5s;
}

/* Theme switch. Colour crossfades on the surfaces that actually change; it is
   deliberately not a universal `transition: all`, which would drag every
   hover and layout change along with it and make the whole site feel soft. */
body,
.topbar, .band, .panel, .card, .pcard, .riddlecard, .door,
.term, .screen, .btn, .chip, .deck, .rrow, .rrow > summary,
.stat, .kpi, .stepcard, .tag, .toc a{
  transition:
    background-color var(--t-slow) var(--ease),
    border-color var(--t-slow) var(--ease),
    color var(--t-slow) var(--ease);
}
/* Buttons and chips still need their fast hover, so those win on hover. */
.btn:hover, .chip:hover{transition-duration:var(--t-fast)}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
}
html{scroll-behavior:smooth}

:where(a,button,input,summary):focus-visible{outline:2px solid var(--ink); outline-offset:2px}

/* ── link underline that draws in ─────────────────────────────────────────── */
.lnk, .fcol a, .phead a{
  background-image:linear-gradient(currentColor, currentColor);
  background-repeat:no-repeat;
  background-position:0 100%;
  background-size:0% 1px;
  transition:background-size var(--t-mid) var(--ease), color var(--t-fast) var(--ease);
}
.lnk:hover, .fcol a:hover, .phead a:hover{background-size:100% 1px}

/* ── buttons lift very slightly, and the arrow leads ──────────────────────── */
.btn{transform:translateZ(0)}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ═══ bands ════════════════════════════════════════════════════════════════
   The page is a stack of full-bleed bands. The background runs edge to edge;
   the inner wrapper keeps every line of text on the same left rule. */
.band{width:100%; padding:var(--rhythm) var(--gut)}
.band > .in{max-width:var(--page); margin-inline:auto}
.band-tight{padding-block:var(--s-4)}

/* graph paper, on the cream bands only. Barely there by design: it should
   read as paper stock, not as a pattern. */
.band-paper{
  background-color:var(--paper);
  background-image:
    linear-gradient(rgba(10,10,10,.026) 1px, transparent 1px),
    linear-gradient(90deg, rgba(10,10,10,.026) 1px, transparent 1px);
  background-size:34px 34px;
}
.band-quiet{background:var(--paper-2); border-block:1px solid var(--rule-soft)}

/* the inverted band. This is the contrast device the whole page leans on. */
.band-dark{background:var(--dark); color:var(--dark-body)}
.band-dark h2,.band-dark h3,.band-dark b{color:var(--dark-ink)}
/* Body copy and table cells inherit --mid by default, which is a DARK grey.
   On the matte band that lands around 1.5:1 and is effectively invisible, so
   every text-bearing element has to be re-pointed here, not just headings. */
.band-dark p,
.band-dark .body,
.band-dark .lede,
.band-dark td{color:var(--dark-body)}
.band-dark .shead p{color:var(--dark-body)}
.band-dark th,
.band-dark .eyebrow,
.band-dark .lbl,
.band-dark .rank,
.band-dark .empty{color:var(--dark-dim)}
.band-dark .eyebrow::after{background:var(--dark-rule)}
.band-dark .panel{background:var(--dark-2); border-color:var(--dark-rule)}
.band-dark .phead{border-color:var(--dark-rule); color:var(--dark-dim)}
.band-dark td,.band-dark th{border-color:var(--dark-rule)}
.band-dark td.hot{color:var(--dark-ink)}
.band-dark td.n{color:var(--dark-body)}
.band-dark .btn{border-color:var(--dark-rule); color:var(--dark-ink)}
.band-dark .btn:hover{border-color:var(--dark-ink)}
.band-dark .screen{background:var(--dark-2); border-color:var(--dark-rule)}
.band-dark .clue{color:var(--dark-ink)}
.band-dark h1{color:var(--dark-ink)}
.band-dark .tag{border-color:var(--dark-rule); color:var(--dark-dim)}
.band-dark .tag b{color:var(--dark-ink)}
.band-dark .tag.on{border-color:var(--live); color:var(--live)}
.band-dark .crumb,.band-dark .shot figcaption{color:var(--dark-dim)}
.band-dark .shot img{border-color:var(--dark-rule)}
.band-dark .lnk{color:var(--dark-dim)}
.band-dark .lnk:hover{color:var(--dark-ink)}

/* ═══ top bar ══════════════════════════════════════════════════════════════
   Replaces the sidebar. Sticky, one hairline, logo left and nav right. */
.topbar{
  position:sticky; top:0; z-index:50;
  background:rgba(250,250,247,.88); backdrop-filter:blur(8px);
  border-bottom:1px solid var(--rule-soft);
}
.topbar .in{
  max-width:var(--page); margin-inline:auto; padding:0 var(--gut);
  display:flex; align-items:center; gap:var(--s-4); height:58px;
}
/* The wordmark reads as a live terminal, not a label sitting there: a caret
   blinks after it, and the name is tracked out so a four-letter word has
   enough presence to anchor the bar. */
.wordmark{
  font-family:var(--dotm); font-weight:700; font-size:24px; letter-spacing:.06em;
  color:var(--ink); text-decoration:none; line-height:1;
  display:inline-flex; align-items:center; gap:.16em;
}
.wordmark::after{
  content:""; width:.13em; height:.72em; background:var(--acc);
  animation:blink 1.05s step-end infinite;
}
.wordmark:hover{color:var(--ink)}
.crumb{color:var(--faint); font-size:var(--fs-small)}
.topbar nav{margin-left:auto; display:flex; gap:var(--s-4); align-items:center}
.topbar nav a{
  text-decoration:none; color:var(--dim); font-size:var(--fs-small); letter-spacing:.02em;
  padding:6px 0; border-bottom:1px solid transparent;
}
.topbar nav a:hover{color:var(--ink)}
.topbar nav a[aria-current="page"]{color:var(--ink); border-bottom-color:var(--ink)}

/* ═══ status line ══════════════════════════════════════════════════════════ */
.status{display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap; font-size:var(--fs-tiny); color:var(--dim)}
.tag{display:inline-flex; align-items:center; gap:var(--s-2); border:1px solid var(--rule); padding:6px var(--s-3)}
.tag b{color:var(--ink); font-weight:500}
.tag.on{border-color:var(--acc); color:var(--acc)}
.spacer{flex:1}
.dot{width:6px; height:6px; border-radius:50%; background:var(--live); flex:none; display:inline-block; animation:pulse 2.4s infinite}
.dot.off{background:var(--faint); animation:none}
@keyframes pulse{50%{opacity:.3}}

/* ═══ type ═════════════════════════════════════════════════════════════════ */
h1{
  font-size:var(--fs-hero); font-weight:500; line-height:1.08;
  letter-spacing:-.02em; color:var(--ink); margin:0 0 var(--s-4);
}
h2{font-size:var(--fs-big); font-weight:500; line-height:1.14; letter-spacing:-.015em; color:var(--ink); margin:0}
h3{font-size:var(--fs-lede); font-weight:500; color:var(--ink); margin:0 0 var(--s-2)}

.lede{font-size:var(--fs-lede); line-height:1.55; color:var(--mid); max-width:var(--measure); margin:0}
.body{max-width:var(--measure); color:var(--mid)}
.lbl{font-size:var(--fs-micro); letter-spacing:var(--track); text-transform:uppercase; color:var(--dim)}
.num{font-variant-numeric:tabular-nums}
.empty{color:var(--dim)}
.money{color:var(--acc)}
.cursor{
  display:inline-block; width:.1em; height:.78em; background:var(--ink);
  vertical-align:-.04em; margin-left:.14em; animation:blink 1.05s step-end infinite;
}
@keyframes blink{50%{opacity:0}}

/* section heading block. Same shape every time. */
/* ── Title Case ─────────────────────────────────────────────────────────────
   Headings, labels and controls only. Deliberately NOT applied to clue text,
   answers, addresses or anything in a terminal block: those are verbatim
   strings, and capitalising a word inside an answer changes the thing a
   player is supposed to copy. */
h1, h2, h3,
.btn, .chip,
.topbar nav a,
.card > .head,
.phead,
.rr-name,
.stepcard b, .pcard b, .door b,
.toc a,
.fcol .lbl,
.statrow .lbl, .stat .lbl, .kpi .lbl, .screen .lbl,
.rc-facts dt,
.replay .side .k{
  text-transform:capitalize;
}
/* the ones meant to shout keep shouting */
.shead .eyebrow, .rr-out, .card > .head .badge, .term .path{text-transform:uppercase}
/* and anything verbatim is put back explicitly */
.clue, .term code, .rr-body p, .doc-body p, .doc-body .callout,
.marquee span, .replay .stream, .wordmark, .empty, .rr-prize, .rr-when{
  text-transform:none;
}

.shead{margin-bottom:var(--s-5)}
.shead .eyebrow{
  display:flex; align-items:center; gap:var(--s-3);
  font-size:var(--fs-micro); letter-spacing:var(--track); text-transform:uppercase;
  color:var(--dim); margin-bottom:var(--s-3);
}
.shead .eyebrow::after{content:""; flex:1; height:1px; background:var(--rule-soft)}
.shead p{margin:var(--s-3) 0 0; color:var(--mid); max-width:var(--measure)}

/* ═══ scroll reveal ════════════════════════════════════════════════════════
   Bands lift in. Children stagger behind their band so a section assembles
   rather than appearing all at once, which is the difference between "an
   animation happened" and "the page is alive". */
.reveal{opacity:0; transform:translateY(16px);
  transition:opacity .55s var(--ease), transform .55s var(--ease)}
.reveal.in{opacity:1; transform:none}

/* Children stagger in on OPACITY ONLY.
   Nothing here touches `transform`, and that is the entire point: the band
   above already supplies the movement, and any transform on the child would
   contend with the hover lift. Two rules animating the same property is what
   made a hovered card look like it was re-appearing rather than rising. */
.reveal .shead,
.reveal .panel,
.reveal .cards > *,
.reveal .steps > *,
.reveal .deck,
.reveal .replay,
.reveal .riddle > *,
.reveal .acts{
  opacity:0;
  /* The card's own hover properties are restated here on purpose. This rule
     is more specific than `.card`, and `transition` is not additive, so
     listing only opacity would silently delete the hover timing and the lift
     would snap. */
  transition:
    opacity .5s var(--ease) var(--rd, 0s),
    transform .42s var(--ease),
    box-shadow .42s var(--ease),
    border-color .42s var(--ease),
    background-color var(--t-slow) var(--ease);
}
.reveal.in .shead,
.reveal.in .panel,
.reveal.in .cards > *,
.reveal.in .steps > *,
.reveal.in .deck,
.reveal.in .replay,
.reveal.in .riddle > *,
.reveal.in .acts{opacity:1}

/* The stagger rides on --rd so it delays the fade only. Using
   `transition-delay` would delay the hover lift by the same amount and make
   every card feel like it was responding late. */
.reveal .shead{--rd:.04s}
.reveal .cards > *:nth-child(1),
.reveal .steps > *:nth-child(1),
.reveal .riddle > *:nth-child(1){--rd:.10s}
.reveal .cards > *:nth-child(2),
.reveal .steps > *:nth-child(2),
.reveal .riddle > *:nth-child(2){--rd:.18s}
.reveal .cards > *:nth-child(3),
.reveal .steps > *:nth-child(3){--rd:.26s}
.reveal .panel,
.reveal .deck,
.reveal .replay{--rd:.12s}
.reveal .acts{--rd:.22s}

@media (prefers-reduced-motion:reduce){
  .reveal,
  .reveal .shead, .reveal .panel, .reveal .cards > *, .reveal .steps > *,
  .reveal .deck, .reveal .replay, .reveal .riddle > *, .reveal .acts{
    opacity:1; transform:none;
  }
}

/* ═══ buttons ══════════════════════════════════════════════════════════════
   → stays on this site.  ↗ leaves it. Applied without exception. */
.btn{
  display:inline-flex; align-items:center; gap:var(--s-3);
  padding:11px var(--s-4); text-decoration:none; cursor:pointer;
  border:1px solid var(--rule); background:transparent; color:var(--ink);
  font-family:var(--mono); font-size:var(--fs-small); letter-spacing:.01em;
  transition:border-color .12s, background .12s, color .12s;
}
.btn:hover{border-color:var(--ink)}
.btn .k{margin-left:auto; color:var(--faint); font-size:var(--fs-micro)}
.btn-primary{background:var(--btn-bg); border-color:var(--btn-bg); color:var(--btn-fg)}
.btn-primary:hover{background:var(--btn-bg-hover); border-color:var(--btn-bg-hover)}
.btn-primary .k{color:var(--btn-fg); opacity:.55}
.btn-block{width:100%; justify-content:flex-start}
.acts{display:flex; gap:var(--s-2); flex-wrap:wrap; margin-top:var(--s-5)}
.lnk{color:var(--dim); text-decoration:none; font-size:var(--fs-small)}
.lnk:hover{color:var(--ink)}
.iconbtn{background:none; border:0; color:var(--faint); cursor:pointer; font:inherit; padding:0 0 0 8px}
.iconbtn:hover{color:var(--ink)}

/* ═══ hero ═════════════════════════════════════════════════════════════════ */
.hero{display:grid; grid-template-columns:1.15fr .85fr; gap:var(--s-6); align-items:center}
.hero .status{margin-bottom:var(--s-5)}

/* The emblem keeps the artwork's own circular shape, which is why it is the
   one element allowed a radius. */
.emblem{margin:0 0 0 auto; position:relative; width:min(100%, 400px)}
.emblem img{width:100%; aspect-ratio:1; border-radius:50%; background:var(--dark)}

/* ═══ the CA ═══════════════════════════════════════════════════════════════
   A contract address is long, and on a phone it either wraps into a mess or
   overflows the page. It scrolls inside its own box instead, so the address
   stays selectable in one piece and the layout never widens. */
.ca{
  display:flex; align-items:stretch; margin-top:var(--s-4);
  border:1px solid var(--rule); background:var(--paper-2);
  max-width:100%; overflow:hidden;
}
.ca-k{
  flex:none; display:flex; align-items:center; padding:0 var(--s-3);
  border-right:1px solid var(--rule); font-size:var(--fs-micro);
  letter-spacing:var(--track); color:var(--dim);
}
.ca code{
  flex:1; min-width:0; padding:11px var(--s-3); font-family:var(--mono);
  font-size:var(--fs-small); color:var(--ink);
  overflow-x:auto; white-space:nowrap;
}
.ca-soon{
  flex:1; padding:11px var(--s-3); font-size:var(--fs-small); color:var(--faint);
}
.ca button{
  flex:none; border:0; border-left:1px solid var(--rule); background:transparent;
  color:var(--dim); cursor:pointer; padding:0 var(--s-3);
  font-family:var(--mono); font-size:var(--fs-micro); letter-spacing:var(--track);
}
.ca button:hover{color:var(--ink)}

/* ═══ marquee ══════════════════════════════════════════════════════════════ */
.marquee{overflow:hidden; white-space:nowrap;
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.marquee-in{display:inline-flex; gap:var(--s-6); animation:slide 40s linear infinite}
.marquee:hover .marquee-in{animation-play-state:paused}
.marquee span{font-size:var(--fs-tiny); letter-spacing:var(--track); text-transform:uppercase;
  color:var(--dim); display:inline-flex; align-items:center; gap:var(--s-3)}
.marquee span::before{content:"/"; color:var(--faint)}
@keyframes slide{to{transform:translateX(-50%)}}

/* ═══ the replay ═══════════════════════════════════════════════════════════ */
.replay{border:1px solid var(--dark-rule); background:var(--dark-2);
  display:grid; grid-template-columns:1fr 280px; min-height:360px}
.replay .stream{padding:var(--s-4); font-size:var(--fs-small); line-height:2; overflow:hidden}
.replay .ln{display:flex; gap:var(--s-3); opacity:0; animation:linein .4s ease both}
.replay .ln .g{color:#5a5d54; flex:none}
.replay .ln .x{color:var(--dark-dim); min-width:0; overflow-wrap:anywhere}
.replay .ln .x b{color:var(--dark-ink); font-weight:400}
.replay .ln.hit .x b,.replay .ln.pay .x{color:var(--live)}
.replay .ln .mask{color:var(--live); letter-spacing:.2em}
@keyframes linein{from{opacity:0; transform:translateY(5px)} to{opacity:1; transform:none}}
.replay .side{border-left:1px solid var(--dark-rule); padding:var(--s-4);
  display:flex; flex-direction:column; gap:var(--s-4)}
.replay .side .k{font-size:var(--fs-micro); letter-spacing:var(--track); text-transform:uppercase; color:var(--dark-dim)}
.replay .side .v{font-size:18px; color:var(--dark-ink); margin-top:5px; font-variant-numeric:tabular-nums; overflow-wrap:anywhere}
.replay .side .v.acc{color:var(--live)}
.replay .side .foot{margin-top:auto; font-size:var(--fs-micro); color:#5a5d54; line-height:1.7}

/* ═══ panels and cards ═════════════════════════════════════════════════════ */
.panel{border:1px solid var(--rule); background:var(--paper)}
.phead{display:flex; align-items:center; gap:var(--s-2); padding:var(--s-3) var(--s-4);
  border-bottom:1px solid var(--rule-soft); font-size:var(--fs-micro);
  letter-spacing:var(--track); text-transform:uppercase; color:var(--dim)}
.phead a{color:var(--dim); text-decoration:none}
.phead a:hover{color:var(--ink)}
.pbody{padding:var(--s-4)}

.cards{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--s-4)}
/* A two-up variant as a class, not an inline style: an inline
   grid-template-columns outranks every media query and the layout then never
   collapses on a phone. */
.cards-2{grid-template-columns:repeat(2,1fr)}

/* Dealt, like the step cards: rounded corners, an inner keyline, a suit in
   the header and a watermark pip behind the body. */
.card{
  position:relative; isolation:isolate;
  border:1px solid var(--rule); border-radius:8px; background:var(--paper);
  display:flex; flex-direction:column;
  box-shadow:0 1px 0 rgba(10,10,10,.04);
  transition:transform .42s var(--ease), box-shadow .42s var(--ease),
             border-color .42s var(--ease),
             background-color var(--t-slow) var(--ease);
  will-change:transform;
}
.card::after{
  content:""; position:absolute; inset:6px; border:1px solid var(--rule-soft);
  border-radius:4px; pointer-events:none; z-index:-1;
}
.card:hover{
  transform:translateY(-4px);
  box-shadow:0 8px 20px rgba(10,10,10,.07);
  border-color:var(--dim);
}
.card .suit{font-size:14px; color:var(--ink); margin-right:2px}
.card.red .suit{color:var(--suit)}
.card .pip{
  position:absolute; right:var(--s-4); bottom:var(--s-5);
  font-size:clamp(80px,7vw,110px); line-height:1; color:var(--ink);
  opacity:.04; z-index:-1; pointer-events:none; user-select:none;
}
.card.red .pip{color:var(--suit); opacity:.06}

.card > .head{display:flex; align-items:center; gap:var(--s-2); padding:var(--s-3) var(--s-4);
  border-bottom:1px solid var(--rule-soft); font-size:var(--fs-small); color:var(--ink)}
.card > .head .badge{margin-left:auto; display:inline-flex; align-items:center; gap:6px;
  font-size:var(--fs-micro); letter-spacing:var(--track); color:var(--acc)}
.card > .head .badge.off{color:var(--faint)}
.card > .b{padding:var(--s-4); flex:1}
.card > .f{padding:0 var(--s-4) var(--s-4)}

.statrow{display:flex; align-items:baseline; justify-content:space-between; gap:var(--s-3)}
.statrow + .statrow{margin-top:var(--s-3); padding-top:var(--s-3); border-top:1px solid var(--rule-soft)}
.statrow .v{font-size:var(--fs-stat); color:var(--ink); font-variant-numeric:tabular-nums}
.statrow .v.acc{color:var(--acc)}

.pair{display:flex; gap:var(--s-5); margin-top:var(--s-4)}
.pair .pv{font-size:var(--fs-stat); color:var(--ink); margin-top:4px; font-variant-numeric:tabular-nums}
.pair .pv.acc{color:var(--acc)}

/* ═══ steps, dealt as a hand ═══════════════════════════════════════════════
   Three playing cards rather than three panels. Each carries a rank-and-suit
   index in opposing corners, the way a real card does, and the second index
   is rotated so it reads correctly when the card is turned around.

   These are the one place a radius is allowed. A playing card with square
   corners does not read as a playing card, and the metaphor is the point. */
.steps{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:var(--s-4); align-items:stretch;
}
.pcard{
  position:relative; isolation:isolate;
  background:var(--paper); border:1px solid var(--rule); border-radius:8px;
  padding:var(--s-6) var(--s-5);
  display:flex; flex-direction:column; justify-content:center;
  min-height:clamp(300px, 30vw, 400px);
  box-shadow:0 1px 0 rgba(10,10,10,.04);
  /* Long and soft on the way up, quicker on the way back down, which is how
     a physical object behaves when you lift it and let it go. */
  transition:transform .42s var(--ease), box-shadow .42s var(--ease),
             border-color .42s var(--ease),
             background-color var(--t-slow) var(--ease);
  will-change:transform;
}
/* the faint inner keyline real cards have inside their border */
.pcard::after{
  content:""; position:absolute; inset:7px; border:1px solid var(--rule-soft);
  border-radius:4px; pointer-events:none; z-index:-1;
}
/* A small, even lift. Anything bigger reads as the card jumping rather than
   responding, and the shadow does most of the work anyway. */
.pcard:hover{
  transform:translateY(-4px);
  box-shadow:0 8px 20px rgba(10,10,10,.07);
  border-color:var(--dim);
}

/* the corner index: rank over suit, top-left and again bottom-right */
.pcard .ix{
  position:absolute; display:flex; flex-direction:column; align-items:center;
  line-height:1; font-size:15px; color:var(--ink); font-weight:500;
}
.pcard .ix .s{font-size:14px; margin-top:3px}
.pcard .ix.tl{top:var(--s-4); left:var(--s-4)}
.pcard .ix.br{bottom:var(--s-4); right:var(--s-4); transform:rotate(180deg)}
.pcard.red .ix{color:var(--suit)}

.pcard b{display:block; color:var(--ink); font-weight:500; font-size:var(--fs-lede); margin-bottom:var(--s-3)}
.pcard p{margin:0; color:var(--mid); font-size:var(--fs-small); line-height:1.75}

/* the big watermark suit behind the copy */
.pcard .pip{
  position:absolute; right:var(--s-5); top:50%; transform:translateY(-50%);
  font-size:clamp(90px,9vw,132px); line-height:1; color:var(--ink);
  opacity:.045; z-index:-1; pointer-events:none; user-select:none;
}
.pcard.red .pip{color:var(--suit); opacity:.07}

/* ═══ chart ════════════════════════════════════════════════════════════════
   Thin, flat, unlit. One fill for solved, one for unclaimed, nothing else. */
/* The chart scrolls sideways rather than compressing. Its min-width grows
   with the number of riddles, so column labels never collide no matter how
   long the archive gets. */
.chart-scroll{overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch}
.chart{width:100%; height:auto; display:block}
.chart .axis{stroke:var(--rule); stroke-width:1}
.chart .tick line{stroke:var(--rule-soft); stroke-width:1}
.chart .tl{fill:var(--faint); font-family:var(--mono); font-size:10px; text-anchor:end}
/* Unclaimed: hollow, with an outline that keeps travelling. That money is
   still out there, so the mark is not allowed to look settled. */
.chart .bar rect{
  fill:none; stroke:var(--rule); stroke-width:1.25;
  stroke-dasharray:4 4; animation:grow .6s cubic-bezier(.2,.8,.3,1) both, march 22s linear infinite;
  animation-delay:var(--d,0ms), 0s;
  transform-box:fill-box; transform-origin:bottom;
}
/* Solved: solid. It is finished and it is gone. */
.chart .bar.won rect{
  fill:var(--acc); stroke:none; stroke-dasharray:none;
  animation:grow .6s cubic-bezier(.2,.8,.3,1) both; animation-delay:var(--d,0ms);
}
.chart .bar:hover rect{stroke:var(--ink)}
.chart .bar.won:hover rect{fill:var(--ink)}
@keyframes march{to{stroke-dashoffset:-160}}
.chart .bl{fill:var(--ink); font-family:var(--mono); font-size:12px; text-anchor:middle}
.chart .bs{fill:var(--faint); font-family:var(--mono); font-size:9px; text-anchor:middle; letter-spacing:.1em}
.chart .bv{fill:var(--dim); font-family:var(--mono); font-size:11px; text-anchor:middle}
.chart .bar.won .bv{fill:var(--acc)}
@keyframes grow{from{transform:scaleY(0)}}

.kpis{display:grid; grid-template-columns:repeat(3,1fr); border-top:1px solid var(--rule-soft)}
.kpi{padding:var(--s-4); border-right:1px solid var(--rule-soft); border-bottom:1px solid var(--rule-soft)}
.kpi:nth-child(3n){border-right:0}
.kpi:nth-last-child(-n+3){border-bottom:0}
.kpi .v{font-size:clamp(22px,2.4vw,32px); font-weight:500; color:var(--ink);
  margin-top:var(--s-2); font-variant-numeric:tabular-nums; letter-spacing:-.02em}
.kpi .v.acc{color:var(--acc)}
.kpi .v.warnv{color:var(--ink)}

/* ═══ docs ═════════════════════════════════════════════════════════════════ */
.doc{display:grid; grid-template-columns:210px minmax(0,1fr); gap:var(--s-6); align-items:start}

.toc{position:sticky; top:78px}
.toc ol{list-style:none; margin:var(--s-3) 0 0; padding:0; counter-reset:toc;
  display:flex; flex-direction:column; gap:var(--s-2)}
.toc li{counter-increment:toc}
.toc a{
  display:flex; gap:var(--s-2); text-decoration:none; color:var(--dim);
  font-size:var(--fs-small); line-height:1.4;
  border-left:1px solid var(--rule-soft); padding:3px 0 3px var(--s-3);
}
.toc a::before{content:counter(toc,decimal-leading-zero); color:var(--faint); flex:none}
.toc a:hover{color:var(--ink)}
.toc a[aria-current]{color:var(--ink); border-left-color:var(--ink)}

.doc-body{max-width:70ch}
.doc-body h2{
  font-size:clamp(20px,2.2vw,28px); margin:var(--s-6) 0 var(--s-3);
  padding-top:var(--s-4); border-top:1px solid var(--rule-soft);
}
.doc-body > h2:first-child{margin-top:0; padding-top:0; border-top:0}
.doc-body h3{margin:var(--s-5) 0 var(--s-2); font-size:var(--fs-lede)}
.doc-body p{margin:0 0 var(--s-3); color:var(--mid); line-height:1.8}
.doc-body b{color:var(--ink); font-weight:500}
.doc-body em{color:var(--ink); font-style:italic}

/* the one line per section that carries the point */
.doc-body .callout{
  border-left:2px solid var(--acc); padding:var(--s-3) 0 var(--s-3) var(--s-4);
  color:var(--ink); margin:var(--s-4) 0;
}
.doc-body .note{color:var(--dim); font-size:var(--fs-small); line-height:1.75}

.steps-list{margin:0 0 var(--s-4); padding:0; list-style:none; counter-reset:st}
.steps-list li{
  counter-increment:st; position:relative; padding-left:var(--s-6);
  margin-bottom:var(--s-4); color:var(--mid); line-height:1.8;
}
.steps-list li::before{
  content:counter(st,decimal-leading-zero); position:absolute; left:0; top:0;
  font-size:var(--fs-small); color:var(--faint);
}

.doorgrid{display:grid; grid-template-columns:1fr 1fr; gap:var(--s-3); margin:var(--s-4) 0}
.door{border:1px solid var(--rule); border-radius:8px; padding:var(--s-4); background:var(--paper)}
.door b{display:block; color:var(--ink); font-weight:500; margin:var(--s-2) 0}
.door p{margin:0; font-size:var(--fs-small); line-height:1.7}

/* ═══ riddle-page hero ═════════════════════════════════════════════════════
   Copy on the left, the image sitting top-right. Same shape as the landing
   hero, which is what makes the two pages feel like one site. */
.phero{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.92fr);
  gap:var(--s-6); align-items:start; margin-top:var(--s-5);
}
.phero-copy{padding-top:var(--s-2)}
.phero .shead{margin-bottom:var(--s-4)}

.shot{margin:0}
.shot img{width:100%; border:1px solid var(--rule)}
.shot figcaption{
  margin-top:var(--s-3); font-size:var(--fs-micro); letter-spacing:.04em;
  color:var(--faint); text-align:right;
}

/* ═══ filters ══════════════════════════════════════════════════════════════ */
.filters{display:flex; align-items:center; gap:var(--s-2); flex-wrap:wrap; margin-bottom:var(--s-4)}
.chip{
  border:1px solid var(--rule); background:transparent; color:var(--dim);
  font:inherit; font-size:var(--fs-small); padding:7px var(--s-3); cursor:pointer;
  transition:color .15s, border-color .15s, background .15s;
}
.chip:hover{color:var(--ink); border-color:var(--ink)}
.chip[aria-pressed="true"]{background:var(--btn-bg); border-color:var(--btn-bg); color:var(--btn-fg)}
.more{display:flex; justify-content:center; margin-top:var(--s-5)}

/* ═══ the archive list ═════════════════════════════════════════════════════
   Collapsed rows, expanded on demand. A list stays scannable at any length,
   where a grid of full cards stops working after about a dozen. */
.deck{display:flex; flex-direction:column; border:1px solid var(--rule); background:var(--paper)}

.rrow{border-bottom:1px solid var(--rule-soft)}
.rrow:last-child{border-bottom:0}

.rrow > summary{
  display:grid; align-items:center; gap:var(--s-4); cursor:pointer;
  grid-template-columns:38px minmax(0,1fr) 120px 90px 90px 20px;
  padding:var(--s-3) var(--s-4); list-style:none;
  transition:background .15s;
}
.rrow > summary::-webkit-details-marker{display:none}
.rrow > summary:hover{background:var(--paper-2)}
.rrow[open] > summary{background:var(--paper-2); border-bottom:1px solid var(--rule-soft)}

.rr-ix{display:flex; align-items:center; gap:3px; color:var(--ink); font-size:var(--fs-small)}
.rrow.red .rr-ix{color:var(--suit)}
.rr-name{color:var(--ink); font-size:var(--fs-base); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.rr-out{
  display:inline-flex; align-items:center; gap:6px;
  font-size:var(--fs-micro); letter-spacing:var(--track); text-transform:uppercase; color:var(--dim);
}
.rr-out.won{color:var(--acc)}
.rr-prize{color:var(--ink); text-align:right; font-variant-numeric:tabular-nums}
.rr-when{color:var(--faint); font-size:var(--fs-small); text-align:right}
.rr-caret{color:var(--faint); text-align:center; transition:transform .22s cubic-bezier(.2,.8,.3,1)}
.rrow[open] .rr-caret{transform:rotate(45deg)}

.rr-body{padding:var(--s-4) var(--s-4) var(--s-5) calc(var(--s-4) + 38px + var(--s-4))}
.rr-body .clue{font-size:14px}
.rr-cols{display:grid; grid-template-columns:1fr 1fr; gap:var(--s-4); margin-top:var(--s-4)}
.rr-body .lbl{display:block; margin-bottom:var(--s-2)}
.rr-body p{margin:0 0 var(--s-3); color:var(--mid); font-size:var(--fs-small)}
.rr-body .term + .lbl{margin-top:var(--s-4)}

/* the expand itself */
.rrow[open] .rr-body{animation:unfold .28s cubic-bezier(.2,.8,.3,1) both}
@keyframes unfold{from{opacity:0; transform:translateY(-6px)} to{opacity:1; transform:none}}

/* ═══ the deck: one card per past riddle ═══════════════════════════════════ */

.riddlecard{
  position:relative; isolation:isolate;
  background:var(--paper); border:1px solid var(--rule); border-radius:8px;
  padding:var(--s-5) var(--s-5) var(--s-4);
  box-shadow:0 1px 0 rgba(10,10,10,.04);
  transition:transform .18s cubic-bezier(.2,.8,.3,1), box-shadow .18s ease;
}
.riddlecard::after{
  content:""; position:absolute; inset:7px; border:1px solid var(--rule-soft);
  border-radius:4px; pointer-events:none; z-index:-1;
}
.riddlecard:hover{
  transform:translateY(-4px);
  box-shadow:0 8px 20px rgba(10,10,10,.07);
  border-color:var(--dim);
}

.riddlecard .ix{
  position:absolute; display:flex; flex-direction:column; align-items:center;
  line-height:1; font-size:14px; color:var(--ink); font-weight:500;
}
.riddlecard .ix .s{font-size:13px; margin-top:3px}
.riddlecard .ix.tl{top:var(--s-3); left:var(--s-3)}
.riddlecard .ix.br{bottom:var(--s-3); right:var(--s-3); transform:rotate(180deg)}
.riddlecard.red .ix{color:var(--suit)}

.riddlecard .pip{
  position:absolute; right:var(--s-5); top:var(--s-5);
  font-size:clamp(70px,6vw,96px); line-height:1; color:var(--ink);
  opacity:.04; z-index:-1; pointer-events:none; user-select:none;
}
.riddlecard.red .pip{color:var(--suit); opacity:.06}

.rc-head{
  display:flex; align-items:baseline; gap:var(--s-3); flex-wrap:wrap;
  padding-left:var(--s-4); margin-bottom:var(--s-4);
}
.rc-head b{font-size:var(--fs-lede); font-weight:500; color:var(--ink)}
.rc-out{
  margin-left:auto; display:inline-flex; align-items:center; gap:6px;
  font-size:var(--fs-micro); letter-spacing:var(--track);
  text-transform:uppercase; color:var(--dim);
}
.rc-out.won{color:var(--acc)}

.rc-body{padding-left:var(--s-4)}
.rc-body .lbl{margin-top:var(--s-4); display:block}
.rc-body .clue{font-size:14px}

.rc-facts{display:grid; grid-template-columns:repeat(2,1fr); gap:var(--s-3) var(--s-4);
  margin:var(--s-4) 0 0; padding:var(--s-4) 0 0; border-top:1px solid var(--rule-soft)}
.rc-facts dt{font-size:var(--fs-micro); letter-spacing:var(--track);
  text-transform:uppercase; color:var(--dim)}
.rc-facts dd{margin:5px 0 0; color:var(--ink); font-size:var(--fs-small)}
.rc-facts dd.acc{color:var(--acc); font-size:var(--fs-stat)}

/* ═══ riddle ═══════════════════════════════════════════════════════════════ */
.riddle{display:grid; grid-template-columns:230px 1fr; gap:var(--s-5); align-items:start}
.screen{border:1px solid var(--rule); background:var(--paper-2); padding:var(--s-4)}
.screen .big{font-size:24px; color:var(--ink); margin-top:var(--s-2); font-variant-numeric:tabular-nums}
.screen .big.money{color:var(--acc)}
.clue{white-space:pre-wrap; font-size:15px; color:var(--ink); line-height:1.8; max-width:var(--measure)}
.clue-sm{font-size:13px; margin-top:var(--s-3); line-height:1.7}

/* ═══ the claim ════════════════════════════════════════════════════════════
   The money half of the riddle page. Kept visually calm on purpose: this is
   where someone types a thing worth real money, and a loud interface here
   reads as a trap. */
.claim{border:1px solid var(--rule); background:var(--paper)}

/* the three phases, as a rail across the top */
.rail{display:flex; border-bottom:1px solid var(--rule-soft)}
.rail .step{
  flex:1; padding:var(--s-3) var(--s-4); font-size:var(--fs-small);
  color:var(--faint); border-right:1px solid var(--rule-soft);
  display:flex; align-items:center; gap:var(--s-2);
  transition:background var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}
.rail .step:last-child{border-right:0}
.rail .step b{
  font-weight:400; width:18px; height:18px; flex:none; display:grid;
  place-items:center; border:1px solid currentColor; font-size:10px;
}
.rail .step.now{color:var(--btn-fg); background:var(--btn-bg)}
.rail .step.done{color:var(--acc)}

.claim-grid{display:grid; grid-template-columns:minmax(0,1fr) 250px}
.claim-form{padding:var(--s-5)}
.claim-side{
  padding:var(--s-5); border-left:1px solid var(--rule-soft);
  display:flex; flex-direction:column;
}
.claim-side .k{
  font-size:var(--fs-micro); letter-spacing:var(--track);
  text-transform:uppercase; color:var(--dim);
}
.claim-side .v{font-size:22px; color:var(--ink); margin:var(--s-1) 0 var(--s-4); font-variant-numeric:tabular-nums}
.claim-side .v.acc{color:var(--acc)}
.claim-side .sidefoot{
  margin-top:auto; padding-top:var(--s-4); border-top:1px solid var(--rule-soft);
  font-size:var(--fs-micro); color:var(--faint); line-height:1.7;
}

.field + .field{margin-top:var(--s-4)}
.field label{
  display:block; font-size:var(--fs-micro); letter-spacing:var(--track);
  text-transform:uppercase; color:var(--dim); margin-bottom:var(--s-2);
}
.field input{
  width:100%; background:var(--paper-2); border:1px solid var(--rule);
  color:var(--ink); font-family:var(--mono); font-size:16px;  /* 16px stops iOS zooming on focus */
  padding:13px var(--s-3); outline:none;
  transition:border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.field input:focus{border-color:var(--ink); background:var(--paper)}
.field input:disabled{color:var(--faint)}
.field .hint{font-size:var(--fs-small); color:var(--faint); margin-top:var(--s-2)}

.claim-form .btn{margin-top:var(--s-5); justify-content:center}
.alt{
  display:block; margin-top:var(--s-3); padding:0; border:0; background:none;
  color:var(--dim); font:inherit; font-size:var(--fs-small); cursor:pointer;
  text-decoration:underline; text-underline-offset:3px;
}
.alt:hover:not(:disabled){color:var(--ink)}
.alt:disabled{color:var(--faint); cursor:default; text-decoration:none}

.msg{
  margin-top:var(--s-4); padding:var(--s-3) var(--s-4);
  border-left:2px solid var(--rule); font-size:var(--fs-base);
  white-space:pre-wrap; color:var(--mid); line-height:1.7;
}
.msg.bad{border-color:var(--bad); color:var(--bad)}
.msg.good{border-color:var(--acc); color:var(--acc)}
.msg.work{border-color:var(--warn)}
.hide{display:none}

/* ═══ terminal block ═══════════════════════════════════════════════════════ */
.term{border:1px solid var(--rule); background:var(--paper-2)}
.term .path{padding:7px var(--s-3); border-bottom:1px solid var(--rule-soft);
  font-size:var(--fs-micro); letter-spacing:var(--track); text-transform:uppercase; color:var(--faint)}
.term .r{display:flex; align-items:stretch}
.term code{flex:1; min-width:0; padding:12px var(--s-3); font-family:var(--mono);
  font-size:var(--fs-small); color:var(--ink); overflow-x:auto; white-space:nowrap}
.term code .p{color:var(--faint); user-select:none}
.term button{flex:none; border:0; border-left:1px solid var(--rule-soft); background:transparent;
  color:var(--dim); cursor:pointer; padding:0 var(--s-3);
  font-family:var(--mono); font-size:var(--fs-micro); letter-spacing:var(--track)}
.term button:hover{color:var(--ink)}
.band-dark .term{background:var(--dark); border-color:var(--dark-rule)}
.band-dark .term code{color:var(--dark-ink)}
.band-dark .term .path{border-color:var(--dark-rule)}
.band-dark .term button{border-color:var(--dark-rule); color:var(--dark-dim)}

/* ═══ tables ═══════════════════════════════════════════════════════════════ */
.scroll-x{overflow-x:auto}
table{width:100%; border-collapse:collapse; font-size:var(--fs-small)}
th{text-align:left; font-size:var(--fs-micro); letter-spacing:var(--track); text-transform:uppercase;
  color:var(--dim); font-weight:400; padding:0 var(--s-3) 10px 0;
  border-bottom:1px solid var(--rule); white-space:nowrap}
td{padding:11px var(--s-3) 11px 0; border-bottom:1px solid var(--rule-soft); color:var(--mid)}
th:last-child,td:last-child{padding-right:0}
td.n,th.n{text-align:right; font-variant-numeric:tabular-nums}
td.hot{color:var(--ink)}
td.acc{color:var(--acc)}
tr:last-child td{border-bottom:0}
.rank{color:var(--faint); font-variant-numeric:tabular-nums}

/* ═══ feed ═════════════════════════════════════════════════════════════════ */
.rows{display:flex; flex-direction:column; font-size:var(--fs-small)}
.row{display:grid; grid-template-columns:auto 1fr auto; gap:var(--s-3);
  align-items:baseline; padding:var(--s-2) 0; border-bottom:1px solid var(--rule-soft)}
.row:last-child{border-bottom:0}
.row .t{color:var(--faint); font-variant-numeric:tabular-nums}
.row .who{color:var(--ink); overflow:hidden; text-overflow:ellipsis}
.row .amt{color:var(--acc); font-variant-numeric:tabular-nums; white-space:nowrap}
.row .amt.flag{color:var(--dim)}

/* ═══ preloader ════════════════════════════════════════════════════════════ */
.boot{position:fixed; inset:0; z-index:9999; background:var(--paper);
  display:grid; place-items:center; padding:var(--s-4); transition:opacity .35s ease}
.boot.gone{opacity:0; pointer-events:none}
.boot-in{width:min(460px,100%)}
.boot pre{margin:0 0 var(--s-4); font-family:var(--mono); font-size:var(--fs-small);
  color:var(--dim); line-height:1.95; white-space:pre-wrap; min-height:9.5em}
.boot-bar{height:1px; background:var(--rule-soft); overflow:hidden}
.boot-bar span{display:block; height:100%; width:34%; background:var(--ink); animation:scan 1.15s ease-in-out infinite}
@keyframes scan{0%{transform:translateX(-100%)} 100%{transform:translateX(400%)}}

/* ═══ footer ═══════════════════════════════════════════════════════════════ */
footer{border-top:1px solid var(--rule); padding:var(--s-6) var(--gut) var(--s-5)}
footer .in{max-width:var(--page); margin-inline:auto}
.fcols{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-4)}
.fcol ul{list-style:none; margin:var(--s-3) 0 0; padding:0; display:flex; flex-direction:column; gap:var(--s-2)}
.fcol li{font-size:var(--fs-small); color:var(--dim)}
.fcol a{text-decoration:none}
.fcol a:hover{color:var(--ink)}
.fbase{display:flex; justify-content:space-between; gap:var(--s-4); flex-wrap:wrap;
  margin-top:var(--s-6); padding-top:var(--s-4); border-top:1px solid var(--rule-soft);
  font-size:var(--fs-micro); letter-spacing:.06em; color:var(--faint)}

/* ═══ responsive ═══════════════════════════════════════════════════════════ */
@media (max-width:1000px){
  :root{--rhythm:56px}
  .cards{grid-template-columns:1fr}
  .hero{grid-template-columns:1fr; gap:var(--s-5)}

  /* The emblem leads on a phone. On a wide screen the headline sits beside
     it and both are seen at once; stacked, the first screen is one thing
     only, and the figure says what this is faster than a sentence does. */
  .hero .emblem{order:-1; max-width:300px; margin-inline:auto}
  .hero .copy{order:1}
  .replay{grid-template-columns:1fr; min-height:0}
  .replay .side{border-left:0; border-top:1px solid var(--dark-rule);
    flex-direction:row; flex-wrap:wrap; gap:var(--s-4)}
  .replay .side .foot{margin-top:0; flex-basis:100%}
}
@media (max-width:760px){
  :root{--gut:18px}
  .topbar .in{height:auto; padding-block:var(--s-2); flex-wrap:wrap; gap:var(--s-2)}
  /* The nav scrolls sideways on a phone; the theme toggle has to sit outside
     that scroller or it ends up parked off the right edge of the page. */
  .topbar nav{
    margin-left:0; width:100%; gap:var(--s-4);
    overflow-x:auto; padding-bottom:2px; align-items:center;
  }
  .themetoggle{margin-left:auto; flex:none}
  .cards, .cards-2{grid-template-columns:1fr}
  .crumb{display:none}
  .steps{grid-template-columns:1fr}
  .stepcard{border-right:0; border-bottom:1px solid var(--rule-soft)}
  .stepcard:last-child{border-bottom:0}

  /* Two across, not one. Six stacked numbers made the archive header a
     screen and a half of scrolling before a single riddle appeared. */
  .kpis{grid-template-columns:repeat(2,1fr)}
  .kpi{padding:var(--s-3) var(--s-4)}
  .kpi .v{font-size:clamp(20px,6vw,26px)}
  .kpi:nth-child(3n){border-right:1px solid var(--rule-soft)}
  .kpi:nth-child(2n){border-right:0}
  .kpi:nth-last-child(-n+3){border-bottom:1px solid var(--rule-soft)}
  .kpi:nth-last-child(-n+2){border-bottom:0}
  .riddle{grid-template-columns:1fr}
  .fcols{grid-template-columns:repeat(2,1fr); gap:var(--s-5)}
  .deck{grid-template-columns:1fr}
  .rc-facts{grid-template-columns:1fr}

  /* The archive row keeps a six-column desktop template otherwise, which is
     ~446px of fixed track and overflows a phone by about 200px. */
  .rrow > summary{
    grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-areas:"ix name caret" "out out prize" ". . when";
    gap:var(--s-2) var(--s-3);
  }
  .rr-ix{grid-area:ix}
  .rr-name{grid-area:name; white-space:normal}
  .rr-out{grid-area:out}
  .rr-prize{grid-area:prize}
  .rr-when{grid-area:when}
  .rr-caret{grid-area:caret}

  .rr-body{padding-left:var(--s-4)}
  .rr-cols{grid-template-columns:1fr}
  .doc{grid-template-columns:1fr}
  .toc{position:static}
  .doorgrid{grid-template-columns:1fr}
  .phero{grid-template-columns:1fr}

  /* the claim stacks, and the phase rail scrolls rather than crushing */
  .claim-grid{grid-template-columns:1fr}
  .claim-side{border-left:0; border-top:1px solid var(--rule-soft)}
  .claim-side .sidefoot{margin-top:var(--s-3)}
  .claim-form{padding:var(--s-4)}
  .rail{overflow-x:auto}
  .rail .step{white-space:nowrap; flex:none}
}

/* Long hex strings are the other overflow source: the code line is nowrap by
   design so an address stays selectable in one piece, so the block it sits in
   has to be allowed to shrink and scroll rather than push the page wider. */
.term{max-width:100%; overflow:hidden}
.term .r{min-width:0}
.term code{min-width:0}
@media (max-width:1000px){
  .deck{grid-template-columns:1fr}
  .phero{grid-template-columns:1fr; gap:var(--s-5)}
  .shot figcaption{text-align:left}
}
