/* studio.css — IronVail Studios' own layer, on top of brand/house.css.
 *
 * AN APP MAY ADD TOKENS. AN APP MAY NEVER REDEFINE ONE. That rule is the whole
 * reason the house palette survives being copied into five repositories, and
 * `node tools/verify.mjs` fails the build if anything below shadows a house
 * token. Everything this file adds is namespaced `--s-`.
 *
 * THE TYPE SCALE IS COPIED HERE ON PURPOSE, AND IT IS NOT A REDEFINITION.
 * house.css declares the steps inside `@theme inline`, which is Tailwind's
 * block — a browser skips an at-rule it does not know, along with everything in
 * it, so on a plain stylesheet like this one `var(--text-title)` resolves to
 * nothing and silently falls back to the inherited size. The vault records
 * IronVail Forge (then Clipper) shipping exactly that bug. So the steps are declared here
 * where this site can see them, and verify.mjs asserts every one of them equals
 * the value in house.css's @theme block.
 *
 * THE 2026-10 REDESIGN. Quieter and larger: fewer boxes, more type, the games
 * shown as pictures rather than described in cards. What did NOT change is the
 * part that makes it IronVail — jet, gold and iron, Archivo, one gold thing per
 * screen. A redesign that touched those would be a rebrand, and that is a
 * different decision. Archivo now loads with its WIDTH axis, and display type
 * is set slightly expanded: it is the cheapest way to make headlines feel
 * current without a second typeface.
 */

/* Archivo, variable on weight and width, Latin subset, self-hosted (SIL Open
 * Font License 1.1; fonts/OFL.txt). */
@font-face {
  font-family: Archivo; font-style: normal; font-weight: 400 900; font-stretch: 100% 125%;
  font-display: swap;
  src: url("/fonts/archivo-latin-var.woff2") format("woff2");
}

:root {
  /* The steps. Values are house's, see the header above. */
  --text-label:    0.6875rem;  /* 11px */
  --text-marginal: 0.8125rem;  /* 13px */
  --text-body:     0.9375rem;  /* 15px */
  --text-lead:     1.0625rem;  /* 17px */
  --text-title:    1.375rem;   /* 22px */
  --text-display:  1.75rem;    /* 28px */
  --text-hero:     3rem;       /* 48px */
  --text-mega:     4rem;       /* 64px */
  --text-colossal: 6.5rem;     /* 104px — marketing hero only */

  /* Studio-local additions. Namespaced so they can never collide. */
  --s-face: Archivo, "Helvetica Neue", Helvetica, Arial, system-ui, sans-serif;
  /* Quiet TEXT. The house's --ink-faint is decoration only (4.2:1 on jet, 4.0
   * on a card, by its own rule never a label); dates, table labels and the
   * footer are labels, so they get this: 5.9:1 on jet, 5.4:1 on a card. */
  --s-ink-quiet: #8A8E94;
  --s-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --s-wrap: 1200px;
  --s-gutter: clamp(1.25rem, 4vw, 2.5rem);
  --s-bar: 64px;
  --s-ease: cubic-bezier(.2, .7, .3, 1);
  --s-wide: 112%;            /* font-stretch for display type */
  --s-section: clamp(4rem, 9vw, 8rem);
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--s-bar) + 16px); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink-soft);
  font-family: var(--s-face);
  font-size: var(--text-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

img, svg { max-width: 100%; }
img { height: auto; }
::selection { background: color-mix(in srgb, var(--gold) 30%, transparent); color: var(--ink); }

/* ---- the one thing every keyboard user needs first ---------------------- */
.skip {
  position: fixed; top: 8px; left: 8px; z-index: 100;
  transform: translateY(-200%);
  background: var(--rubric); color: var(--on-rubric);
  padding: 10px 16px; border-radius: 99px;
  font-weight: 700; text-decoration: none;
}
.skip:focus { transform: none; }

:where(a, button, input, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--rubric);
  outline-offset: 3px;
  border-radius: 6px;
}

.wrap { width: 100%; max-width: var(--s-wrap); margin: 0 auto; padding: 0 var(--s-gutter); }

/* ---- type ----------------------------------------------------------------
 * Only steps from the scale; clamp() moves BETWEEN two steps and never lands
 * anywhere else. */
