/* ─────────────────────────────────────────────────────────────
   PONS CITY - site
   The design idea, in one line: GLASS IS THE APP, THE CITY INSIDE IT IS THE
   WORLD. Every container is pons's own liquid glass with its generous radii,
   and every piece of CONTENT inside those containers is hard-edged and on a
   16px grid. The contrast is deliberate and it is the whole visual argument.
   Colour comes from tokens.css and is never redefined here.
   ───────────────────────────────────────────────────────────── */

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

/* 🔴 ONE ADDED INK, and it is added rather than a token redefined.
   tokens.css carries pons's own `--text-subtle: #f2f2f266`. Measured against
   --bg-page that composites to #686868 and scores 3.52:1, which is right for a
   RULE and a fail for a sentence: AA wants 4.5:1 for anything under 24px.
   `--chrome-dark` is the same story at 4.14:1.
   Measured on the composited pixels, not on the token:
       #f2f2f2  17.36:1   --text-primary
       #9a9a9a   6.91:1   --text-dim
       #808080   4.93:1   --ink-quiet   <- the quiet step, still legible
       #686868   3.52:1   --text-subtle (rules and hairlines only, never text)
       #687868   4.14:1   --chrome-dark (borders and the status dot, never text)
   axe-core reported ZERO contrast violations on this page because the body carries
   a background-image, which makes axe abstain rather than fail. The 47 failures this
   replaces were found by computing the composite ourselves. A green from a tool that
   abstained is not a pass. */
:root { --ink-quiet: #808080; }

/* The street grid, at the threshold of visible. One 16px grid under everything,
   because SPEC section 2 says there is one grid and this is the site obeying it. */
body {
  background-color: var(--bg-page);
  background-image:
    linear-gradient(to right, rgba(242, 242, 242, .014) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(242, 242, 242, .014) 1px, transparent 1px);
  background-size: 16px 16px;
  background-position: 0 0;
}

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gap-3); }
.prose { max-width: var(--maxw-prose); }
.prose > p + p { margin-top: 1.1em; }
.prose strong { font-weight: 700; color: var(--text-primary); }

/* Clipped rather than parked at left:-9999px. An off-canvas element is a real element
   sitting outside the viewport, so every honest overflow probe reports it. */
.skip {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  background: var(--accent); color: var(--bg-page);
  font-family: var(--ff-mono); font-weight: 700; font-size: 13px;
  text-transform: uppercase; letter-spacing: .1em; text-decoration: none;
}
.skip:focus {
  position: fixed; left: var(--gap-3); top: var(--gap-2); z-index: 100;
  width: auto; height: auto; overflow: visible; clip-path: none;
  padding: 10px 16px; border-radius: var(--r-sm);
}

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

hr.rule { border: 0; height: 1px; background: var(--rule); margin: 0; }

/* ── the glass language, read off pons's own bundle ───────────── */
.glass {
  position: relative;
  background: var(--glass-fill);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-card);
  -webkit-backdrop-filter: blur(18px) saturate(130%);
  backdrop-filter: blur(18px) saturate(130%);
}
/* the sheen: one bright hairline under the top edge, exactly like a lit panel */
.glass::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(180deg, var(--lg-specular) 0, transparent 1px),
              linear-gradient(180deg, var(--lg-sheen) 0, transparent 40%);
}

