/* ===========================================================================
   RIVAESA - landing stylesheet
   ---------------------------------------------------------------------------
   Rewritten 2026-08-04. The previous sheet dressed the site as a warm brown
   parchment book. The GAME is not that: src/index.css ships --bg #080c12,
   --panel-bg #0e1520, --panel-border #1e2d42, --text #c0cce0, --gold #c8a448,
   and the title screen a player lands on is a cool violet vortex under a gold
   wordmark. A site that does not look like the product it sells is the single
   loudest "template" tell there is, so every colour below is lifted from the
   running game and every plate is drawn the way the game draws a panel.

   Type is the game's own too: Cinzel and Alegreya, the same two woff2 files
   src/components/popups-1a.css loads, copied into landing/fonts/. Self-hosted
   on purpose. playtest/live-site.mjs asserts the landing page reaches NOTHING
   off its own origin, so a Google Fonts link would fail the deploy test, and
   the previous sheet's system Palatino stack is a large part of why the page
   read as a generic template.

   Zero network dependencies: no CDN, no remote images, no analytics.
   No em dashes anywhere, including comments: build/check-landing-text.mjs
   refuses to build if it finds one, in any of its five spellings, and it scans
   comments as well as copy. Use a comma, a colon, or an en dash.

   CONTENTS
     1  Fonts
     2  Tokens
     3  Base and rhythm
     4  Buttons
     5  Site header
     6  Hero
     7  Lede
     7b Waitlist
     8  Section plates and headings
     9  Trailer
    10  Screenshot reel
    11  Worlds
    12  Facts strip
    13  Depth grid
    14  Beta panel
    15  FAQ
    16  Closer
    17  Site footer
    18  Shared chrome for /privacy, /terms, /404   <- KEEP, three pages use it
    19  Reveal, reduced motion, print
   =========================================================================== */

/* ==========================================================================
   1  Fonts
   Same files the game itself serves. Cinzel is display only (headings and the
   wordmark); Alegreya carries every word of body copy.
   ========================================================================== */
@font-face{
  font-family:'Cinzel';
  font-style:normal;
  font-weight:500 700;
  font-display:swap;
  src:url('/fonts/cinzel-latin.woff2') format('woff2');
}
@font-face{
  font-family:'Alegreya';
  font-style:normal;
  font-weight:400 900;
  font-display:swap;
  src:url('/fonts/alegreya-latin.woff2') format('woff2');
}
/* No page currently sets an italic, so this face is declared and never fetched:
   a browser only downloads an @font-face file when a glyph actually needs it,
   so the 44 KB is deploy weight and never reaches a visitor. It is kept
   because /privacy.html and /terms.html are long prose that will grow an <em>
   sooner or later, and the alternative is a synthesised oblique nobody would
   notice was wrong. Delete the rule AND landing/fonts/alegreya-italic-latin.woff2
   together if that stops being true. */
@font-face{
  font-family:'Alegreya';
  font-style:italic;
  font-weight:400 900;
  font-display:swap;
  src:url('/fonts/alegreya-italic-latin.woff2') format('woff2');
}

/* ==========================================================================
   2  Tokens
   ========================================================================== */
:root{
  /* Straight out of src/index.css, with one deeper step for the page ground
     so a --panel plate still separates from it at a glance. */
  --void:#070b11;
  --deep:#0a1017;
  --panel:#0e1520;
  --panel-2:#131d2c;
  --edge:#1e2d42;
  --edge-hi:#2c4160;

  --gold:#c8a448;
  --gold-hi:#f0d493;
  --gold-dim:#8a7233;

  --text:#c6d2e6;
  /* Cleared 4.5:1 against both --void and --panel before it was written down.
     Do not darken it without re-measuring. */
  --text-dim:#8496b3;

  /* The key art's two signature hues, used sparingly: violet for the arcane,
     teal for the swirl. They tie the page to landing/img/key-art.webp. */
  --violet:#8f6ce8;
  --teal:#5fc9dc;

  --serif:'Alegreya','Iowan Old Style','Palatino Linotype',Palatino,Georgia,serif;
  --display:'Cinzel','Trajan Pro','Iowan Old Style',Georgia,serif;
  --sans:ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;

  --shell:1200px;
  --pad:clamp(20px,5vw,40px);
  --band:clamp(72px,9vw,124px);
  --r:6px;

  /* A bevel and a tight seat, not a border plus a wide diffuse cloud. Carrying
     both a hairline edge and a big soft shadow on the same element is a
     generated-page tell, and the game's own panels do not do it either. */
  --plate:linear-gradient(180deg,var(--panel-2),var(--panel));
  --lift:inset 0 1px 0 rgba(255,255,255,.055), 0 6px 16px rgba(0,0,0,.45);
}