h1, h2, h3 {
  color: var(--ink); font-weight: 800; letter-spacing: -.03em; line-height: 1.06;
  margin: 0; font-stretch: var(--s-wide); text-wrap: balance;
}
h1 { font-size: clamp(var(--text-display), 5vw, var(--text-hero)); }
h2 { font-size: clamp(var(--text-title), 3vw, var(--text-display)); }
h3 { font-size: var(--text-lead); letter-spacing: -.015em; line-height: 1.25; }
p { margin: 0 0 var(--space-4); text-wrap: pretty; }
a { color: var(--link); text-underline-offset: 3px; }

/* An eyebrow. The one place --ink-faint is legal is decoration; this carries
 * meaning, so it is --ink-soft. */
.kicker {
  display: block; font-size: var(--text-label); font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: var(--space-3);
}
.lede { font-size: clamp(var(--text-lead), 1.6vw, var(--text-title)); line-height: 1.5; color: var(--ink-soft); max-width: 40ch; }
.fine { font-size: var(--text-marginal); color: var(--ink-soft); }
.faint { font-size: var(--text-marginal); color: var(--s-ink-quiet); }

/* ---- header ---------------------------------------------------------------
 * Transparent until the page moves, then a frosted bar. site.js sets
 * data-scrolled; without script it is simply the frosted bar from the start,
 * which is the safe way round. */
.top {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--ground) 82%, transparent);
  backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--hairline);
  transition: background .25s var(--s-ease), border-color .25s var(--s-ease);
}
.top[data-scrolled="false"] { background: transparent; border-bottom-color: transparent;
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.bar { display: flex; align-items: center; gap: var(--space-5); min-height: var(--s-bar); }

.lockup { display: flex; align-items: center; gap: 10px; text-decoration: none; margin-right: auto; }
.lockup img { width: 22px; height: auto; }
.wordmark {
  font-size: var(--text-body); font-weight: 900; letter-spacing: -.02em;
  text-transform: uppercase; white-space: nowrap; font-stretch: var(--s-wide);
}
/* "Iron" in iron and "Vail" in gold — the wordmark says what the drawing says.
 * The em is the descriptor and is neither. */
.wordmark b { color: var(--iron); font-weight: 900; }
.wordmark i { color: var(--gold); font-style: normal; font-weight: 900; }
.wordmark em {
  color: var(--ink-soft); font-style: normal; font-weight: 600;
  font-size: .78em; letter-spacing: .14em; margin-left: .2em;
}
.wordmark.big { font-size: var(--text-title); margin: var(--space-3) 0 var(--space-2); }

.nav { display: flex; align-items: center; gap: 2px; }
.nav a {
  color: var(--ink-soft); text-decoration: none; font-weight: 600;
  font-size: var(--text-marginal); padding: 8px 14px; border-radius: 99px;
  white-space: nowrap; transition: color .15s var(--s-ease), background .15s var(--s-ease);
}
.nav a:hover { color: var(--ink); background: var(--hover); }
/* The active section is one of the things allowed to be gold. */
.nav a[aria-current="page"] { color: var(--gold); }
.nav a.acct {
  border: 1px solid var(--rule-strong); color: var(--ink); margin-left: var(--space-3);
}
.nav a.acct:hover { border-color: var(--ink-faint); background: var(--hover); }
.nav a.acct[data-signedin] { border-color: color-mix(in srgb, var(--gold) 55%, transparent); color: var(--gold); }
.nav a.acct[data-signedin]::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--good); margin-right: 8px; vertical-align: 1px;
}

.menu { display: none; background: none; border: 0; padding: 10px; cursor: pointer; }
.menu span { display: block; width: 20px; height: 2px; background: var(--ink); margin: 4px 0; border-radius: 2px;
  transition: transform .2s var(--s-ease), opacity .2s var(--s-ease); }
