/* ─── page.css — the shared skeleton for the seven hand-written documents ─────
 *
 * ONE layout, type scale and chrome for /privacy, /terms, /support and the four
 * SEO guides.
 *
 * WHY THIS FILE EXISTS. tokens.css settled what colour the site is. It did not
 * settle what the site LOOKS like, so the seven documents kept their own
 * <style> blocks — and those blocks were ~90% identical to each other, differing
 * only in trivia nobody chose: h2 at 16px on one page and 17px on the next, list
 * items 4px apart here and 6px apart there, a `.tip` box on one page and an
 * identical `.contact` box on another. Seven copies of one design meant the
 * redesign that moved the SPA onto a fluid type scale, a display face and a mono
 * "instrumentation" voice simply never reached them: they got the new colours
 * and kept the old layout, which is a worse result than not sharing tokens at
 * all — the pages looked deliberately dated instead of merely different.
 *
 * This is the same argument tokens.css makes, one level up. A heading size that
 * appears on seven pages should be decided once.
 *
 * WHAT IT IS NOT. It is not the SPA's stylesheet. The SPA is a marketing page
 * built from Tailwind utilities and cannot link this; these are documents served
 * flat with no build step and cannot import that. What they share is the
 * LANGUAGE — the same faces, the same fluid scale, the same numbered-rule
 * section head, the same surface ladder — restated in plain CSS so a reader
 * moving from the home page to the privacy page does not change websites.
 *
 * NAMING. New custom properties are `--doc-*`. `--pl-*` belongs to tokens.css
 * and bare names belong to the games; a document has no business claiming
 * either. Class names deliberately ECHO the SPA (`.t-label`, `.t-lead`,
 * `.panel`) where they mean the same thing, because that rhyme is the point.
 *
 * Every colour below comes from a var(). Nothing here restates a hex — see
 * scripts/check-tokens.mjs, which fails the build if anything does.
 */

:root {
  /* ── Type scale ─────────────────────────────────────────────────────────────
   * The SPA's ~1.25 ratio and its clamp()-based fluidity, pitched one step down
   * the whole way: a hero shouts and a document is read. Body is 17px rather
   * than the 15px these pages used to run — 15px grey on near-black at a 90ch
   * measure is the single biggest reason they felt like fine print. */
  --doc-fs-title: clamp(2.125rem, 4.6vw, 3.125rem);
  --doc-fs-h2: clamp(1.3125rem, 2.1vw, 1.625rem);
  --doc-fs-lead: clamp(1.125rem, 1.5vw, 1.3125rem);
  /* Card titles: the rung between h2 and body the scale was missing. */
  --doc-fs-h3: 1.125rem;
  --doc-fs-body: 1.0625rem;
  --doc-fs-small: 0.9375rem;
  --doc-fs-label: 0.75rem;
  --doc-fs-micro: 0.6875rem;

  /* ── Measure ────────────────────────────────────────────────────────────────
   * --pl-measure-prose is 760px, which at 17px is ~85 characters — past the
   * point where the eye reliably finds the next line. The token is right for
   * what it names (the page's prose COLUMN, headings and panels included); the
   * running text inside it wants a tighter cap, so it gets one in ch, which
   * tracks the font rather than the monitor. `ch` is the advance of `0`, which
   * in Inter is a good deal wider than the average letter, so this measures out
   * at ~74 real characters a line rather than 58 — at the top of the readable
   * band, where the SPA's own `.t-small` sits, and well in from the ~100 these
   * pages ran at 15px across the full 760px column. */
  --doc-measure: 58ch;

  /* ── Rhythm ─────────────────────────────────────────────────────────────── */
  --doc-sp-section: clamp(2.5rem, 5vw, 3.5rem);
  --doc-nav-h: 4rem;
}

@media (min-width: 768px) {
  :root {
    --doc-nav-h: 4.5rem;
  }
}

/* ── Reset ──────────────────────────────────────────────────────────────────
 * Deliberately narrow. The old blocks opened with `* { margin:0; padding:0 }`,
 * which also flattens list indentation and then pays for it with a hand-tuned
 * padding-left on every ul — the reason the seven pages disagreed about how far
 * a bullet sits from its text. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body,
h1,
h2,
h3,
p,
figure,
blockquote,
dl,
dd {
  margin: 0;
}

body {
  background: var(--pl-bg);
  color: var(--pl-text);
  font-family: var(--pl-font-sans);
  font-size: var(--doc-fs-body);
  line-height: 1.75;
  /* Clears the fixed brand strip pinned above the navbar. */
  padding-top: 3px;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

