/* Planet Plink marketing site styles. Owner: Site agent.

   Serves the landing page at / and the five long-form pages (/privacy, /terms, /support,
   /about, /press). It is the ONLY stylesheet those pages load.

   WHY THE PALETTE IS DEFINED HERE AND NOT LINKED. These pages used to link /css/tokens.css.
   They cannot any more: worker/index.js isGameAsset() treats everything under /css/ as part of
   the game bundle and 302s it to / for public traffic, so the link would resolve to an HTML
   document and the whole site would render unstyled. The block below therefore mirrors the
   values in app/css/tokens.css for exactly the tokens this file uses. It is the one place on the
   site where a colour literal is allowed, which is why each of those lines carries allow-hex.
   Contract 0.6 otherwise stands: every rule beneath the block uses var(--token) and nothing else.
   If a value changes in app/css/tokens.css, change it here too.

   Other rules this file obeys (docs/CONTRACT.md 0.7, 0.8, 12.1, 12.2):
     - Radii from the 12.2 scale only: cards 20, controls 16, chips 999.
     - Dark by default, matching the game. No external fonts, no CDNs, no network requests.
     - Gold is the download action and nothing else. Numbers, headings and links are ink.
     - Text contrast at least 4.5:1.
     - Every interactive target at least 44x44 CSS px.
     - Mobile first. The layout holds from 360px up and is designed for 375px.
*/

/* ------------------------------------------------------------------ palette (mirrors app/css/tokens.css) */

:root {
  color-scheme: dark;

  --bg-top: #1A0B2E;        /* allow-hex */
  --bg-mid: #0F1626;        /* allow-hex */
  --bg-bot: #050814;        /* allow-hex */
  --neb-a-wash: rgba(123, 47, 191, 0.26);
  --neb-b-wash: rgba(27, 108, 168, 0.22);

  --surface: #1A2238;       /* allow-hex */
  --surface-2: #232C46;     /* allow-hex */

  --gold-hi: #FFD86B;       /* allow-hex */
  --gold: #FFC53D;          /* allow-hex */
  --gold-lo: #E8A317;       /* allow-hex */
  --gold-ink: #3A2600;      /* allow-hex */
  --gold-bevel: #8C6110;    /* allow-hex */
  --gold-glow: rgba(255, 197, 61, 0.38);
  --gold-tint: rgba(255, 197, 61, 0.14);

  --ink: #F2F4F8;           /* allow-hex */
  --ink-soft: #A9B2C6;      /* allow-hex */
  --ink-mute: #9AA5BC;      /* allow-hex */

  --accent: #56B4E9;        /* allow-hex */
  --success: #3DD68C;       /* allow-hex */
  --success-tint: rgba(61, 214, 140, 0.14);
  --warn: #E69F00;          /* allow-hex */

  --hilite: rgba(255, 255, 255, 0.14);
  --line: rgba(255, 255, 255, 0.10);
  --line-strong: rgba(255, 255, 255, 0.18);
  --glass: rgba(255, 255, 255, 0.06);
  --scrim: rgba(5, 8, 20, 0.55);
  --gloss-1: rgba(255, 255, 255, 0.18);
  --gloss-3: rgba(255, 255, 255, 0.55);
  --shade-3: rgba(0, 0, 0, 0.55);
  --shadow-card: 0 12px 26px -12px rgba(0, 0, 0, 0.68), inset 0 1px 0 var(--hilite);
  --bevel-h: 4px;
  --bevel-h-down: 1px;
  --press-y: 3px;

  --r-card: 20px;
  --r-control: 16px;
  --r-chip: 999px;

  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --tap: 44px;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --fs-xs: 12px;
  --fs-sm: 14px;
  --fs-md: 16px;
  --fs-lg: 20px;
  --lh-tight: 1.1;
  --lh-body: 1.45;
  --fw-medium: 500;
  --fw-bold: 700;
  --fw-black: 800;
  --tr-tight: -0.02em;

  --dur-1: 140ms;
  --e-out: cubic-bezier(0.2, 0.8, 0.2, 1);

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);

  /* The page gutter, so every section lines up on one edge at every width. */
  --gutter: max(20px, var(--safe-left));
}

@media (prefers-reduced-motion: reduce) {
  :root { --dur-1: 0ms; }
}