.menu[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 760px) {
  .menu { display: block; }
  .top:has(.menu[aria-expanded="true"]) { background: var(--ground); }
  .nav {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 2px;
    background: var(--ground); border-bottom: 1px solid var(--rule);
    padding: var(--space-3) var(--s-gutter) var(--space-6);
  }
  .nav[hidden] { display: none; }
  .nav a { padding: 14px 4px; font-size: var(--text-title); font-weight: 700; border-radius: 0;
    border-bottom: 1px solid var(--rule); font-stretch: var(--s-wide); letter-spacing: -.02em; }
  .nav a:hover { background: transparent; }
  .nav a.acct { margin: var(--space-5) 0 0; text-align: center; border-radius: 99px;
    font-size: var(--text-body); border: 1px solid var(--rule-strong); }
}

/* ---- buttons --------------------------------------------------------------
 * ONE gold button per screen. `.btn` is the primary; `.ghost` is achromatic on
 * purpose and must stay that way — it is what a new page reaches for by
 * default, and if it went gold the restraint would be gone within a pass. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--rubric); color: var(--on-rubric);
  border: 1px solid transparent; border-radius: 99px;
  padding: 11px 22px; font: inherit; font-weight: 700; font-size: var(--text-marginal);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background .15s var(--s-ease), transform .15s var(--s-ease), border-color .15s var(--s-ease);
}
.btn:hover { background: var(--rubric-deep); }
.btn:active { transform: translateY(1px); }
.btn.big { padding: 15px 28px; font-size: var(--text-body); }
.btn[disabled] { opacity: .55; cursor: default; transform: none; }
.btn .arrow { transition: transform .2s var(--s-ease); }
.btn:hover .arrow { transform: translateX(3px); }

.btn.ghost { background: transparent; color: var(--ink); border-color: var(--rule-strong); }
.btn.ghost:hover { background: var(--hover); border-color: var(--ink-faint); }

/* A tertiary action, and it sits FLUSH with the copy above it. */
.btn.quiet {
  background: transparent; color: var(--ink); border-color: transparent;
  padding: 8px 0; font-weight: 700; border-radius: 0;
}
.btn.quiet:hover { color: var(--gold); background: transparent; }

.btns { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }

/* A text link with an arrow, for "more" — never gold text, the arrow is. */
.go { display: inline-flex; gap: 8px; align-items: center; color: var(--ink); font-weight: 700;
  font-size: var(--text-marginal); text-decoration: none; }
.go::after { content: "\2192"; color: var(--gold); transition: transform .2s var(--s-ease); }
.go:hover::after { transform: translateX(3px); }

/* ---- sections ------------------------------------------------------------ */
section { padding: var(--s-section) 0; }
section.tight { padding: calc(var(--s-section) * .55) 0; }
section + section { padding-top: 0; }
.head { max-width: 64ch; margin-bottom: clamp(var(--space-6), 4vw, 3.5rem); }
.head h1, .head h2 { margin-bottom: var(--space-4); }
.head p { font-size: var(--text-lead); }
.split { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: var(--space-4) var(--space-6);
  max-width: none; }
.split > div { max-width: 60ch; }

.rule { border: 0; border-top: 1px solid var(--rule); margin: 0; }

/* ---- entrances ------------------------------------------------------------
 * The hero rises once on load, in CSS. Nothing below the fold animates in:
 * a scroll-driven fade was tried and left whole sections at opacity 0 in a
 * full-page capture — a page whose content can be invisible is a page that is
 * empty to a crawler, a printer and a screenshot. */
@keyframes s-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
.rise { animation: s-rise .8s var(--s-ease) both; }
.rise.d1 { animation-delay: .08s; } .rise.d2 { animation-delay: .16s; } .rise.d3 { animation-delay: .24s; }

