@charset "utf-8";
/* ============================================================================
   SuerMarioBrosCoin — site.css
   Late-80s cartridge label meets a modern dark terminal.
   Dark is the default and the design; the light theme only re-points tokens.

   0.  Tokens
   1.  Reset + base typography
   2.  Reveal (scroll-in) primitive
   3.  Skip link
   4.  Site header  — wordmark, nav toggle, nav, language toggle
   5.  Shared components — buttons, chips, section scaffolding
   6.  Hero — layout, staggered entrance, idle portrait float
   6b. Contract band
   6c. Ticker strip — the clipped marquee between hero and contract
   7.  Receipt
   8.  Lore
   9.  Tokenomics
   10. Ledger — table, hover, rollout 6 anomaly pulse
   11. Arcade — game cards, canvas stage, HUD, touch pad
   12. Footer
   13. Konami CRT easter egg
   14. Reduced motion / no-script safety nets
   ========================================================================== */


/* ============================================================================
   0. TOKENS
   Every colour is declared here on bare :root. The light block below
   re-points these same names and introduces nothing new.
   ========================================================================== */
:root {
  color-scheme: dark light;

  /* --- palette sampled off the sprite artwork ---------------------------- */
  --sky:    #6EA5FF;   /* flat sky behind the creature   */
  --body:   #C0FF72;   /* the creature itself            */
  --gold:   #F6D142;   /* sand                           */
  --crown:  #FFCC00;   /* crown                          */
  --red:    #F54435;   /* boots                          */

  /* --- surfaces + ink ---------------------------------------------------- */
  --ink:    #0B0D14;
  --ink-2:  #141824;
  --ink-3:  #1C2233;
  --line:   #2A3145;
  --text:   #E8ECF8;
  --muted:  #9AA6C4;

  /* --- semantic ---------------------------------------------------------- */
  --brand:      var(--body);
  --on-brand:   #0B0D14;
  --accent:     var(--sky);
  --focus:      var(--crown);
  --shadow:     #04050A;
  --screen:     #05070E;
  --on-screen:  var(--text);   /* foreground for anything sitting on --screen */
  --on-accent:  var(--ink);    /* foreground for anything sitting on --accent */

  /* --- washes + decoration ---------------------------------------------- */
  --dot:        rgba(110, 165, 255, .16);
  --scan:       rgba(0, 0, 0, .30);
  --scan-lite:  rgba(255, 255, 255, .03);
  --red-wash:   rgba(245, 68, 53, .12);
  --gold-wash:  rgba(246, 209, 66, .08);
  --overlay-bg: rgba(11, 13, 20, .88);
  --hover:      rgba(110, 165, 255, .10);

  /* --- type -------------------------------------------------------------- */
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-display: "Press Start 2P", var(--font-mono);

  /* --- metrics ----------------------------------------------------------- */
  --gutter: clamp(16px, 4vw, 48px);
  --shell: 1180px;
  --measure: 68ch;
  --bd: 3px;
  --pop: 6px;
  --header-h: 84px;
}

/* Light scheme. Two entry points: the OS preference for viewers who never chose,
   and an explicit data-theme="light" stamp, which must also beat a dark OS. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --sky:    #1F5FD6;
    --body:   #4C7F05;
    --gold:   #9C6F00;
    --crown:  #8A5E00;
    --red:    #C32718;

    --ink:    #F3F0E3;
    --ink-2:  #FFFFFF;
    --ink-3:  #E9E5D5;
    --line:   #12161F;
    --text:   #0B0D14;
    --muted:  #4B5670;

    --on-brand:   #FFFFFF;
    --shadow:     #12161F;
    --screen:     #10131C;
    --on-screen:  #F3F0E3;
    --on-accent:  #FFFFFF;

    --dot:        rgba(18, 22, 31, .16);
    --scan:       rgba(18, 22, 31, .10);
    --scan-lite:  rgba(255, 255, 255, .18);
    --red-wash:   rgba(195, 39, 24, .10);
    --gold-wash:  rgba(156, 111, 0, .12);
    --overlay-bg: rgba(243, 240, 227, .92);
    --hover:      rgba(31, 95, 214, .10);
  }
}

:root[data-theme="light"] {
    --sky:    #1F5FD6;
    --body:   #4C7F05;
    --gold:   #9C6F00;
    --crown:  #8A5E00;
    --red:    #C32718;

    --ink:    #F3F0E3;
    --ink-2:  #FFFFFF;
    --ink-3:  #E9E5D5;
    --line:   #12161F;
    --text:   #0B0D14;
    --muted:  #4B5670;

    --on-brand:   #FFFFFF;
    --shadow:     #12161F;
    --screen:     #10131C;
    --on-screen:  #F3F0E3;
    --on-accent:  #FFFFFF;

    --dot:        rgba(18, 22, 31, .16);
    --scan:       rgba(18, 22, 31, .10);
    --scan-lite:  rgba(255, 255, 255, .18);
    --red-wash:   rgba(195, 39, 24, .10);
    --gold-wash:  rgba(156, 111, 0, .12);
    --overlay-bg: rgba(243, 240, 227, .92);
    --hover:      rgba(31, 95, 214, .10);
}


/* ============================================================================
   1. RESET + BASE TYPOGRAPHY
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;                 /* belt-and-braces; nothing should need it */
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background-color: var(--ink);
  background-image: radial-gradient(var(--dot) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: 0 0;
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 16px;
  line-height: 1.65;
  overflow-wrap: break-word;        /* long dataset ids / uuids never push the page */
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-weight: 400; margin: 0; }
p, ul, ol, dl, dd, figure, pre { margin: 0; }
ul, ol { padding: 0; list-style: none; }

img, canvas {
  image-rendering: crisp-edges;
  image-rendering: pixelated;
  max-width: 100%;
}

a { color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { color: var(--text); }

button { font: inherit; color: inherit; }

/* one focus ring for the whole site */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 0;
}
/* the script parks focus on section wrappers after a nav jump — no ring there */
[tabindex="-1"]:focus { outline: none; }

::selection { background: var(--brand); color: var(--on-brand); }

.site-main { display: block; isolation: isolate; }

/* sticky header clearance for in-page anchors */
.hero[id], .section[id] { scroll-margin-top: var(--header-h); }


/* ============================================================================
   2. REVEAL PRIMITIVE
   Content is visible by default. The hidden state is opt-in and applies ONLY
   once a script that can undo it again has demonstrably run: site.js adds the
   `js` class to :root as the first thing it does at boot.
   If that class never appears — site.js 404s, is blocked by CSP or an
   extension, or throws — every [data-reveal] block stays readable and the only
   thing lost is the animation. `scripting: none` alone could not do this: it
   does not match when JS is enabled but the script simply never runs.
   ========================================================================== */
