/* GENERATED by tools/build-pages.py: css/bundle-about.css = tokens.css + base.css + components.css + about.css + game-palette.css.
   Do not edit; edit the source files and re-run the builder. */

/* ---- css/tokens.css ---- */
/* Ploposaurus.com design tokens (design system v2, 2026-10-12).
 *
 * The ONLY stylesheet allowed to hold colour literals (tools/check-page.py
 * enforces it). Three layers, and only the second one is for components:
 *
 *   1. primitives: the board's hex values, transcribed from
 *      docs/brand/brand.json (theme.semantic.dark, charts, productPalette).
 *      game-palette.css (generated) also reads --plum-deep and --white.
 *   2. semantic: the board's 19 shadcn names plus four site roles (score,
 *      success, on-bright ink, strong foreground), alpha tokens derived from
 *      them with color-mix(), gradients, type, space, radii, motion, z-index.
 *   3. component aliases live next to their component, never here.
 *
 * Naming hazard (docs/brand/BRAND.md): the primitive --muted is INK
 * (#B5A8D6, the board's mutedForeground). Components never use it directly;
 * they use --muted-foreground. The board's muted SURFACE is --muted-surface.
 */

:root {
  color-scheme: dark;

  /* ------------------------------------------------------------ primitives */
  --plum-deep: #1a0b2e; /* semantic.dark.background, productPalette.launchBackground */
  --plum-mid: #2d1457; /* semantic.dark.card */
  --plum-soft: #241149; /* semantic.dark.popover */
  --plum-muted: #3b2a5e; /* semantic.dark.muted (surface) */
  --plum-border: #473273; /* semantic.dark.border */
  --plum-input: #553c8a; /* semantic.dark.input */
  --ink: #0a0a1a; /* productPalette.background */
  --teal: #2dd4bf; /* theme.accent, semantic.dark.primary */
  --pink: #f093fb; /* semantic.dark.accent */
  --violet: #a78bfa; /* semantic.dark.secondary */
  --coral: #f5576c; /* semantic.dark.destructive */
  --gold: #fbbf24; /* charts.categorical[2], score only */
  --mint: #4ade80; /* charts.categorical[5], success only */
  --sky: #38bdf8; /* charts.categorical[6], decorative only (BRAND.md item 4) */
  --white: #ffffff; /* productPalette.foreground */
  --cream: #fde68a; /* semantic.dark.foreground */
  --muted: #b5a8d6; /* semantic.dark.mutedForeground (INK, see hazard above) */

  /* -------------------------------------------- semantic: the board's names */
  --background: var(--plum-deep);
  --foreground: var(--cream);
  --card: var(--plum-mid);
  --card-foreground: var(--cream);
  --popover: var(--plum-soft);
  --popover-foreground: var(--cream);
  --primary: var(--teal);
  --primary-foreground: var(--plum-deep);
  --secondary: var(--violet);
  --secondary-foreground: var(--plum-deep);
  --muted-surface: var(--plum-muted);
  --muted-foreground: var(--muted);
  --accent: var(--pink);
  --accent-foreground: var(--plum-deep);
  --destructive: var(--coral);
  --destructive-foreground: var(--white);
  --border: var(--plum-border);
  --input: var(--plum-input);
  --ring: var(--teal);

  /* -------------------------------------------------- semantic: site roles */
  --foreground-strong: var(--white); /* headings and UI ink on plum */
  --on-bright: var(--ink); /* ink on gold, coral, block and mint fills */
  --deep: var(--ink); /* bezels, footer ground */
  --score: var(--gold); /* reward signal only */
  --success: var(--mint); /* positive states only */

  /* -------------------------------------------------------- alpha tokens
     One quantized ladder (03 05 08 12 16 22 28 35 45 55 65 82 94), each
     derived from a primitive above so no rgba() literal exists anywhere. */
  --sheen-a03: color-mix(in srgb, var(--white) 3%, transparent);
  --sheen-a05: color-mix(in srgb, var(--white) 5%, transparent);
  --sheen-a08: color-mix(in srgb, var(--white) 8%, transparent);
  --sheen-a12: color-mix(in srgb, var(--white) 12%, transparent);
  --sheen-a22: color-mix(in srgb, var(--white) 22%, transparent);
  --sheen-a28: color-mix(in srgb, var(--white) 28%, transparent);
  --sheen-a35: color-mix(in srgb, var(--white) 35%, transparent);
  --sheen-a65: color-mix(in srgb, var(--white) 65%, transparent);
  --shade-a28: color-mix(in srgb, var(--ink) 28%, transparent);
  --shade-a35: color-mix(in srgb, var(--ink) 35%, transparent);
  --shade-a45: color-mix(in srgb, var(--ink) 45%, transparent);
  --shade-a55: color-mix(in srgb, var(--ink) 55%, transparent);
  --shade-a65: color-mix(in srgb, var(--ink) 65%, transparent);
  --shade-a94: color-mix(in srgb, var(--ink) 94%, transparent);
  --primary-a08: color-mix(in srgb, var(--teal) 8%, transparent);
  --primary-a12: color-mix(in srgb, var(--teal) 12%, transparent);
  --primary-a16: color-mix(in srgb, var(--teal) 16%, transparent);
  --primary-a22: color-mix(in srgb, var(--teal) 22%, transparent);
  --primary-a28: color-mix(in srgb, var(--teal) 28%, transparent);
  --primary-a35: color-mix(in srgb, var(--teal) 35%, transparent);
  --primary-a55: color-mix(in srgb, var(--teal) 55%, transparent);
  --accent-a05: color-mix(in srgb, var(--pink) 5%, transparent);
  --accent-a08: color-mix(in srgb, var(--pink) 8%, transparent);
  --accent-a16: color-mix(in srgb, var(--pink) 16%, transparent);
  --accent-a22: color-mix(in srgb, var(--pink) 22%, transparent);
  --accent-a28: color-mix(in srgb, var(--pink) 28%, transparent);
  --accent-a35: color-mix(in srgb, var(--pink) 35%, transparent);
  --accent-a55: color-mix(in srgb, var(--pink) 55%, transparent);
  --secondary-a16: color-mix(in srgb, var(--violet) 16%, transparent);
  --secondary-a22: color-mix(in srgb, var(--violet) 22%, transparent);
  --secondary-a28: color-mix(in srgb, var(--violet) 28%, transparent);
  --secondary-a35: color-mix(in srgb, var(--violet) 35%, transparent);
  --secondary-a45: color-mix(in srgb, var(--violet) 45%, transparent);
  --background-a45: color-mix(in srgb, var(--plum-deep) 45%, transparent);
  --background-a55: color-mix(in srgb, var(--plum-deep) 55%, transparent);
  --background-a65: color-mix(in srgb, var(--plum-deep) 65%, transparent);
  --background-a82: color-mix(in srgb, var(--plum-deep) 82%, transparent);
  --background-a94: color-mix(in srgb, var(--plum-deep) 94%, transparent);
  --card-a65: color-mix(in srgb, var(--plum-mid) 65%, transparent);
  --card-a94: color-mix(in srgb, var(--plum-mid) 94%, transparent);
  --popover-a65: color-mix(in srgb, var(--plum-soft) 65%, transparent);
  --popover-a82: color-mix(in srgb, var(--plum-soft) 82%, transparent);
  --popover-a94: color-mix(in srgb, var(--plum-soft) 94%, transparent);
  --score-a22: color-mix(in srgb, var(--gold) 22%, transparent);
  --score-a35: color-mix(in srgb, var(--gold) 35%, transparent);
  --score-a55: color-mix(in srgb, var(--gold) 55%, transparent);
  --success-a05: color-mix(in srgb, var(--mint) 5%, transparent);
  --success-a35: color-mix(in srgb, var(--mint) 35%, transparent);
  --foreground-a05: color-mix(in srgb, var(--cream) 5%, transparent);
  --foreground-a22: color-mix(in srgb, var(--cream) 22%, transparent);

  /* ------------------------------------------------------------ gradients
     Every stop is a board token (usage.do: block gradient pink to violet,
     mint to teal on gameplay blocks, partner stops must be board tokens). */
  --block-grad: linear-gradient(135deg, var(--pink), var(--violet));
  --grad-mint-teal: linear-gradient(135deg, var(--mint), var(--teal));
  --grad-sky-violet: linear-gradient(135deg, var(--sky), var(--violet));
  --grad-violet-sky: linear-gradient(135deg, var(--violet), var(--sky));
  --grad-teal-sky: linear-gradient(135deg, var(--teal), var(--sky));
  --grad-gold-coral: linear-gradient(135deg, var(--gold), var(--coral));
  --grad-coral-pink: linear-gradient(135deg, var(--coral), var(--pink));
  --grad-ribbon: linear-gradient(90deg, var(--coral), var(--pink), var(--violet), var(--coral));
  --grad-display: linear-gradient(92deg, var(--teal) 8%, var(--pink) 78%);
  --grad-page: linear-gradient(180deg, var(--plum-deep) 0%, var(--ink) 100%);
  --grad-ink-to-plum: linear-gradient(180deg, var(--ink) 0%, var(--plum-deep) 100%);
  --grad-plum-to-card: linear-gradient(180deg, var(--plum-deep) 0%, var(--plum-mid) 100%);
  --grad-card-face: linear-gradient(170deg, var(--plum-mid), var(--plum-soft));
  --grad-glass: linear-gradient(150deg, var(--sheen-a08), var(--sheen-a03));
  --grad-panel: linear-gradient(160deg, var(--popover-a82), var(--background-a45));
  --grad-cta: linear-gradient(135deg, var(--plum-soft), var(--ink));

  /* hero corner rings: data-URI SVG strokes in --pink and --violet at 14%
     (a data URI cannot read a custom property, so the hex is spelled out
     here, URL-encoded, and nowhere else) */
  --deco-ring-accent: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'%3E%3Cg transform='rotate(22 240 240)'%3E%3Crect x='0.5' y='0.5' width='479' height='479' rx='230' fill='none' stroke='%23f093fb' stroke-opacity='0.14'/%3E%3C/g%3E%3C/svg%3E");
  --deco-ring-secondary: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='448' height='448' viewBox='0 0 448 448'%3E%3Cg transform='rotate(-36 224 224)'%3E%3Crect x='0.5' y='0.5' width='447' height='447' rx='215' fill='none' stroke='%23a78bfa' stroke-opacity='0.14'/%3E%3C/g%3E%3C/svg%3E");

  /* ------------------------------------------------------------- elevation */
  --shadow-card: 0 18px 44px var(--shade-a35);
  --shadow-float: 0 25px 45px var(--shade-a45);
  --shadow-bar: 0 18px 44px var(--shade-a65);
  --shadow-block: inset 0 2px 0 var(--sheen-a35), 0 18px 24px var(--shade-a28);
  --drop-art: drop-shadow(0 18px 22px var(--shade-a55));

  /* ------------------------------------------------------------ typography
     One fluid scale, 320px to 1280px viewport: 1.25 ratio at the small end,
     about 1.41 at the large end. --step--1 never drops below 14px (M11). */
  --font-display: Rajdhani, 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-body: 'Segoe UI', system-ui, -apple-system, sans-serif;
  --step--1: clamp(0.875rem, 0.8542rem + 0.1042vw, 0.9375rem);
  --step-0: clamp(1rem, 0.9583rem + 0.2083vw, 1.125rem);
  --step-1: clamp(1.25rem, 1.1458rem + 0.5208vw, 1.5625rem);
  --step-2: clamp(1.5625rem, 1.3333rem + 1.1458vw, 2.25rem);
  --step-3: clamp(1.9375rem, 1.5208rem + 2.0833vw, 3.1875rem);
  --step-4: clamp(2.4375rem, 1.75rem + 3.4375vw, 4.5rem);
  --step-5: clamp(3.0625rem, 1.9583rem + 5.5208vw, 6.375rem);
  --leading-tight: 0.95;
  --leading-snug: 1.25;
  --leading-body: 1.65;
  --measure: 40rem;

  /* -------------------------------------------------- space (4px based) */
  --space-1: 0.25rem; /* 4 */
  --space-2: 0.5rem; /* 8 */
  --space-3: 0.75rem; /* 12 */
  --space-4: 1rem; /* 16 */
  --space-5: 1.5rem; /* 24 */
  --space-6: 2rem; /* 32 */
  --space-7: 3rem; /* 48 */
  --space-8: 4rem; /* 64 */
  --section-y: clamp(2.5rem, 1.75rem + 3vw, 4.5rem); /* 40px at 320 up to 72px at 1500 */
  --gutter: clamp(1rem, 0.6rem + 2vw, 1.5rem);
  --shell-max: 70rem; /* 1120px */
  --target: 2.75rem; /* 44px minimum hit area */

  /* ----------------------------------------------------------------- radii */
  --radius-sm: 0.625rem; /* theme.radius: tiles, small controls */
  --radius-md: 1rem; /* cards, buttons, panels */
  --radius-lg: 1.5rem; /* feature surfaces, frames */
  --radius-pill: 999px;

  /* --------------------------------------------------------------- z-index */
  --z-raised: 1;
  --z-art: 2;
  --z-float: 3;
  --z-top: 4;
  --z-header: 30;
  --z-sticky: 35;
  --z-menu: 40;
  --z-skip: 50;

  /* ---------------------------------------------------------------- motion
     theme.motion on the board. The single reduced-motion rule lives in
     base.css; component states are authored so the un-animated frame is the
     correct static frame. */
  --motion-fast: 140ms;
  --motion-base: 220ms;
  --motion-slow: 420ms;
  --motion-loop: 4.5s;
  --ease-pop: cubic-bezier(0.22, 1.2, 0.36, 1);
  --ease-out: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* ------------------------------------------------------------ safe areas
     The viewport meta carries viewport-fit=cover, so fixed and edge-to-edge
     UI must keep clear of notches and the home indicator. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}