/* ---- the home hero -------------------------------------------------------- */
.hero { position: relative; overflow: hidden; padding: clamp(4rem, 9vw, 7rem) 0 clamp(4rem, 9vw, 7rem); isolation: isolate; }
.hero::before {
  /* A field of hairlines, fading out — structure without a picture. */
  content: ""; position: absolute; inset: 0; z-index: -2;
  background-image:
    linear-gradient(var(--hairline) 1px, transparent 1px),
    linear-gradient(90deg, var(--hairline) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 70% 60% at 70% 40%, #000 0%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 70% 40%, #000 0%, transparent 75%);
}
.hero::after {
  content: ""; position: absolute; z-index: -1; width: 70vmax; height: 70vmax;
  right: -22vmax; top: -30vmax; border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--gold) 13%, transparent), transparent);
}
.hero h1 {
  /* Two sentences, so smaller and wider than a one-line mark would be: the
   * buttons have to clear the fold on a laptop. */
  font-size: clamp(var(--text-hero), 6.4vw, 5.25rem);
  line-height: .98; letter-spacing: -.04em; max-width: 17ch; margin-bottom: var(--space-6);
}
.hero h1 em { font-style: normal; color: var(--gold); display: block; }
.hero .lede { margin-bottom: var(--space-6); }
.heromark { position: absolute; right: var(--s-gutter); bottom: clamp(3rem, 8vw, 6rem); opacity: .9; }
.heromark img { width: clamp(90px, 13vw, 170px); }
@media (max-width: 860px) { .heromark { display: none; } }

/* The strip of live games under the hero. */
.now { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); align-items: center;
  margin-top: clamp(var(--space-6), 6vw, 4.5rem); padding-top: var(--space-5); border-top: 1px solid var(--rule); }
.now .kicker { margin: 0; }
.now a { color: var(--ink); text-decoration: none; font-weight: 600; font-size: var(--text-marginal); }
.now a:hover { color: var(--gold); }
.now a::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--good); margin-right: 8px; vertical-align: 1px; }

/* ---- game tiles -----------------------------------------------------------
 * The picture is the card. The title is a stretched link so the whole tile
 * opens the game's page, and the Play button sits above that link rather than
 * inside it — a button nested in a link is two controls a screen reader
 * announces as one. */
.tiles { display: grid; gap: clamp(var(--space-5), 3vw, var(--space-7)) var(--space-5); }
@media (min-width: 720px) { .tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .tiles.three { grid-template-columns: repeat(3, 1fr); } }

.tile { position: relative; display: flex; flex-direction: column; gap: var(--space-4); }
.frame {
  position: relative; aspect-ratio: 16 / 10; border-radius: 18px; overflow: hidden;
  background: var(--leaf); border: 1px solid var(--hairline);
}
.frame .art { width: 100%; height: 100%; display: block; transition: transform .8s var(--s-ease); }
.tile:hover .frame .art { transform: scale(1.035); }
.frame::after {
  /* A thin line of the game's own hue along the bottom edge — the one place a
   * tile carries its colour outside the picture. */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--s-hue, var(--iron)); opacity: .8;
}
.tile .chip { position: absolute; top: 14px; left: 14px; z-index: 2; }
.tile .body { display: flex; flex-direction: column; gap: var(--space-2); }
.tile :is(h2, h3) { font-size: clamp(var(--text-title), 2.4vw, var(--text-display)); font-weight: 800; letter-spacing: -.03em; }
.tile :is(h2, h3) a { color: var(--ink); text-decoration: none; }
.tile :is(h2, h3) a::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: 18px; }
.tile :is(h2, h3) a:focus-visible { outline: none; }
.tile:has(:is(h2, h3) a:focus-visible) .frame { outline: 2px solid var(--rubric); outline-offset: 3px; }
.tile .kicker { margin: 0; }
.tile p { margin: 0; color: var(--ink-soft); font-size: var(--text-marginal); max-width: 52ch; }
.tile .acts { position: relative; z-index: 2; display: flex; gap: var(--space-4); align-items: center; margin-top: var(--space-2); }
.tile.soon .frame { filter: saturate(.6); }

/* The feature tile — one game, wide, picture beside the words. */
.tile.wide { gap: var(--space-5); }
@media (min-width: 900px) {
  .tile.wide { grid-column: 1 / -1; display: grid; grid-template-columns: 1.35fr 1fr; align-items: center; gap: var(--space-7); }
  .tile.wide .frame { aspect-ratio: 16 / 9; }
  .tile.wide.flip { grid-template-columns: 1fr 1.35fr; }
  .tile.wide.flip .frame { order: 2; }
}

/* ---- chips ---------------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: var(--text-label); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink);
  background: color-mix(in srgb, var(--ground) 72%, transparent);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--rule-strong); border-radius: 99px;
  padding: 4px 10px; white-space: nowrap;
}
/* A live game is a status, not the screen's primary action, so it is not gold.
 * It gets a second channel — the word itself — rather than colour alone. */