[data-reveal] {
  transition: opacity .5s ease, transform .5s cubic-bezier(.2, .7, .3, 1);
}
:root.js [data-reveal]:not(.is-visible) {
  opacity: 0;
  transform: translateY(12px);
  transition: none;              /* going hidden must never animate out */
}
[data-reveal].is-visible { opacity: 1; transform: none; }

/* belt and braces for scripting switched off outright */
@media (scripting: none) {
  [data-reveal] { opacity: 1; transform: none; }
}


/* ============================================================================
   3. SKIP LINK
   ========================================================================== */
.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 200;
  transform: translateY(-180%);
  padding: 12px 16px;
  background: var(--brand);
  color: var(--on-brand);
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  font-family: var(--font-display);
  font-size: 10px;
  line-height: 1.4;
  text-decoration: none;
  transition: transform .18s ease;
}
.skip-link:focus,
.skip-link:focus-visible { transform: translateY(0); color: var(--on-brand); }


/* ============================================================================
   4. SITE HEADER
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--ink);
  border-bottom: var(--bd) solid var(--line);
}
/* hard-stop cartridge stripe instead of a soft shadow */
.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--bd) * -1);
  height: var(--bd);
  background: linear-gradient(90deg,
    var(--red)   0 20%,
    var(--gold)  20% 40%,
    var(--body)  40% 60%,
    var(--sky)   60% 80%,
    var(--crown) 80% 100%);
}

.site-header__inner {
  position: relative;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: 10px;
  display: flex;
  flex-wrap: wrap;                 /* safety valve: nav drops, never overflows */
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

/* --- wordmark -------------------------------------------------------------*/
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  text-decoration: none;
  color: var(--text);
}
.wordmark__mark {
  flex: none;
  display: inline-block;
  padding: 4px 6px;
  background: var(--ink-2);
  border: 2px solid var(--gold);
  box-shadow: 3px 3px 0 var(--shadow);
  color: var(--gold);
  font-family: var(--font-display);
  font-size: 14px;
  line-height: 1;
}
.wordmark__name {
  font-family: var(--font-display);
  font-size: clamp(8px, 2.6vw, 14px);
  line-height: 1.2;
  letter-spacing: 0;
  white-space: nowrap;
}
.wordmark:hover .wordmark__name { color: var(--brand); }

/* --- hamburger ------------------------------------------------------------*/
.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: var(--ink-2);
  border: var(--bd) solid var(--line);
  box-shadow: 4px 4px 0 var(--shadow);
  cursor: pointer;
  transition: transform .08s steps(1), box-shadow .08s steps(1), background-color .15s;
}
.nav-toggle:hover { background: var(--ink-3); }
.nav-toggle:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--shadow); }
.nav-toggle[aria-expanded="true"] {
  background: var(--brand);
  color: var(--on-brand);
  border-color: var(--brand);
}
.nav-toggle__bars {
  position: relative;
  display: block;
  width: 16px;
  height: 3px;
  background: currentColor;
  box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor;
}
.nav-toggle__label {
  font-family: var(--font-display);
  font-size: 9px;
  line-height: 1;
}

/* --- nav ------------------------------------------------------------------*/
.site-nav {
  display: none;
  flex-basis: 100%;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding-block: 6px 12px;
  border-top: 2px solid var(--line);
}
.site-nav.is-open { display: flex; }

/* with scripting off the MENU button can never open anything, so retire it
   and leave the section links on the page instead */
@media (scripting: none) {
  .nav-toggle { display: none; }
  .site-nav { display: flex; }
}

.site-nav__list { display: flex; flex-direction: column; gap: 2px; }
.site-nav__item { min-width: 0; }
.site-nav__item + .site-nav__item { border-top: 1px solid var(--line); }

.site-nav__link {
  display: block;
  padding: 10px 8px;
  color: var(--muted);
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  border-left: var(--bd) solid transparent;
  transition: color .15s, background-color .15s, border-color .15s;
}
.site-nav__link:hover { color: var(--text); background: var(--hover); }
.site-nav__link.is-active { color: var(--accent); border-left-color: var(--accent); }

@media (min-width: 860px) {
  .nav-toggle { display: none; }
  .site-nav {
    display: flex;
    flex-basis: auto;
    flex-direction: row;
    align-items: center;
    gap: clamp(8px, 1.4vw, 18px);
    padding-block: 0;
    border-top: 0;
  }
  .site-nav__list { flex-direction: row; gap: 2px; }
  .site-nav__item + .site-nav__item { border-top: 0; }
  .site-nav__link {
    padding: 8px 6px;
    font-size: 11px;
    border-left: 0;
    border-bottom: var(--bd) solid transparent;
  }
  .site-nav__link.is-active { border-left-color: transparent; border-bottom-color: var(--accent); }
}
@media (min-width: 1060px) {
  .site-nav__link { padding: 8px 10px; font-size: 12px; }
}


/* ============================================================================
   5. SHARED COMPONENTS
   ========================================================================== */

/* --- buttons --------------------------------------------------------------*/
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 18px;
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  font-family: var(--font-display);
  font-size: clamp(9px, 2.2vw, 11px);
  line-height: 1.5;
  letter-spacing: .02em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
  transition: transform .08s steps(1), box-shadow .08s steps(1),
              background-color .15s, color .15s, border-color .15s;
}
.btn:active { transform: translate(2px, 2px); box-shadow: 4px 4px 0 var(--shadow); }

.btn--primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}
.btn--primary:hover { background: var(--crown); border-color: var(--crown); color: var(--on-brand); }

.btn--ghost {
  background: var(--ink-2);
  border-color: var(--accent);
  color: var(--accent);
}
.btn--ghost:hover { background: var(--accent); color: var(--ink); }

.btn--link {
  display: inline;                  /* keeps the underline unbroken under the arrow */
  padding: 0;
  /* padding on an inline box still enlarges the hit area without shifting the line */
  padding-block: 10px;
  border: 0;
  box-shadow: none;
  background: none;
  color: var(--gold);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
  text-align: left;
  justify-content: flex-start;
}
.btn--link::after { content: " >"; }
.btn--link:hover { color: var(--text); }
.btn--link:active { color: var(--crown); }