/* ==========================================================================
   3  Base and rhythm
   ========================================================================== */
*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; scroll-padding-top:76px; }

body{
  margin:0;
  background:var(--void);
  color:var(--text);
  font-family:var(--serif);
  font-size:clamp(17px,.5vw + 15.6px,19px);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

/* The ground stays FLAT. A first pass put a violet radial glow at the top of
   the page and a teal one at the bottom, pulled from the key art. They looked
   fine and they were still wrong: a radial halo behind the hero, and a violet
   to blue gradient, are two of the most reliable signatures of a generated
   page, and neither was solving a problem. The game itself paints a flat
   #080c12 behind everything, and the pages worth copying (Path of Exile, Old
   School RuneScape, RimWorld) all sit on a flat ground or a real texture. So
   there is no ::before layer here at all, on purpose. */

img,video{ display:block; max-width:100%; }
a{ color:var(--gold); }
a:hover{ color:var(--gold-hi); }

h1,h2,h3{
  font-family:var(--display);
  font-weight:600;
  line-height:1.14;
  margin:0;
  color:var(--gold-hi);
  letter-spacing:.01em;
}

:focus-visible{ outline:2px solid var(--gold); outline-offset:3px; border-radius:2px; }

.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--gold); color:#12100a; padding:12px 18px;
  font-family:var(--sans); font-weight:700; text-decoration:none;
}
.skip:focus{ left:12px; top:12px; }

#main:focus{ outline:none; }   /* it takes focus from the skip link only */

.shell{ width:100%; max-width:var(--shell); margin:0 auto; padding-inline:var(--pad); }
.shell--narrow{ max-width:860px; }

.section{ padding-block:var(--band); }
.section--tight{ padding-block:calc(var(--band) * .62); }
.band{ background:var(--deep); border-block:1px solid var(--edge); }

.fineprint{ font-family:var(--sans); font-size:13.5px; line-height:1.6; color:var(--text-dim); }

/* ==========================================================================
   4  Buttons
   Chunky and metal, the way a game's site draws a button. Deliberately not a
   soft SaaS pill: square-ish, a bevelled top highlight, a hard bottom edge.
   ========================================================================== */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.55em;
  min-height:52px; padding:0 26px;
  font-family:var(--sans); font-weight:700; font-size:15px;
  letter-spacing:.055em; text-transform:uppercase; text-decoration:none;
  border-radius:var(--r); border:1px solid transparent;
  transition:transform .12s ease, filter .16s ease, background .16s ease, border-color .16s ease;
}
.btn:active{ transform:translateY(1px); }

/* The bevel is an inset highlight and a hard dark edge, not a coloured glow.
   A gold halo under a gold button is the "shadow whose colour is not neutral"
   tell, and it made the button look like it was hovering rather than sitting
   in the page. */
