/* ===========================================================================
   Semblature — site stylesheet

   The game's own palette (prototype canon): ink ground, verdigris + brass
   accents. Two typographic registers on purpose, echoing the game's rule that
   fiction and bench text never share a face: Spectral carries the fiction, mono
   carries the facts. Spectral holds the wordmark slot until the real one
   exists.

   Layout is a THREE-TRACK GRID, not a single narrow column. Every page has the
   same two edges — a text measure for prose and a wide track for anything that
   is not prose (screenshots, card grids, the header and the footer) — so the
   width changes read as a system instead of an accident. `.flow` sets the
   tracks; children opt out with `.u-wide` / `.u-full`. Full-bleed `.band`
   sections give the page horizontal presence at any viewport width, which a
   centred ribbon of text cannot.
   =========================================================================== */

/* --------------------------------------------------------------- 1. fonts */

/* ONE family, three real faces. Spectral was drawn by Production Type for
   reading on screen, which is the job the body copy actually has here, and
   running the display slot and the prose out of the same family is what makes
   the page read as one typographic voice rather than two borrowed ones.

   The Italic is a real italic and is not optional: `.thesis` sets a whole
   pull-quote in it and the prose leans on <em>, and a browser-synthesised
   oblique of a serif shears the letterforms instead of redrawing them.

   No SemiBold Italic — nothing in the content nests bold inside italic
   (checked, not assumed), so a fourth file would be dead weight.

   Subset to Latin + the punctuation the site emits, then WOFF2: 792 KB of TTF
   down to 117 KB for all three. Regenerate with
   `python web/tools/make-webfonts.py` — never hand-edit the binary, and never
   self-host Palatino Linotype (guardrail P-11: naming a Windows font in a CSS
   stack is fine; shipping or converting the file is not). */
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-Regular.woff2?v=947a5504') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-Italic.woff2?v=947a5504') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Spectral';
  src: url('fonts/Spectral-SemiBold.woff2?v=947a5504') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* -------------------------------------------------------------- 2. tokens */