/* --- chips ----------------------------------------------------------------*/
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 7px 10px;
  background: var(--ink-2);
  border: 2px solid var(--line);
  box-shadow: 3px 3px 0 var(--shadow);
}
.chip__label {
  flex: none;
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.4;
  letter-spacing: .04em;
  color: var(--gold);
}
.chip__value {
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .02em;
  overflow-wrap: anywhere;
}

.chip--constraint {
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  border-color: var(--accent);
}
.chip__id {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  overflow-wrap: anywhere;
}
.chip__args {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: .03em;
  overflow-wrap: anywhere;
}

/* --- section scaffolding --------------------------------------------------*/
.section { border-top: var(--bd) solid var(--line); }
.section--lore,
.section--arcade { background-color: var(--ink-2); background-image: none; }

/* one palette colour per section, picked up by the kicker marker below */
.hero                { --tone: var(--gold); }
.section--receipt    { --tone: var(--gold); }
.contract            { --tone: var(--gold); }
.section--lore       { --tone: var(--sky); }
.section--tokenomics { --tone: var(--brand); }
.section--ledger     { --tone: var(--red); }
.section--arcade     { --tone: var(--crown); }

.section__inner {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: clamp(48px, 8vw, 104px);
}

.section__kicker,
.hero__kicker,
.game-card__kicker {
  font-family: var(--font-display);
  font-size: clamp(7px, 2.2vw, 10px);
  line-height: 1.8;
  letter-spacing: .1em;
  color: var(--accent);
  margin-bottom: 14px;
}
.section__kicker::before,
.hero__kicker::before,
.game-card__kicker::before {
  content: "";
  display: inline-block;
  width: .7em;
  height: .7em;
  margin-right: .7em;
  background: var(--tone, var(--gold));
  vertical-align: baseline;
}

.section__title {
  font-family: var(--font-display);
  font-size: clamp(1rem, 4.6vw, 2.25rem);
  line-height: 1.4;
  letter-spacing: 0;
  overflow-wrap: break-word;
  margin-bottom: 22px;
}

.section__intro {
  max-width: var(--measure);
  color: var(--muted);
  font-size: 16px;
  margin-bottom: clamp(28px, 4vw, 44px);
}


/* ============================================================================
   6. HERO
   ========================================================================== */
.hero { position: relative; border-top: 0; }

/* scanline film — decorative only */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    var(--scan) 0 2px,
    var(--scan-lite) 2px 4px);
  opacity: .18;
}

.hero__inner {
  position: relative;
  z-index: 1;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: clamp(40px, 7vw, 92px);
  display: grid;
  gap: clamp(28px, 5vw, 56px);
  align-items: center;
}

.hero__copy { min-width: 0; }

.hero__title {
  font-family: var(--font-display);
  font-size: clamp(.95rem, 4.6vw, 1.6rem);
  line-height: 1.3;
  letter-spacing: 0;
  overflow-wrap: break-word;
  margin-bottom: 18px;
}
/* the wordmark is 17 unbroken characters — size it off its own column */
@supports (container-type: inline-size) {
  .hero__copy { container-type: inline-size; }
  .hero__title { font-size: clamp(.95rem, 5.2cqw, 2.6rem); }
}

.hero__ticker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 22px;
}
.hero__ticker-value {
  font-family: var(--font-display);
  font-size: clamp(1rem, 3.4vw, 1.5rem);
  line-height: 1.3;
  color: var(--gold);
}
.hero__copy-btn {
  min-width: 12ch;
  padding: 9px 11px;
  background: var(--ink-2);
  border: 2px solid var(--gold);
  color: var(--gold);
  font-family: var(--font-display);
  font-size: 9px;
  line-height: 1.4;
  cursor: pointer;
  box-shadow: 3px 3px 0 var(--shadow);
  transition: transform .08s steps(1), box-shadow .08s steps(1),
              background-color .15s, color .15s;
}
.hero__copy-btn:hover { background: var(--gold); color: var(--on-brand); }
.hero__copy-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--shadow); }

.hero__hook {
  max-width: var(--measure);
  font-size: 17px;
  margin-bottom: 14px;
}
.hero__sub {
  max-width: var(--measure);
  color: var(--muted);
  font-size: 15px;
  margin-bottom: clamp(24px, 4vw, 34px);
}

.hero__supply {
  display: inline-block;
  max-width: 100%;
  padding: 16px 18px;
  background: var(--ink-2);
  border: var(--bd) solid var(--gold);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  margin-bottom: clamp(22px, 3.5vw, 32px);
}
.hero__supply-label {
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.6;
  letter-spacing: .12em;
  color: var(--muted);
  margin-bottom: 10px;
}
.hero__supply-figure { margin-bottom: 8px; }
.hero__supply-value {
  font-family: var(--font-display);
  font-size: clamp(.85rem, 4vw, 1.75rem);
  line-height: 1.25;
  color: var(--crown);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.hero__supply-raw {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: .02em;
  overflow-wrap: anywhere;
}

.hero__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: clamp(24px, 4vw, 34px);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

/* --- community links ------------------------------------------------------
   The two places people actually go. Kept as a plain list of outbound links
   with the same hard edges as everything else, deliberately quieter than the
   two calls to action above them so they do not compete with the arcade.
   -------------------------------------------------------------------------- */
.social {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.social__item { min-width: 0; }

.social__link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 13px;
  border: 2px solid var(--line);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.3;
  text-decoration: none;
  transition: color .15s, border-color .15s, background-color .15s;
}
.social__link:hover {
  color: var(--text);
  border-color: var(--gold);
  background: var(--hover);
}

.social__mark {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding-inline: 4px;
  background: var(--gold);
  color: var(--on-brand);
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1;
}

@media (pointer: coarse) {
  .social__link { min-height: 44px; }
}

.hero__portrait { min-width: 0; }
.hero__img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 420px;
  margin-inline: auto;
  background: var(--sky);
  border: var(--bd) solid var(--line);
  box-shadow: 10px 10px 0 var(--shadow);
}

@media (min-width: 900px) {
  .hero__inner { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); }
  .hero__img { max-width: 100%; }
}

/* --- entrance --------------------------------------------------------------
   Staggered and ungated: kicker at 0ms through to the buttons at 300ms, each
   pass 320ms long, so the last frame lands at ~620ms.
   Nothing here can strand content. The resting state of every element below —
   the state it has when no animation runs at all — is the finished, visible
   one; `backwards` holds the first frame only for that element's own delay,
   300ms at the outside, and that delay waits on no script, class or observer.
   If the animation never runs, the hero is simply already there.
   -------------------------------------------------------------------------- */
@keyframes hero-rise {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to   { opacity: 1; transform: none; }
}
@keyframes hero-art-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes hero-art-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -5px, 0); }
}