/* ── masthead ─────────────────────────────────────────────────── */
.masthead {
  position: sticky; top: 0; z-index: 40;
  padding-top: var(--gap-2);
  padding-bottom: var(--gap-2);
  background: linear-gradient(180deg, var(--banner-bg) 55%, transparent);
}
.masthead-bar {
  display: flex; align-items: center; gap: var(--gap-3);
  padding: 10px 10px 10px 14px;
  border-radius: var(--radius-float);
}
.masthead-mark { display: flex; align-items: center; gap: 12px; text-decoration: none; flex: 0 0 auto; }
/* the mark is a raster of a 34px pixel face. 1x only, NEAREST, never a fraction. */
.masthead-mark img { display: block; width: 130px; height: 24px; }
.chainchip {
  font-family: var(--ff-mono); font-weight: 700; font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-muted);
  border: 1px solid var(--divider); border-radius: var(--radius-pill);
  padding: 5px 10px; white-space: nowrap;
  font-feature-settings: var(--ff-features-mono);
}
.chainchip b { color: var(--accent); font-weight: 700; }
.masthead nav { margin-left: auto; display: flex; gap: 4px; align-items: center; }
.masthead nav a {
  font-family: var(--ff-mono); font-weight: 700; font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted); text-decoration: none;
  padding: 8px 10px; border-radius: var(--radius-pill);
}
.masthead nav a:hover { color: var(--accent); background: var(--accent-soft); }
@media (max-width: 860px) { .masthead nav { display: none; } }
@media (max-width: 379px) { .chainchip { display: none; } }

/* ── sections ─────────────────────────────────────────────────── */
main { display: block; }
section { padding-block: var(--gap-7); }
section + section { border-top: 1px solid var(--rule); }
@media (max-width: 700px) { section { padding-block: var(--gap-6); } }

.eyebrow { display: block; margin-bottom: var(--gap-3); }
.eyebrow::before { content: "// "; color: var(--accent-mid); }
h2 { margin: 0 0 var(--gap-4); }
h3 { margin: 0 0 var(--gap-2); }
p { margin: 0; }

/* ── hero ─────────────────────────────────────────────────────── */
.hero { padding-top: var(--gap-4); padding-bottom: var(--gap-6); position: relative; }
/* one soft light behind the cabinet. lime is a LIGHT, so this is the only place
   it is allowed to be large, and it is under 4% alpha. */
.hero::before {
  content: ""; position: absolute; z-index: -1;
  /* 100%, never 110%. A decorative pseudo-element wider than its parent is invisible to
     a querySelectorAll overflow probe and still adds to scrollWidth, which is exactly
     the shape of bug that survives a clean-looking audit. */
  left: 50%; top: 0; width: min(900px, 100%); height: 520px;
  transform: translateX(-50%);
  background: radial-gradient(60% 50% at 50% 30%, rgba(212, 252, 80, .07), transparent 70%);
  pointer-events: none;
}
.hero-grid { display: grid; gap: var(--gap-5); align-items: start; }
/* 522px is not a taste number. It is exactly the box a 480px canvas needs:
   480 + 16 stage padding + 4 stage border + 20 cabinet padding + 2 cabinet border.
   Sizing the column to the SCREEN means the cabinet hugs its own screen instead of
   framing a large black margin, at every device pixel ratio. */
@media (min-width: 1040px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr) 522px; gap: var(--gap-5); align-items: center; }
}

/* 🔴 On a screen with genuine room for it, the city is drawn at a 2x integer scale and
   becomes the largest object on the page, which is what the POV asks for. It is gated on
   HEIGHT as well as width: a 960x540 cabinet needs about 670px of vertical space under
   the headline, and a game whose bottom half is below the fold is worse than a smaller
   one you can see all of. */
@media (min-width: 1680px) and (min-height: 940px) {
  /* the masthead widens with the hero so the mark sits on the same left edge as the
     headline. A bar centred at 1120 above a hero centred at 1560 reads as a mistake
     rather than as the deliberate two-measure structure it is. */
  .masthead .wrap, .hero .wrap { max-width: 1560px; }
  .hero-grid { grid-template-columns: minmax(0, 1fr) 1002px; }
}

.hero h1 { margin: 0 0 var(--gap-5); }
.hero h1 span { display: block; }
.hero h1 .lit { color: var(--accent); }
.hero .lede { color: var(--text-muted); margin-bottom: var(--gap-4); }
.hero-note { font-size: var(--fs-small); color: var(--text-dim); margin-top: var(--gap-3); }

/* on a phone the CITY is the first thing on the page, not a paragraph about it */
@media (max-width: 1039px) { .cabinet { order: -1; } }