/* ---- css/base.css ---- */
/* Ploposaurus.com base layer: fonts, reset, element typography, layout
 * primitives, and the site's ONE reduced-motion rule. Loads after tokens.css
 * on every page. Mobile-first: the only width queries anywhere on the site
 * are min-width 640px, 1024px and 1280px (tools/check-page.py enforces it).
 *
 * Rajdhani ships 500 and 700 only. A render probe on 2026-10-12 found no
 * text set at 600 on any page, so that face is no longer declared or
 * shipped; normal-weight display text uses the 500 face explicitly.
 */

@font-face {
  font-family: Rajdhani;
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../assets/fonts/rajdhani-500.woff2') format('woff2');
}
@font-face {
  font-family: Rajdhani;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/rajdhani-700.woff2') format('woff2');
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* anchors land below the sticky header */
  scroll-padding-top: calc(4.5rem + var(--safe-top));
}
body {
  margin: 0;
  overflow-x: hidden;
  color: var(--foreground-strong);
  background:
    radial-gradient(circle at 85% -10%, var(--primary-a08), transparent 34rem),
    radial-gradient(circle at 8% 30%, var(--accent-a05), transparent 30rem),
    var(--grad-page);
  background-color: var(--background);
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 500;
  line-height: 1.5;
  /* short pages (404, legal) keep the footer on the bottom edge */
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}
body > main {
  flex: 1 0 auto;
}
a {
  color: inherit;
}
img,
svg,
video {
  display: block;
  max-width: 100%;
}
img {
  /* width/height attributes reserve space; auto keeps the intrinsic ratio
     wherever CSS sets only one dimension */
  height: auto;
}
figure,
dl,
dd {
  margin: 0;
}
button {
  font: inherit;
}
[hidden] {
  display: none !important;
}

/* ------------------------------------------------------------ typography */

h1,
h2,
h3 {
  margin: 0;
  font-weight: 700;
  text-wrap: balance;
}
h1 {
  font-size: var(--step-4);
  line-height: 0.88;
  letter-spacing: -0.045em;
  text-transform: uppercase;
}
h2 {
  font-size: var(--step-3);
  line-height: var(--leading-tight);
  letter-spacing: -0.035em;
  text-transform: uppercase;
}
h3 {
  font-size: var(--step-1);
  line-height: var(--leading-snug);
  letter-spacing: 0.01em;
}
p {
  text-wrap: pretty;
}
/* a hyphenated compound that must never split at its hyphen (M8); headings
   already balance, so the compound moves to the next line whole */
.nobreak {
  white-space: nowrap;
}
.prose {
  font-family: var(--font-body);
  font-weight: 400;
}
/* eyebrow: a short sentence-case label with a teal dot, used sparingly
   (design brief, anti-generic list: no tracked-out ALL-CAPS eyebrows; the
   lowercase-led ones stay). No uppercase transform and no letter-spacing:
   tools/check-page.py fails either on any .eyebrow rule, fails tracked
   caps anywhere, and caps the count per page. The dot is structure in the
   primary teal (an icon-sized fill, not text), which the board allows. */