[data-anim="hero"] .hero__kicker,
[data-anim="hero"] .hero__title,
[data-anim="hero"] .hero__ticker,
[data-anim="hero"] .hero__hook,
[data-anim="hero"] .hero__sub,
[data-anim="hero"] .hero__supply,
[data-anim="hero"] [data-anim="chips"],
[data-anim="hero"] .hero__actions {
  animation: hero-rise .32s cubic-bezier(.2, .7, .3, 1) backwards;
}
[data-anim="hero"] .hero__title  { animation-delay: 60ms; }
[data-anim="hero"] .hero__ticker { animation-delay: 120ms; }
[data-anim="hero"] .hero__hook,
[data-anim="hero"] .hero__sub,
[data-anim="hero"] .hero__supply { animation-delay: 180ms; }
[data-anim="hero"] [data-anim="chips"] { animation-delay: 240ms; }
[data-anim="hero"] .hero__actions { animation-delay: 300ms; }

/* the portrait arrives with the title, from a hair further down */
[data-anim="art"] {
  animation: hero-art-in .34s cubic-bezier(.2, .7, .3, 1) 120ms backwards;
}

/* idle float: five pixels, nine seconds, on the <img> so it cannot collide
   with the entrance transform on the <figure>. Transform only — the hard
   offset shadow travels with it and nothing around it moves. */
[data-anim="art"] .hero__img {
  animation: hero-art-float 9s ease-in-out 1.4s infinite;
}


/* ============================================================================
   6b. CONTRACT
   The one element on the page that does not come out of row 26670, so it is
   banded off from the evidence sections instead of sitting among them.
   ========================================================================== */
.contract {
  border-block: var(--bd) solid var(--gold);
  background: var(--ink-2);
}

.contract__inner {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: clamp(22px, 4vw, 38px);
  display: grid;
  justify-items: start;
  gap: 14px;
}

.contract__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(9px, 2.2vw, 12px);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gold);
}

.contract__addr {
  margin: 0;
  width: 100%;
}

.contract__addr code {
  display: block;
  padding: 14px 16px;
  background: var(--ink);
  border: var(--bd) solid var(--gold);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: clamp(12px, 2.7vw, 19px);
  line-height: 1.55;
  letter-spacing: .02em;
  overflow-wrap: anywhere;   /* 42 characters must never widen the page */
  user-select: all;          /* one click takes the whole address */
}

.contract__note {
  margin: 0;
  max-width: var(--measure);
  color: var(--muted);
  font-size: 14px;
  line-height: 1.65;
}


/* ============================================================================
   6c. TICKER STRIP
   The record's headline numbers, on a loop, above the contract band.

   Why it cannot widen the page: .ticker is an ordinary block box whose used
   width is a min() of three things that are all <= the viewport, so it is
   never wider than its container; overflow: hidden makes it the clipping box,
   so the track's overflow ends here instead of being handed up to <main>; and
   the only thing that ever moves is a transform on the track, which adds
   nothing to an ancestor's scrollable overflow once it is clipped. No width,
   no margin and no scroll offset is animated.

   Why the loop is seamless: the track holds two identical copies of the line
   and travels exactly -50% of its own width, i.e. exactly one copy, so the
   frame at the end is the frame at the start. That only holds if the window
   is never wider than one copy — otherwise the tail of the second copy runs
   out mid-loop and leaves a hole. Hence the pair of 96ch numbers below: the
   strip is capped at 96ch and each line is floored at 96ch, both resolved
   against the same inherited font, so copy >= window by construction, with no
   assumption about which font actually loaded. The phrase measures ~116ch in
   Press Start 2P and ~124ch in the mono fallback (its floor for any font is
   96 characters + 8.8ch of separator and padding), so the min-width is
   insurance that never has to engage.

   Padding lives on the lines, inside the repeat unit. Any padding on the
   track would throw the -50% off by half of itself.
   ========================================================================== */
.ticker {
  display: flex;
  align-items: stretch;
  overflow: hidden;              /* the clip. everything above depends on it */
  width: min(96ch, var(--shell), calc(100% - 2 * var(--gutter)));
  margin: 0 auto clamp(26px, 4vw, 40px);
  background: var(--ink-2);
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  font-family: var(--font-display);
  font-size: 10px;
  line-height: 1.8;
  letter-spacing: .12em;
  color: var(--muted);
}

/* the track is wider than the strip and slides; the viewport is what clips it,
   so the moving text can never reach across the pause control and swallow its
   clicks the way it did when both were direct children of .ticker */
.ticker__viewport {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker-run 34s linear infinite;
}
@keyframes ticker-run {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }   /* -50% of two copies = one copy */
}

.ticker__line {
  flex: none;
  min-width: 96ch;               /* never narrower than the window it crosses */
  padding-block: 11px;
  padding-inline: 1.4ch;         /* identical on both copies, so the seam is even */
  white-space: nowrap;
}
.ticker__sep { margin-inline: .5ch; color: var(--gold); }

/* Park it while someone is reading it.
   :focus-within is inert as long as the strip holds nothing focusable (it is
   two <p> copies today), and :hover never fires on touch, so neither branch
   is a WCAG 2.2.2 mechanism on its own. .is-paused is the pointer-independent
   hook: index.html still has to grow the control that drives it — a
   .ticker__pause is that mechanism: a real focusable button, so the strip can
   be stopped by keyboard and by touch and not only by a hovering mouse, which
   is what WCAG 2.2.2 (Pause, Stop, Hide) actually asks for. Hover and
   focus-within stay as conveniences on top of it.                          */
/* Hover-to-read is scoped to the TEXT, not the whole strip. Scoped to .ticker it
   also covered the pause button, so after clicking resume the pointer was still
   hovering the strip and the animation never restarted; :focus-within had the
   same effect for the keyboard, and is now redundant next to a real button. */
.ticker__viewport:hover .ticker__track,
.ticker.is-paused .ticker__track { animation-play-state: paused; }

.ticker__pause {
  flex: none;
  position: relative;
  z-index: 1;
  align-self: stretch;
  padding-inline: 12px;
  background: var(--ink-2);
  border: 0;
  border-left: var(--bd) solid var(--line);
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1;
  letter-spacing: .1em;
  cursor: pointer;
  transition: color .15s, background-color .15s;
}
.ticker__pause:hover { color: var(--text); background: var(--ink-3); }
.ticker__pause[aria-pressed="true"] { color: var(--gold); }


/* ============================================================================
   7. RECEIPT
   ========================================================================== */