.btn--play,
.btn.primary{
  color:#140f04;
  background:linear-gradient(180deg,var(--gold-hi),var(--gold) 52%,#a9832f);
  border-color:#6d5520;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5), 0 2px 0 #5c4718, 0 10px 22px rgba(0,0,0,.5);
}
.btn--play:hover,
.btn.primary:hover{ filter:brightness(1.08); color:#140f04; }

.btn--ghost{
  color:var(--text);
  background:rgba(20,32,50,.62);
  border-color:var(--edge-hi);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
}
.btn--ghost:hover{ background:rgba(30,45,66,.8); border-color:var(--gold-dim); color:var(--gold-hi); }

.btn--big{ min-height:60px; padding:0 34px; font-size:16px; }
.btn--sm{ min-height:44px; padding:0 18px; font-size:13px; }
.btn .arrow{ font-size:1.35em; line-height:0; transform:translateY(-1px); }

/* ==========================================================================
   5  Site header
   ========================================================================== */
.site-header{
  position:sticky; top:0; z-index:60;
  background:rgba(7,11,17,.82);
  backdrop-filter:blur(10px) saturate(130%);
  border-bottom:1px solid var(--edge);
}
.header-in{ display:flex; align-items:center; gap:18px; min-height:62px; }

.wordmark{
  font-family:var(--display); font-size:21px; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--gold); text-decoration:none; white-space:nowrap;
}
.wordmark:hover{ color:var(--gold-hi); }

.nav{ display:flex; gap:2px; margin-left:auto; }
.nav a{
  font-family:var(--sans); font-size:13.5px; letter-spacing:.03em;
  color:var(--text-dim); text-decoration:none;
  display:inline-flex; align-items:center; min-height:38px; padding:0 12px; border-radius:var(--r);
}
.nav a:hover{ color:var(--gold-hi); background:rgba(200,164,72,.08); }

.menu{ margin-left:auto; display:none; position:relative; }
.menu summary{
  list-style:none; cursor:pointer;
  font-family:var(--sans); font-size:13px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--text); display:inline-flex; align-items:center; min-height:44px; padding:0 14px;
  border:1px solid var(--edge-hi); border-radius:var(--r); background:rgba(20,32,50,.6);
}
.menu summary::-webkit-details-marker{ display:none; }
.menu-panel{
  position:absolute; right:0; top:calc(100% + 8px); z-index:70;
  display:grid; min-width:210px; padding:8px;
  background:var(--panel); border:1px solid var(--edge-hi); border-radius:var(--r);
  box-shadow:0 22px 50px rgba(0,0,0,.6);
}
.menu-panel a{
  font-family:var(--sans); font-size:14px; color:var(--text); text-decoration:none;
  padding:11px 12px; border-radius:4px;
}
.menu-panel a:hover{ background:rgba(200,164,72,.1); color:var(--gold-hi); }
.header-cta{ margin-left:0; }

@media (max-width:900px){
  .nav{ display:none; }
  .menu{ display:block; }
}
@media (max-width:420px){
  .header-cta .arrow{ display:none; }
  .header-cta{ padding:0 14px; }
}

/* ==========================================================================
   6  Hero
   Full-bleed key art, the treatment every game site in the reference set uses
   (Valheim, Hades, Brighter Shores): the art and the logo lockup ARE the hero.
   The wordmark is painted into landing/img/key-art.webp, so the <h1> is
   visually hidden rather than absent, and the art is NOT scrimmed flat: only
   the bottom third darkens, under the copy that needs the contrast.
   ========================================================================== */
.hero{ position:relative; isolation:isolate; background:var(--deep); }
.hero__media{ position:absolute; inset:0; z-index:-2; overflow:hidden; }
.hero__media img{
  width:100%; height:100%; object-fit:cover; object-position:center 55%;
}
/* Two gradients, both doing one job. The top one only has to stop the sticky
   header dissolving into the canopy. The bottom one is the working half: it
   turns the lower quarter into near-solid ground for the buttons WITHOUT
   washing out the middle of the picture, which is where the wordmark and the
   ribbon of magic live. The old page scrimmed its hero flat to 55 percent
   everywhere and the screenshot underneath was unreadable. */
.hero__scrim{
  position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(7,11,17,.6) 0, rgba(7,11,17,0) 18%),
    linear-gradient(0deg, var(--void) 1%, rgba(7,11,17,.92) 15%, rgba(7,11,17,.3) 30%, transparent 46%);
}

/* justify-content:flex-end parks everything in that dark bottom band, clear of
   the wordmark, which sits at roughly 48 to 57 percent of the art's height.

   The height is the smaller of two limits: the viewport below the 62px header,
   and 57.11vw, which is the key art's own height at the current width
   (731/1280). The second limit is the one that stops the art being cut off:
   the old 900px cap forced a 2560-wide box to stay 900 tall while cover
   scaled the art to 1462, which threw away 38 percent of the picture, the
   mage's feet and the log with it. Now the box tracks the art's aspect until
   the viewport runs out, at which point object-position 55% sheds what little
   is left roughly evenly into the canopy at the top and the mist at the
   bottom, both of which are empty. At 1280 wide and below-the-cap heights the
   art fits pixel-for-pixel with no crop at all. */
.hero__in{
  display:flex; flex-direction:column; align-items:center; justify-content:flex-end;
  min-height:clamp(560px, 92vh, 1500px);
  min-height:clamp(560px, min(100svh - 62px, 57.11vw), 1500px);
  padding-block:80px 54px;
  text-align:center;
}
/* Below 700px the <picture> swaps to the 768x1344 portrait art, whose full
   height at the current width is 175vw, not 57.11vw. */