/* ------------------------------------------------------------------ reset */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
  color: var(--ink);
  background-color: var(--bg-bot);
  /* 12.1 rule 1: the background is a place, not a color. Two nebula washes over a vertical ground. */
  background-image:
    radial-gradient(70% 46% at 12% 4%, var(--neb-a-wash), transparent 68%),
    radial-gradient(64% 40% at 92% 16%, var(--neb-b-wash), transparent 70%),
    linear-gradient(var(--bg-top), var(--bg-mid) 42%, var(--bg-bot));
  background-repeat: no-repeat;
  background-attachment: scroll;
  min-height: 100%;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: var(--fw-black);
  letter-spacing: var(--tr-tight);
  line-height: var(--lh-tight);
  text-wrap: balance;
}

p, ul, ol, dl, table { margin: 0; }

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

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

/* ------------------------------------------------------------------ shell */

.skip {
  position: absolute;
  left: var(--s-4);
  top: calc(var(--safe-top) + var(--s-2));
  z-index: 40;
  transform: translateY(-200%);
  padding: var(--s-3) var(--s-4);
  min-height: var(--tap);
  border-radius: var(--r-control);
  background: var(--gold);
  color: var(--gold-ink);
  font-weight: var(--fw-bold);
  text-decoration: none;
}

.skip:focus { transform: translateY(0); }

/* ==================================================================================
   THE LANDING PAGE (/). A shop window: a wordmark, one sentence, two store buttons,
   four facts and three screenshots. Nothing here links to a playable build, because
   there is not one on the public web.
   ================================================================================== */

.window,
.facts,
.cast,
.shots {
  width: 100%;
  max-width: 760px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.window { padding-block: clamp(36px, 9vw, 76px) clamp(32px, 7vw, 56px); }

/* ---- the wordmark lockup ---- */

.lockup {
  margin: 0 0 clamp(18px, 4vw, 26px);
}

/* The full wordmark, not the 40 px mark this rule used to size. The mark had a text sibling
   spelling the name; the wordmark IS the name, so it carries the lockup on its own. */
.lockup img {
  display: block;
  width: min(280px, 62vw);
  height: auto;
}

/* ---- the one sentence ---- */

.window h1 {
  margin-block: var(--s-5) var(--s-4);
  font-size: clamp(32px, 8.2vw, 52px);
  max-width: 16ch;
}

.window .lede {
  max-width: 46ch;
  font-size: clamp(16px, 2.4vw, 19px);
  color: var(--ink-soft);
}

/* ---- the two store buttons: the one action on this page, and the only gold on it ---- */

.get {
  list-style: none;
  padding: 0;
  margin-top: clamp(24px, 6vw, 36px);
  display: grid;
  gap: var(--s-3);
  grid-template-columns: 1fr;
}

/* 12.1 rule 5: chunky, not hairline. Bottom bevel, inner top highlight, press translates down.
   The 1px border is transparent on the gold state so that swapping to the quiet state below
   cannot change the button's box and shift the layout. */
.store {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: 60px;
  padding: var(--s-2) var(--s-5);
  border: 1px solid var(--gold-bevel);
  border-radius: var(--r-control);
  background: linear-gradient(var(--gold-hi), var(--gold) 46%, var(--gold-lo));
  box-shadow:
    0 var(--bevel-h) 0 var(--gold-bevel),
    inset 0 1px 0 var(--gloss-3),
    0 12px 26px -12px var(--gold-glow);
  color: var(--gold-ink);
  text-decoration: none;
  transition: transform var(--dur-1) var(--e-out), box-shadow var(--dur-1) var(--e-out);
}

.store:hover { color: var(--gold-ink); }

.store:active {
  transform: translateY(var(--press-y));
  box-shadow: 0 var(--bevel-h-down) 0 var(--gold-bevel), inset 0 1px 0 var(--gloss-3);
}

.store .glyph { fill: currentColor; flex: none; }

.store .label {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
}

.store .sup {
  font-size: 11px;
  font-weight: var(--fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.store .name {
  font-size: var(--fs-lg);
  font-weight: var(--fw-black);
  letter-spacing: var(--tr-tight);
}

/* hero.js marks the visitor's platform on <html>, and the store they are NOT on drops back to a
   quiet control. Both remain real links at the same size, so with JavaScript off (or on a
   desktop, or for a crawler) the page simply shows two equal gold buttons. Nothing is hidden,
   reordered or disabled, and no layout moves. */
:root[data-os="ios"] .get > li:nth-child(2) > .store,
:root[data-os="android"] .get > li:nth-child(1) > .store {
  background: var(--glass);
  border-color: var(--line-strong);
  box-shadow: 0 var(--bevel-h) 0 var(--shade-3), inset 0 1px 0 var(--gloss-1);
  color: var(--ink);
}

:root[data-os="ios"] .get > li:nth-child(2) > .store:hover,
:root[data-os="android"] .get > li:nth-child(1) > .store:hover { color: var(--ink); }

.under {
  margin-top: var(--s-4);
  font-size: var(--fs-sm);
  color: var(--ink-mute);
}

@media (min-width: 560px) {
  .get { grid-template-columns: 1fr 1fr; }
  .store { justify-content: flex-start; }
}

/* ---- the proof strip ---- */

.facts,
.cast,
.shots { padding-block: clamp(28px, 6vw, 48px); }

.facts { border-top: 1px solid var(--line); }

.facts h2,
.shots h2 {
  margin-bottom: var(--s-4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.facts ul {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 1px;
  grid-template-columns: 1fr;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--line);
  overflow: hidden;
}

.facts li {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  padding: var(--s-4);
  background: var(--surface);
}

.facts b {
  flex: none;
  min-width: 4.2ch;
  font-size: clamp(22px, 5.4vw, 28px);
  font-weight: var(--fw-black);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tr-tight);
  color: var(--ink);
}

.facts span {
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

@media (min-width: 600px) {
  .facts ul { grid-template-columns: 1fr 1fr; }
}

/* ---- the screenshots ---- */

.shots {
  max-width: 1000px;
  border-top: 1px solid var(--line);
}

.shots ul {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--s-5);
  grid-template-columns: 1fr;
  justify-items: start;
}

.shots img {
  width: 100%;
  max-width: 300px;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
}

.shots p {
  margin-top: var(--s-3);
  max-width: 38ch;
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

@media (min-width: 720px) {
  .shots ul { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-5); }
  .shots img { max-width: 100%; }
}

/* ---- the one line footer ---- */

.footline {
  border-top: 1px solid var(--line);
  background: var(--scrim);
  padding: var(--s-3) var(--gutter) calc(var(--s-5) + var(--safe-bottom));
}

.footline p {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--s-5);
  width: 100%;
  max-width: 1000px;
  margin-inline: auto;
}

.footline a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  min-width: var(--tap);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--ink-soft);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.footline a:hover { color: var(--ink); text-decoration: underline; }

/* ==================================================================================
   THE LONG-FORM PAGES (/privacy, /terms, /support, /about, /press).
   ================================================================================== */

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

.masthead {
  position: relative;
  z-index: 20;
  border-bottom: 1px solid var(--line);
  background: var(--scrim);
  padding-top: var(--safe-top);
}

.masthead .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
  min-height: 64px;
  padding-block: var(--s-2);
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap);
  color: var(--ink);
  font-weight: var(--fw-black);
  font-size: var(--fs-lg);
  letter-spacing: var(--tr-tight);
  text-decoration: none;
}