.receipt {
  background: var(--ink-2);
  border: var(--bd) solid var(--line);
  box-shadow: 8px 8px 0 var(--shadow);
}

/* fake terminal title bar */
.receipt__bar {
  display: flex;
  align-items: center;
  gap: 46px;
  padding: 10px 14px;
  background: var(--ink-3);
  border-bottom: var(--bd) solid var(--line);
}
.receipt__dot {
  flex: none;
  width: 9px;
  height: 9px;
  background: var(--red);
  box-shadow: 15px 0 0 var(--gold), 30px 0 0 var(--brand);
}
.receipt__bar-title {
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.4;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}

.receipt__list { padding: clamp(14px, 3vw, 24px); }

.receipt__row {
  display: grid;
  gap: 2px 18px;
  padding: 10px 10px;
  border-bottom: 1px solid var(--line);
}
.receipt__row:last-child { border-bottom: 0; }
.receipt__row--flag {
  background: var(--gold-wash);
  border-left: var(--bd) solid var(--gold);
}

.receipt__key {
  font-family: var(--font-display);
  font-size: 9px;
  line-height: 1.7;
  letter-spacing: .05em;
  color: var(--muted);
}
.receipt__val {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .01em;
  overflow-wrap: anywhere;
}
.receipt__val--uuid { font-size: 13px; font-weight: 400; color: var(--accent); }

@media (min-width: 620px) {
  .receipt__row { grid-template-columns: minmax(0, 190px) minmax(0, 1fr); align-items: baseline; }
}

/* --- verbatim prompt ------------------------------------------------------*/
.receipt__prompt-block {
  padding: clamp(14px, 3vw, 24px);
  border-top: var(--bd) solid var(--line);
  border-bottom: var(--bd) solid var(--line);
  background: var(--ink);
}
.receipt__prompt-label {
  font-family: var(--font-display);
  font-size: 9px;
  line-height: 1.7;
  letter-spacing: .1em;
  color: var(--gold);
  margin-bottom: 14px;
}
.receipt__prompt {
  margin-bottom: 18px;
  padding: 16px;
  background: var(--screen);
  border: 2px solid var(--line);
  border-left: var(--bd) solid var(--brand);
  color: var(--on-screen);
  font-family: var(--font-mono);
  font-size: 13.5px;
  line-height: 1.7;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  tab-size: 2;
}

.receipt__prompt-line { display: inline; }
.receipt__prompt::after {
  content: "";
  display: inline-block;
  width: .55em;
  height: 1em;
  margin-left: .18em;
  vertical-align: -.15em;
  background: var(--on-screen);
  animation: caret-blink 1.1s steps(2, end) infinite;
}
@keyframes caret-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

.receipt__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}
.receipt__prompt-note {
  max-width: var(--measure);
  font-size: 14px;
  color: var(--muted);
}

.receipt__note {
  max-width: var(--measure);
  padding: clamp(14px, 3vw, 24px);
  font-size: 14px;
  color: var(--text);
}
.receipt__verify {
  padding: 0 clamp(14px, 3vw, 24px) clamp(18px, 3vw, 26px);
}


/* ============================================================================
   8. LORE
   ========================================================================== */
.lore { display: grid; gap: clamp(18px, 3vw, 28px); }
.lore__item { min-width: 0; }

.lore-card {
  height: 100%;
  padding: clamp(18px, 3vw, 28px);
  background: var(--ink);
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
}
.lore-card__num {
  display: inline-block;
  padding: 6px 9px;
  margin-bottom: 16px;
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 3px 3px 0 var(--shadow);
  font-family: var(--font-display);
  font-size: 12px;
  line-height: 1;
}

.lore-card__title {
  font-family: var(--font-display);
  font-size: clamp(.72rem, 2.6vw, 1.1rem);
  line-height: 1.6;
  color: var(--gold);
  overflow-wrap: break-word;
  margin-bottom: 16px;
}
.lore-card__body {
  max-width: var(--measure);
  font-size: 15.5px;
  color: var(--text);
}

/* --- hover / focus ---------------------------------------------------------
   The lift rides on the <li>, never on .lore-card: the card carries
   [data-reveal], whose transform and transition belong to that primitive and
   are left exactly as they were. Border and shadow land in one step on the
   card itself, which is the cartridge idiom the buttons already use.
   -------------------------------------------------------------------------- */
.lore__item { transition: transform .18s cubic-bezier(.2, .7, .3, 1); }
.lore__item:hover,
.lore__item:focus-within { transform: translate3d(-2px, -2px, 0); }
.lore__item:hover .lore-card,
.lore__item:focus-within .lore-card {
  border-color: var(--tone, var(--accent));
  box-shadow: calc(var(--pop) + 2px) calc(var(--pop) + 2px) 0 var(--shadow);
}