.chip.on::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--good);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 22%, transparent); }

/* ---- cards (support, press, the account page's lists) -------------------- */
.grid { display: grid; gap: var(--space-4); }
@media (min-width: 700px) { .grid.two { grid-template-columns: 1fr 1fr; } }
@media (min-width: 860px) { .grid.three { grid-template-columns: repeat(3, 1fr); } }

.card {
  display: block; background: var(--leaf); border: 1px solid var(--hairline);
  border-radius: 18px; padding: var(--space-6);
  text-decoration: none; color: inherit;
  transition: border-color .2s var(--s-ease), background .2s var(--s-ease);
}
a.card:hover { border-color: var(--rule-strong); background: var(--leaf-2); }
.card h3 { margin: var(--space-2) 0; }
.card p { color: var(--ink-soft); font-size: var(--text-marginal); margin-bottom: 0; }
.cardtop { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.cardtop time { font-size: var(--text-label); color: var(--s-ink-quiet); white-space: nowrap; }
.more { display: block; margin-top: var(--space-4); font-size: var(--text-marginal); font-weight: 700; color: var(--ink); }
.more::after { content: " \2192"; color: var(--gold); }

/* ---- principles ---------------------------------------------------------- */
.tenets { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; counter-reset: t;
  border-top: 1px solid var(--rule); }
@media (min-width: 760px) { .tenets { grid-template-columns: repeat(2, 1fr); column-gap: var(--space-7); } }
@media (min-width: 1040px) { .tenets { grid-template-columns: repeat(3, 1fr); } }
.tenets li { counter-increment: t; padding: var(--space-5) 0 var(--space-6); border-bottom: 1px solid var(--rule); }
.tenets li::before { content: counter(t, decimal-leading-zero); display: block; font-family: var(--s-mono);
  font-size: var(--text-label); color: var(--s-ink-quiet); margin-bottom: var(--space-4); }
.tenets b { display: block; color: var(--ink); font-size: var(--text-lead); font-weight: 800; letter-spacing: -.015em;
  font-stretch: var(--s-wide); margin-bottom: var(--space-2); }
.tenets span { font-size: var(--text-marginal); color: var(--ink-soft); }

/* ---- news rows ----------------------------------------------------------- */
.posts { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.posts li { border-bottom: 1px solid var(--rule); }
.posts a { display: grid; gap: var(--space-2) var(--space-6); padding: var(--space-5) 0; text-decoration: none; color: inherit;
  transition: padding .25s var(--s-ease); }
@media (min-width: 760px) { .posts a { grid-template-columns: 11rem 1fr auto; align-items: baseline; } }
.posts a:hover { padding-left: var(--space-3); }
.posts time, .posts .lbl { font-size: var(--text-marginal); color: var(--s-ink-quiet); font-variant-numeric: tabular-nums; }
.posts :is(h2, h3) { color: var(--ink); font-size: clamp(var(--text-lead), 2vw, var(--text-title)); }
.posts p { grid-column: 2; margin: 0; font-size: var(--text-marginal); max-width: 64ch; }
@media (max-width: 759px) { .posts p { grid-column: auto; } }
.posts .tag { font-size: var(--text-label); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
@media (min-width: 760px) { .posts .tag { grid-column: 3; grid-row: 1; } }

/* ---- news entries -------------------------------------------------------- */
.entry {
  display: grid; gap: var(--space-3) var(--space-7);
  border-top: 1px solid var(--rule); padding: var(--space-7) 0;
}
@media (min-width: 860px) { .entry { grid-template-columns: 14rem 1fr; } }
.entry .cardtop { flex-direction: column; gap: var(--space-2); }
.entry .cardtop time { font-size: var(--text-marginal); }
.entry h2 { margin: 0 0 var(--space-4); }
.entry p { color: var(--ink-soft); max-width: 66ch; }
.entry .text > :last-child { margin-bottom: 0; }

/* ---- the CTA band -------------------------------------------------------- */
.band {
  position: relative; overflow: hidden; isolation: isolate;
  border: 1px solid var(--hairline); border-radius: 24px; background: var(--leaf);
  padding: clamp(var(--space-6), 6vw, 4.5rem);
  display: grid; gap: var(--space-5); align-items: center;
}
@media (min-width: 860px) { .band { grid-template-columns: 1.4fr auto; } }
.band::after { content: ""; position: absolute; z-index: -1; width: 520px; height: 520px; right: -160px; bottom: -300px;
  border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--gold) 12%, transparent), transparent); }