/* block with an inline dot (not inline-flex): when a long eyebrow wraps,
   most visibly centred ones, the dot stays with the first word instead of
   floating beside a two-line block */
.eyebrow {
  display: block;
  margin: 0;
  color: var(--foreground);
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  line-height: var(--leading-snug);
}
.eyebrow::before {
  content: '';
  display: inline-block;
  margin-right: var(--space-2);
  vertical-align: 0.05em;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--primary);
  box-shadow: 0 0 0.9rem var(--primary);
}

/* --------------------------------------------------------------- layout */

.shell {
  width: 100%;
  max-width: calc(var(--shell-max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: max(var(--gutter), var(--safe-left)) max(var(--gutter), var(--safe-right));
}
.section {
  padding-block: var(--section-y);
}
/* one rhythm: neighbouring sections share their boundary instead of
   stacking two full paddings (the 150px+ blank tops in register T5) */
.section + .section {
  padding-top: calc(var(--section-y) * 0.5);
}
.section--flush-top {
  padding-top: 0;
}
.sprite-sheet {
  display: none;
}

/* ------------------------------------------------------- focus and skip */

:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 4px;
}
.skip-link {
  position: absolute;
  top: -4rem;
  left: var(--space-4);
  z-index: var(--z-skip);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 700;
  text-decoration: none;
}
.skip-link:focus {
  top: calc(var(--space-4) + var(--safe-top));
}

/* --------------------------------------------------------- reduced motion
   The only prefers-reduced-motion rule on the site. Every animated
   component is authored so its un-animated state is the correct static
   frame (the merge demo rests on its merged frame, cards rest unflipped). */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- css/components.css ---- */
/* Ploposaurus.com shared components. Loads after tokens.css and base.css on
 * every page. Components reference semantic tokens only (never a primitive
 * like --teal, never a colour literal); tools/check-page.py enforces both.
 * Width queries: min-width 640px / 1024px / 1280px only. Cards that change
 * shape with their own room use @container on .shell instead.
 */

.shell {
  container-type: inline-size;
}

/* ================================================================ header
   One header partial on every page (tools/build-pages.py). Below 1024px a
   Menu button discloses the links; with scripting off the links render as
   a plain wrapped list instead, so nothing depends on js/nav.js. */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  padding-top: var(--safe-top);
  border-bottom: 1px solid var(--secondary-a16);
  background: var(--background-a94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.site-header__bar {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  min-height: 3.75rem;
}
.brand {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  margin-right: auto;
  text-decoration: none;
}
.brand img {
  width: auto;
  height: 1.75rem;
}

/* the in-row pill: 640-1023 only (below 640 the panel carries the CTA,
   from 1024 the nav list's own last item does) */
.site-header .nav-cta {
  display: none;
}

.menu-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: var(--target);
  min-height: var(--target);
  padding: 0 var(--space-4);
  border: 1px solid var(--secondary-a35);
  border-radius: var(--radius-pill);
  background: var(--sheen-a05);
  color: var(--foreground-strong);
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background var(--motion-fast) var(--ease-out);
}
.menu-button:hover,
.menu-button[aria-expanded='true'] {
  border-color: var(--primary);
  background: var(--primary-a12);
}
.menu-icon {
  position: relative;
  width: 1.125rem;
  height: 0.75rem;
}
.menu-icon::before,
.menu-icon::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition:
    transform var(--motion-base) var(--ease-out),
    top var(--motion-base) var(--ease-out);
}
.menu-icon::before {
  top: 0;
  box-shadow: 0 5px 0 currentColor;
}
.menu-icon::after {
  top: 10px;
}
.menu-button[aria-expanded='true'] .menu-icon::before {
  top: 5px;
  box-shadow: none;
  transform: rotate(45deg);
}
.menu-button[aria-expanded='true'] .menu-icon::after {
  top: 5px;
  transform: rotate(-45deg);
}

/* the disclosure panel (phones and tablets) */
.site-nav {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: var(--z-menu);
  max-height: calc(100svh - 4rem - var(--safe-top));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-2) max(var(--gutter), var(--safe-right)) var(--space-5)
    max(var(--gutter), var(--safe-left));
  border-bottom: 1px solid var(--border);
  background: var(--popover);
  box-shadow: var(--shadow-float);
}
.site-header.is-open .site-nav {
  display: block;
}
.site-nav__list {
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-nav__list > li {
  border-bottom: 1px solid var(--secondary-a16);
}
.site-nav__list > li.site-nav__cta {
  margin-top: var(--space-4);
  border-bottom: 0;
}
.nav-link {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 3.25rem;
  padding-left: var(--space-4);
  color: var(--foreground-strong);
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: color var(--motion-fast) var(--ease-out);
}
.nav-link:hover {
  color: var(--foreground);
}
/* current page: a teal marker (structure), never teal text on plum */
.nav-link[aria-current='page']::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 4px;
  height: 1.4em;
  border-radius: var(--radius-pill);
  background: var(--primary);
  translate: 0 -50%;
}
.site-nav__cta .btn-pill {
  justify-content: center;
  width: 100%;
  min-height: 3.25rem;
  font-size: var(--step-1);
}

/* scripting off: no button, the links show as a wrapped list */
@media (scripting: none) {
  .menu-button {
    display: none;
  }
  .site-nav {
    display: block;
    position: static;
    flex: 1 0 100%;
    max-height: none;
    padding: 0 0 var(--space-2);
    border: 0;
    background: none;
    box-shadow: none;
  }
  .site-nav__list {
    display: flex;
    flex-wrap: wrap;
    gap: 0 var(--space-4);
  }
  .site-nav__list > li {
    border: 0;
  }
  .nav-link {
    min-height: var(--target);
    padding-left: 0;
    font-size: var(--step-0);
  }
  .nav-link[aria-current='page']::before {
    display: none;
  }
  .site-nav__cta {
    display: none;
  }
}

@media (min-width: 640px) {
  .brand img {
    height: 1.875rem;
  }
  .site-header .nav-cta {
    display: inline-flex;
  }
  .site-nav__list > li.site-nav__cta {
    display: none;
  }
}

@media (min-width: 1024px) {
  .menu-button,
  .site-header .nav-cta {
    display: none;
  }
  .site-nav,
  .site-header.is-open .site-nav {
    display: block;
    position: static;
    max-height: none;
    overflow: visible;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
  }
  .site-nav__list {
    display: flex;
    align-items: center;
    gap: var(--space-5);
  }
  .site-nav__list > li {
    border: 0;
  }
  .site-nav__list > li.site-nav__cta {
    display: block;
    margin: 0 0 0 var(--space-2);
  }
  .nav-link {
    min-height: var(--target);
    padding: 0;
    color: var(--muted-foreground);
    font-size: var(--step-0);
    letter-spacing: 0.02em;
  }
  .nav-link:hover,
  .nav-link[aria-current='page'] {
    color: var(--foreground-strong);
  }
  .nav-link[aria-current='page']::before {
    top: auto;
    bottom: 0.35rem;
    left: 0;
    right: 0;
    width: auto;
    height: 3px;
    translate: none;
  }
  .site-nav__cta .btn-pill {
    width: auto;
    min-height: var(--target);
    font-size: var(--step-0);
  }
}

/* =============================================================== buttons */

.btn-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--target);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-pill);
  background: var(--primary);
  color: var(--primary-foreground);
  font-size: var(--step-0);
  font-weight: 700;
  white-space: nowrap;
  text-decoration: none;
  box-shadow: 0 6px 18px var(--primary-a28);
  transition:
    transform var(--motion-fast) var(--ease-out),
    filter var(--motion-fast) var(--ease-out);
}
.btn-pill:hover {
  transform: translateY(-2px);
  filter: brightness(1.08);
}
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-wrap: balance;
  min-height: var(--target);
  margin-top: var(--space-5);
  padding: var(--space-2) var(--space-5);
  border: 2px solid var(--primary);
  border-radius: var(--radius-pill);
  color: var(--foreground);
  font-weight: 700;
  text-decoration: none;
  transition:
    background var(--motion-fast) var(--ease-out),
    transform var(--motion-fast) var(--ease-out);
}
.btn-ghost:hover {
  background: var(--primary-a16);
  transform: translateY(-2px);
}
.more-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  margin-top: var(--space-5);
  color: var(--primary);
  font-weight: 700;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}