.btnrow { display: flex; flex-wrap: wrap; gap: var(--gap-2); }
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--ff-mono); font-weight: 700; font-size: 13px; letter-spacing: .12em;
  text-transform: uppercase; text-decoration: none;
  padding: 13px 18px; border-radius: var(--radius-pill);
  border: 1px solid var(--divider); color: var(--text-primary);
  background: var(--bg-elevated); cursor: pointer;
  transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}
.btn:hover { border-color: var(--chrome-dark); background: var(--panel); }
/* the lit sign: lime as EMITTED light, never as a poster fill */
.btn-lit {
  color: var(--accent); background: var(--accent-soft);
  border-color: var(--accent); box-shadow: var(--glow-md);
}
.btn-lit:hover { color: var(--bg-page); background: var(--accent); border-color: var(--accent); }

/* ── the cabinet: glass outside, hard pixels inside ───────────── */
.cabinet { border-radius: var(--radius-float); padding: 10px; }
.cabinet-head {
  display: flex; align-items: center; gap: var(--gap-2);
  padding: 4px 6px 10px;
}
.cabinet-title {
  font-family: var(--ff-hud); font-size: var(--fs-hud-2x); line-height: 24px;
  color: var(--accent); letter-spacing: 0;
}
.cabinet-state {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  font-family: var(--ff-mono); font-weight: 700; font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-quiet);
}
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--chrome-dark); flex: 0 0 auto; }
.cabinet.is-live .dot { background: var(--live-dot); box-shadow: 0 0 8px var(--accent); }
.cabinet.is-live .cabinet-state { color: var(--accent); }

/* the fit box: this is what the game measures. It has a size of its own and never
   takes one from its contents, so the measurement can never feed back on itself.
   Its height comes from the ratio ALONE: pairing aspect-ratio with a min-height makes
   the box grow in WIDTH instead, which is a trap this studio has shipped before
   (_tools/css_traps.py rule 3). */
.stage-fit {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
}
/* the stage is the hard-edged world: no radius, chrome rails, black ground. It hugs
   the canvas, so the frame is a bezel rather than a large black margin. */
.stage {
  position: relative;
  width: fit-content;
  max-width: 100%;
  /* Hidden until hero.mjs has sized the canvas. The frame hugs the canvas, so its
     width changes the moment the integer scale is applied, and a VISIBLE element
     changing size is exactly what CLS measures. An invisible one contributes nothing
     and the reserved .stage-fit box above never moves. */
  visibility: hidden;
  background: var(--bg-page);
  border: 2px solid var(--chrome-dark);
  border-radius: 0;
  overflow: hidden;
  padding: 8px;
  background-image: var(--scanline);
}
/* 🔴 max-width WITHOUT height:auto would squash the ratio, because mount() writes an
   inline width AND an inline height. max-width beats the inline width, so the height
   has to be freed too or the canvas distorts. Same trap as width/height attributes
   defeating aspect-ratio on an image element. On a narrow dpr-1 viewport this is the one place
   the integer scale is given up, in exchange for never overflowing. */
.stage canvas { display: block; max-width: 100%; height: auto; }
.stage-boot {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--ff-hud); font-size: var(--fs-hud-2x); color: var(--accent);
  background: var(--bg-page); text-align: center; padding: var(--gap-3);
}
.stage-boot.gone { display: none; }
.stage.ready { visibility: visible; }
.stage:focus-within { border-color: var(--accent); box-shadow: var(--glow-sm); }

.cabinet-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-2);
  padding: 10px 6px 4px;
  font-family: var(--ff-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-quiet);
}
.cabinet-foot .keys { display: flex; gap: 6px; flex-wrap: wrap; }
kbd {
  font-family: var(--ff-mono); font-weight: 700; font-size: 10px; letter-spacing: .06em;
  color: var(--chrome-mid); background: var(--bg-elevated);
  border: 1px solid var(--rule-bright); border-bottom-width: 2px;
  border-radius: var(--r-sm); padding: 3px 6px; min-width: 22px; text-align: center;
}
.cabinet-foot .spacer { margin-left: auto; }
.cabinet-hint {
  padding: 0 6px 4px;
  /* a sentence, not a label: 12px and half the tracking of the chips around it */
  font-family: var(--ff-mono); font-size: 12px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-dim);
}
/* A phone has no keyboard and nothing to click, so the WASD chips and the word
   "click" are swapped for the thumbstick and the word "tap". */