html {
  scroll-behavior: smooth;
  /* Anything reached by an in-page anchor has to clear the sticky navbar. */
  scroll-padding-top: calc(var(--doc-nav-h) + 2rem);
}

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

::selection {
  background: var(--pl-accent);
  color: var(--pl-on-accent);
}

:focus-visible {
  outline: 2px solid var(--pl-accent);
  outline-offset: 3px;
}

img {
  max-width: 100%;
  height: auto;
}

/* ── Shell ──────────────────────────────────────────────────────────────────
 * ONE column and ONE gutter, shared with the SPA's `.shell`, so the navbar
 * mark, the first character of the first heading and the footer's copyright
 * line all sit on the same left edge. */
.shell {
  width: 100%;
  max-width: var(--pl-measure-wide);
  margin-inline: auto;
  padding-inline: var(--pl-gutter);
}

/* ── The mono voice ─────────────────────────────────────────────────────────
 * Every label, kicker, date and caption on these pages is this one thing at one
 * size. It is the site's instrumentation register and it stops being
 * instrumentation the moment it has variants. */
.t-label {
  font-family: var(--pl-font-mono);
  font-size: var(--doc-fs-label);
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--pl-muted);
}

.t-label-sm {
  font-family: var(--pl-font-mono);
  font-size: var(--doc-fs-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--pl-muted);
}

/* ── Skip link ───────────────────────────────────────────────────────────── */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--pl-accent);
  color: var(--pl-on-accent);
  font-family: var(--pl-font-mono);
  font-size: var(--doc-fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 0 0 var(--pl-radius-sm) 0;
}

.skip-link:focus {
  left: 0;
}

/* ── Brand strip ────────────────────────────────────────────────────────────
 * The site's one piece of pure signature: 3px of the brand pair above the
 * navbar, exactly as the SPA pins it. */
.topbar {
  position: fixed;
  inset-inline: 0;
  top: 0;
  height: 3px;
  z-index: 60;
  background: linear-gradient(
    90deg,
    var(--pl-accent) 0%,
    var(--pl-accent-2) 55%,
    var(--pl-accent) 100%
  );
}

/* ── Navbar ─────────────────────────────────────────────────────────────────
 * Sticky rather than the SPA's fixed: a document has no hero to sit over, and
 * sticky keeps the first heading from hiding under the bar on load. Translucent
 * for the same reason the SPA is — content passing under a solid bar looks like
 * it is being deleted — and it degrades to opaque rather than to a smear. */
.site-nav {
  position: sticky;
  top: 3px;
  z-index: 50;
  background: color-mix(in srgb, var(--pl-bg) 88%, transparent);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--pl-border-soft);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-nav {
    background: var(--pl-bg);
  }
}

.site-nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: var(--doc-nav-h);
}

/* The mark is a screen with a signal in it — the product — not a gamepad. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  text-decoration: none;
  color: var(--pl-text);
  flex-shrink: 0;
}

.brand__mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 1.75rem;
  border: 1px solid var(--pl-border-soft);
  border-radius: 3px;
  flex-shrink: 0;
}

.brand__mark::before {
  content: "";
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 999px;
  background: var(--pl-accent);
}

.brand__mark::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -3px;
  transform: translateX(-50%);
  width: 0.75rem;
  height: 3px;
  background: var(--pl-accent);
  opacity: 0.6;
}

.brand__name {
  font-family: var(--pl-font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.site-nav__links {
  display: flex;
  align-items: center;
  gap: 2rem;
}

.site-nav__links a {
  text-decoration: none;
  color: var(--pl-dim);
  transition: color 0.2s ease;
}

.site-nav__links a:hover,
.site-nav__links a[aria-current="page"] {
  color: var(--pl-accent);
}

/* Below this the bar cannot hold a wordmark and three labels without one of
   them wrapping into the other. The footer carries the full set. */
@media (max-width: 39.99em) {
  .site-nav__links {
    display: none;
  }
}

/* ── The document ─────────────────────────────────────────────────────────── */
/* No bottom padding: the footer already owns the gap below the last section,
   and carrying one on each side of that seam is how you get a 170px hole. */
.doc {
  padding-top: clamp(3rem, 6vw, 4.5rem);
}

/* Running text gets the tighter cap; the column itself keeps the prose token so
   panels and rules still have room to breathe. */
.doc__body {
  max-width: var(--doc-measure);
}

/* ── Document head ──────────────────────────────────────────────────────────
 * The SPA's numbered rule: a mono kicker, then a hairline running off to the
 * right. It is what makes a page announce which KIND of page it is before the
 * title has to. */
.kicker {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.kicker__text {
  color: var(--pl-accent);
}

.kicker__rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--pl-border-soft), transparent);
}