.more-link:hover {
  color: var(--foreground);
}
.back-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-6);
}

/* ========================================================== store badges
   Release batch 3. The official Apple and Google artwork, staged verbatim in
   assets/badges/ (docs/ASSET_PROVENANCE.md), rendered by the store-badges
   partial in tools/build-pages.py. Rules that bind every line below:
   - never recolour, crop, distort, rotate, animate or filter the badge, and
     never put anything over it (both guidelines); the hover and focus rings
     sit outside the artwork, in its clear space
   - equal visible height side by side, App Store first (Apple); Google's
     badge the same size or larger than the others (Google)
   - minimum visible height 40px on screen (Apple; Google's floor is 28px)
   - clear space a quarter of the badge height on every side (both; the
     sticky bar uses Apple's one-tenth rule for very limited layout space)
   - every badge link is at least 44px tall (WCAG 2.5.8, qa-visual TGT)
   --badge-h is the VISIBLE badge height: 40px at 320 (Apple's floor), 46px
   at 390, 52px from about 450px. The pair plus its gap is 6.35 badge
   heights wide plus 16px, which fits the shell at every phone width; a
   narrower box (a card) simply wraps it to two rows.
   Google ships its badge inside transparent padding of 41/168 of the badge
   height (Google's own quarter-height clear space), so its image is drawn
   250/168 of --badge-h tall and pulled back by that padding on every side;
   the link box is then exactly the visible badge. */

.store-links {
  --badge-h: clamp(2.5rem, 0.6rem + 9.4vw, 3.25rem);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin-top: var(--space-6);
}
.store-badge {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  min-height: var(--target);
  border-radius: var(--radius-sm);
}
.store-badge img {
  display: block;
  width: auto;
  max-width: none;
}
.store-badge__ios {
  height: var(--badge-h);
}
.store-badge__play {
  height: calc(var(--badge-h) * 250 / 168);
  margin: calc(var(--badge-h) * -41 / 168);
}
.store-badge:hover {
  outline: 2px solid var(--primary-a55);
  outline-offset: 4px;
}
.store-badge:focus-visible {
  outline: 3px solid var(--ring);
  outline-offset: 4px;
}
.tiny-note {
  margin: var(--space-4) 0 0;
  color: var(--sheen-a65);
  font-size: var(--step--1);
}
.platform-note {
  min-height: 1.25rem;
  margin: var(--space-2) 0 0;
  color: var(--foreground);
  font-size: var(--step--1);
}

/* ===================================================== section chrome */

.section-heading {
  max-width: 44rem;
  margin-bottom: var(--space-7);
}
.section-heading h2 {
  margin-top: var(--space-3);
}
/* a heading with no eyebrow above it starts flush (batch 3 pruned most) */
.section-heading > h2:first-child,
.page-head h1:first-child,
.download-cta h2:first-child {
  margin-top: 0;
}

/* Desktop spacing pass (release batch 3). From 1024px a section whose
   content is one narrow column puts its heading beside it instead of
   above it, so the right 40% of a 1440 screen is no longer empty for a
   whole screen at a time (about: story, factsheet, mascot; /dinos: quiz). */
@media (min-width: 1024px) {
  .section--split > .shell {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: var(--space-8);
    align-items: start;
  }
  .section--split .section-heading {
    margin-bottom: 0;
  }
  /* a heading with a short intro and a link: the heading takes the left
     half, the intro and link sit opposite it, bottom-aligned */
  .section-heading.is-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--space-8);
    align-items: end;
    max-width: none;
  }
  .section-heading.is-split > .eyebrow {
    grid-column: 1;
    grid-row: 1;
  }
  .section-heading.is-split > h2 {
    grid-column: 1;
    grid-row: 2 / span 2;
  }
  .section-heading.is-split > .section-intro {
    grid-column: 2;
    grid-row: 2;
    margin: 0;
  }
  .section-heading.is-split > .more-link {
    grid-column: 2;
    grid-row: 3;
    justify-self: start;
  }
}
.section-intro {
  max-width: var(--measure);
  margin: var(--space-4) 0 0;
  color: var(--muted-foreground);
  line-height: 1.7;
}
.page-head {
  padding-block: var(--space-7) var(--space-6);
  background:
    radial-gradient(circle at 82% -10%, var(--accent-a16), transparent 26rem),
    radial-gradient(circle at 12% 60%, var(--primary-a08), transparent 26rem),
    var(--background);
}
.page-head h1 {
  margin: var(--space-4) 0 var(--space-4);
}
.page-head .lede {
  max-width: var(--measure);
  margin: 0;
  color: var(--muted-foreground);
  font-size: var(--step-0);
  line-height: var(--leading-body);
}
@media (min-width: 1024px) {
  .page-head {
    padding-block: var(--space-8) var(--space-7);
  }
}

/* section treatments shared by index, about and how-to-play */
.howto {
  background: var(--grad-ink-to-plum);
}
.about {
  /* the glow sits inside the section and fades out before any edge, so the
     section boundary never shows as a hard seam */
  background:
    radial-gradient(ellipse 40rem 26rem at 82% 32%, var(--primary-a08), transparent 70%),
    var(--background);
}
.screens {
  background: var(--grad-plum-to-card);
}

/* ============================================ steps (index, how-to-play) */

.step-grid {
  display: grid;
  gap: var(--space-4);
}
.step-card {
  padding: var(--space-5);
  border: 1px solid var(--accent-a22);
  border-radius: var(--radius-lg);
  background: var(--grad-glass);
  box-shadow: var(--shadow-card);
}
.step-num {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-foreground);
  font-size: var(--step-1);
  font-weight: 700;
  box-shadow: 0 8px 20px var(--accent-a28);
}
.step-art {
  margin: 0 0 var(--space-4);
}
.step-art svg {
  width: 100%;
  max-width: 15rem;
  height: auto;
  margin-inline: auto;
  /* the burst lines sit a few units past the viewBox edge */
  overflow: visible;
}
.step-card h3 {
  margin: 0 0 var(--space-2);
}
.step-card p {
  margin: 0;
  color: var(--muted-foreground);
  line-height: 1.6;
}
/* Sized by the shell, not the viewport: one column on phones; on tablets a
   single column of wide cards that sit their art beside their words; three
   upright cards once the shell is wide enough for them. */
@container (min-width: 36rem) and (max-width: 59.99rem) {
  .step-card {
    display: grid;
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: var(--space-6);
    align-items: start;
  }
  .step-card .step-num {
    grid-column: 2;
    grid-row: 1;
  }
  .step-card .step-art {
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: center;
    margin: 0;
  }
  .step-card h3,
  .step-card p:not(.step-art) {
    grid-column: 2;
  }
}
@container (min-width: 60rem) {
  .step-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* step-art SVG paint */
.sa-stop-pink {
  stop-color: var(--accent);
}
.sa-stop-violet {
  stop-color: var(--secondary);
}
.sa-col {
  fill: var(--sheen-a05);
  stroke: var(--sheen-a22);
}
.sa-col--hot {
  fill: var(--accent-a08);
  stroke: var(--accent);
}
.sa-ink {
  fill: var(--on-bright);
}
.sa-stroke {
  stroke: var(--accent);
}
.sa-fill {
  fill: var(--accent);
}

/* the merge ladder */
.ladder {
  margin-top: var(--space-7);
}
.ladder-row {
  display: flex;
  /* centred when the run fits; "safe" falls back to start-aligned when it
     scrolls, so the 2 never hides off the left edge */
  justify-content: safe center;
  gap: var(--space-2);
  padding: var(--space-2);
  overflow-x: auto;
  border-radius: var(--radius-md);
  background: var(--sheen-a05);
  scrollbar-width: thin;
}
.ladder-tile {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  min-width: 3.6rem;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--card);
  color: var(--foreground-strong);
  font-size: var(--step-0);
  font-weight: 700;
  box-shadow: inset 0 1px 0 var(--sheen-a22);
}
.ladder-tile.final {
  /* solid colour = the lower-contrast stop, so contrast tooling measures the
     real worst case under the gradient (ink on coral) */
  background: var(--grad-gold-coral) var(--destructive);
  color: var(--on-bright);
  box-shadow: 0 10px 26px var(--score-a35);
}
.ladder-note {
  margin: var(--space-3) 0 0;
  color: var(--muted-foreground);
  font-size: var(--step--1);
}