.hint-touch { display: none; }
body.touch .hint-touch { display: block; }
body.touch .hint-fine { display: none; }
body.touch .cabinet-foot .keys { display: none; }
.iconbtn {
  font-family: var(--ff-mono); font-weight: 700; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-muted);
  background: var(--bg-elevated); border: 1px solid var(--divider);
  border-radius: var(--radius-pill); padding: 7px 12px; cursor: pointer;
  transition: color .18s ease, border-color .18s ease;
}
.iconbtn:hover { color: var(--accent); border-color: var(--accent-mid); }
.iconbtn[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); }

/* touch controls. Coarse pointers only, and always OUTSIDE the play area. */
.ctl { display: none; }
body.touch .ctl { display: block; }
.padrow { display: none; }
body.touch .padrow {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--gap-3); padding: var(--gap-3) 6px 4px;
  touch-action: none;
}
#pad {
  position: relative; width: 132px; height: 132px; border-radius: 50%;
  background: var(--bg-white); border: 2px solid var(--accent-mid);
  flex: 0 0 auto; touch-action: none;
}
#pad::before, #pad::after { content: ""; position: absolute; background: var(--kerb); }
#pad::before { left: 12%; right: 12%; top: 50%; height: 1px; }
#pad::after { top: 12%; bottom: 12%; left: 50%; width: 1px; }
#knob {
  position: absolute; left: 50%; top: 50%;
  width: 50px; height: 50px; margin: -25px 0 0 -25px; border-radius: 50%;
  background: var(--bg-elevated); border: 2px solid var(--accent); pointer-events: none;
}
#btnA {
  width: 96px; height: 96px; border-radius: 50%; flex: 0 0 auto;
  background: var(--accent-soft); border: 2px solid var(--accent); color: var(--accent);
  font-family: var(--ff-mono); font-weight: 700; font-size: 20px; letter-spacing: .1em;
  cursor: pointer; touch-action: none;
}
#btnA.on { background: var(--accent); color: var(--bg-page); }

/* ── readout strips ───────────────────────────────────────────── */
.readout { margin-bottom: var(--gap-4); border-radius: var(--radius-panel); padding: var(--gap-3) var(--gap-4) var(--gap-4); }
.readout-grid { display: grid; gap: var(--gap-3) var(--gap-5); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.stat { border-top: 1px solid var(--rule); padding-top: 10px; }
.stat dt {
  font-family: var(--ff-mono); font-weight: 700; font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-quiet); margin: 0 0 4px;
}
.stat dd {
  margin: 0; font-family: var(--ff-mono); font-weight: 500;
  font-size: var(--fs-data-lg); line-height: 1.3; color: var(--text-primary);
  font-feature-settings: var(--ff-features-mono);
  font-variant-numeric: tabular-nums slashed-zero;
}
.stat dd.zeroed { color: var(--text-dim); }
.readout-note {
  margin-top: var(--gap-3); padding-top: var(--gap-3); border-top: 1px solid var(--rule);
  font-size: var(--fs-small); color: var(--text-muted);
}
.readout-note b { color: var(--accent); font-weight: 700; }

/* ── hard-edged content blocks ────────────────────────────────── */
/* a spec strip is a printed strip: no radius, one rule per line, mono */
.strip { list-style: none; margin: var(--gap-4) 0 0; padding: 0; border-top: 1px solid var(--rule); max-width: var(--maxw-prose); }
.strip li {
  border-bottom: 1px solid var(--rule); padding: 11px 0 11px 20px; position: relative;
  font-family: var(--ff-mono); font-size: var(--fs-data); color: var(--text-muted);
  font-feature-settings: var(--ff-features-mono);
}
.strip li::before {
  content: ""; position: absolute; left: 0; top: 1.05em;
  width: 8px; height: 2px; background: var(--accent);
}