h1,
.t-title {
  font-family: var(--pl-font-display);
  font-size: var(--doc-fs-title);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-wrap: balance;
  /* Wide enough that the longest article title balances onto two lines rather
     than three with a stranded middle one. */
  max-width: 22ch;
  color: var(--pl-text);
}

/* The date line under a legal title. Instrumentation, not prose. */
.doc__updated {
  margin-top: 1.25rem;
}

/* ── Lead ───────────────────────────────────────────────────────────────────
 * One paragraph, larger than the body and narrower than the measure, so the
 * opening reads as an opening instead of as the first of eleven paragraphs. */
.lead {
  font-size: var(--doc-fs-lead);
  line-height: 1.55;
  color: var(--pl-dim);
  max-width: 52ch;
  margin-top: 1.75rem;
}

/* ── Sections ───────────────────────────────────────────────────────────────
 * Separated by the SPA's step motif: a hairline across the column with a short
 * accent tick at its left end. Cheaper than another paragraph explaining that a
 * new subject has started, and it gives the eye a rung to land on when
 * skimming — which is the entire job on the legal pages. */
.doc__section {
  margin-top: var(--doc-sp-section);
}

.doc__section--ruled {
  position: relative;
  /* Asymmetric on purpose: the rule belongs to the section BELOW it, so it
     sits closer to the heading it introduces than to the text it closes. */
  padding-top: 1.75rem;
  border-top: 1px solid var(--pl-border-soft);
}

.doc__section--ruled::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 3rem;
  height: 1px;
  background: var(--pl-accent);
}

.doc h2 {
  font-family: var(--pl-font-display);
  font-size: var(--doc-fs-h2);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--pl-text);
  /* Narrower than the prose measure — the SPA caps its headings the same way —
     but not so narrow that a two-clause FAQ question breaks on its em dash. */
  text-wrap: balance;
  max-width: 34ch;
  scroll-margin-top: calc(var(--doc-nav-h) + 2rem);
}

.doc h3 {
  font-family: var(--pl-font-display);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--pl-text);
}

/* ── Flow ───────────────────────────────────────────────────────────────────
 * One owner for vertical space. Every block gets its top margin from here, so
 * "how far below a heading does a list start" is answered once. */
.doc p,
.doc ul,
.doc ol,
.doc .panel {
  margin-top: 1.125rem;
}

.doc h2 + p,
.doc h2 + ul,
.doc h2 + ol,
.doc h3 + p,
.doc h3 + ul,
.doc h3 + ol {
  margin-top: 0.875rem;
}

.doc p,
.doc li {
  color: var(--pl-dim);
}

.doc strong {
  color: var(--pl-text);
  font-weight: 600;
}

.doc em {
  color: var(--pl-text);
  font-style: italic;
}

/* ── Lists ──────────────────────────────────────────────────────────────────
 * Markers are drawn rather than inherited so the bullet is the brand's colour
 * and sits on the first line's optical centre. With stylesheets blocked these
 * fall back to the browser's own discs and digits, which is the correct
 * degradation for a document. */
.doc ul,
.doc ol {
  list-style: none;
  padding-left: 0;
}

.doc li + li {
  margin-top: 0.625rem;
}

.doc ul > li {
  position: relative;
  padding-left: 1.625rem;
}

.doc ul > li::before {
  content: "";
  position: absolute;
  left: 0.1875rem;
  top: 0.72em;
  width: 0.375rem;
  height: 0.375rem;
  transform: rotate(45deg);
  background: var(--pl-accent);
  opacity: 0.85;
}

/* Numbered steps are set the way the home page sets its three: zero-padded, in
   the mono voice, in the accent. */
.doc ol {
  counter-reset: doc-step;
}

.doc ol > li {
  position: relative;
  counter-increment: doc-step;
  padding-left: 2.5rem;
}

.doc ol > li::before {
  content: counter(doc-step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--pl-font-mono);
  font-size: var(--doc-fs-label);
  letter-spacing: 0.12em;
  line-height: 2.1;
  color: var(--pl-accent);
}

/* ── Links ──────────────────────────────────────────────────────────────────
 * Underlined, because an accent-coloured word in a grey paragraph is not a
 * strong enough signal on a dark page — but underlined faintly and offset, so a
 * paragraph with four links in it still reads as a paragraph. */