/* ================================== the gameplay clip (index, how-to) */

/* copy, then the clip, then its notes (caption, facts, chips). From
   1024px: copy top-left, notes bottom-left, the clip on the right, so the
   column beside a tall 9:16 video is composed instead of half empty. */
.clip-split {
  display: grid;
  gap: var(--space-5);
}
.clip-split .section-heading {
  margin-bottom: 0;
}
.clip-block {
  width: min(100%, 22rem);
  margin: 0 auto;
}
.clip-notes {
  text-align: center;
}
@media (min-width: 1024px) {
  .clip-split {
    grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
    grid-template-rows: auto 1fr;
    grid-template-areas:
      'copy clip'
      'notes clip';
    column-gap: var(--space-8);
    row-gap: var(--space-5);
  }
  .clip-copy {
    grid-area: copy;
  }
  .clip-split .clip-block {
    grid-area: clip;
    width: 100%;
  }
  .clip-notes {
    grid-area: notes;
    align-self: end;
    text-align: left;
  }
  .clip-notes .clip-chips {
    justify-content: flex-start;
  }
  /* short copy (how-to-play): copy and chips form one block, centred
     against the clip, instead of pinning to its top and bottom edges */
  .clip-split--centered {
    grid-template-rows: 1fr auto auto 1fr;
    grid-template-areas:
      '. clip'
      'copy clip'
      'notes clip'
      '. clip';
  }
  .clip-split--centered .clip-notes {
    align-self: start;
  }
  .clip-notes .clip-caption {
    margin-top: 0;
    font-size: var(--step-3);
    line-height: var(--leading-tight);
  }
}
.clip-block video {
  width: 100%;
  aspect-ratio: 9 / 16;
  border: 4px solid var(--deep);
  border-radius: var(--radius-lg);
  background: var(--deep);
  box-shadow: var(--shadow-float);
}
.clip-caption {
  margin: var(--space-4) 0 0;
  font-size: var(--step-1);
  font-weight: 700;
  letter-spacing: 0.01em;
}
.clip-facts {
  margin: var(--space-2) 0 0;
  color: var(--muted-foreground);
  font-size: var(--step--1);
  line-height: 1.5;
}
.clip-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.clip-chip {
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--secondary-a45);
  border-radius: var(--radius-pill);
  color: var(--foreground);
  font-size: var(--step--1);
  font-weight: 700;
}
.clip-chip.is-score {
  border-color: var(--score-a55);
  color: var(--score);
}

/* respect block (store description, kept near purchase talk) */
.respect {
  max-width: 42rem;
  margin: var(--space-6) auto 0;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--accent-a28);
  border-radius: var(--radius-md);
  background: var(--accent-a05);
}
.respect p {
  margin: 0;
  color: var(--muted-foreground);
  line-height: 1.6;
}

/* ============================================================ download CTA */

.download-cta {
  padding-block: var(--section-y);
  text-align: center;
  background:
    radial-gradient(circle at 50% 0, var(--primary-a22), transparent 30rem),
    var(--grad-cta);
  background-color: var(--popover);
}
.download-cta h2 {
  max-width: 48rem;
  margin: var(--space-3) auto 0;
}
.download-cta .section-intro {
  max-width: 35rem;
  margin: var(--space-4) auto 0;
}
.download-cta .store-links {
  justify-content: center;
}
.download-cta .back-row {
  justify-content: center;
}
.honest-note {
  max-width: 39rem;
  margin: var(--space-5) auto 0;
  color: var(--sheen-a65);
  font-size: var(--step--1);
  line-height: 1.55;
}

/* ================================================================ footer */

.site-footer {
  padding-block: var(--space-6) calc(var(--space-6) + var(--safe-bottom));
  background: var(--deep);
  color: var(--sheen-a65);
  font-size: var(--step--1);
}
.site-footer__grid {
  display: grid;
  gap: var(--space-4);
}
.footer-brand {
  display: grid;
  gap: var(--space-2);
}
.footer-brand img {
  width: auto;
  height: 1.5rem;
}
.footer-brand span {
  color: var(--foreground);
  font-size: var(--step-0);
  font-weight: 700;
}
.footer-links ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}
.footer-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--target);
  min-height: var(--target);
  font-size: var(--step-0);
  font-weight: 700;
}
.footer-links a[aria-current='page'] {
  color: var(--foreground-strong);
  text-decoration: underline;
  text-decoration-color: var(--primary);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.35em;
}
.site-footer a {
  color: inherit;
  text-decoration: none;
}
.site-footer a:hover {
  color: var(--foreground);
}
.site-footer .tiny-note {
  margin-top: var(--space-4);
  color: var(--sheen-a65);
}
/* the store trademark credit line (Apple's badge guidelines): quiet, after
   the copyright, never larger than the 14px floor */
.site-footer .credit-line {
  max-width: 48rem;
  margin-top: var(--space-2);
}
.tiny-note a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
@media (min-width: 1024px) {
  .site-footer__grid {
    grid-template-columns: auto 1fr;
    align-items: center;
  }
  .footer-links ul {
    justify-content: flex-end;
  }
}

/* ============================================================ sticky bar
   Plan A3. js/site.js shows it (.is-shown) only while no other install CTA
   is on screen, and sets html.has-sticky-bar while it does. Phones: one
   line, edge to edge, clear of the home indicator. From 640px: a floating
   card. Short landscape (height under 500px): never shown. */

.sticky-download {
  container: sticky / inline-size;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) max(var(--gutter), var(--safe-right)) calc(var(--space-2) + var(--safe-bottom))
    max(var(--gutter), var(--safe-left));
  border-top: 1px solid var(--primary-a35);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--background-a94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--shadow-bar);
  /* hiding is instant (invisible and untouchable at once, so a leaving bar
     never sits over a CTA that is scrolling in); only the arrival slides */
  visibility: hidden;
  pointer-events: none;
  translate: 0 calc(100% + var(--space-6));
  transition:
    translate 0s linear var(--motion-base),
    visibility 0s;
}
.sticky-download.is-shown {
  visibility: visible;
  pointer-events: auto;
  translate: 0 0;
  transition:
    translate var(--motion-base) var(--ease-out),
    visibility 0s;
}
.sticky-copy {
  display: grid;
  min-width: 0;
  line-height: 1.2;
}
.sticky-copy strong {
  overflow: hidden;
  font-size: var(--step-0);
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* the second line returns once the bar is a card (640px and up) */
.sticky-copy span {
  display: none;
  color: var(--muted-foreground);
  font-size: var(--step--1);
}
.sticky-store {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  min-height: var(--target);
  margin-left: auto;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
/* the official badges in the bar: 40px visible (Apple's on-screen minimum),
   with Apple's one-tenth clear space for very limited layout space (the
   bar's own padding and gap give more than that). Shown for a phone whose
   platform js/site.js can read (.is-ios / .is-android: that store alone),
   and from 640px (both); otherwise the text link above stays. */
.sticky-badges {
  --badge-h: 2.5rem;
  display: none;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--space-3);
  margin-left: auto;
}
.sticky-download.is-ios .sticky-badges,
.sticky-download.is-android .sticky-badges {
  display: flex;
}
/* under 23rem (a 320 or 360 phone) a badge, the copy and the dismiss
   button do not fit on one line; the badge wins and the copy steps out */
@container sticky (max-width: 23rem) {
  .sticky-download.is-ios .sticky-copy,
  .sticky-download.is-android .sticky-copy {
    display: none;
  }
  .sticky-download.is-ios .sticky-badges,
  .sticky-download.is-android .sticky-badges {
    margin-right: auto;
    margin-left: 0;
  }
}
.sticky-download.is-ios .sticky-store,
.sticky-download.is-android .sticky-store,
.sticky-download.is-ios .store-badge[data-store='android'],
.sticky-download.is-android .store-badge[data-store='ios'] {
  display: none;
}
.sticky-close {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  min-width: var(--target);
  min-height: var(--target);
  margin: 0 calc(-1 * var(--space-2)) 0 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted-foreground);
  font-size: var(--step-1);
  line-height: 1;
  cursor: pointer;
}
.sticky-close:hover {
  color: var(--foreground-strong);
}
/* while the bar shows: reserve its height at the end of the page, and
   hide the header's own Get the game pill (one install CTA at a time) */