.mark .dot {
  width: 14px;
  height: 14px;
  border-radius: var(--r-chip);
  background: radial-gradient(circle at 34% 30%, var(--gold-hi), var(--gold) 52%, var(--gold-lo));
  box-shadow: 0 0 0 1px var(--gold-bevel), 0 0 14px var(--gold-glow);
  flex: none;
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
}

.nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-inline: var(--s-3);
  border-radius: var(--r-control);
  color: var(--ink-soft);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  text-decoration: none;
}

.nav a:hover { color: var(--ink); background: var(--glass); }
.nav a[aria-current="page"] { color: var(--gold); }

/* ------------------------------------------------------------------ sections */

.band { padding-block: clamp(40px, 8vw, 88px); }
.band + .band { border-top: 1px solid var(--line); }

.overline {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.overline::before {
  content: "";
  flex: 1 1 auto;
  order: 2;
  height: 1px;
  background: var(--line);
  transform: translateY(-4px);
}

.overline > :first-child { order: 1; flex: none; }
.overline > :last-child { order: 3; flex: none; }

h2 { font-size: clamp(26px, 5.2vw, 40px); }
h3 { font-size: var(--fs-lg); }

.lede {
  max-width: 62ch;
  font-size: clamp(17px, 2.2vw, 21px);
  color: var(--ink-soft);
}

.prose { max-width: 68ch; }
.prose > * + * { margin-top: var(--s-4); }
.prose h2 { margin-top: var(--s-6); }
.prose h3 { margin-top: var(--s-5); }
.prose ul, .prose ol { padding-left: var(--s-5); }
.prose li + li { margin-top: var(--s-2); }
.prose p, .prose li { color: var(--ink-soft); }
.prose strong { color: var(--ink); font-weight: var(--fw-bold); }
.prose a { font-weight: var(--fw-bold); }

.muted { color: var(--ink-mute); font-size: var(--fs-sm); }

.hero { padding-block: clamp(32px, 7vw, 72px) clamp(40px, 8vw, 80px); }

.kicker {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

h1 {
  margin-block: var(--s-3) var(--s-4);
  font-size: clamp(38px, 9.4vw, 76px);
}

h1 .ember {
  background: linear-gradient(var(--gold-hi), var(--gold-lo));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero .lede { margin-bottom: var(--s-5); }

.tlink {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  color: var(--ink-soft);
  font-weight: var(--fw-bold);
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
}

.tlink:hover { color: var(--ink); border-bottom-color: var(--gold); }

/* ------------------------------------------------------------------ cards */

.cards {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: 1fr;
  list-style: none;
  padding: 0;
}

.card {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: linear-gradient(var(--surface), var(--surface-2));
  box-shadow: var(--shadow-card);
  padding: var(--s-5);
}

.card .num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-bottom: var(--s-3);
  border-radius: var(--r-chip);
  border: 1px solid var(--gold-bevel);
  background: var(--gold-tint);
  color: var(--gold);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: var(--fw-black);
}

.card h3 { margin-bottom: var(--s-2); }
.card p { color: var(--ink-soft); }
.card p + p { margin-top: var(--s-3); }

/* The three pillars are asymmetric on purpose: no uniform 3-up icon grid (12.1). */
@media (min-width: 760px) {
  .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .cards > :first-child { grid-column: span 3; }
}

@media (min-width: 1000px) {
  .cards > :first-child { grid-column: span 1; }
  .cards { grid-template-columns: 1.25fr 1fr 1fr; }
}

/* ------------------------------------------------------------------ spec strip */

.spec {
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--line);
  overflow: hidden;
  list-style: none;
  padding: 0;
}

.spec > li {
  background: var(--surface);
  padding: var(--s-4);
}

.spec dt {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.spec dd {
  margin: var(--s-1) 0 0;
  font-size: clamp(24px, 5vw, 34px);
  font-weight: var(--fw-black);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tr-tight);
  color: var(--ink);
}

.spec .foot {
  margin-top: var(--s-1);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

@media (min-width: 720px) { .spec { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ------------------------------------------------------------------ ruled list */

.ruled { list-style: none; padding: 0; }

.ruled > li {
  display: grid;
  gap: var(--s-1) var(--s-4);
  grid-template-columns: 1fr;
  padding-block: var(--s-4);
  border-top: 1px solid var(--line);
}

.ruled > li:last-child { border-bottom: 1px solid var(--line); }

.ruled .k {
  font-weight: var(--fw-black);
  letter-spacing: var(--tr-tight);
  color: var(--ink);
}

.ruled .v { color: var(--ink-soft); }

@media (min-width: 720px) {
  .ruled > li { grid-template-columns: minmax(180px, 26%) 1fr; }
}

/* ------------------------------------------------------------------ promise */

.promise {
  border: 1px solid var(--gold-bevel);
  border-radius: var(--r-card);
  background: linear-gradient(var(--surface-2), var(--surface));
  box-shadow: var(--shadow-card);
  padding: clamp(20px, 4vw, 36px);
}

.promise h2 { max-width: 26ch; }
.promise .lede { margin-top: var(--s-3); }

.claims { list-style: none; padding: 0; margin-top: var(--s-5); display: grid; gap: var(--s-4); }

.claims > li {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: var(--s-3);
  align-items: start;
}

.claims .tick {
  width: 26px;
  height: 26px;
  border-radius: var(--r-chip);
  background: var(--success-tint);
  border: 1px solid var(--success);
  position: relative;
  flex: none;
}

.claims .tick::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 6px;
  width: 9px;
  height: 5px;
  border-left: 2px solid var(--success);
  border-bottom: 2px solid var(--success);
  transform: rotate(-45deg);
}

.claims b { display: block; color: var(--ink); font-weight: var(--fw-black); }
.claims span { color: var(--ink-soft); }

@media (min-width: 760px) { .claims { grid-template-columns: 1fr 1fr; gap: var(--s-4) var(--s-5); } }

/* ------------------------------------------------------------------ FAQ */

.faq { list-style: none; padding: 0; }

.faq > li {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--surface);
  padding: var(--s-5);
}

.faq > li + li { margin-top: var(--s-4); }
.faq h3 { margin-bottom: var(--s-3); }
.faq p { color: var(--ink-soft); }
.faq p + p { margin-top: var(--s-3); }
.faq ul { margin-top: var(--s-3); padding-left: var(--s-5); color: var(--ink-soft); }
.faq li + li { margin-top: var(--s-2); }

/* ------------------------------------------------------------------ notice */

.notice {
  border: 1px solid var(--warn);
  border-left-width: 4px;
  border-radius: var(--r-control);
  background: var(--gold-tint);
  padding: var(--s-4);
  color: var(--ink);
}

.notice p + p { margin-top: var(--s-3); }
.notice strong { color: var(--ink); }

/* ------------------------------------------------------------------ colophon */

.colophon {
  border-top: 1px solid var(--line);
  padding-block: var(--s-6) calc(var(--s-6) + var(--safe-bottom));
  background: var(--scrim);
}

.colophon .cols {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: 1fr;
}

.colophon h2 {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: var(--s-3);
}

.colophon ul { list-style: none; padding: 0; }

.colophon li a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  color: var(--ink-soft);
  font-weight: var(--fw-bold);
  text-decoration: none;
}

.colophon li a:hover { color: var(--ink); text-decoration: underline; }
.colophon .fine { margin-top: var(--s-5); color: var(--ink-mute); font-size: var(--fs-sm); max-width: 70ch; }
.colophon .fine p + p { margin-top: var(--s-2); }

@media (min-width: 720px) {
  .colophon .cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ------------------------------------------------------------------ tables */

.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-card); }