.doc a {
  color: var(--pl-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  text-decoration-color: color-mix(in srgb, var(--pl-accent) 45%, transparent);
  transition: text-decoration-color 0.2s ease;
}

.doc a:hover {
  text-decoration-color: var(--pl-accent);
}

/* ── Panel ──────────────────────────────────────────────────────────────────
 * The one raised shape, lifted from the SPA verbatim. The hairline top
 * highlight is what makes a dark box read as lit from above rather than as a
 * lighter rectangle. Replaces the `.tip` and `.contact` boxes, which were the
 * same component under two names on two pages. */
.panel {
  position: relative;
  background: var(--pl-surface-2);
  border: 1px solid var(--pl-border-soft);
  border-radius: var(--pl-radius);
  padding: clamp(1.125rem, 3vw, 1.5rem) clamp(1.25rem, 3.5vw, 1.75rem);
}

.panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--pl-text) 16%, transparent),
    transparent
  );
  pointer-events: none;
}

.panel > :first-child {
  margin-top: 0;
}

.panel h2 {
  font-size: 1.125rem;
}

/* ── Contents ───────────────────────────────────────────────────────────────
 * The legal pages' jump list. Their job is to be scannable, and the cheapest
 * way to make eleven headings scannable is to show all eleven at once. */
.doc .toc {
  margin-top: 2.5rem;
}

.doc .toc__list {
  display: grid;
  gap: 0.5rem 2rem;
  margin-top: 1rem;
  counter-reset: toc;
}

@media (min-width: 40em) {
  .doc .toc__list {
    grid-template-columns: 1fr 1fr;
  }
}

/* Every rule here outranks the generic list styling above by one class, which
   is deliberate — a jump list is a control, not prose, so it takes the mono
   index rather than the accent diamond. */
.doc .toc__list li {
  counter-increment: toc;
  margin-top: 0;
  padding-left: 2.25rem;
  position: relative;
}

.doc .toc__list li::before {
  content: counter(toc, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0;
  width: auto;
  height: auto;
  transform: none;
  background: none;
  opacity: 1;
  font-family: var(--pl-font-mono);
  font-size: var(--doc-fs-micro);
  letter-spacing: 0.12em;
  line-height: 1.9;
  color: var(--pl-muted);
}

.doc .toc__list a {
  color: var(--pl-text);
  font-size: var(--doc-fs-small);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.doc .toc__list a:hover {
  color: var(--pl-accent);
  border-bottom-color: var(--pl-border-soft);
}

/* ── Footer ─────────────────────────────────────────────────────────────────
 * The SPA's footer, restated: the mark and a one-line signature on the left,
 * the link set on the right, and the copyright alone under a rule. The rule
 * sits on an inner box rather than on `.shell` — `.shell` carries the gutter as
 * padding, so a border there overshoots the text edge. */
.site-footer {
  border-top: 1px solid var(--pl-border-soft);
  background: var(--pl-surface);
  margin-top: clamp(4rem, 9vw, 7rem);
}

.site-footer__top {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
  padding-block: 3rem;
}

@media (min-width: 48em) {
  .site-footer__top {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
    gap: 4rem;
  }
}

/* The signature block never gives up width — the longest link set (six items on
   the hosting guide) would otherwise squeeze "local Wi-Fi" onto its own line. */
.site-footer__top > :first-child {
  flex-shrink: 0;
}

.site-footer__sig {
  margin-top: 1rem;
}

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}

/* Two fixed rows filled column-by-column rather than a single wrapping line.
   These footers carry a page-specific link set — four items on the legal pages,
   six on the hosting guide — and a wrapping row put the sixth on a line of its
   own, right-aligned, looking like a mistake. Two rows is tidy at every count. */
@media (min-width: 48em) {
  .site-footer__nav {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(2, auto);
    justify-content: end;
    justify-items: end;
    gap: 0.75rem 2.5rem;
  }
}

.site-footer__nav a {
  text-decoration: none;
  transition: color 0.2s ease;
}

.site-footer__nav a:hover {
  color: var(--pl-accent);
}

.site-footer__legal {
  border-top: 1px solid var(--pl-border-soft);
  padding-block: 1.5rem;
}

/* ─── Catalog ────────────────────────────────────────────────────────────────
 *
 * The five GENERATED pages — the game library and its four category pages —
 * emitted by packages/server/scripts/generate-games-page.ts.
 *
 * They live here rather than in that script for one specific reason: a
 * stylesheet built as a template string inside the generator is where a stray
 * hex value goes to survive forever, because the generator rewrites those pages
 * on every build and quietly overwrites any hand fix. The generator now emits no
 * CSS at all, so there is nowhere for a sixth copy of the palette to hide.
 */

.catnav { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 1.75rem; }
.catnav a {
  color: var(--pl-dim);
  border: 1px solid var(--pl-border-soft);
  border-radius: 999px;
  padding: 7px 15px;
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.catnav a:hover { color: var(--pl-text); border-color: color-mix(in srgb, var(--pl-accent) 40%, transparent); }
.catnav a.is-active {
  color: var(--pl-bg);
  background: var(--pl-accent);
  border-color: var(--pl-accent);
}

/* One column on a phone, and never a card narrower than it can hold a title. */
.game-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 14px;
  margin-bottom: var(--doc-sp-section);
}

.game-card {
  background: var(--pl-surface-2);
  border: 1px solid var(--pl-border-soft);
  border-radius: var(--pl-radius);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* The 1px lit top edge the panels use, so a card reads as the same object
   * family as everything else on the site. */
  background-image: linear-gradient(var(--pl-surface-3), transparent 1px);
}

.game-card__head { display: flex; align-items: center; gap: 11px; }

/* The game's OWN drawn mark — the same sprite the TV tile and the phone use,
 * inlined as a data URI. Inlined rather than linked on purpose: a referenced
 * asset can 404 into silence, which on this platform is a recurring and
 * completely invisible failure. */
.game-card__mark { width: 34px; height: 34px; flex: 0 0 34px; display: block; }

.game-card__title { font-size: var(--doc-fs-h3); line-height: 1.15; }
.game-card__meta { color: var(--pl-muted); }
.game-card__desc { color: var(--pl-dim); font-size: 0.95rem; }

.game-card__howto { margin-top: 2px; border-top: 1px solid var(--pl-border-soft); padding-top: 10px; }
.game-card__objective { font-weight: 600; margin-bottom: 6px; font-size: 0.9rem; }
.game-card__howto ol { padding-left: 0; list-style: none; counter-reset: step; }
.game-card__howto li {
  counter-increment: step;
  position: relative;
  padding-left: 26px;
  margin-bottom: 4px;
  color: var(--pl-dim);
  font-size: 0.875rem;
}
/* The zero-padded index the home page uses for its steps. */
.game-card__howto li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  left: 0;
  color: var(--pl-accent);
  font-family: var(--pl-font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  top: 0.25em;
}

.cat-section { margin-bottom: var(--doc-sp-section); }
.cat-section__intro { color: var(--pl-dim); max-width: 62ch; margin-bottom: 16px; }

/* A category heading on the full catalog links to that category's own page.
 * It must read as a HEADING that happens to be clickable, not as a link — the
 * generator used to force this with an inline style attribute, which is exactly
 * the kind of thing that belongs in a stylesheet. */
.cat-section h2 a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s ease;
}
.cat-section h2 a:hover { border-bottom-color: var(--pl-accent); }
/* The arrow is decoration, so it is drawn here rather than written into the
 * heading text, where it would end up in the document outline and in search
 * results. */