.has-sticky-bar body {
  padding-bottom: calc(var(--space-8) + var(--safe-bottom));
}
/* WCAG 2.4.11: focus navigation scrolls a control clear of the bar, never
   under it (scroll-padding shrinks the "visible" area focus scrolls into) */
.has-sticky-bar {
  scroll-padding-bottom: calc(var(--space-8) + var(--space-3) + var(--safe-bottom));
}
/* a landmark focused by script after a dismiss shows no ring of its own */
main[tabindex='-1']:focus,
main section[tabindex='-1']:focus {
  outline: none;
}
.site-header .nav-cta,
.site-nav__cta {
  transition:
    opacity var(--motion-fast) var(--ease-out),
    visibility 0s;
}
.has-sticky-bar .site-header .nav-cta {
  visibility: hidden;
  opacity: 0;
}
@media (min-width: 640px) {
  .sticky-download {
    bottom: calc(var(--space-4) + var(--safe-bottom));
    width: min(40rem, 100% - 2 * var(--gutter));
    margin-inline: auto;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--primary-a35);
    border-radius: var(--radius-md);
    gap: var(--space-4);
  }
  .sticky-copy span {
    display: block;
  }
  .sticky-badges {
    display: flex;
  }
  .sticky-store {
    display: none;
  }
  .has-sticky-bar body {
    padding-bottom: calc(var(--space-8) + var(--space-6) + var(--safe-bottom));
  }
  .has-sticky-bar {
    scroll-padding-bottom: calc(var(--space-8) + var(--space-7) + var(--safe-bottom));
  }
}
@media (min-width: 1024px) {
  .has-sticky-bar .site-nav__cta {
    visibility: hidden;
    opacity: 0;
  }
}
@media (max-height: 499.98px) {
  .sticky-download {
    display: none;
  }
}

/* =================================================================== 404 */

.lost {
  padding-block: var(--space-6) var(--section-y);
}
.lost-inner {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  text-align: center;
}
.lost .code {
  margin: 0;
  background: var(--grad-display);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-size: var(--step-5);
  font-weight: 700;
  line-height: 0.85;
  letter-spacing: -0.05em;
}
.lost h1 {
  font-size: var(--step-2);
  letter-spacing: 0.01em;
  line-height: var(--leading-snug);
  text-transform: none;
}
.lost p {
  max-width: 26rem;
  margin: 0;
  color: var(--muted-foreground);
  line-height: var(--leading-body);
}
.lost .btn-pill {
  margin-top: var(--space-2);
}
.lost .store-links {
  justify-content: center;
  margin-top: var(--space-2);
}
.lost .mascot-404 {
  width: 8.5rem;
  margin-top: var(--space-4);
  filter: var(--drop-art);
}
@media (min-width: 640px) {
  .lost {
    padding-top: var(--space-8);
  }
  .lost-inner {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      'code art'
      'title art'
      'copy art'
      'action art'
      'badges art';
    justify-items: start;
    align-items: center;
    column-gap: var(--space-7);
    max-width: 52rem;
    text-align: left;
  }
  .lost .code {
    grid-area: code;
  }
  .lost h1 {
    grid-area: title;
  }
  .lost p {
    grid-area: copy;
  }
  .lost .btn-pill {
    grid-area: action;
  }
  .lost .store-links {
    grid-area: badges;
    justify-content: flex-start;
  }
  .lost .mascot-404 {
    grid-area: art;
    width: 14rem;
    margin: 0;
  }
}

/* ---- css/about.css ---- */
/* about.html only: the story, the factsheet, the mascot, the game library
 * strip and the feature cards. Loads after tokens, base and components.
 */

.story {
  max-width: 42.5rem;
}
.story p {
  margin: 0 0 var(--space-4);
  color: var(--muted-foreground);
  line-height: 1.7;
}
.story .story-roar {
  margin: 0;
  color: var(--foreground);
  font-size: var(--step-1);
  font-weight: 700;
}

/* factsheet: label over value on phones, two columns from 640px */
.factsheet {
  max-width: 47.5rem;
  border-top: 1px solid var(--secondary-a28);
}
.factsheet div {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--secondary-a28);
}
.factsheet dt {
  color: var(--foreground);
  font-weight: 700;
}
.factsheet dd {
  color: var(--muted-foreground);
  line-height: 1.6;
}
.factsheet dd a {
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  color: var(--primary);
  font-weight: 700;
  text-decoration: none;
}
.factsheet dd a:hover {
  text-decoration: underline;
}
@media (min-width: 640px) {
  .factsheet div {
    grid-template-columns: minmax(110px, 190px) 1fr;
    gap: var(--space-2) var(--space-5);
    align-items: baseline;
  }
}

/* the current mascot (2026-09 logo kit T-rex head, game web export) */
.mascot-feature {
  display: grid;
  justify-items: center;
  gap: var(--space-5);
  margin-top: var(--space-6);
  text-align: center;
}
.mascot-feature img {
  width: clamp(160px, 22vw, 240px);
  filter: var(--drop-art);
}
.mascot-feature figcaption {
  max-width: 32.5rem;
  color: var(--muted-foreground);
  font-size: var(--step-0);
  line-height: 1.6;
}
.mascot-feature figcaption strong {
  display: block;
  margin-bottom: var(--space-1);
  color: var(--foreground);
  font-family: var(--font-display);
  font-size: var(--step-2);
}
@media (min-width: 1024px) {
  .section--split .mascot-feature {
    margin-top: 0;
  }
}
@media (min-width: 640px) {
  .mascot-feature {
    grid-template-columns: auto 1fr;
    align-items: center;
    justify-items: start;
    gap: clamp(var(--space-5), 4vw, var(--space-7));
    text-align: left;
  }
}

/* dino art strip (game DINO_ART, not the kit mascot) */
.dino-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--space-4);
  margin-top: var(--space-6);
}
.dino-strip article {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-4) var(--space-4) var(--space-5);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm) var(--radius-md) var(--radius-md) var(--radius-sm);
  background: var(--sheen-a03);
}
.dino-strip img.game-dino-portrait {
  width: 60px;
  height: 60px;
}
.dino-strip h3 {
  margin: 0;
}
.dino-strip p {
  margin: 0;
  color: var(--muted-foreground);
  font-size: var(--step--1);
  line-height: 1.5;
}