@media (max-width:699px){
  .hero__in{
    min-height:clamp(560px, 92vh, 900px);
    min-height:clamp(560px, min(100svh - 62px, 175vw), 900px);
  }
}
/* Visually hidden but read by search engines and screen readers: the visible
   wordmark lives inside the key art. */
.hero h1{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap;
}

.hero__cta{ display:flex; flex-wrap:wrap; gap:14px; justify-content:center; }

.hero__note{
  margin:22px 0 0; display:flex; flex-wrap:wrap; gap:8px 14px; justify-content:center;
  font-family:var(--sans); font-size:13px; letter-spacing:.05em; text-transform:uppercase;
  color:var(--text-dim); text-shadow:0 1px 8px rgba(0,0,0,.9);
}
.hero__note .sep{ color:var(--gold-dim); }

/* ==========================================================================
   7  Lede
   One short paragraph directly under the art, which is what Balatro, Valheim
   and Brighter Shores all do in place of a wall of feature copy.
   ========================================================================== */
/* The hook the hero used to carry, moved down here where it has clean ground
   instead of the key art's own wordmark under it. */
.lede__hook{
  max-width:26ch; margin:0 auto 26px; text-align:center;
  font-family:var(--display); font-weight:600;
  font-size:clamp(28px,3.4vw,46px); line-height:1.16; color:#f4ecdb;
}

.lede{
  max-width:52ch; margin:0 auto; text-align:center;
  font-size:clamp(19px,1.1vw + 15px,23px); line-height:1.55; color:var(--text);
}
.lede b{ color:var(--gold-hi); font-weight:700; }
.lede__sub{
  max-width:60ch; margin:18px auto 0; text-align:center;
  font-size:17px; line-height:1.7; color:var(--text-dim);
}

/* ==========================================================================
   7b  Waitlist
   The one form on the site. It borrows the plate and the gold button, so the
   only new chrome here is the email field and the row it shares with the
   button. The row wraps, and below 560px the button takes the full width, so
   nothing pokes past a 390px screen: landing-look measures horizontal
   overflow and fails the run on 2px.
   ========================================================================== */
.waitlist{
  position:relative;              /* seats the offscreen honeypot */
  max-width:600px; margin:0 auto;
  padding:clamp(24px,3.4vw,40px);
  text-align:center;
}

/* Visually hidden, read by screen readers: same clip pattern as the hero h1. */
.waitlist-label{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap;
}

.waitlist-row{ display:flex; flex-wrap:wrap; gap:12px; justify-content:center; }
.waitlist-row input[type="email"]{
  flex:1 1 240px; min-width:0; min-height:52px; padding:0 16px;
  font-family:var(--serif); font-size:17px; color:var(--text);
  background:var(--void); border:1px solid var(--edge-hi); border-radius:var(--r);
}
.waitlist-row input[type="email"]::placeholder{ color:var(--text-dim); opacity:.7; }

/* .btn was written for <a>. A <button> brings its own UA chrome; the class
   already restates font, border and background, so only these two remain. */
button.btn{ cursor:pointer; -webkit-appearance:none; appearance:none; }
.btn[disabled]{ opacity:.55; pointer-events:none; }

/* Honeypot: offscreen, not display:none, which the lazier bots check for.
   Negative left never widens the page; only right-side overflow scrolls. */
.waitlist-hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* min-height keeps the plate from jumping when the status line appears. */
.waitlist-msg{ margin:14px 0 0; min-height:1.6em; font-size:16px; line-height:1.6; color:var(--gold-hi); }
.waitlist-privacy{ margin:8px 0 0; }
.waitlist-noscript{ margin:14px 0 0; }

@media (max-width:560px){
  .waitlist-row .btn{ flex:1 1 100%; }
}

/* ==========================================================================
   8  Section plates and headings
   A centred Cinzel plate on a gold rule, in place of the eyebrow / headline /
   lead stack that ran on every section of the old page. That stack is a SaaS
   pattern; a game site labels a section and gets out of the way.
   ========================================================================== */