.cat-section h2 a::after {
  content: " →";
  color: var(--pl-accent);
  font-size: 0.8em;
}

/* The way out of the catalogue. Sits above the kicker so it is the first thing
   in the content column, and is deliberately quiet — it is an exit, not a
   call to action. */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
  font-family: var(--pl-font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pl-dim);
  text-decoration: none;
  transition: color 0.16s ease, gap 0.16s ease;
}

.back-link:hover,
.back-link:focus-visible {
  color: var(--pl-gold);
  gap: 0.6rem;
}

/* ── /status.html — R6R3-03 §4a ────────────────────────────────────────────
   The status page has no stylesheet of its own, for the same reason nothing
   else here does: `npm run check:tokens` asserts every page in this directory
   links /tokens.css and restates no palette colour, and a page-local <style>
   is how the site came to have twelve disagreeing stylesheets in the first
   place. Every colour below is a token.

   STATE IS NEVER HUE ALONE. Each row carries a text label as well as a dot,
   because a red/amber pair converges under deuteranopia — and because the
   whole reason this page exists is to say something true in words. */
.status-card {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.9rem;
  margin-bottom: 0.75rem;
}

.status-dot {
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--pl-muted);
}

.status-dot--up { background: var(--pl-gold); }
.status-dot--busy { background: var(--pl-dim); }
.status-dot--down { background: var(--pl-text); }

.status-label {
  font-family: var(--pl-font-display);
  font-size: clamp(1.15rem, 3.5vw, 1.5rem);
  line-height: 1.2;
}

.status-meta {
  font-family: var(--pl-font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pl-muted);
}

.status-detail {
  color: var(--pl-dim);
}

.status-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
  margin-top: 1.25rem;
}

.status-figure {
  font-family: var(--pl-font-display);
  font-size: clamp(1.5rem, 5vw, 2rem);
  line-height: 1.1;
}