:root {
  /* Dark-only, and deliberately: this is the game's own palette (prototype
     canon), so a light variant would be a second register for no gain.
     Declaring the scheme makes form controls and scrollbars match the page. */
  color-scheme: dark;

  /* --- ground -------------------------------------------------------- */
  --ink-0: #0d1116;        /* recessed bands, footer */
  --ink:   #12161d;        /* page */
  --ink-2: #1a202a;        /* cards */
  --ink-3: #232b37;        /* raised chips */
  --ink-veil: rgba(18, 22, 29, 0.86);   /* sticky header */

  /* --- ink on ground -------------------------------------------------
     Measured against --ink: fg 14.5:1, fg-2 11.6:1, dim 7.0:1. `dim` is for
     mono META ONLY — dates, captions, fact lines. Running prose never uses it,
     because grey body copy at a smaller size is most of what "hard to read"
     actually means. */
  --fg:   #e8e6e0;
  --fg-2: #c9cfd8;
  --dim:  #9aa2ae;

  /* --- accents -------------------------------------------------------- */
  --verd:  #46b096;        /* links (6.8:1) */
  --brass: #d8a648;        /* emphasis, buttons (8.2:1) */

  /* --- lines ----------------------------------------------------------
     Two weights on purpose. `line` is a decorative hairline and is allowed to
     be quiet. `line-strong` clears 3:1 on --ink and is what any INTERACTIVE
     boundary uses, per WCAG 1.4.11. */
  --line: #2b3542;
  --line-strong: #5b6779;

  /* --- type ------------------------------------------------------------
     Spectral leads and Georgia is the fallback, in that order for a reason:
     both are screen faces with a large x-height and sturdy stems, and
     light-on-dark punishes the thin strokes of the Palatino/old-style group
     badly at reading size — which is what the body copy used to resolve to on
     Windows. Palatino Linotype stays at the end of the stack, NAMED only:
     naming a Windows face in CSS is explicitly cleared, shipping the file is
     not (decisions 32.2, guardrail P-11). */
  --serif: 'Spectral', Georgia, 'Iowan Old Style', Charter, 'Palatino Linotype', 'Times New Roman', serif;
  --mono: ui-monospace, 'Cascadia Mono', 'SF Mono', Consolas, 'Liberation Mono', monospace;
  --disp: 'Spectral', Georgia, serif;   /* same family, weight 600 */

  /* Fluid scale. h2 tops out near 2× the body size so a section heading is
     unmistakably a section heading — the old 1.4rem sat a hair above the
     paragraphs and did no work. */
  --t-xs:   0.8rem;
  --t-sm:   0.9375rem;
  --t-base: clamp(1.125rem, 1.06rem + 0.33vw, 1.28rem);   /* 18 -> 20.5px; see measure note */
  --t-lg:   clamp(1.1875rem, 1.121rem + 0.33vw, 1.3125rem);
  --t-h3:   clamp(1.1875rem, 1.105rem + 0.41vw, 1.375rem);
  --t-h2:   clamp(1.625rem, 1.348rem + 1.39vw, 2.25rem);
  --t-h1:   clamp(2rem, 1.612rem + 1.94vw, 2.875rem);
  --t-disp: clamp(1.6rem, 8.2vw, 4.25rem);   /* vw-driven: see .title */

  --lh-tight: 1.15;
  --lh-head: 1.22;
  --lh-body: 1.68;

  /* --- space ----------------------------------------------------------- */
  --s-1: 0.25rem; --s-2: 0.5rem;  --s-3: 0.75rem; --s-4: 1rem;
  --s-5: 1.5rem;  --s-6: 2rem;    --s-7: 3rem;    --s-8: 4rem;
  --band-y: clamp(3rem, 6vw, 5rem);

  /* --- measure ---------------------------------------------------------
     `--w-text` is in rem, not ch, so the column does not resize when the font
     stack resolves differently on another platform. 38rem is ~66 characters of
     Spectral at the fluid base size — measured in the browser, not estimated.
     If the body face ever changes, re-measure: the same column held ~72
     characters of Spectral at the previous base size and ~68 of Georgia. */
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --w-text: 38rem;
  --w-wide: 64rem;

  /* --- surface --------------------------------------------------------- */
  --r-sm: 3px; --r-md: 6px; --r-lg: 10px;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 8px 24px -12px rgba(0, 0, 0, 0.7);
  --ring: 2px solid var(--brass);
  --ring-off: 3px;
}

/* ------------------------------------------------------- 3. reset + base */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* the header is sticky, so anchors must not land under it */
  scroll-padding-top: 5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--fg);
  font-family: var(--serif);
  font-size: var(--t-base);
  line-height: var(--lh-body);
  text-rendering: optimizeLegibility;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
  overflow-wrap: break-word;
}

::selection { background: rgba(216, 166, 72, 0.28); color: var(--fg); }

img, svg, video { max-width: 100%; height: auto; }

/* Links: a real underline, offset clear of the descenders, thickened on
   hover rather than swapped for a colour — colour is never the only channel
   anything is carried by on this project (guardrail P-1). */
a {
  color: var(--verd);
  text-underline-offset: 0.18em;
  text-decoration-thickness: from-font;
}
a:hover { color: var(--fg); text-decoration-thickness: 2px; }

:where(a, button, summary, [tabindex]):focus-visible {
  outline: var(--ring);
  outline-offset: var(--ring-off);
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute; left: var(--s-4); top: var(--s-4);
  transform: translateY(-250%);
  z-index: 50;
  background: var(--brass); color: var(--ink);
  font-family: var(--mono); font-size: var(--t-xs);
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  padding: var(--s-3) var(--s-4); border-radius: var(--r-sm);
}
.skip-link:focus { transform: translateY(0); color: var(--ink); }

/* ------------------------------------------------------------ 4. layout */

/* The three-track grid. Everything sits in `text` unless it says otherwise.
   All three tracks share a centre line, so the wide edge reads as a deliberate
   outdent of the text edge rather than a second, unrelated column. */
.flow, .page, .entry {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, calc((var(--w-wide) - var(--w-text)) / 2))
    [text-start] min(100% - var(--gutter) * 2, var(--w-text)) [text-end]
    minmax(0, calc((var(--w-wide) - var(--w-text)) / 2)) [wide-end]
    minmax(var(--gutter), 1fr) [full-end];
}
.flow > *, .page > *, .entry > * { grid-column: text; min-width: 0; }
.u-wide { grid-column: wide; }
.u-full { grid-column: full; }