table { border-collapse: collapse; width: 100%; font-size: var(--fs-sm); }

th, td {
  text-align: left;
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
  white-space: nowrap;
}

th {
  color: var(--ink-mute);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: var(--surface-2);
}

td:first-child { color: var(--ink); font-weight: var(--fw-bold); white-space: normal; }
tbody tr:last-child td { border-bottom: 0; }

/* Table captions sit under the table, left aligned, and read as a note rather than a title. */
caption { caption-side: bottom; text-align: left; padding: var(--s-3) var(--s-4) var(--s-4); }

/* A table whose cells hold sentences rather than data. The default `nowrap` above is right for a
   compact data table and hostile here: a 40-word cell forces a 2,000px column that a reader has to
   drag through. So every cell wraps and the table keeps a floor width instead, which means the
   .tablewrap scroll is a nudge rather than a journey. */
table.t-prose { min-width: 32rem; }
table.t-prose th, table.t-prose td { white-space: normal; }
table.t-prose td:first-child { min-width: 8rem; }

/* ------------------------------------------------------------------ misc */

/* Inline code, used only where a source file has to be named. */
code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  padding: 1px var(--s-1);
  border-radius: var(--s-1);
  background: var(--glass);
  color: var(--ink);
}

/* An email address written out in running text. It is a real mailto everywhere it appears. */
.mail {
  font-family: var(--font-mono);
  font-weight: var(--fw-bold);
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* Spacing utilities. Small, named, and used instead of inline style attributes so every value
   stays on the token scale and the pages hold no CSS of their own. */
.mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }

/* The overline is a left/right mono pair with a rule between them, and below about 640px the two
   labels plus the rule do not fit on one line. They are flex: none so that the rule takes the slack,
   which means at narrow widths the right-hand label pushes past the viewport. So below 640px the pair
   stacks and the rule goes away. Caught by measuring the page at 375px, not by eye. */
@media (max-width: 639px) {
  .overline {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s-1);
  }
  .overline::before { display: none; }
  .overline > :first-child { order: 1; }
  .overline > :last-child { order: 2; }
}

/* Contract 0.8 sets a 44x44 floor on interactive elements. Every affordance on this site meets it:
   the store buttons are 60px, and nav, colophon, footer and .tlink links carry min-height: var(--tap).
   The one class of exception is a link inside a sentence of running text on the long-form pages,
   which is the case WCAG 2.5.8 (Target Size Minimum, AA) explicitly exempts ("the target is in a
   sentence or block of text"), and padding one to 44px tall would wreck the line rhythm around it. */

/* A .tlink placed at the end of a .ruled value gets its own line and its own 44px target. */
.ruled .v .tlink { margin-top: var(--s-2); margin-right: var(--s-4); }

/* 12.1 rule 9: reduced motion keeps every gradient, shadow and color. Only movement stops. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}


/* ------------------------------------------------------------------ the clip and the cast
   The page shows the game rather than describing it, so these two blocks carry the weight.

   .clip is an animated WebP of real play, captured by scripts/footage.mjs from the shipped build.
   It is a plain <img>, which means no player chrome, no autoplay policy to satisfy, and nothing to
   fall back to when JavaScript is off. It is sized in CSS so the page never reflows around it.

   prefers-reduced-motion cannot pause an animated WebP, so under that setting the clip is replaced
   by a still: the page keeps its picture and stops moving, which is the point of the setting. */