@media (min-width: 1080px) {
  .lore { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


/* ============================================================================
   9. TOKENOMICS
   ========================================================================== */
.facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(14px, 2.5vw, 22px);
  margin-bottom: clamp(32px, 5vw, 52px);
}
.facts__item { min-width: 0; }

.fact {
  height: 100%;
  padding: clamp(16px, 2.6vw, 24px);
  background: var(--ink-2);
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
}
.fact--raw { border-color: var(--gold); background: var(--gold-wash); }

.fact__label {
  font-family: var(--font-display);
  font-size: 10px;
  line-height: 1.6;
  letter-spacing: .1em;
  color: var(--accent);
  margin-bottom: 14px;
}
.fact__value {
  font-size: clamp(1rem, 2.2vw, 1.1rem);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: .01em;
  overflow-wrap: anywhere;
  margin-bottom: 10px;
}
.fact__value--raw { color: var(--gold); font-size: clamp(.9rem, 2vw, 1.05rem); }
.fact__note { font-size: 13.5px; line-height: 1.6; color: var(--muted); }

.prose { max-width: var(--measure); }
.prose__p { font-size: 16px; margin-bottom: 18px; }
.prose__p:last-child { margin-bottom: 0; }

@media (min-width: 760px) {
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* four across only once each card can hold SuerMarioBrosCoin unbroken */
@media (min-width: 1180px) {
  .facts { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}


/* ============================================================================
   10. LEDGER
   ========================================================================== */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  background: var(--ink-2);
  margin-bottom: 22px;
}

.ledger {
  width: 100%;
  min-width: 30rem;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

/* the caption repeats the section kicker verbatim — kept for screen readers only */
.ledger__caption {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ledger__head { background: var(--ink-3); }
.ledger__th {
  padding: 14px 12px;
  text-align: left;
  font-family: var(--font-display);
  font-size: 8px;
  font-weight: 400;
  line-height: 1.7;
  letter-spacing: .08em;
  color: var(--gold);
  border-bottom: var(--bd) solid var(--line);
}

.ledger__body td {
  padding: 12px;
  font-size: 14px;
  border-bottom: 1px solid var(--line);
}
.ledger__body tr:last-child td { border-bottom: 0; }
.ledger__body tr:hover { background: var(--hover); }

.ledger td[data-col="rollout"] { font-weight: 600; color: var(--accent); white-space: nowrap; }
.ledger td[data-col="reward"] { font-weight: 600; color: var(--brand); white-space: nowrap; }
.ledger td[data-col="out"]    { text-align: right; white-space: nowrap; }
.ledger td[data-col="verdict"]{ color: var(--muted); }

.ledger__body tr.is-failed { background: var(--red-wash); }
.ledger__body tr.is-failed td { color: var(--red); }
.ledger__body tr.is-failed td[data-col="rollout"],
.ledger__body tr.is-failed td[data-col="reward"],
.ledger__body tr.is-failed td[data-col="verdict"] { color: var(--red); font-weight: 600; }

/* --- hover / focus: the rows read as objects, nothing reflows -------------- */
.ledger__body tr {
  transition: background-color .18s ease,
              transform .18s cubic-bezier(.2, .7, .3, 1);
}
.ledger__body tr:hover,
.ledger__body tr:focus-within { transform: translate3d(0, -1px, 0); }
.ledger__body tr:not(.is-failed):hover td[data-col="verdict"],
.ledger__body tr:not(.is-failed):focus-within td[data-col="verdict"] { color: var(--text); }

/* --- rollout 6, the one that came back 0.0 ---------------------------------
   The row already reads red. The pulse only makes it breathe, so the eye finds
   the anomaly in a column of eights: opacity alone, 3.6s, a 22% dip — no
   colour strobe, no layout, nothing that moves. It parks on hover and focus so
   the row can be read still.
   Bound to BOTH spellings on purpose. site.js empties [data-ledger-body] and
   re-renders the eight rows from lore-data.js, and the row it builds carries
   `is-failed` only — so .ledger__row--failed is the markup contract and holds
   before the script runs and with scripting off, while .is-failed is the one
   that survives the rebuild. Either alone would leave the anomaly unmarked in
   one of the two states the page has to be correct in.
   -------------------------------------------------------------------------- */
.ledger__row--failed td[data-col="rollout"],
.ledger__body tr.is-failed td[data-col="rollout"] { box-shadow: inset 3px 0 0 var(--red); }

.ledger__row--failed,
.ledger__body tr.is-failed { animation: anomaly-pulse 3.6s ease-in-out 1.2s infinite; }
@keyframes anomaly-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .78; }
}
.ledger__row--failed:hover,
.ledger__row--failed:focus-within,
.ledger__body tr.is-failed:hover,
.ledger__body tr.is-failed:focus-within { animation-play-state: paused; }

.ledger__note {
  max-width: var(--measure);
  font-size: 14px;
  color: var(--muted);
  letter-spacing: .02em;
}


/* ============================================================================
   11. ARCADE
   ========================================================================== */
.arcade__blurb {
  max-width: var(--measure);
  font-size: 15px;
  color: var(--muted);
  margin-bottom: clamp(24px, 4vw, 36px);
}
.arcade__noscript {
  max-width: var(--measure);
  padding: 14px 16px;
  margin-bottom: 24px;
  background: var(--red-wash);
  border: var(--bd) solid var(--red);
  color: var(--text);
  font-size: 14px;
}

.arcade {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(24px, 4vw, 40px);
  align-items: start;
}

.game-card {
  min-width: 0;
  padding: clamp(16px, 3vw, 28px);
  background: var(--ink);
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
}
.game-card__kicker { margin-bottom: 10px; }
.game-card__title {
  font-family: var(--font-display);
  font-size: clamp(.8rem, 2.8vw, 1.15rem);
  line-height: 1.5;
  color: var(--brand);
  overflow-wrap: break-word;
  margin-bottom: 14px;
}
.game-card__intro {
  max-width: var(--measure);
  font-size: 15px;
  color: var(--text);
  margin-bottom: 12px;
}
.game-card__controls {
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.9;
  letter-spacing: .04em;
  color: var(--muted);
  margin-bottom: 18px;
}

/* --- hover / focus ---------------------------------------------------------
   The same 2px lift as the lore cards. The :has() guard drops the whole rule
   while a cabinet is blown up: a transform on an ancestor becomes the
   containing block for .game.is-cinema (position: fixed) and would pin the
   fullscreen fallback inside its own card. Hovering the card still matches
   while the overlay is up, because :hover propagates to ancestors — hence the
   guard rather than a z-index fix. Browsers without :has() drop the rule and
   get no lift, which is the safe direction to fail in.
   -------------------------------------------------------------------------- */
.game-card {
  transition: transform .18s cubic-bezier(.2, .7, .3, 1),
              box-shadow .18s ease,
              border-color .18s ease;
}
.game-card:not(:has(.is-full, .is-cinema)):hover,
.game-card:not(:has(.is-full, .is-cinema)):focus-within {
  transform: translate3d(-2px, -2px, 0);
  box-shadow: calc(var(--pop) + 2px) calc(var(--pop) + 2px) 0 var(--shadow);
  border-color: var(--tone, var(--gold));
}

/* --- the machine ----------------------------------------------------------*/
.game {
  background: var(--ink-2);
  border: var(--bd) solid var(--line);
  box-shadow: var(--pop) var(--pop) 0 var(--shadow);
  margin-bottom: 18px;
}

.game__screen {
  position: relative;
  overflow: hidden;
  background: var(--screen);
  color: var(--on-screen);       /* the <canvas> fallback text lives in here */
}
/* lets the overlay scale to the stage instead of the viewport */
@supports (container-type: size) {
  .game__screen { container-type: size; container-name: stage; }
}

.game__canvas {
  /* The element fills the stage and object-fit letterboxes the pixels inside
     it, so a portrait board keeps its shape in a landscape cabinet. Sizing it
     by aspect-ratio + max-height does NOT work here: max-height clamps the
     height without pulling the width in with it, which stretched the climber
     to twice its box. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  image-rendering: pixelated;
  display: block;
}

/* ONE CABINET, FOUR GAMES.
   The four canvases have four different native resolutions, but a lineup of
   cards in four different shapes reads as an accident rather than a design.
   Every stage is therefore the same 4:3 box and each canvas is scaled to fit
   inside it, centred, with the screen colour showing as bars wherever the
   game's own shape does not fill the box - a portrait board in a landscape
   cabinet, which is exactly what it is.

   object-fit does the letterboxing, so the canvas rule stays class-level and
   the full-screen override further down - where the engine writes exact pixel
   sizes instead - still outranks it. */
#game-emission-run,
#game-constraint-climb,
#game-rollout-breaker,
#game-step-170 {
  max-width: 560px;
  margin-inline: auto;
}

#game-emission-run     .game__screen,
#game-constraint-climb .game__screen,
#game-rollout-breaker  .game__screen,
#game-step-170         .game__screen {
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
}

.game__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(5px, 1.2vw, 10px);
  overflow: hidden;
  padding: clamp(8px, 4%, 22px);
  text-align: center;
  background: var(--overlay-bg);
  background-image: repeating-linear-gradient(
    to bottom, var(--scan) 0 2px, transparent 2px 4px);
}
.game__overlay.is-hidden { display: none; }

