/* ─── PartyLink landing — the design tokens ──────────────────────────────────
 *
 * ONE definition of the site's colour, type and spacing, for all twelve pages.
 *
 * WHY THIS FILE EXISTS. Before it, the landing site had three separate and
 * disagreeing palettes: the React SPA (`src/styles/index.css` + a tailwind
 * theme) said the background was #0a0c10; the seven hand-written documents each
 * carried their OWN <style> block saying #0c0e12; and the five catalog pages
 * inherited a third copy from a `SHARED_CSS` string hardcoded inside
 * `packages/server/scripts/generate-games-page.ts`. Twelve pages, twelve
 * stylesheets, no shared token between any of them — so every redesign was a
 * twelve-way manual edit, and the generated five silently reverted to the old
 * palette on the next build.
 *
 * HOW IT IS CONSUMED. It is a real file served from /tokens.css, which is what
 * lets both kinds of page use it:
 *   • the static pages `<link rel="stylesheet" href="/tokens.css">` it;
 *   • the generator emits that same link instead of its own palette block;
 *   • the SPA imports it, and the tailwind theme reads these variables rather
 *     than restating hex values.
 *
 * Changing a colour here changes the whole site, including the generated pages,
 * and survives a rebuild. That is the entire point.
 *
 * NAMING. Everything is prefixed `--pl-` on purpose. The GAMES use bare
 * `--accent`, and an unprefixed token here would leak into any page that ever
 * embeds one.
 */

/* ─── The faces ──────────────────────────────────────────────────────────────
 *
 * The @font-face rules live HERE, in the same file as the `--pl-font-*` stacks
 * that name them, because splitting the two is exactly how this broke before:
 * the catalog pages linked tokens.css — which NAMES Inter and Space Grotesk —
 * without ever loading the faces, so the site's five busiest SEO pages silently
 * rendered in the system stack while every other page did not. Nothing renders
 * a name without also fetching the file now, and a new page that links
 * /tokens.css (which check:tokens forces it to) is correct by construction.
 *
 * SELF-HOSTED, not Google. Every page used to open a connection to
 * fonts.googleapis.com and fonts.gstatic.com. On a site carrying a cookie
 * banner and a privacy policy that is a third party seeing the IP of everyone
 * who reads the privacy policy — and it was the ONLY third-party request those
 * twelve static pages made. Serving the bytes ourselves removes it, drops two
 * DNS+TLS handshakes off the critical path, and puts the landing site on the
 * same footing as packages/host and packages/controller, which have always
 * self-hosted via @fontsource.
 *
 * THE FILES. Copied verbatim out of the @fontsource-variable packages pinned in
 * packages/landing/package.json; `npm run sync:fonts` re-copies them after a
 * version bump. They are committed because the twelve static pages have NO
 * build step — they are plain HTML and cannot import from node_modules, so the
 * faces have to exist at a real URL. The SPA deliberately reads these same
 * files rather than importing the packages, so the two halves cannot drift.
 *
 * WHAT IS AND IS NOT IN THEM.
 *   • VARIABLE weight axes, so one file per family covers every weight the site
 *     asks for (Inter 400–700, JetBrains Mono 400–500, Space Grotesk 300–700)
 *     with no faux-bolding and no per-weight downloads.
 *   • LATIN subset only. The rendered copy is English; the only non-ASCII
 *     characters anywhere on the site are — – · © × → and the first five are
 *     latin. Cyrillic, Greek, Vietnamese and latin-ext are dropped: they were
 *     never requested, and shipping them would roughly double the bytes.
 *   • NORMAL only, no italic file. `.doc em` is synthesised — which is what
 *     already happened, since the old Google request never asked for an ital
 *     axis either. Real italics would be an improvement, but a 50KB one for two
 *     <em>s, and this change is about how fonts load, not which ones.
 *
 * `swap` on all three: the text must be readable while 111KB of font is in
 * flight. `block` would leave the page blank, which is strictly worse than the
 * CDN this replaces.
 *
 * The family names are the plain ones — "Inter", not @fontsource's "Inter
 * Variable" — so the `--pl-font-*` stacks below stay exactly as they were and
 * every page that already asked for Inter keeps getting Inter.
 *
 * No `unicode-range`: it exists to stop a browser downloading the Cyrillic file
 * for an English page, and there is one file per family here, so there is
 * nothing to choose between. A character the file does not carry falls back
 * glyph-by-glyph on its own. */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter-latin-wght-normal.woff2") format("woff2-variations");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-display: swap;
  font-weight: 300 700;
  src: url("/fonts/space-grotesk-latin-wght-normal.woff2") format("woff2-variations");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url("/fonts/jetbrains-mono-latin-wght-normal.woff2") format("woff2-variations");
}