.head{ text-align:center; margin-bottom:clamp(30px,4vw,48px); }
.head h2{ font-size:clamp(26px,2.7vw,38px); letter-spacing:.06em; text-transform:uppercase; }
.head .sub{
  margin:14px auto 0; max-width:60ch;
  font-size:clamp(16.5px,.6vw + 15px,18.5px); color:var(--text-dim);
}
.head .rule{
  display:flex; align-items:center; justify-content:center; gap:12px;
  margin:0 auto 16px; max-width:340px;
}
.head .rule::before,
.head .rule::after{
  content:''; flex:1; height:1px;
  background:linear-gradient(90deg,transparent,var(--gold-dim));
}
.head .rule::after{ background:linear-gradient(270deg,transparent,var(--gold-dim)); }
/* The one place the key art's violet is spent below the fold, so the hero's
   palette echoes at least once instead of being declared and forgotten. */
.head .rule i{
  width:7px; height:7px; transform:rotate(45deg);
  background:var(--gold); box-shadow:0 0 0 4px rgba(143,108,232,.16);
}

/* The plate itself: the shape the game draws a panel with. */
.plate{
  background:var(--plate);
  border:1px solid var(--edge);
  border-radius:var(--r);
  box-shadow:var(--lift);
}

/* A screenshot inside a plate. Its whole job is to be BIG: the old page put
   nine 380px thumbnails on the page and none of them was legible. */
.shot{ margin:0; }
/* Every plate is locked to the game canvas's own 1566x787, so a grid of them
   has one baseline and the captions line up. The class-creation shot is the
   odd one out at 1600x900 because it photographs the DOM rather than the
   canvas, so `contain` letterboxes it by about 80px a side rather than
   cropping the screen's title off the top. The bars are invisible: the plate
   ground and that screen's own background are the same near-black. Measured
   at a 543px plate the bars are about 30px a side. */
.shot__win{
  position:relative; overflow:hidden;
  aspect-ratio:1566 / 787;
  border-radius:var(--r);
  background:#05080d;
  box-shadow:inset 0 0 0 1px var(--edge-hi), 0 8px 24px rgba(0,0,0,.55);
}
.shot__win img{ width:100%; height:100%; object-fit:contain; }
.shot figcaption{
  margin-top:12px;
  font-size:15.5px; line-height:1.6; color:var(--text-dim);
}
.shot figcaption b{ color:var(--gold-hi); font-weight:700; }

/* ==========================================================================
   9  Trailer
   ========================================================================== */
.trailer__win{ aspect-ratio:16 / 9; border-color:var(--gold-dim); }
.trailer__video{ width:100%; height:auto; aspect-ratio:16/9; background:#05080d; }
.trailer__fallback{ padding:26px; text-align:center; color:var(--text-dim); }

.trailer__cta{ margin-top:30px; text-align:center; }
.trailer__note{ margin:14px 0 0; font-family:var(--sans); font-size:13.5px; color:var(--text-dim); }

/* ==========================================================================
   10  Screenshot reel
   Two across at 1200px is roughly 580px a plate, about three times the area
   the old three-across grid gave each shot.
   ========================================================================== */
.reel{ display:grid; grid-template-columns:repeat(2,1fr); gap:clamp(20px,2.6vw,34px); }
@media (max-width:760px){ .reel{ grid-template-columns:1fr; } }

/* ==========================================================================
   11  Worlds
   Three wide rows, one per world, art on alternating sides. The old page gave
   Elderwood no card at all even though it is where every player starts.
   ========================================================================== */
.worlds{ display:grid; gap:clamp(22px,3vw,40px); }
.world{
  margin:0;
  display:grid; grid-template-columns:1.08fr .92fr; align-items:center;
  gap:clamp(20px,2.6vw,38px);
  padding:clamp(18px,2vw,26px) 0;
}
.world:nth-child(even){ grid-template-columns:.92fr 1.08fr; }
.world:nth-child(even) .world__art{ order:2; }
.world__body{ padding:clamp(4px,1vw,14px); }
.world__band{
  display:inline-block; margin-bottom:12px;
  font-family:var(--sans); font-size:11px; font-weight:700;
  letter-spacing:.16em; text-transform:uppercase; color:var(--gold);
  padding:5px 10px; border:1px solid rgba(200,164,72,.32); border-radius:3px;
  background:rgba(200,164,72,.07);
  white-space:nowrap;
}
.world__body h3{ font-size:clamp(23px,2.1vw,30px); letter-spacing:.03em; margin-bottom:12px; }
.world__body p{ margin:0 0 12px; font-size:17px; line-height:1.6; }
.world__body p:last-child{ margin-bottom:0; }
.world__hook{ color:var(--text); }
.world__hook b{ color:var(--gold-hi); font-weight:700; }
.world__places{ font-size:15px; line-height:1.65; color:var(--text-dim); }

/* ⚠️ BOTH selectors, and it has to be both. A media query contributes NOTHING
   to specificity, so `.world` (0,1,0) in here loses to `.world:nth-child(even)`
   (0,2,0) up at line 445, and world two kept its desktop two-column split on a
   350px phone: a postage-stamp screenshot beside a 20-character measure, in
   the section whose whole job is proving three worlds exist. */
@media (max-width:820px){
  .world,
  .world:nth-child(even){ grid-template-columns:1fr; }
  .world:nth-child(even) .world__art{ order:0; }
}

.note{
  margin:clamp(28px,3.4vw,44px) 0 0;
  max-width:78ch;
  padding:20px 24px;
  border-left:3px solid var(--gold-dim);
  background:rgba(14,21,32,.7);
  border-radius:0 var(--r) var(--r) 0;
  font-size:16.5px; line-height:1.65; color:var(--text-dim);
}
.note b{ color:var(--gold-hi); font-weight:700; }

/* ==========================================================================
   12  Facts strip
   Six short items under the trailer. Word budget is the point: the old page
   ran 60 to 70 words a cell here, which nobody reads.
   ========================================================================== */
.facts{
  list-style:none; margin:clamp(34px,4vw,52px) 0 0; padding:0;
  display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(20px,2.4vw,32px);
}
.facts b{
  display:block; margin-bottom:7px;
  font-family:var(--sans); font-size:11.5px; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--gold);
}
.facts li{
  border-top:1px solid var(--edge); padding-top:16px;
  font-size:16px; line-height:1.65; color:var(--text-dim);
}