/* kicker, title and the start button never get pushed out: only the blurb
   gives way on a short stage */
.game__overlay-kicker,
.game__overlay-title,
.game__start { flex: none; }
.game__overlay-text { flex: 0 1 auto; min-height: 0; overflow-y: auto; }

.game__overlay-kicker {
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.6;
  letter-spacing: .14em;
  color: var(--gold);
  animation: coin-pulse 1.4s steps(2, end) infinite;
}
/* the trough stays above 4.5:1 against the overlay: gold at .25 was ~1.7:1 */
@keyframes coin-pulse { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .62; } }

.game__overlay-title {
  font-family: var(--font-display);
  font-size: clamp(.62rem, 2.4vw, 1.1rem);
  line-height: 1.5;
  color: var(--text);
  overflow-wrap: break-word;
}
.game__overlay-text {
  max-width: 46ch;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

.game__start {
  margin-top: 4px;
  padding: 12px 16px;
  background: var(--brand);
  border: var(--bd) solid var(--brand);
  color: var(--on-brand);
  box-shadow: 5px 5px 0 var(--shadow);
  font-family: var(--font-display);
  font-size: 10px;
  line-height: 1.4;
  cursor: pointer;
  transition: transform .08s steps(1), box-shadow .08s steps(1), background-color .15s;
}

@container stage (min-width: 0px) {
  .game__overlay-kicker { font-size: clamp(6px, 2.6cqw, 8px); }
  .game__overlay-title  { font-size: clamp(9px, 5cqw, 1.1rem); }
  .game__overlay-text   { font-size: clamp(9px, 3.7cqw, 13px); }
  .game__start          { font-size: clamp(8px, 3.4cqw, 10px); padding: clamp(8px, 3cqw, 12px) clamp(10px, 4cqw, 16px); }
}
.game__start:hover { background: var(--crown); border-color: var(--crown); }
.game__start:active { transform: translate(2px, 2px); box-shadow: 3px 3px 0 var(--shadow); }

/* --- HUD ------------------------------------------------------------------*/
.game__hud {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 10px 12px;
  background: var(--ink-3);
  border-top: var(--bd) solid var(--line);
}
.game__stat { display: inline-flex; align-items: baseline; gap: 6px; }
.game__stat-label {
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.4;
  letter-spacing: .06em;
  color: var(--muted);
}
.game__stat-value {
  font-family: var(--font-display);
  font-size: 10px;
  line-height: 1.4;
  color: var(--crown);
  font-variant-numeric: tabular-nums;
}
.game__mute {
  margin-left: auto;
  padding: 7px 9px;
  background: transparent;
  border: 2px solid var(--line);
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.3;
  cursor: pointer;
  transition: color .15s, border-color .15s, background-color .15s;
}
.game__mute:hover { color: var(--text); border-color: var(--muted); }
.game__mute[aria-pressed="true"] { color: var(--red); border-color: var(--red); }

/* --- touch pad — coarse pointers only ------------------------------------
   The box lives on the base rule, so the full-screen switch further down —
   which flips `display` alone, under the wider `pointer: coarse` — cannot
   render an unstyled pad on a coarse pointer that also reports hover: hover
   (touch laptops, TV and console browsers). The media queries are activation
   only; none of this paints while the pad is display: none.               */
.game__touch {
  display: none;
  gap: 8px;
  padding: 10px;
  border-top: var(--bd) solid var(--line);
  background: var(--ink-2);
}

@media (hover: none) and (pointer: coarse) {
  .game__touch { display: flex; }
}
.game__touch-btn {
  flex: 1 1 0;
  min-width: 44px;
  min-height: 52px;
  padding: 10px 8px;
  background: var(--ink-3);
  border: var(--bd) solid var(--line);
  box-shadow: 4px 4px 0 var(--shadow);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  transition: transform .06s steps(1), box-shadow .06s steps(1), background-color .1s;
}
.game__touch-btn--jump { flex: 1.4 1 0; color: var(--crown); }
.game__touch-btn.is-down {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--shadow);
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}

/* --- outcome banners ------------------------------------------------------*/
.game-card__outcomes { display: grid; gap: 8px; }
.game-card__outcome {
  padding: 10px 12px;
  border-left: var(--bd) solid var(--line);
  background: var(--ink-2);
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.9;
  letter-spacing: .04em;
  overflow-wrap: break-word;
}
.game-card__outcome--win  { border-left-color: var(--brand); color: var(--brand); }
.game-card__outcome--lose { border-left-color: var(--red);   color: var(--red); }

/* --- the lineup ------------------------------------------------------------
   One cabinet per row on a phone, two from 760px up. The left column is the
   wider one because it holds the two landscape stages; the right column holds
   the portrait climber, which is capped at 300px anyway, and the 8:5 flyer.
   Each stage takes its height from its own canvas ratio (set by the ID rules
   above), so the two rows never have to agree on a height — align-items:start
   lets every card stop at its natural length.
   -------------------------------------------------------------------------- */