/* ── the notice plate ─────────────────────────────────────────────────────
   A thick coloured rail down the left of a card is the single most recognisable
   AI-UI tell, and the first version of this block had one. The replacement is a
   motif the game already draws on its own title panel: a hard-edged plate on the
   deepest ink with one 2px lime rule across the TOP. Lime stays a light on an
   edge rather than a stripe down a side, and the notice reads as a sign in the
   city rather than a callout in a template. */
.honesty {
  margin-top: var(--gap-4);
  padding: var(--gap-3) var(--gap-4);
  border: 1px solid var(--accent-mid);
  border-top: 2px solid var(--accent);
  border-radius: 0;
  background: var(--banner-bg);
  color: var(--text-muted); font-size: var(--fs-small);
  max-width: var(--maxw-prose);
}
/* the two disclosures that cost the reader money if they are missed: same plate,
   more air, and a heading. */
.honesty-loud {
  margin-top: var(--gap-5);
  padding: var(--gap-4);
  color: var(--text-dim);
  max-width: 62ch;
}
.honesty-loud h3 { color: var(--accent); font-size: var(--fs-h4); margin-bottom: var(--gap-2); }
.honesty-loud p + p { margin-top: .9em; }

/* the ledger: this is a rent roll, so the money block is set like one */
.ledger {
  margin: var(--gap-4) 0 0; padding: var(--gap-4); max-width: 34rem;
  background: var(--bg-white); border: 1px solid var(--rule-bright); border-radius: 0;
  font-family: var(--ff-mono); font-feature-settings: var(--ff-features-mono);
  font-variant-numeric: tabular-nums slashed-zero;
}
.ledger-row { display: flex; align-items: baseline; gap: var(--gap-3); padding: 7px 0; }
.ledger-row .n { width: 5.5em; flex: 0 0 auto; font-size: var(--fs-data-lg); font-weight: 500; }
.ledger-row .d { color: var(--text-muted); font-size: var(--fs-small); font-family: var(--ff-body); }
.ledger-sum { border-top: 2px solid var(--chrome-dark); margin-top: 6px; padding-top: 12px; }
.ledger-sum .n { color: var(--accent); }

/* a plain data table, hard edges, no zebra */
.table { width: 100%; border-collapse: collapse; margin-top: var(--gap-4); }
.table caption { text-align: start; padding-bottom: var(--gap-2); color: var(--text-dim); font-size: var(--fs-small); }
.table th, .table td {
  text-align: start; padding: 11px 12px 11px 0; border-bottom: 1px solid var(--rule);
  font-family: var(--ff-mono); font-size: var(--fs-data); vertical-align: baseline;
  font-feature-settings: var(--ff-features-mono);
  font-variant-numeric: tabular-nums slashed-zero;
}
.table th {
  font-weight: 700; font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-quiet); border-bottom-color: var(--rule-bright);
}
.table td.dim { color: var(--text-dim); }
.table td.addr { overflow-wrap: anywhere; }
.tablewrap { overflow-x: auto; }

/* ── the law list: what the contract CANNOT do ────────────────── */
.law { list-style: none; margin: var(--gap-4) 0 0; padding: 0; display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 760px) { .law { grid-template-columns: 1fr 1fr; } }
.law li { background: var(--bg-white); padding: var(--gap-3) var(--gap-3) var(--gap-3) 38px; position: relative; font-size: var(--fs-small); color: var(--text-muted); }
.law li strong { display: block; color: var(--text-primary); font-weight: 700; margin-bottom: 3px; }
/* a hard 8px pixel, not a tick glyph: the absence is the point and it is drawn, not written */
.law li::before {
  content: ""; position: absolute; left: var(--gap-3); top: calc(var(--gap-3) + 6px);
  width: 8px; height: 8px; background: var(--accent-mid); box-shadow: 0 0 0 1px var(--accent-soft);
}