/* A plain centred container for the shell (header, footer), aligned to the
   same wide edge the content uses. */
/* Full-bleed section bands. Alternating grounds are what stop a long page from
   reading as one thin ribbon of text on a big screen. */
.band { padding-block: var(--band-y); }
.band-deep { background: var(--ink-0); }
.band + .band-deep, .band-deep + .band { border-top: 1px solid var(--line); }

main { display: block; }
.page-main { padding-block: clamp(2.5rem, 5vw, 4rem) var(--s-8); }

/* -------------------------------------------------------- 5. typography */

h1, h2, h3, h4 {
  font-family: var(--disp);
  font-weight: 600;
  line-height: var(--lh-head);
  text-wrap: balance;
  color: var(--fg);
}

h1 { font-size: var(--t-h1); line-height: var(--lh-tight); margin: 0 0 var(--s-5); }

/* Section headings carry a short brass rule. It is the one repeated marker
   that tells you a new section started without relying on size alone, and it
   works identically on the home page and inside a markdown page. */
h2 {
  font-size: var(--t-h2);
  letter-spacing: 0.01em;
  margin: clamp(2.5rem, 5vw, 3.75rem) 0 var(--s-4);
}
h2::before {
  content: "";
  display: block;
  width: 2.25rem; height: 2px;
  margin-bottom: var(--s-4);
  background: var(--brass);
  opacity: 0.9;
}
:is(.band, section) > .flow > h2:first-child,
h2:first-child { margin-top: 0; }

h3 {
  font-size: var(--t-h3);
  color: var(--brass);
  margin: var(--s-6) 0 var(--s-2);
}