.band h2 { margin-bottom: var(--space-3); }
.band h2 a { color: inherit; text-decoration: none; }
.band h2 a:hover { color: var(--gold); }
.band .fine { margin-top: var(--space-3); }
.band p { margin: 0; max-width: 54ch; }

/* ---- a game's own page ---------------------------------------------------- */
.gamehero { position: relative; isolation: isolate; min-height: clamp(460px, 72vh, 760px);
  display: flex; align-items: flex-end; padding: 0 0 clamp(var(--space-6), 6vw, 4.5rem); margin-top: calc(var(--s-bar) * -1); }
.gamehero .art { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -2; }
.gamehero::after { content: ""; position: absolute; inset: 0; z-index: -1;
  /* Darken where the words are — the left and the floor — and leave the
   * picture its colour everywhere else. */
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--ground) 78%, transparent) 0%, transparent 62%),
    linear-gradient(to bottom, color-mix(in srgb, var(--ground) 50%, transparent) 0%, transparent 22%,
      transparent 60%, var(--ground) 100%); }
@media (max-width: 760px) { .gamehero::after { background:
    linear-gradient(to bottom, color-mix(in srgb, var(--ground) 40%, transparent) 0%, transparent 25%,
      color-mix(in srgb, var(--ground) 80%, transparent) 62%, var(--ground) 100%); } }
.gamehero h1 { font-size: clamp(var(--text-hero), 10vw, var(--text-colossal)); line-height: .92; letter-spacing: -.05em;
  margin-bottom: var(--space-4); }
.gamehero .lede { color: var(--ink); max-width: 46ch; margin-bottom: var(--space-6); }
.gamehero .chip { margin-bottom: var(--space-5); }
.notyet { color: var(--ink); max-width: 46ch; }

.about { display: grid; gap: var(--space-7); }
@media (min-width: 900px) { .about { grid-template-columns: 1.3fr 1fr; gap: clamp(var(--space-7), 7vw, 6rem); } }
.about .text p { font-size: var(--text-lead); color: var(--ink-soft); }
.about .text p:first-child { color: var(--ink); }

/* ---- fact strips ---------------------------------------------------------- */
.facts { list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.facts li { display: flex; flex-direction: column; gap: 2px; padding: var(--space-4) 0; border-bottom: 1px solid var(--rule); }
.facts li:nth-child(odd) { padding-right: var(--space-4); }
.facts b { color: var(--ink); font-size: var(--text-body); font-weight: 700; }
.facts span { color: var(--s-ink-quiet); font-size: var(--text-label); text-transform: uppercase; letter-spacing: .12em; }

/* ---- feature list --------------------------------------------------------- */
.feats { display: grid; gap: 0; counter-reset: f; border-top: 1px solid var(--rule); }
.feat { counter-increment: f; display: grid; gap: var(--space-2) var(--space-6); padding: var(--space-6) 0; border-bottom: 1px solid var(--rule); }
@media (min-width: 760px) { .feat { grid-template-columns: 4rem 1fr 1.4fr; align-items: baseline; } }
.feat::before { content: counter(f, decimal-leading-zero); font-family: var(--s-mono); font-size: var(--text-label); color: var(--ink-faint); }
.feat h3 { font-size: clamp(var(--text-lead), 1.8vw, var(--text-title)); }
.feat p { font-size: var(--text-body); margin: 0; }

/* ---- forms ---------------------------------------------------------------- */
.form { display: grid; gap: var(--space-4); }
.field { display: grid; gap: 6px; }
label { font-size: var(--text-marginal); font-weight: 600; color: var(--ink); }
/* A form field's border IS a UI component boundary, so WCAG 1.4.11 wants 3:1
 * against both the page and the fill. Neither rule token gets there — only
 * --ink-faint clears both (4.24 / 3.63). */
input, textarea, select {
  font: inherit; font-size: var(--text-body);
  background: var(--leaf-3); color: var(--ink);
  border: 1px solid var(--ink-faint); border-radius: 12px;
  padding: 12px 14px; width: 100%;
  transition: border-color .15s var(--s-ease), box-shadow .15s var(--s-ease);
}
input::placeholder, textarea::placeholder { color: var(--s-ink-quiet); }
input:focus, textarea:focus { border-color: var(--gold); outline: none;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold) 18%, transparent); }
textarea { min-height: 130px; resize: vertical; }