/* ── THE CARRY: the strongest thing on the page, laid out as such ─ */
.carry {
  margin-top: var(--gap-5); border-radius: var(--radius-glass); padding: var(--gap-5);
  border-color: var(--accent-mid);
}
.carry h3 { font-size: var(--fs-h2); color: var(--accent); margin-bottom: var(--gap-3); }
.carry .prose { max-width: 58ch; }
.carry .kicker {
  margin-top: var(--gap-4); padding-top: var(--gap-4); border-top: 1px solid var(--accent-mid);
  font-family: var(--ff-body); font-weight: 800; font-size: var(--fs-h3); line-height: 1.2;
  color: var(--text-primary); max-width: 24ch;
}

/* ── the map ──────────────────────────────────────────────────── */
.map-grid { display: grid; gap: var(--gap-4); margin-top: var(--gap-5); }
/* 🔴 both columns are DEFINITE. An `auto` column would shrink to fit the canvas,
   and the canvas sizes itself from that column, so the map would lock at its first
   guess and never grow. */
@media (min-width: 1000px) { .map-grid { grid-template-columns: minmax(0, 1fr) 22rem; align-items: start; gap: var(--gap-4); } }
.map-cabinet { border-radius: var(--radius-float); padding: 10px; }
.map-stage {
  position: relative; background: var(--bg-page);
  border: 2px solid var(--chrome-dark); border-radius: 0;
  display: flex; align-items: center; justify-content: center; padding: 6px;
}
#citymap { display: block; max-width: 100%; height: auto; cursor: crosshair; }
#citymap:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
/* the honesty badge. Always on the map, never dismissible. */
/* bottom RIGHT: the bottom-left corner of the map is lot 90, THE BRIDGE, and a badge
   that covers a landmark is a badge that edits the map it is annotating. */
.seeded {
  position: absolute; right: 8px; bottom: 8px; z-index: 2; max-width: calc(100% - 16px);
  background: var(--banner-bg); border: 1px solid var(--accent-mid);
  padding: 6px 9px; border-radius: 0;
}
.seeded b {
  display: block; font-family: var(--ff-hud); font-size: var(--fs-hud); line-height: 12px;
  color: var(--accent); letter-spacing: 0; font-weight: 400;
}
.seeded span { display: block; margin-top: 3px; font-family: var(--ff-mono); font-size: 12px; color: var(--text-dim); }

.lotpanel { border-radius: var(--radius-panel); padding: var(--gap-4); }
.lotpanel h3 {
  font-family: var(--ff-mono); font-weight: 700; font-size: var(--fs-label); letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent); margin-bottom: var(--gap-3);
}
.lotpanel .lotline {
  font-family: var(--ff-mono); font-weight: 500; font-size: var(--fs-data-lg);
  color: var(--text-primary); font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: var(--ff-features-mono);
}
.lotpanel p { margin-top: var(--gap-2); font-size: var(--fs-small); color: var(--text-muted); }
.lotpanel .hint { margin-top: var(--gap-3); font-size: var(--fs-small); color: var(--text-dim); }
.legend { list-style: none; margin: var(--gap-3) 0 0; padding: var(--gap-3) 0 0; border-top: 1px solid var(--rule); display: grid; gap: 8px; }
.legend li { display: flex; align-items: center; gap: 10px; font-family: var(--ff-mono); font-size: 11px; letter-spacing: .06em; color: var(--ink-quiet); text-transform: uppercase; }
.swatch { width: 14px; height: 14px; flex: 0 0 auto; border-radius: 0; box-shadow: inset 0 0 0 1px var(--rule-bright); }
.map-caption { margin-top: var(--gap-3); font-size: var(--fs-small); color: var(--text-muted); max-width: var(--maxw-prose); }

/* ── FAQ ──────────────────────────────────────────────────────── */
.faq { margin-top: var(--gap-4); display: grid; gap: var(--gap-4) var(--gap-6); }
@media (min-width: 900px) { .faq { grid-template-columns: 1fr 1fr; } }
.faq > div { border-top: 1px solid var(--rule); padding-top: var(--gap-3); }
.faq h3 { font-size: var(--fs-h4); margin-bottom: 6px; }
.faq p { color: var(--text-muted); font-size: var(--fs-small); }
.faq p + p { margin-top: .8em; }