/* feature cards: six, so 1, 2 then 3 columns never leave an orphan */
.feature-grid {
  display: grid;
  gap: var(--space-4);
}
.feature-card {
  padding: var(--space-5);
  border: 1px solid var(--secondary-a22);
  border-radius: var(--radius-lg);
  background: var(--grad-glass);
  box-shadow: var(--shadow-card);
}
.feature-icon {
  display: grid;
  place-items: center;
  width: 3.2rem;
  height: 3.2rem;
  margin-bottom: var(--space-5);
  border-radius: var(--radius-md);
  color: var(--on-bright);
}
.feature-icon svg {
  width: 1.7rem;
  height: 1.7rem;
}
.feature-card.f-pink .feature-icon {
  background: var(--block-grad);
}
.feature-card.f-teal .feature-icon {
  background: var(--grad-teal-sky);
}
.feature-card.f-violet .feature-icon {
  background: var(--grad-violet-sky);
}
.feature-card.f-gold .feature-icon {
  background: var(--grad-gold-coral);
}
.feature-card.f-mint .feature-icon {
  background: var(--grad-mint-teal);
}
.feature-card.f-coral .feature-icon {
  background: var(--grad-coral-pink);
}
.feature-card h3 {
  margin: 0 0 var(--space-2);
}
.feature-card p {
  margin: 0;
  color: var(--muted-foreground);
  line-height: 1.55;
}
@media (min-width: 640px) {
  .feature-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .feature-card {
    min-height: 13.5rem;
  }
}
@media (min-width: 1024px) {
  .feature-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---- css/game-palette.css ---- */
/* GENERATED by tools/build-dinos.py from docs/brand/brand.json gamePalette.
   Do not edit by hand: change the board, then re-run the build.
   Game colours paint only the game object they name (BRAND.md, Game palette).
   Every fill reads var(--sil, <token>): a container that sets --sil turns
   the dino into a one-colour silhouette (the /dinos mystery cards). */

:root {
  --biome-hatchling-meadow: #4ade80;
  --biome-fern-jungle: #34d399;
  --biome-riverbend: #38bdf8;
  --biome-lava-fields: #fb923c;
  --biome-crystal-caverns: #c084fc;
  --biome-tar-pits: #d97706;
  --biome-thunder-cliffs: #60a5fa;
  --biome-frozen-tundra: #7dd3fc;
  --biome-ashen-wastes: #f87171;
  --biome-apex-summit: #fbbf24;
  --season-dawn: #fbbf24;
  --season-tide: #38bdf8;
  --season-ember: #fb923c;
  --season-frost: #67e8f9;
  --season-bloom: #f472b6;
  --season-storm: #a78bfa;
  --season-dusk: #818cf8;
  --season-golden: #eab308;
  --season-void: #7c3aed;
  --season-zenith: #f43f5e;
  --species-compy-body: #86efac;
  --species-raptor-body: #4ade80;
  --species-anky-body: #38bdf8;
  --species-anky-spikes: #0ea5e9;
  --species-stego-body: #fb923c;
  --species-stego-plates: #ea580c;
  --species-trike-frill: #a855f7;
  --species-trike-body: #c084fc;
  --species-trike-horns: #7c3aed;
  --species-bronto-body: #a78bfa;
  --species-ptero-body: #60a5fa;
  --species-ptero-crest: #3b82f6;
  --species-spino-sail: #14b8a6;
  --species-spino-body: #5eead4;
  --species-rex-body: #f87171;
  --species-apex-body: #fbbf24;
  --species-apex-crown: #f59e0b;
  --species-apex-crown-jewel: #ef4444;
  --species-dilophosaurus-body: #7ca982;
  --species-mamenchisaurus-body: #7d8a63;
  --species-parasaurolophus-body: #7fa07e;
  --species-parasaurolophus-crest: #a3bfa0;
  --species-eoraptor-body: #8a9a5b;
  --species-pisanosaurus-body: #b08968;
  --species-panphagia-body: #8f9f7a;
  --species-herrerasaurus-body: #6f8f7a;
  --species-riojasaurus-body: #9c7f5e;
  --species-scutellosaurus-body: #b07d5a;
  --species-kayentavenator-body: #7c9a6d;
  --species-sarahsaurus-body: #b09a76;
  --species-scelidosaurus-detail: #5c6a44;
  --species-scelidosaurus-body: #7c8a5e;
  --species-yinlong-body: #9a8b5f;
  --species-limusaurus-body: #9db87e;
  --species-guanlong-body: #b08968;
  --species-sinraptor-body: #8a7f6d;
  --species-leaellynasaura-body: #8b9a6b;
  --species-qantassaurus-body: #9a8b5f;
  --species-timimus-body: #a98b6d;
  --species-minmi-body: #93846c;
  --species-minmi-detail: #736549;
  --species-muttaburrasaurus-detail: #d8c8a8;
  --species-muttaburrasaurus-body: #6b533d;
  --species-akainacephalus-detail: #7a6d54;
  --species-akainacephalus-body: #9a8b6f;
  --species-hagryphus-body: #cbb287;
  --species-gryposaurus-body: #a0846f;
  --species-gryposaurus-detail: #bda48c;
  --species-nasutoceratops-detail: #b8bd84;
  --species-nasutoceratops-body: #9aa06a;
  --species-shuvuuia-body: #c9b287;
  --species-protoceratops-body: #b3a06b;
  --species-protoceratops-detail: #d6c39a;
  --species-halszkaraptor-body: #7d8ba0;
  --species-pinacosaurus-body: #8a7a5c;
  --species-pinacosaurus-detail: #6b5d45;
  --species-citipati-body: #a3a380;
  --species-struthiosaurus-body: #8f7d63;
  --species-struthiosaurus-detail: #6f5f49;
  --species-balaur-body: #7b7f8a;
  --species-telmatosaurus-body: #9c8a6e;
  --species-telmatosaurus-detail: #b8a583;
  --species-magyarosaurus-detail: #6b6358;
  --species-magyarosaurus-body: #8a8175;
  --species-hatzegopteryx-detail: #e7d8b0;
  --species-hatzegopteryx-body: #b45309;
  --species-sphaerotholus-body: #a89b7a;
  --species-ornithomimus-body: #d8c99b;
  --species-anodontosaurus-detail: #5f6b51;
  --species-anodontosaurus-body: #7d8a6a;
  --species-hypacrosaurus-detail: #8fb0ab;
  --species-hypacrosaurus-body: #6f8f8a;
  --species-eotriceratops-detail: #c9a06b;
  --species-eotriceratops-body: #a97c50;
  --species-thescelosaurus-body: #7d8a6a;
  --species-pachycephalosaurus-body: #8a6a4a;
  --species-pachycephalosaurus-detail: #d8c8a8;
  --species-anzu-body: #9aa88a;
  --species-edmontosaurus-detail: #96ac86;
  --species-edmontosaurus-body: #7a8f6f;
  --species-torosaurus-body: #8f7355;
  --species-torosaurus-detail: #b89b74;
  --species-tsidiiyazhi-body: #b8a288;
  --species-lithornis-body: #b38f66;
  --species-presbyornis-body: #cfd3cc;
  --species-waimanu-body: #8fa3b0;
  --species-gastornis-body: #7d6248;
}

.fill-mystery {
  fill: var(--sil, var(--plum-deep));
}
.dino-eye {
  fill: var(--sil, var(--plum-deep));
}
.dino-glint {
  fill: var(--sil, var(--white));
}
.fill-season-dawn {
  fill: var(--sil, var(--season-dawn));
}
.fill-season-tide {
  fill: var(--sil, var(--season-tide));
}
.fill-season-ember {
  fill: var(--sil, var(--season-ember));
}
.fill-season-frost {
  fill: var(--sil, var(--season-frost));
}
.fill-season-bloom {
  fill: var(--sil, var(--season-bloom));
}
.fill-season-storm {
  fill: var(--sil, var(--season-storm));
}
.fill-season-dusk {
  fill: var(--sil, var(--season-dusk));
}
.fill-season-golden {
  fill: var(--sil, var(--season-golden));
}
.fill-season-void {
  fill: var(--sil, var(--season-void));
}
.fill-season-zenith {
  fill: var(--sil, var(--season-zenith));
}
.fill-species-compy-body {
  fill: var(--sil, var(--species-compy-body));
}
.fill-species-raptor-body {
  fill: var(--sil, var(--species-raptor-body));
}
.fill-species-anky-body {
  fill: var(--sil, var(--species-anky-body));
}
.fill-species-anky-spikes {
  fill: var(--sil, var(--species-anky-spikes));
}
.fill-species-stego-body {
  fill: var(--sil, var(--species-stego-body));
}
.fill-species-stego-plates {
  fill: var(--sil, var(--species-stego-plates));
}
.fill-species-trike-frill {
  fill: var(--sil, var(--species-trike-frill));
}
.fill-species-trike-body {
  fill: var(--sil, var(--species-trike-body));
}
.fill-species-trike-horns {
  fill: var(--sil, var(--species-trike-horns));
}
.fill-species-bronto-body {
  fill: var(--sil, var(--species-bronto-body));
}
.fill-species-ptero-body {
  fill: var(--sil, var(--species-ptero-body));
}
.fill-species-ptero-crest {
  fill: var(--sil, var(--species-ptero-crest));
}
.fill-species-spino-sail {
  fill: var(--sil, var(--species-spino-sail));
}
.fill-species-spino-body {
  fill: var(--sil, var(--species-spino-body));
}
.fill-species-rex-body {
  fill: var(--sil, var(--species-rex-body));
}
.fill-species-apex-body {
  fill: var(--sil, var(--species-apex-body));
}
.fill-species-apex-crown {
  fill: var(--sil, var(--species-apex-crown));
}
.fill-species-apex-crown-jewel {
  fill: var(--sil, var(--species-apex-crown-jewel));
}
.fill-species-dilophosaurus-body {
  fill: var(--sil, var(--species-dilophosaurus-body));
}
.fill-species-mamenchisaurus-body {
  fill: var(--sil, var(--species-mamenchisaurus-body));
}
.fill-species-parasaurolophus-body {
  fill: var(--sil, var(--species-parasaurolophus-body));
}
.fill-species-parasaurolophus-crest {
  fill: var(--sil, var(--species-parasaurolophus-crest));
}
.fill-species-eoraptor-body {
  fill: var(--sil, var(--species-eoraptor-body));
}
.fill-species-pisanosaurus-body {
  fill: var(--sil, var(--species-pisanosaurus-body));
}
.fill-species-panphagia-body {
  fill: var(--sil, var(--species-panphagia-body));
}
.fill-species-herrerasaurus-body {
  fill: var(--sil, var(--species-herrerasaurus-body));
}
.fill-species-riojasaurus-body {
  fill: var(--sil, var(--species-riojasaurus-body));
}
.fill-species-scutellosaurus-body {
  fill: var(--sil, var(--species-scutellosaurus-body));
}
.fill-species-kayentavenator-body {
  fill: var(--sil, var(--species-kayentavenator-body));
}
.fill-species-sarahsaurus-body {
  fill: var(--sil, var(--species-sarahsaurus-body));
}
.fill-species-scelidosaurus-detail {
  fill: var(--sil, var(--species-scelidosaurus-detail));
}
.fill-species-scelidosaurus-body {
  fill: var(--sil, var(--species-scelidosaurus-body));
}
.fill-species-yinlong-body {
  fill: var(--sil, var(--species-yinlong-body));
}
.fill-species-limusaurus-body {
  fill: var(--sil, var(--species-limusaurus-body));
}
.fill-species-guanlong-body {
  fill: var(--sil, var(--species-guanlong-body));
}
.fill-species-sinraptor-body {
  fill: var(--sil, var(--species-sinraptor-body));
}
.fill-species-leaellynasaura-body {
  fill: var(--sil, var(--species-leaellynasaura-body));
}
.fill-species-qantassaurus-body {
  fill: var(--sil, var(--species-qantassaurus-body));
}
.fill-species-timimus-body {
  fill: var(--sil, var(--species-timimus-body));
}
.fill-species-minmi-body {
  fill: var(--sil, var(--species-minmi-body));
}
.fill-species-minmi-detail {
  fill: var(--sil, var(--species-minmi-detail));
}
.fill-species-muttaburrasaurus-detail {
  fill: var(--sil, var(--species-muttaburrasaurus-detail));
}
.fill-species-muttaburrasaurus-body {
  fill: var(--sil, var(--species-muttaburrasaurus-body));
}
.fill-species-akainacephalus-detail {
  fill: var(--sil, var(--species-akainacephalus-detail));
}
.fill-species-akainacephalus-body {
  fill: var(--sil, var(--species-akainacephalus-body));
}
.fill-species-hagryphus-body {
  fill: var(--sil, var(--species-hagryphus-body));
}
.fill-species-gryposaurus-body {
  fill: var(--sil, var(--species-gryposaurus-body));
}
.fill-species-gryposaurus-detail {
  fill: var(--sil, var(--species-gryposaurus-detail));
}
.fill-species-nasutoceratops-detail {
  fill: var(--sil, var(--species-nasutoceratops-detail));
}
.fill-species-nasutoceratops-body {
  fill: var(--sil, var(--species-nasutoceratops-body));
}
.fill-species-shuvuuia-body {
  fill: var(--sil, var(--species-shuvuuia-body));
}
.fill-species-protoceratops-body {
  fill: var(--sil, var(--species-protoceratops-body));
}
.fill-species-protoceratops-detail {
  fill: var(--sil, var(--species-protoceratops-detail));
}
.fill-species-halszkaraptor-body {
  fill: var(--sil, var(--species-halszkaraptor-body));
}
.fill-species-pinacosaurus-body {
  fill: var(--sil, var(--species-pinacosaurus-body));
}
.fill-species-pinacosaurus-detail {
  fill: var(--sil, var(--species-pinacosaurus-detail));
}
.fill-species-citipati-body {
  fill: var(--sil, var(--species-citipati-body));
}
.fill-species-struthiosaurus-body {
  fill: var(--sil, var(--species-struthiosaurus-body));
}
.fill-species-struthiosaurus-detail {
  fill: var(--sil, var(--species-struthiosaurus-detail));
}
.fill-species-balaur-body {
  fill: var(--sil, var(--species-balaur-body));
}
.fill-species-telmatosaurus-body {
  fill: var(--sil, var(--species-telmatosaurus-body));
}
.fill-species-telmatosaurus-detail {
  fill: var(--sil, var(--species-telmatosaurus-detail));
}
.fill-species-magyarosaurus-detail {
  fill: var(--sil, var(--species-magyarosaurus-detail));
}
.fill-species-magyarosaurus-body {
  fill: var(--sil, var(--species-magyarosaurus-body));
}
.fill-species-hatzegopteryx-detail {
  fill: var(--sil, var(--species-hatzegopteryx-detail));
}
.fill-species-hatzegopteryx-body {
  fill: var(--sil, var(--species-hatzegopteryx-body));
}
.fill-species-sphaerotholus-body {
  fill: var(--sil, var(--species-sphaerotholus-body));
}
.fill-species-ornithomimus-body {
  fill: var(--sil, var(--species-ornithomimus-body));
}
.fill-species-anodontosaurus-detail {
  fill: var(--sil, var(--species-anodontosaurus-detail));
}
.fill-species-anodontosaurus-body {
  fill: var(--sil, var(--species-anodontosaurus-body));
}
.fill-species-hypacrosaurus-detail {
  fill: var(--sil, var(--species-hypacrosaurus-detail));
}
.fill-species-hypacrosaurus-body {
  fill: var(--sil, var(--species-hypacrosaurus-body));
}
.fill-species-eotriceratops-detail {
  fill: var(--sil, var(--species-eotriceratops-detail));
}
.fill-species-eotriceratops-body {
  fill: var(--sil, var(--species-eotriceratops-body));
}
.fill-species-thescelosaurus-body {
  fill: var(--sil, var(--species-thescelosaurus-body));
}
.fill-species-pachycephalosaurus-body {
  fill: var(--sil, var(--species-pachycephalosaurus-body));
}
.fill-species-pachycephalosaurus-detail {
  fill: var(--sil, var(--species-pachycephalosaurus-detail));
}
.fill-species-anzu-body {
  fill: var(--sil, var(--species-anzu-body));
}
.fill-species-edmontosaurus-detail {
  fill: var(--sil, var(--species-edmontosaurus-detail));
}
.fill-species-edmontosaurus-body {
  fill: var(--sil, var(--species-edmontosaurus-body));
}
.fill-species-torosaurus-body {
  fill: var(--sil, var(--species-torosaurus-body));
}
.fill-species-torosaurus-detail {
  fill: var(--sil, var(--species-torosaurus-detail));
}
.fill-species-tsidiiyazhi-body {
  fill: var(--sil, var(--species-tsidiiyazhi-body));
}
.fill-species-lithornis-body {
  fill: var(--sil, var(--species-lithornis-body));
}
.fill-species-presbyornis-body {
  fill: var(--sil, var(--species-presbyornis-body));
}
.fill-species-waimanu-body {
  fill: var(--sil, var(--species-waimanu-body));
}
.fill-species-gastornis-body {
  fill: var(--sil, var(--species-gastornis-body));
}
.biome-hatchling-meadow {
  --biome: var(--biome-hatchling-meadow);
}
.biome-fern-jungle {
  --biome: var(--biome-fern-jungle);
}
.biome-riverbend {
  --biome: var(--biome-riverbend);
}
.biome-lava-fields {
  --biome: var(--biome-lava-fields);
}
.biome-crystal-caverns {
  --biome: var(--biome-crystal-caverns);
}
.biome-tar-pits {
  --biome: var(--biome-tar-pits);
}
.biome-thunder-cliffs {
  --biome: var(--biome-thunder-cliffs);
}
.biome-frozen-tundra {
  --biome: var(--biome-frozen-tundra);
}
.biome-ashen-wastes {
  --biome: var(--biome-ashen-wastes);
}
.biome-apex-summit {
  --biome: var(--biome-apex-summit);
}
.dot-season-dawn {
  background: var(--season-dawn);
}
.dot-season-tide {
  background: var(--season-tide);
}
.dot-season-ember {
  background: var(--season-ember);
}
.dot-season-frost {
  background: var(--season-frost);
}
.dot-season-bloom {
  background: var(--season-bloom);
}
.dot-season-storm {
  background: var(--season-storm);
}
.dot-season-dusk {
  background: var(--season-dusk);
}
.dot-season-golden {
  background: var(--season-golden);
}
.dot-season-void {
  background: var(--season-void);
}
.dot-season-zenith {
  background: var(--season-zenith);
}