:root {
  /* ── Surfaces, darkest to lightest ────────────────────────────────────────
   * The page, then three raised levels. The old palettes disagreed on the base
   * by two hex points (#0a0c10 vs #0c0e12) — a difference nobody could see but
   * which meant no two pages were ever actually the same colour. The SPA's
   * value wins, because it is the page most visitors land on. */
  --pl-bg: #0a0c10;
  --pl-surface: #0c0e12;
  --pl-surface-2: #12151c;
  --pl-surface-3: #1a1c20;
  --pl-surface-4: #282a2e;

  /* ── Ink ───────────────────────────────────────────────────────────────── */
  --pl-text: #e8ecf4;
  /* Two subordinate ranks, both nudged up. `dim` is body copy — 0.6 on this
   * black is a grey that people squint at across a room, 0.68 still reads as
   * clearly quieter than the heading it sits under. `muted` was 0.38, about
   * 4.0:1: legal for large text, thin and lifeless at the 11–12px mono caption
   * size it is actually used for. 0.5 puts it near 6:1. */
  --pl-dim: rgba(232, 236, 244, 0.68);
  --pl-muted: rgba(232, 236, 244, 0.5);

  /* ── Brand ─────────────────────────────────────────────────────────────────
   * The cyan/pink pair the site has always used. Note this is the ONE place the
   * platform cyan is still correct: it is the product's mark, not a game's
   * accent, and §1's "no game stays on --accent" is a rule about games. */
  --pl-accent: #00e5ff;
  --pl-accent-2: #ff2b7b;
  --pl-accent-3: #e00066;
  /* Text placed ON a filled accent. Dark, because both brand colours are
   * bright enough that white on them fails contrast. */
  --pl-on-accent: #00363d;

  /* ── Lines ─────────────────────────────────────────────────────────────── */
  --pl-border: #3b494c;
  /* The hairline that separates one panel from the page. At 0.1 it vanished on
   * anything but a bright monitor, so every card read as a floating slab with
   * no edge; 0.14 is still a whisper but survives a dim TV-room. */
  --pl-border-soft: rgba(0, 229, 255, 0.14);

  /* ── Type ──────────────────────────────────────────────────────────────────
   * The static pages fell back to the system stack while the SPA asked for
   * Inter, so a visitor moving from the home page to the privacy page changed
   * typeface. Same stack everywhere now. */
  --pl-font-sans: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --pl-font-display: "Space Grotesk", var(--pl-font-sans);
  --pl-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ── Measure and rhythm ──────────────────────────────────────────────────
   * Two column widths: prose is narrow enough to read, the catalog is wide
   * enough to grid. These were 760px and 1080px in two unrelated files. */
  --pl-measure-prose: 760px;
  --pl-measure-wide: 1080px;
  --pl-gutter: 24px;

  --pl-radius-sm: 8px;
  --pl-radius: 12px;
  --pl-radius-lg: 20px;

  /* Elevation on a near-black page cannot be done with a small dark blur —
   * there is nothing darker to cast. These are long, soft and offset downward
   * so the light reads as coming from above the screen. */
  --pl-shadow: 0 24px 60px -24px rgba(0, 0, 0, 0.9), 0 2px 8px rgba(0, 0, 0, 0.5);
  /* A glow, not a halo: tight to the element and thrown downward, so a filled
   * accent button looks lit rather than blurred. */
  --pl-glow-accent: 0 8px 28px -8px rgba(0, 229, 255, 0.5);
  --pl-glow-accent-2: 0 8px 28px -8px rgba(255, 43, 123, 0.5);
}

/* The site is dark-only and says so, rather than letting the browser guess and
 * render form controls and scrollbars in a light theme over a black page. */
:root {
  color-scheme: dark;
}