@media (max-width:860px){ .facts{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:520px){ .facts{ grid-template-columns:1fr; } }

/* ==========================================================================
   13  Depth grid
   ========================================================================== */
/* Deliberately NOT cards. Six equal-height bordered boxes in a three column
   grid, each with a label over a heading over two lines of body, is the exact
   shape every landing page generator emits, and no amount of good copy inside
   one survives the shape. These are text blocks under a gold hairline, set to
   the top of their row so they are allowed to be different lengths, which is
   what an actual person writing about six unequal systems produces. */
.grid{
  display:grid; grid-template-columns:repeat(3,1fr);
  align-items:start;
  gap:clamp(26px,3vw,44px) clamp(24px,3vw,40px);
}
@media (max-width:920px){ .grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:600px){ .grid{ grid-template-columns:1fr; } }

.cell{ border-top:1px solid var(--gold-dim); padding-top:18px; }
/* ⚠️ .cell__meta is a <p>, so a bare `.cell p` rule (0,1,1) outranks it
   (0,1,0) and silently ate its font-size and colour: the labels shipped at
   14.5px in cool grey instead of 11px gold caps. The body rule is scoped with
   :not() so the label wins. --gold, not --gold-dim: gold-dim measures 4.26:1
   on --void, which fails AA for 11px text. */
.cell__meta{
  margin:0 0 10px;
  font-family:var(--sans); font-size:11px; font-weight:700;
  letter-spacing:.16em; text-transform:uppercase; color:var(--gold);
}
.cell h3{ font-size:20px; letter-spacing:.02em; margin-bottom:10px; }
.cell p:not(.cell__meta){ margin:0; font-size:16px; line-height:1.7; color:var(--text-dim); }
.cell p b{ color:var(--text); font-weight:700; }

/* ==========================================================================
   14  Bullet panel
   The gold-edged frame the "Bring a friend" list sits in. It was written for
   the "What is not here yet" beta panel, which was cut on 2026-08-04; the
   class name stayed because the frame is the same frame.
   ========================================================================== */
.beta{ padding:clamp(26px,3.4vw,46px); border-color:var(--gold-dim); }

.marks{ list-style:none; margin:0; padding:0; display:grid; gap:15px; }
.marks li{
  position:relative; max-width:74ch; padding-left:26px;
  font-size:16px; line-height:1.7; color:var(--text-dim);
}
.marks li::before{
  content:''; position:absolute; left:4px; top:.62em;
  width:7px; height:7px; transform:rotate(45deg);
  background:var(--gold-dim);
}
.marks b{ color:var(--text); font-weight:700; }

/* ==========================================================================
   15  FAQ
   ========================================================================== */
.faq details{ border-bottom:1px solid var(--edge); }
.faq details:first-child{ border-top:1px solid var(--edge); }
.faq summary{
  list-style:none; cursor:pointer;
  display:flex; align-items:center; gap:14px;
  padding:20px 0;
  font-family:var(--serif); font-size:clamp(17.5px,1.1vw,20px); font-weight:700;
  color:var(--gold-hi);
}
.faq summary::-webkit-details-marker{ display:none; }
.faq summary::after{
  content:'+'; margin-left:auto; flex:none;
  font-family:var(--sans); font-size:22px; line-height:1; color:var(--gold);
  transition:transform .18s ease;
}
.faq details[open] summary::after{ transform:rotate(45deg); }
.faq summary:hover{ color:var(--gold); }
.faq .answer{ padding:0 44px 22px 0; }
.faq .answer p{
  margin:0 0 .85em; font-size:16px; line-height:1.7; color:var(--text-dim);
}
.faq .answer p:last-child{ margin-bottom:0; }
.faq .answer b{ color:var(--text); font-weight:700; }

/* ==========================================================================
   16  Closer
   ========================================================================== */
.closer{ position:relative; isolation:isolate; padding-block:clamp(90px,11vw,150px); text-align:center; }
.closer__media{ position:absolute; inset:0; z-index:-2; overflow:hidden; }
/* Blurred on purpose. This is the one place a screenshot is used as ATMOSPHERE
   rather than as evidence, and unblurred the leftover combat HUD read straight
   through the scrim: "-172", "-191" and two Lv20 nameplates sat behind the
   headline competing with it. Blur turns the frame back into a place. The
   scale hides the transparent edge blur pulls in at the boundary. */
.closer__media img{
  width:100%; height:100%; object-fit:cover;
  filter:blur(7px) saturate(1.06);
  transform:scale(1.05);
}
.closer__scrim{
  position:absolute; inset:0; z-index:-1;
  background:linear-gradient(180deg, var(--void) 0, rgba(7,11,17,.72) 34%, rgba(7,11,17,.78) 66%, var(--void) 100%);
}
.closer h2{ font-size:clamp(27px,3.2vw,42px); letter-spacing:.04em; margin-bottom:16px; }
.closer p{ margin:0 auto 28px; max-width:46ch; color:var(--text); }

/* ==========================================================================
   17  Site footer
   ========================================================================== */
.site-footer{ border-top:1px solid var(--edge); background:var(--deep); padding-block:44px 56px; }
.foot-in{ display:flex; flex-wrap:wrap; gap:26px 44px; justify-content:space-between; align-items:flex-start; }
.foot-brand{ max-width:34ch; }
.foot-brand .fineprint{ margin:10px 0 0; }
.foot-links{ display:flex; flex-wrap:wrap; gap:4px 22px; align-items:flex-start; }
.foot-links a{
  font-family:var(--sans); font-size:14px; color:var(--text-dim); text-decoration:none;
  padding:10px 0;
}
.foot-links a:hover{ color:var(--gold-hi); }
/* The rule spans the footer; only the text is measured. Constraining both put
   a hairline across the left two thirds and nothing across the right. */
.foot-rule{ margin:34px 0 0; padding-top:22px; border-top:1px solid var(--edge); }
.foot-note{ margin:0; max-width:76ch; }

/* ==========================================================================
   18  Shared chrome for the legal pages and 404
   /privacy.html, /terms.html and /404.html link this same stylesheet and use
   nav.top, .brand, .links, .prose, .updated, .notfound, .btn.primary and a
   bare <footer>. KEEP THESE HOOKS. playtest/route-split.mjs checks the 404
   page is styled and clicks a.btn.primary.
   ========================================================================== */
nav.top{
  position:sticky; top:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding-block:12px;
  padding-inline:max(var(--pad), calc((100% - var(--shell)) / 2 + var(--pad)));
  background:rgba(7,11,17,.86);
  backdrop-filter:blur(12px) saturate(120%);
  border-bottom:1px solid var(--edge);
}
nav.top .brand{
  font-family:var(--display); font-size:20px; font-weight:600;
  letter-spacing:.18em; text-transform:uppercase;
  color:var(--gold); text-decoration:none; white-space:nowrap;
}
nav.top .brand:hover{ color:var(--gold-hi); }
nav.top .links{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 8px; }
nav.top .links a{
  font-family:var(--sans); font-size:14px; color:var(--text-dim); text-decoration:none;
  display:inline-flex; align-items:center; min-height:32px; padding:0 10px; border-radius:var(--r);
}
nav.top .links a:hover{ color:var(--gold-hi); background:rgba(200,164,72,.08); }

.prose{ max-width:780px; margin:0 auto; padding:clamp(44px,7vw,72px) var(--pad) clamp(64px,9vw,96px); }
.prose h1{ color:var(--gold); font-size:clamp(31px,4vw,42px); margin:0 0 10px; }
.prose .updated{
  font-family:var(--sans); font-size:13px; letter-spacing:.06em;
  color:var(--text-dim); margin:0 0 36px;
}
.prose h2{ color:var(--gold); font-size:clamp(20px,1.8vw,24px); margin:38px 0 12px; }
.prose p{ color:var(--text); margin:0 0 1em; }
.prose ul{ margin:0 0 1em; padding-left:22px; }
.prose li{ color:var(--text); margin:8px 0; }
.prose li strong, .prose p strong{ color:var(--gold-hi); font-weight:600; }
.prose a{ color:var(--gold); text-underline-offset:.2em; }
.prose a:hover{ color:var(--gold-hi); }

.notfound{ text-align:center; padding:clamp(72px,12vw,140px) var(--pad); }
.notfound h1{ color:var(--gold); font-size:clamp(64px,12vw,104px); margin:0; letter-spacing:.02em; }
.notfound p{ color:var(--text-dim); font-size:clamp(17px,1.6vw,20px); margin:14px 0 28px; }
.notfound .btn{ margin-bottom:24px; }

footer{
  padding:40px var(--pad) 64px;
  text-align:center;
  color:var(--text-dim);
  font-family:var(--sans);
  font-size:14px;
  border-top:1px solid var(--edge);
}
footer a{ color:var(--gold); text-decoration:none; }
footer a:hover{ color:var(--gold-hi); }
.site-footer{
  font-family:var(--serif);
  text-align:left;              /* the bare footer{} rule above centres the legal pages */
  padding-inline:0;             /* ... and pads them; the shell already does that here */
}
.site-footer a{ text-decoration:none; }

/* -- Phone. Three things that are fine on a 1200px shell and wrong on a 350px
      column: centred multi-line paragraphs (every line starts somewhere new,
      so the eye hunts for the left edge), the FAQ answer's 44px right padding
      (it clears a glyph that sits on the summary row, not beside the answer,
      and costs 12% of the reading measure), and the separator slashes in the
      hero trust line, which are their own flex items and so wrap to the head
      of a line as stray punctuation. ---------------------------------------- */
@media (max-width:560px){
  .lede, .head .sub{ text-align:left; }
  .faq .answer{ padding-right:0; }
  .hero__note{ display:grid; grid-template-columns:repeat(2,auto); gap:7px 20px; justify-content:center; }
  .hero__note .sep{ display:none; }
  .world__band{ letter-spacing:.1em; }
}

/* ==========================================================================
   19  Reveal, reduced motion, print
   The .js class is set in <head> before paint, so with JavaScript disabled
   nothing on this page is ever hidden.
   ========================================================================== */
.js .reveal{ opacity:0; transform:translateY(16px); }
.js .reveal.is-in{
  opacity:1; transform:none;
  transition:opacity .7s ease, transform .7s cubic-bezier(.2,.7,.3,1);
}

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation:none !important; transition:none !important; }
  .js .reveal{ opacity:1 !important; transform:none !important; }
  .btn:active{ transform:none !important; }
}

@media print{
  .site-header, .hero__media, .hero__scrim, .closer__media, .closer__scrim, .skip{ display:none !important; }
  body{ background:#fff; color:#000; }
  .hero__in{ min-height:auto; padding-block:0 24px; }
  h1,h2,h3,.lede__hook{ color:#000 !important; text-shadow:none; }
  .head .sub,.cell p,.facts li,.marks li,.fineprint,.shot figcaption,.hero__note{ color:#333 !important; }
  .faq details{ break-inside:avoid; }
  .faq .answer{ display:block !important; }
}