@media (min-width: 760px) {
  /* Two equal columns. The old split and the per-shape column assignments
     existed because the four cabinets used to be four different shapes; they
     are one shape now, so the cards just flow and every cabinet gets the same
     width, which is the whole point of the shared 4:3 stage. */
  .arcade { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


/* --- full screen ----------------------------------------------------------
   One card blown up to fill the screen. Driven by the `is-full` class the
   engine toggles, never by a :fullscreen selector: a single unrecognised
   vendor pseudo-class would invalidate the whole rule in older browsers.
   The per-game max-width and aspect-ratio rules further up are ID-based, so
   the overrides here have to carry an ID too or they silently lose.
   -------------------------------------------------------------------------- */
.game__full {
  padding: 7px 9px;
  background: transparent;
  border: 2px solid var(--line);
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 8px;
  line-height: 1.3;
  cursor: pointer;
  transition: color .15s, border-color .15s, background-color .15s;
}
.game__full:hover { color: var(--text); border-color: var(--muted); }
.game__full[aria-pressed="true"] { color: var(--crown); border-color: var(--crown); }

#game-emission-run.is-full,
#game-constraint-climb.is-full,
#game-rollout-breaker.is-full,
#game-step-170.is-full {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  border: 0;
  box-shadow: none;
  background: #000;
}

#game-emission-run.is-full .game__screen,
#game-constraint-climb.is-full .game__screen,
#game-rollout-breaker.is-full .game__screen,
#game-step-170.is-full .game__screen {
  flex: 1 1 auto;
  min-height: 0;
  aspect-ratio: auto;          /* the stage is whatever the screen leaves over */
  display: grid;
  place-items: center;
  background: #000;
}

/* the engine writes exact pixel dimensions here, scaled to the stage */
.game.is-full .game__canvas { position: static; width: auto; height: auto; object-fit: fill; }
.game.is-full .game__hud,
.game.is-full .game__touch { flex: none; }
.game.is-full::backdrop { background: #000; }

/* fallback for browsers that refuse fullscreen on anything but a <video> */
.game.is-cinema { position: fixed; inset: 0; z-index: 999; }
:root.has-cinema,
:root.has-cinema body { overflow: hidden; }

/* full screen on a phone is exactly when the pad matters most */
@media (pointer: coarse) {
  .game.is-full .game__touch { display: flex; }
}


/* ============================================================================
   12. FOOTER
   ========================================================================== */
.site-footer {
  border-top: var(--bd) solid var(--line);
  background-color: var(--ink-2);
  background-image: none;
}
.site-footer__inner {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: clamp(32px, 5vw, 64px);
}
.site-footer__disclaimer {
  max-width: 80ch;
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--muted);
  margin-bottom: 24px;
}
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  padding-block: 18px;
  border-top: 2px solid var(--line);
  border-bottom: 2px solid var(--line);
  margin-bottom: 20px;
}
.site-footer__link-item { min-width: 0; }
.site-footer__link {
  font-size: 13px;
  letter-spacing: .03em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  overflow-wrap: anywhere;
}
.site-footer__link:hover { border-bottom-color: currentColor; }

.site-footer__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  font-size: 12px;
  color: var(--muted);
}
.site-footer__year {
  font-family: var(--font-display);
  font-size: 10px;
  line-height: 1.4;
  color: var(--gold);
}
.site-footer__sep { color: var(--line); }
.site-footer__sign { letter-spacing: .02em; }


/* ============================================================================
   13. KONAMI CRT EASTER EGG  (body.is-crt, toggled by site.js)
   ========================================================================== */
/* The grade goes on the in-flow wrappers, never on <body>. A filter makes its
   own element the containing block for every position:fixed descendant, so a
   filter on <body> pins .skip-link, the .game.is-cinema fullscreen fallback
   and the scanline layer below to the document instead of the viewport. The
   :has() guard drops the grade off <main> while a cabinet is blown up, for the
   same reason the .game-card lift is guarded further up; it is a rule of its
   own so a browser without :has() still grades the header and the footer. The
   dot grid painted by <body> stays ungraded, which is invisible at that
   contrast. */
body.is-crt .site-header,
body.is-crt .site-footer {
  filter: saturate(1.4) contrast(1.12) hue-rotate(-6deg);
}
body.is-crt .site-main:not(:has(.game.is-full, .game.is-cinema)) {
  filter: saturate(1.4) contrast(1.12) hue-rotate(-6deg);
}
body.is-crt::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 900;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom,
      rgba(0, 0, 0, .30) 0 2px,
      rgba(255, 255, 255, .04) 2px 4px),
    repeating-linear-gradient(to right,
      rgba(245, 68, 53, .07) 0 1px,
      rgba(192, 255, 114, .07) 1px 2px,
      rgba(110, 165, 255, .07) 2px 3px);
  animation: crt-roll 5s linear infinite;
}
@keyframes crt-roll {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 0 4px, 0 0; }
}


/* ============================================================================
   14. REDUCED MOTION — nothing moves, nothing stays hidden
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important;
    transition-delay: 0ms !important;
  }

  [data-reveal],
  [data-reveal].is-visible {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  .btn:active,
  .nav-toggle:active,
  .hero__copy-btn:active,
  .game__start:active,
  .game__touch-btn.is-down { transform: none; }

  /* --- everything this stylesheet animates, switched off at the source ------
     The blanket rules above only crush durations; these remove the animations
     outright so nothing can be left mid-transform, and re-state the resting
     state each of these elements already had. The page stays complete: the
     hero is simply present, the strip shows its first copy, rollout 6 keeps
     its red wash and its inset marker.
     ---------------------------------------------------------------------- */
  [data-anim="hero"] .hero__kicker,
  [data-anim="hero"] .hero__title,
  [data-anim="hero"] .hero__ticker,
  [data-anim="hero"] .hero__hook,
  [data-anim="hero"] .hero__sub,
  [data-anim="hero"] .hero__supply,
  [data-anim="hero"] [data-anim="chips"],
  [data-anim="hero"] .hero__actions,
  [data-anim="art"],
  [data-anim="art"] .hero__img,
  .ticker__track,
  .ledger__row--failed,
  .ledger__body tr.is-failed,
  .receipt__prompt::after,
  .game__overlay-kicker,
  body.is-crt::after {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  /* the lifts stop lifting; the colour shifts stay, so hover still answers */
  .lore__item:hover,
  .lore__item:focus-within,
  .game-card:hover,
  .game-card:focus-within,
  .ledger__body tr:hover,
  .ledger__body tr:focus-within { transform: none !important; }
}


/* --- touch targets --------------------------------------------------------
   On a coarse pointer every control the hand actually aims at gets real room.
   Kept out of the pointer:fine path so the desktop chrome stays compact.      */
@media (pointer: coarse) {
  .nav-toggle,
  .game__mute,
  .game__full,
  .game__start,
  .hero__copy-btn,
  .btn,
  [data-start],
  [data-copy] {
    min-height: 44px;
  }
  .nav-toggle,
  .game__mute,
  .game__full,
  .hero__copy-btn { padding-inline: 16px; }
  .btn--link { padding-block: 17px; }   /* inline box: padding is the only way to grow the hit area */
  .site-nav__link { padding-block: 14px; }
}