p { margin: 0 0 var(--s-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

strong { font-weight: 600; color: var(--fg); }
em { font-style: italic; }

/* The lede is the most important paragraph on the page, so it is LARGER and
   in the full text colour. It used to be smaller and grey. */
.lede {
  font-size: var(--t-lg);
  color: var(--fg);
  margin-bottom: var(--s-5);
}

/* The mono register: facts, dates, labels. Never below 0.8rem — the old
   0.72rem landed at ~11px, which is where "hard to read" starts. */
.eyebrow, .entry-date, .entry-meta, .facts, .shots-note, .foot-links,
.stat, .built .what, .built .ai, .site-head nav a, .btn, .nav-toggle, .toc {
  font-family: var(--mono);
}

.eyebrow {
  font-size: var(--t-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 var(--s-3);
}

/* Anchor permalinks on markdown headings: present for anyone who wants to
   link to an answer, invisible until you go looking for one. */
.anchor {
  margin-left: 0.4em;
  color: var(--line-strong);
  text-decoration: none;
  font-family: var(--mono);
  font-size: 0.6em;
  opacity: 0;
  transition: opacity 0.15s;
}
h2:hover .anchor, h3:hover .anchor, .anchor:focus-visible { opacity: 1; }
.anchor:hover { color: var(--brass); }

/* ----------------------------------------------------------- 6. header */

.site-head-outer {
  position: sticky; top: 0; z-index: 20;
  background: var(--ink-veil);
  border-bottom: 1px solid var(--line);
}
@supports (backdrop-filter: blur(4px)) {
  .site-head-outer { backdrop-filter: blur(10px) saturate(1.2); }
}
/* On a short viewport a sticky bar is a tax, not a convenience. */
@media (max-height: 32rem) { .site-head-outer { position: static; } }

/* The shell containers pad INSIDE their max-width, while the flow grid's wide
   track does not — so `max-width: var(--w-wide)` put the header and footer a
   full gutter inboard of the content they sit above and below. Adding the
   gutters back to the cap makes the two edges resolve to the same pixel at
   every viewport. This is the alignment the whole layout is for; do not
   "simplify" it back to a bare --w-wide. */
.site-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  max-width: calc(var(--w-wide) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--s-3) var(--gutter);
}

.brand {
  display: inline-flex; align-items: center; gap: 0.55rem;
  color: var(--fg); text-decoration: none;
  font-family: var(--disp); font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.22em; text-transform: uppercase;
  white-space: nowrap;
}
.brand:hover { color: var(--brass); }
.brand svg { color: var(--verd); flex: none; }

.site-head nav { display: flex; gap: var(--s-5); align-items: center; }
.site-head nav a {
  position: relative;
  color: var(--dim); text-decoration: none;
  font-size: var(--t-xs);
  letter-spacing: 0.12em; text-transform: uppercase;
  padding-block: var(--s-2);
}
.site-head nav a:hover { color: var(--fg); }
.site-head nav .nav-steam { color: var(--brass); }

/* Current section: an underline as well as a colour change, so the state is
   not carried by colour alone. */
.site-head nav a[aria-current] { color: var(--fg); }
.site-head nav a[aria-current]::after {
  content: ""; position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--brass);
}

/* ------------------------------------------------------------- 7. hero */

.hero {
  text-align: center;
  padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(2rem, 4vw, 3rem);
}
.hero > * { grid-column: wide; }

.title {
  font-family: var(--disp);
  font-size: var(--t-disp);
  line-height: 1.05;
  letter-spacing: 0.28em;
  margin: 0;
  text-indent: 0.28em; /* balance the tracking */
}
.title::before { content: none; }

.subtitle {
  font-family: var(--mono);
  font-size: clamp(0.85rem, 0.75rem + 0.5vw, 1.05rem);
  color: var(--brass);
  letter-spacing: 0.26em; text-transform: uppercase;
  margin: var(--s-4) 0 0;
}
.pron {
  font-family: var(--mono); font-size: 0.88em; color: var(--dim);
  text-transform: none; letter-spacing: 0.02em; font-style: normal;
  white-space: nowrap;
}

/* `width`, not `max-width`: an auto-margin grid item is sized shrink-to-fit,
   and an SVG with only a viewBox reports a 300px intrinsic width — which is
   exactly what the bench collapsed to. */
.bench { width: min(44rem, 100%); margin: clamp(2rem, 4vw, 3rem) auto 0; }
.bench svg { width: 100%; height: auto; display: block; }

.thesis {
  font-size: var(--t-lg);
  margin: clamp(2rem, 4vw, 2.75rem) auto 0;
  width: min(34rem, 100%);
  font-style: italic;
  color: var(--fg);
  text-wrap: balance;
}

.facts {
  font-size: var(--t-xs);
  color: var(--dim);
  letter-spacing: 0.14em;
  margin: var(--s-5) 0 0;
}

.cta { margin: var(--s-6) 0 var(--s-4); }
.cta-sub {
  color: var(--fg-2);
  font-size: var(--t-sm);
  margin: 0 auto var(--s-2);
  width: min(34rem, 100%);
}

/* ---------------------------------------------------- 8. unit anatomy SVG

   Every colour sampled from the 2026-08-24 build, and the host glyph
   contour-traced from it, so the site and the game agree. */
.panel { fill: #263242; stroke: #374555; stroke-width: 1.4; transition: stroke 0.4s; }
.plate { fill: #1c2632; stroke: #2b3646; stroke-width: 1.2; }
.plate-line { fill: #3f4c5d; }
.numeral {
  fill: #3b2a16; font-family: var(--disp); font-weight: 600; font-size: 25px;
  text-anchor: middle; dominant-baseline: central;
}
.chev { fill: #e8a34b; }
.ring-cream { fill: #fff3dd; }
.ring-dark { fill: #4e433f; }
.disc { fill: #e8a34b; }

/* Unaligned: the statement reads false, so the port never lit. */
.ring-dash { fill: none; stroke: #5a6a7a; stroke-width: 2.4; stroke-dasharray: 6 4.8; }
.disc-dark { fill: #161c26; }
.numeral-dim { fill: #71808f; }
.chev-dim { fill: #5a6a7a; }

/* Four status slots per unit, laid out as the game lays them out:
   working / broken down the left, clear / hosting a Shade down the right.
   Glyph colours sampled from the build. No verdict is entered at rest, because
   entering them is the game. */
.slot { fill: #222c3a; stroke: #33405a; stroke-width: 1; }
.m-ok, .m-bad { fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.m-ok { stroke: #719f43; }
.m-bad { stroke: #ac543a; }
.m-clear { fill: none; stroke: #75a3bf; stroke-width: 1.7; }
.m-shade { fill: #8b67b7; }

/* Seeming vs being: attention lights the Shade slot on the two that have
   one, the way the game lights a slot you have committed to. */
.inhabited .host-slot { transition: fill 0.55s ease, stroke 0.55s ease; }
.bench:hover .inhabited .host-slot,
.bench:focus-within .inhabited .host-slot { fill: #3a2d50; stroke: #a678d8; }
.bench:hover .panel, .bench:focus-within .panel { stroke: #4a5c72; }

@media (prefers-reduced-motion: no-preference) {
  .inhabited .host-slot { animation: admit 9s ease-in-out infinite; animation-delay: var(--d, 0s); }
  @keyframes admit {
    0%, 55%, 100% { fill: #222c3a; stroke: #33405a; }
    70%, 85% { fill: #3a2d50; stroke: #a678d8; }
  }
  .bench:hover .inhabited .host-slot { animation: none; fill: #3a2d50; stroke: #a678d8; }
}

/* --------------------------------------------------------- 9. buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem;                 /* 44px touch target */
  padding: 0.7rem 1.6rem;
  background: var(--brass); color: var(--ink);
  text-decoration: none; border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--mono); font-size: var(--t-sm); font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
  transition: background-color 0.18s, color 0.18s, transform 0.18s, box-shadow 0.18s;
}
.btn:hover {
  background: #eec26e; color: var(--ink);
  box-shadow: 0 6px 20px -8px rgba(216, 166, 72, 0.55);
  transform: translateY(-1px);
}
.btn:active { transform: translateY(0); box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover, .btn:active { transform: none; transition: none; }
}

/* --------------------------------------------- 10. premise + the loop */

/* Three steps across the wide track at desk width: the loop is the pitch, and
   a three-across row shows it is a loop of three at a glance. */
.loop {
  grid-column: wide;
  list-style: none;
  counter-reset: step;
  padding: 0;
  margin: var(--s-6) 0 0;
  display: grid;
  gap: var(--s-5);
}
@media (min-width: 52rem) { .loop { grid-template-columns: repeat(3, 1fr); gap: var(--s-6); } }

.loop li {
  counter-increment: step;
  margin: 0;
  padding-top: var(--s-5);
  border-top: 2px solid var(--line);
}
.loop li::before {
  content: counter(step);
  display: block;
  font-family: var(--mono);
  font-size: var(--t-lg);
  font-weight: 700;
  color: var(--brass);
  line-height: 1;
  margin-bottom: var(--s-3);
}
.loop h3 { margin: 0 0 var(--s-2); color: var(--fg); font-size: var(--t-h3); }
.loop p { margin: 0; color: var(--fg-2); }

/* ------------------------------------------------------ 11. screenshots

   These captures are almost entirely TEXT: statements, chips, the report's
   rows. Inside the reading measure a three-across grid renders each one about
   165px wide, which is roughly a ninth of capture width and leaves the
   statements as grey smear. So the grid takes the wide track and runs two
   across, and every shot links to the full-size capture for anyone who wants
   to actually read a bench. */
/* The heading and the note LABEL the grid, so they take the same edge as the
   grid. Leaving them on the text edge over a wide row of images reads as a
   misalignment rather than as a deliberate outdent — that pattern only earns
   its keep when the prose is the primary content and the wide block is a
   figure inside it, which is the case in `.premise` and not here. */
.shots h2, .shots-note { grid-column: wide; }

.shots-note {
  font-size: var(--t-sm);
  color: var(--dim);
  letter-spacing: 0.01em;
  /* shares the grid's left edge, but a note is still prose and the wide track
     is ~110 characters */
  max-width: 46rem;
  margin-bottom: var(--s-6);
}

.shot-row {
  grid-column: wide;
  display: grid;
  gap: var(--s-5);
  /* Two across only while a column can still stay above ~26rem; under that it
     drops to one full-width shot rather than two unreadable ones. The min()
     guards the floor so a narrow phone can't be made to overflow. */
  grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr));
}
.shot-row figure { margin: 0; }
.shot-row a {
  display: block;
  border-radius: var(--r-md);
  text-decoration: none;
}
.shot-row img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--ink-0);
  transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
}
.shot-row a:hover img {
  border-color: var(--verd);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.shot-row figcaption {
  font-family: var(--mono);
  font-size: var(--t-xs);
  color: var(--dim);
  letter-spacing: 0.06em;
  margin-top: var(--s-3);
  display: flex; align-items: baseline; gap: 0.5em;
}
/* The affordance is a word, not just a cursor: the caption says the shot
   opens. */
.shot-row figcaption::after {
  content: "FULL SIZE ↗";
  margin-left: auto;
  color: var(--line-strong);
  white-space: nowrap;
}
.shot-row a:hover + figcaption::after,
.shot-row figure:hover figcaption::after { color: var(--verd); }

@media (prefers-reduced-motion: reduce) {
  .shot-row a:hover img { transform: none; }
}

/* ------------------------------------------------- 12. the fairness block

   The CLASS still says `covenant` and the HEADING says "Fair by design", and
   that mismatch is deliberate. `covenant` is the project's internal name for
   this — guardrail `D-2`, Round 16.8 — so the selector stays greppable against
   the decision record. The word is too elevated to say out loud to a player,
   which is why the display copy does not. Don't reconcile them.

   What `D-2` actually locks is the SUBSTANCE (never require a guess; solutions
   verified unique; the budget always suffices) and that it stays store-facing.
   The three cards are that substance. The label above them is free. */

/* This heading used to be centred, tracked, all-caps mono — a formal
   declaration, which is what "THE FAIRNESS COVENANT" was. "Fair by design" is
   a plain sentence and does not want the ceremony, so it takes the same
   treatment as every other section heading on the page. The three cards are
   distinction enough: they are the only card grid here and the only verdigris
   in the body. */
.covenant h2 { grid-column: wide; margin-bottom: var(--s-5); }

.covenant-grid {
  grid-column: wide;
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}
.covenant-grid > div {
  background: var(--ink-2);
  border: 1px solid var(--line);
  border-top: 2px solid var(--verd);
  border-radius: var(--r-md);
  padding: var(--s-5);
}
.covenant-grid h3 { margin: 0 0 var(--s-3); color: var(--brass); }
.covenant-grid p { margin: 0; color: var(--fg-2); font-size: var(--t-sm); }

/* --------------------------------------------------- 13. entry listings */

.entry-list { list-style: none; margin: 0; padding: 0; }
.entry-list li {
  padding: var(--s-5) 0;
  border-top: 1px solid var(--line);
}
.entry-list li:last-child { border-bottom: 1px solid var(--line); }

.entry-date, .entry-meta {
  font-size: var(--t-xs);
  color: var(--dim);
  letter-spacing: 0.12em; text-transform: uppercase;
}
.entry-list .entry-date { display: block; margin-bottom: var(--s-2); }
.entry-list a {
  font-family: var(--disp); font-weight: 600;
  font-size: var(--t-h3);
  color: var(--fg);
  text-decoration: none;
  line-height: var(--lh-head);
}
.entry-list a:hover { color: var(--verd); text-decoration: underline; }
.entry-desc { margin: var(--s-2) 0 0; color: var(--fg-2); font-size: var(--t-sm); }

.empty { color: var(--dim); font-style: italic; }
.more { margin-top: var(--s-5); }
.feed-link { margin-top: var(--s-6); }
.entry-meta { display: block; margin-bottom: var(--s-3); }
.entry-back { margin-top: var(--s-8); }

.from-studio {
  color: var(--fg-2);
  font-size: var(--t-sm);
}

/* ---------------------------------------------------------- 14. drafts */

.draft-tag {
  font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: #e08585;
  border: 1px solid #e08585; border-radius: var(--r-sm); padding: 0.05em 0.4em;
  vertical-align: middle;
}
.draft-banner {
  position: relative; z-index: 30;
  background: #7c2b2b; color: #fff; text-align: center;
  font-family: var(--mono); font-size: var(--t-sm); padding: var(--s-2);
}

/* ----------------------------------------------------- 15. prose bodies */

.page > h1:first-child, .entry > h1:first-child { margin-top: 0; }

.page ul, .page ol, .entry ul, .entry ol {
  margin: 0 0 var(--s-4);
  padding-left: 1.3em;
}
.page li, .entry li { margin-bottom: var(--s-3); }
.page li::marker, .entry li::marker { color: var(--brass); }

blockquote {
  margin: var(--s-5) 0;
  padding: var(--s-1) var(--s-5);
  border-left: 3px solid var(--verd);
  color: var(--fg-2);
  font-style: italic;
}

pre {
  background: var(--ink-0); border: 1px solid var(--line);
  padding: var(--s-4); border-radius: var(--r-md);
  overflow-x: auto; font-size: var(--t-sm);
  line-height: 1.5;
}
code { font-family: var(--mono); font-size: 0.88em; }
:not(pre) > code {
  background: var(--ink-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 0.1em 0.35em;
}

hr { border: none; border-top: 1px solid var(--line); margin: var(--s-7) 0; }

/* ------------------------------------------------- 16. on-this-page rail

   Wide screens only. The reference pages (FAQ, press kit, privacy, the AI
   disclosure) are long and are read by looking things up, and the space beside
   a centred measure was doing nothing. Below the breakpoint there is no rail
   and the page is exactly what it was — the prose never depends on it. */
.toc { display: none; }

@media (min-width: 78rem) {
  .with-toc {
    display: grid;
    grid-template-columns:
      minmax(0, 1fr)
      min(100% - var(--gutter) * 2, var(--w-text))
      minmax(0, 1fr);
    column-gap: var(--gutter);
  }
  .with-toc > .page { grid-column: 2; display: block; padding: 0; }
  .with-toc > .toc { grid-column: 1; justify-self: end; }

  .toc {
    display: block;
    position: sticky; top: 5.5rem;
    width: min(15rem, 100%);
    max-height: calc(100vh - 8rem);
    overflow-y: auto;
    padding-right: var(--s-5);
    font-size: var(--t-xs);
  }
  .toc-title {
    display: block;
    color: var(--dim);
    letter-spacing: 0.14em; text-transform: uppercase;
    margin-bottom: var(--s-3);
  }
  .toc ol { list-style: none; margin: 0; padding: 0; }
  .toc li { margin: 0 0 var(--s-3); }
  .toc a {
    color: var(--fg-2);
    text-decoration: none;
    display: block;
    line-height: 1.4;
    padding: 0.15rem 0;
    border-left: 2px solid transparent;
    padding-left: var(--s-3);
    margin-left: -2px;
  }
  .toc a:hover { color: var(--verd); border-left-color: var(--verd); }
}

/* ------------------------------------- 17. disclosure entries (ai.html)

   Each asset class gets its own heading with a status chip. The shipped /
   not-yet-shipped split is the first thing a reader needs and should never
   have to be dug out of a sentence.

   The chip carries its own WORD, not just a colour, the same rule the game
   itself is held to (no information by colour alone), and it is what makes
   the distinction survive a screen reader or a greyscale print. */
.made {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-3);
  margin: var(--s-8) 0 var(--s-3);
  padding-top: var(--s-5);
  border-top: 1px solid var(--line);
  color: var(--fg);
}
.made + p { margin-top: 0; }
h2 + .made { margin-top: var(--s-5); border-top: none; padding-top: 0; }

/* Entry headings carry TWO axes, and they are different questions: ship status
   (is this in players' hands yet) and AI status (was a model involved). One
   pill each, always in that order, so the page can be scanned down the
   right-hand side without reading a word of prose.

   The AI pill is the LOUDER of the two, and the quiet one is "no AI". That
   asymmetry is deliberate: on a disclosure page the safe direction to bias is
   toward surfacing AI, never toward making it easy to skim past. */
.made-t { font-size: var(--t-h3); line-height: var(--lh-head); margin-right: 0.1rem; }

.stat {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 0.25rem 0.55rem;
  border: 1px solid;
  border-radius: 2px;
  white-space: nowrap;
  position: relative;
  top: -0.15em;
}
/* Shipped: brass, the palette's "live" accent, and it is in players' hands. */
.stat-ship { color: var(--brass); border-color: #6b5220; background: #241d0e; }
/* Not yet: recessed, so the page reads at a glance as mostly still ahead. */
.stat-soon { color: var(--dim); border-color: var(--line); background: var(--ink-2); }
.stat-ai   { color: var(--fg);  border-color: #4d5b6d; background: var(--ink-3); }
.stat-noai { color: var(--dim); border-color: var(--line); background: transparent; }

/* The build list: facts, so mono, and tight enough to scan as a table. */
.built { list-style: none; margin: 0; padding: 0; }
.built li {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: var(--s-1) var(--s-4);
  padding: var(--s-3) 0;
  border-top: 1px solid var(--line);
  margin: 0;
}
.built li:last-child { border-bottom: 1px solid var(--line); }
.built .what { font-size: var(--t-sm); color: var(--fg); }
.built .how { color: var(--fg-2); font-size: var(--t-sm); }
.built .ai {
  color: var(--brass); font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.1em;
}
@media (max-width: 34rem) { .built li { grid-template-columns: 1fr; } }

/* ----------------------------------------------------------- 18. footer */

.site-foot {
  background: var(--ink-0);
  border-top: 1px solid var(--line);
  padding-block: var(--s-7) var(--s-8);
  margin-top: var(--s-8);
}
.band-deep + .site-foot { border-top-color: transparent; }

.foot-inner {
  max-width: calc(var(--w-wide) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5) var(--s-7);
  align-items: baseline;
  justify-content: space-between;
}

.foot-title {
  font-family: var(--disp); font-weight: 600; letter-spacing: 0.22em;
  font-size: var(--t-sm); margin: 0;
  text-transform: uppercase;
}
.foot-title span {
  display: block;
  letter-spacing: 0.01em; font-family: var(--serif); font-weight: 400;
  color: var(--fg-2); text-transform: none;
  font-size: var(--t-sm); margin-top: var(--s-2);
}

.foot-links {
  display: flex; flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  font-size: var(--t-xs);
  letter-spacing: 0.08em; text-transform: uppercase;
  margin: 0; padding: 0; list-style: none;
}
.foot-links a { color: var(--dim); text-decoration: none; }
.foot-links a:hover { color: var(--fg); text-decoration: underline; }

.foot-fine {
  max-width: calc(var(--w-wide) + var(--gutter) * 2);
  margin: var(--s-6) auto 0;
  padding-inline: var(--gutter);
  color: var(--dim); font-size: var(--t-sm);
}

/* -------------------------------------------------------- 19. mobile nav

   Two layers on purpose: the media query alone un-crams the header with no JS
   at all (the nav wraps to its own row), and the .js-nav layer collapses it
   behind a button when the script has run. Touch targets are 44px; the button
   is a real <button> with aria-expanded, not a checkbox hack, because this
   site advertises its accessibility on the store page. */
.nav-toggle { display: none; }
.nav-icon rect { fill: currentColor; }

@media (max-width: 46rem) {
  .site-head { flex-wrap: wrap; row-gap: var(--s-2); }
  .site-head nav { flex-basis: 100%; flex-wrap: wrap; gap: 0; }

  .nav-toggle {
    display: inline-flex; align-items: center; gap: var(--s-2);
    min-height: 2.75rem; padding: 0 var(--s-3);
    background: none; color: var(--fg-2); cursor: pointer;
    border: 1px solid var(--line-strong); border-radius: var(--r-sm);
    font-size: var(--t-xs);
    letter-spacing: 0.12em; text-transform: uppercase;
  }
  .nav-toggle:hover, .nav-toggle:focus-visible { color: var(--fg); border-color: var(--brass); }

  .js-nav .site-head nav { display: none; }
  .js-nav .site-head nav[data-open] { display: flex; flex-direction: column; }
  .js-nav .site-head nav[data-open] a {
    display: block; width: 100%;
    padding: var(--s-3) 0; font-size: var(--t-sm);
    border-top: 1px solid var(--line);
  }
  .site-head nav a[aria-current]::after { left: 0; right: auto; width: 1.5rem; bottom: 0.35rem; }
}

/* ------------------------------------------------------- 20. motion + print */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .site-head-outer, .nav-toggle, .toc, .skip-link, .cta, .draft-banner { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .band, .site-foot { background: none; padding-block: 0; }
  a { color: #000; }
  .page, .entry, .flow { display: block; max-width: none; }
  h2::before { background: #000; }
}