/* ── what this is not ─────────────────────────────────────────── */
.nots { list-style: none; margin: var(--gap-4) 0 0; padding: 0; display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
@media (min-width: 760px) { .nots { grid-template-columns: 1fr 1fr; } }
.nots li { background: var(--bg-white); padding: var(--gap-3); font-size: var(--fs-small); color: var(--text-muted); }
.nots li strong { color: var(--accent-red); font-weight: 700; }
.stamp {
  display: inline-block; margin-top: var(--gap-4);
  font-family: var(--ff-hud); font-size: var(--fs-hud-2x); line-height: 24px; color: var(--accent);
  border: 2px solid var(--accent-mid); padding: 10px 14px; border-radius: 0;
  text-transform: uppercase;
}

/* ── footer ───────────────────────────────────────────────────── */
footer { border-top: 1px solid var(--rule); padding-block: var(--gap-6) var(--gap-5); }
footer .disclaimer { max-width: var(--maxw-prose); font-size: var(--fs-small); color: var(--text-dim); }
.footnav { display: flex; flex-wrap: wrap; gap: var(--gap-3); margin-top: var(--gap-4); }
.footnav a {
  font-family: var(--ff-mono); font-weight: 700; font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; text-decoration: none; color: var(--text-muted);
}
.footnav a:hover { color: var(--accent); }
.blockstamp {
  margin-top: var(--gap-4); font-family: var(--ff-mono); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-quiet);
  font-feature-settings: var(--ff-features-mono);
}
.footmark { margin-top: var(--gap-5); }
.footmark img { display: block; width: 144px; height: 46px; }

.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── odds and ends ────────────────────────────────────────────── */
/* the qualifier line of the H1 in chrome, not lime. The statement is white, the
   condition on it is metal. Spending lime here would blow the 12% budget on one line. */
.hero h1 .qual { color: var(--chrome-mid); }

code {
  font-family: var(--ff-mono); font-size: .92em; color: var(--accent);
  background: var(--accent-soft); padding: 1px 5px; border-radius: var(--r-sm);
  font-feature-settings: var(--ff-features-mono);
}

/* the landmark index under the map: five buttons that select a lot */
.lmlist { list-style: none; margin: var(--gap-3) 0 0; padding: var(--gap-3) 0 0; border-top: 1px solid var(--rule); display: grid; gap: 2px; }
.lmbtn {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: transparent; border: 0; border-radius: var(--r-sm);
  padding: 6px 8px; cursor: pointer; text-align: start;
  font-family: var(--ff-mono); font-size: 12px; letter-spacing: .08em;
  color: var(--text-muted); text-transform: uppercase;
  transition: color .18s ease, background-color .18s ease;
}
.lmbtn:hover { color: var(--accent); background: var(--accent-soft); }
.lmlot {
  min-width: 26px; text-align: center; color: var(--chrome-mid);
  border: 1px solid var(--rule-bright); border-radius: 0; padding: 2px 4px;
  font-variant-numeric: tabular-nums slashed-zero;
}

/* utility spacing, so the markup carries no inline styles and the CSP can stay
   `style-src 'self'` with no unsafe-inline anywhere */
.gap-top { margin-top: var(--gap-4); }
.gap-top-lg { margin-top: var(--gap-6); }
.sw-down  { background: #262626; }
.sw-edge  { background: #171717; }
.sw-mark  { background: #687868; }
.sw-carry { background: #d4fc50; }

/* 404 */
.lost { min-height: 72svh; display: grid; align-content: center; }
.lost .fence {
  width: 100%; max-width: 328px; height: 96px; margin-bottom: var(--gap-4);
  background-color: #171717;
  background-image:
    linear-gradient(45deg, #2a2a2a 1px, transparent 1px),
    linear-gradient(-45deg, #2a2a2a 1px, transparent 1px);
  background-size: 8px 8px;
  border: 1px solid #2a2a2a;
}
.lost-lede { margin-top: var(--gap-3); color: var(--text-muted); max-width: 46ch; }