.hint { font-size: var(--text-marginal); color: var(--ink-soft); }

/* Status blocks. Each pairs its tone with a WORD — red and green measure dE 6.4
 * under deuteranopia, which is below the safe floor. */
.note { border-radius: 12px; padding: var(--space-4); font-size: var(--text-marginal);
  border: 1px solid var(--rule-strong); background: var(--leaf-2); color: var(--ink-soft); }
.note b { color: var(--ink); }
.note.bad { background: var(--neg-bg); border-color: color-mix(in srgb, var(--neg-fg) 34%, transparent); color: var(--neg-fg); }
.note.good { background: var(--pos-bg); border-color: color-mix(in srgb, var(--pos-fg) 34%, transparent); color: var(--pos-fg); }
.note.warn { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn-fg) 34%, transparent); color: var(--warn-fg); }
.note.bad b, .note.good b, .note.warn b { color: inherit; }
.note p { margin: 0 0 var(--space-2); }
.note p:last-child { margin: 0; }

/* The server's own words, kept for a screenshot. */
.detail { margin-top: var(--space-3); }
.detail summary { cursor: pointer; font-size: var(--text-label); color: var(--s-ink-quiet); }
.detail pre {
  font-family: var(--s-mono); font-size: var(--text-label); color: var(--ink-soft);
  background: var(--ground); border: 1px solid var(--rule); border-radius: 10px;
  padding: var(--space-3); margin: var(--space-2) 0 0; overflow-x: auto; white-space: pre-wrap;
  word-break: break-word;
}

/* ---- panels --------------------------------------------------------------- */
.panel {
  background: var(--leaf); border: 1px solid var(--hairline);
  border-radius: 20px; padding: clamp(var(--space-5), 4vw, var(--space-7));
}
.panel + .panel { margin-top: var(--space-4); }
.panel h2 { margin-bottom: var(--space-3); }
.panelgrid { display: grid; gap: var(--space-4); align-items: start; }
/* A grid item's min-width is its content's by default, so the tab strip's
 * max-content width pushed the whole panel past a phone screen. */
.panelgrid > * { min-width: 0; }
@media (min-width: 860px) { .panelgrid { grid-template-columns: 1.1fr .9fr; gap: var(--space-6); } }

/* SCROLLS RATHER THAN PUSHES — at 320px the three tabs are wider than the
 * panel, and without this the whole PAGE scrolled sideways. */
.tabs {
  display: flex; gap: 4px; padding: 4px; margin-bottom: var(--space-5);
  background: var(--leaf-2); border-radius: 99px; width: max-content; max-width: 100%;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  flex: 0 0 auto; background: none; border: 0; border-radius: 99px;
  color: var(--ink-soft); font: inherit; font-weight: 700; font-size: var(--text-marginal);
  padding: 8px 16px; cursor: pointer; transition: color .15s var(--s-ease), background .15s var(--s-ease);
}
.tabs button:hover { color: var(--ink); }
/* The active tab is a raised segment, not gold — the gold on this screen is
 * the submit button, and a screen gets one. */
.tabs button[aria-selected="true"] { color: var(--ink); background: var(--leaf-3); box-shadow: var(--shadow); }

.rows { display: grid; gap: 0; margin: 0; }
.row {
  display: flex; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-3) 0; border-bottom: 1px solid var(--rule);
  font-size: var(--text-marginal);
}
.row:last-child { border-bottom: 0; }
.row b { color: var(--ink); font-weight: 700; }
.row span { color: var(--ink-soft); text-align: right; word-break: break-word; }
.row dt { color: var(--ink-soft); font-weight: 600; }
.row dd { margin: 0; color: var(--ink); text-align: right; word-break: break-word; }
.row .mono { font-family: var(--s-mono); font-size: var(--text-label); }