.clip {
  margin: clamp(22px, 5vw, 34px) 0 clamp(24px, 5vw, 36px);
  width: min(240px, 62vw);
}
.clip img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 20px;
  border: 1px solid var(--line);
  box-shadow: 0 22px 60px rgb(0 0 0 / 0.55), 0 0 0 1px rgb(255 255 255 / 0.03) inset;
}

.cast h2 { margin: 0 0 clamp(14px, 3vw, 20px); }
.cast img {
  display: block;
  width: 100%;
  max-width: 640px;
  height: auto;
  border-radius: 16px;
}
.cast p {
  margin: clamp(12px, 3vw, 18px) 0 0;
  color: var(--ink-soft);
  max-width: 42ch;
}

@media (prefers-reduced-motion: reduce) {
  .clip img { content: url("/www/clip-still.webp"); }
}


/* The availability line belongs to the two store buttons above it, so it is centred on them
   rather than left aligned to the column like the rest of the page. */
.under {
  text-align: center;
  max-width: 720px;
}

/* ------------------------------------------------------------------ the guide trainers
   Two playable widgets in the game guide. Both are progressive enhancement: the markup ships a
   static explanation, and guide.js adds `is-live` to the container only once it is actually
   building the interactive version, which is what hides the fallback. With scripts off the
   fallback is what you read, and nothing is missing. */
.g-progress { border: 1px solid var(--line); border-radius: 16px; padding: var(--s-4); }
.g-label { margin: 0 0 var(--s-3); color: var(--ink-soft); display: flex; align-items: center; gap: 8px; }
.g-label b { color: var(--ink); }
.g-pip {
  width: 12px; height: 12px; flex: none; border-radius: 50%;
  border: 2px solid var(--line); background: transparent;
}
.g-pip.is-on { background: var(--gold); border-color: var(--gold); }
.g-track { height: 6px; border-radius: 3px; background: rgb(255 255 255 / 0.08); overflow: hidden; }
.g-fill { display: block; height: 100%; width: 0; background: var(--gold); transition: width 240ms ease; }
.g-done { margin: var(--s-3) 0 0; color: var(--gold); font-weight: var(--fw-black); }

.trainer {
  margin-top: var(--s-5);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: var(--s-4);
  background: rgb(255 255 255 / 0.02);
}
.trainer h3 { margin: 0 0 var(--s-3); }
.trainer-off { margin: 0; color: var(--ink-soft); }
.trainer.is-live .trainer-off { display: none; }

.g-canvas {
  display: block; width: 100%; max-width: 380px;
  border-radius: 12px; touch-action: none; cursor: ew-resize;
  background: rgb(0 0 0 / 0.25);
}
.g-canvas:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

.trainer-read {
  margin: var(--s-3) 0 0; display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-4);
  align-items: center; color: var(--ink-soft);
}
.trainer-read b { color: var(--ink); }
.trainer-note { flex-basis: 100%; color: var(--ink-soft); }
.trainer-note.is-win { color: var(--gold); font-weight: var(--fw-black); }
.trainer-again {
  min-height: var(--tap); padding: 0 var(--s-4); border-radius: 12px;
  border: 1px solid var(--line); background: transparent; color: var(--ink); cursor: pointer;
  font: inherit;
}
.trainer-again:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.g-board { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.g-cell {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 84px; min-height: var(--tap); padding: var(--s-3) var(--s-2);
  border: 1px solid var(--line); border-radius: 12px; background: transparent;
  color: var(--ink-soft); font: inherit; font-size: var(--fs-xs); cursor: pointer;
}
.g-cell img { width: 56px; height: 56px; object-fit: contain; }
.g-cell.is-picked { border-color: var(--gold); background: var(--gold-tint); color: var(--ink); }
.g-cell:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .g-fill { transition: none; }
}