/* ---- prose (legal, studio) ----------------------------------------------- */
.prose { max-width: 68ch; }
.prose p { font-size: var(--text-lead); }
.prose h2 { margin: var(--space-7) 0 var(--space-4); }
.prose h3 { margin: var(--space-6) 0 var(--space-2); }
.prose ul, .prose ol { padding-left: 1.25em; margin: 0 0 var(--space-4); }
.prose li { margin-bottom: var(--space-2); }
.prose strong { color: var(--ink); }

/* ---- swatches (press) ---------------------------------------------------- */
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-3); }
.sw { border: 1px solid var(--hairline); border-radius: 14px; overflow: hidden; }
.sw .chipbox { height: 72px; }
.sw .meta { padding: 10px 12px; background: var(--leaf); }
.sw b { display: block; color: var(--ink); font-size: var(--text-marginal); }
.sw code { font-family: var(--s-mono); font-size: var(--text-label); color: var(--ink-soft); }

/* ---- footer --------------------------------------------------------------- */
.foot { border-top: 1px solid var(--rule); margin-top: var(--s-section); padding: clamp(var(--space-7), 6vw, 5rem) 0 var(--space-6); }
.cols { display: grid; gap: var(--space-6); grid-template-columns: 1fr 1fr; }
@media (min-width: 760px) { .cols { grid-template-columns: 2fr 1fr 1fr 1fr; } }
.brandcol { grid-column: 1 / -1; }
@media (min-width: 760px) { .brandcol { grid-column: auto; } }
.col h2 { font-size: var(--text-label); letter-spacing: .16em; text-transform: uppercase; color: var(--s-ink-quiet);
  margin-bottom: var(--space-3); font-weight: 700; font-stretch: 100%; }
.col a { display: block; color: var(--ink-soft); text-decoration: none; font-size: var(--text-marginal); padding: 5px 0; }
.col a:hover { color: var(--ink); }
.brandcol .fine { margin: 0; max-width: 34ch; }
.brandcol img { width: 30px; }

.legal { margin-top: clamp(var(--space-6), 5vw, 4rem); padding-top: var(--space-4); border-top: 1px solid var(--rule);
  display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5); justify-content: space-between; }
.legal p { margin: 0; font-size: var(--text-label); color: var(--s-ink-quiet); }
.build { font-family: var(--s-mono); user-select: text; -webkit-user-select: text; }
.build b { color: var(--ink-soft); font-weight: 600; }

[hidden] { display: none !important; }

/* Apps stack as bands (build.mjs appCard): space them like the panels. */
.band + .band { margin-top: var(--space-4); }

/* ---- 2026-11-12 audit ---------------------------------------------------- */
/* Read by a screen reader, not drawn: a section heading where the layout
 * needs none but the outline does. */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Stand-alone text links get a 24px-tall target (WCAG 2.2, 2.5.8). */
.go { padding-block: 4px; }
.facts a { display: inline-block; padding-block: 4px; }
.posts .lbl { text-transform: uppercase; letter-spacing: .12em; font-size: var(--text-label); }
/* A cross-fade between pages where the browser supports it; none for anyone
 * who has asked for less motion. */
@media (prefers-reduced-motion: no-preference) { @view-transition { navigation: auto; } }
.lost { min-height: 60vh; display: grid; align-content: center; }
@media print {
  .top, .foot .cols, .menu, .btns, .skip { display: none !important; }
  body { background: #fff; color: #000; }
  * { color: #000 !important; background: none !important; box-shadow: none !important; }
  a { text-decoration: underline; }
}
.now a { display: inline-block; padding-block: 4px; }

/* ---- waitlist form ----------------------------------------------------- */
.wl { display: grid; gap: var(--space-3); max-width: 34rem; }
.wl-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.wl-row input { flex: 1 1 16rem; width: auto; }
.wl-row .btn { flex: 0 0 auto; }
.wl .fine { margin: 0; }
.wl-msg { margin: 0; font-weight: 600; color: var(--ink); }
.wl-msg:empty { display: none; }
.wl[data-state="done"] .wl-row { display: none; }
/* The honeypot: off-screen for people, still a field to a bot. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
