/* ═══════════════════════════════════════════════════════════════════════════
   THM · highwaymen.cc
   Design language: infrastructure documentation.
   The clan's one contribution to 6b6t is a standard — five blocks wide — so
   the page is built out of the vernacular of the thing itself: survey plates,
   mileposts, cross-sections, dashed centrelines, coordinate labels.
   Substrate is basalt-dark; signal orange is used as ink, never as light.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
img, svg, canvas, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
figure { margin: 0; }

/* ── Tokens ──────────────────────────────────────────────────────────────── */
:root {
  /* Tells the browser what to paint before this file even arrives, so a new
     document never flashes the default white canvas. */
  color-scheme: dark;

  /* Surface */
  --void:     #0d0b0c;
  --basalt:   #151214;

  /* Ink — warm greys, real values rather than white-at-opacity */
  --bone:     #efe9e3;
  --ash:      #a29a95;
  --ash-dim:  #837b77;   /* 4.7:1 on --void */

  /* Rules */
  --rule:     rgba(239, 233, 227, 0.09);
  --rule-2:   rgba(239, 233, 227, 0.19);

  /* Signal — the clan orange. Ink, borders, small fills. Never a glow. */
  --signal:      #ee6b1f;
  --signal-hi:   #ff7d33;                    /* hover only */
  --signal-line: rgba(238, 107, 31, 0.45);
  --discord:      #5865f2;
  --discord-hi:   #4a56d8;                   /* hover only */
  --discord-ink:  #8b95f6;                   /* discord as text on basalt */
  --discord-line: rgba(88, 101, 242, 0.45);

  /* Space — 4px base */
  --s2: 0.5rem; --s3: 0.75rem; --s4: 1rem;  --s5: 1.5rem;
  --s6: 2rem;   --s7: 3rem;    --s8: 4rem;  --s9: 6rem;

  /* Type */
  --display: 'Archivo', system-ui, sans-serif;
  --serif:   'Newsreader', Georgia, serif;
  --mono:    'IBM Plex Mono', ui-monospace, monospace;

  /* The blocks stay square — they are blocks. The chrome around them does not. */
  --r-xs: 5px;   /* badges, chips, lane labels */
  --r-sm: 9px;   /* buttons, controls */
  --r:    14px;  /* panels, plates, frames, the map */

  --ease: cubic-bezier(0.22, 0.9, 0.24, 1);
  --nav-h: 60px;
  --gut: clamp(1.25rem, 4vw, 3rem);
}

html[data-theme='light'] {
  color-scheme: light;

  --void:     #f3efe8;
  --basalt:   #e9e3d9;

  --bone:     #1a1614;
  --ash:      #57504b;
  --ash-dim:  #6f6862;   /* 4.8:1 on --void */

  --rule:     rgba(26, 22, 20, 0.13);
  --rule-2:   rgba(26, 22, 20, 0.26);

  --signal:      #b34305;   /* 4.9:1 on --void */
  --signal-hi:   #932f00;
  --signal-line: rgba(179, 67, 5, 0.45);
  --discord-ink: #3b45c9;
}

/* ── Base ────────────────────────────────────────────────────────────────── */
/* Landing page ↔ profile navigations crossfade instead of blanking. One at-rule
   does every page in the site; browsers without support just navigate.
   Declared at top level on purpose — wrapped in a @media it is unreliable, and
   an opt-in the browser ignores means a blank frame between pages. Reduced
   motion is honoured below instead, on the transition's own pseudo-elements,
   which `*` in the reduced-motion block does not reach. */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

html { font-size: 16px; scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  background: var(--void);
  color: var(--bone);
  font-family: var(--serif);
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.7;
  overflow-x: clip;
  min-height: 100dvh;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--signal); color: #fff; }

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}

/* ── Type roles ──────────────────────────────────────────────────────────── */
/* Display: Archivo held at an expanded width — stamped signage, not condensed. */
.display, .h2, .h3, .num {
  font-family: var(--display);
  font-stretch: 118%;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.display {
  font-weight: 800;
  font-size: clamp(2.75rem, 9vw, 6.75rem);
  line-height: 0.85;
  font-stretch: 120%;
}
.h2 {
  font-weight: 700;
  font-size: clamp(1.9rem, 4.2vw, 3.1rem);
  line-height: 0.96;
  font-stretch: 112%;
  text-transform: none;
  letter-spacing: -0.025em;
}
.h3 {
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.25;
  font-stretch: 106%;
  letter-spacing: 0.005em;
  text-transform: none;
}
.num {
  font-weight: 700;
  font-stretch: 100%;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  text-transform: none;
}

.mono {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  line-height: 1.4;
}
.mono-sm { font-size: 0.625rem; letter-spacing: 0.18em; }

.prose { color: var(--ash); text-wrap: pretty; }
.prose strong { color: var(--bone); font-weight: 600; }
.prose em { font-style: italic; }
.prose p + p { margin-top: var(--s4); }
.prose a { color: var(--signal); text-decoration: underline; text-underline-offset: 3px; }

/* ── Layout ──────────────────────────────────────────────────────────────── */
/* One shell, 1400px. Every grid section reaches the full width; reading measures
   are capped per component (62ch prose, 56ch log, 46ch reasons) so widening the
   shell never widens a line of text. Images that want the whole screen sit
   outside `.wrap` — see `.crew`. */
.wrap { width: 100%; max-width: 1400px; margin-inline: auto; padding-inline: var(--gut); }

.band { position: relative; padding-block: clamp(3.5rem, 6.5vw, 5.5rem); }

/* Section header: kicker on the left, a fact on the right, hairline under.
   The right-hand slot always carries real information, never decoration. */
.head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s5);
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--s7);
}
.head .kicker { color: var(--signal); white-space: nowrap; }
.head .meta { color: var(--ash-dim); text-align: right; }
.head-title { margin-bottom: var(--s5); max-width: 22ch; }
.lede {
  font-size: 1.1875rem;
  line-height: 1.6;
  color: var(--ash);
  max-width: 52ch;
  text-wrap: pretty;
}

/* ── Section seam ────────────────────────────────────────────────────────── */
/* One full-bleed hairline. The five-wide idea is carried by the drawings and
   the copy, not by a texture. */
.seam {
  height: 1px;
  border: none;
  background: var(--rule-2);
  margin-block: clamp(3rem, 8vw, 6rem);
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 46px;
  padding: 0 1.5rem;
  border-radius: var(--r-sm);
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  border: 1px solid transparent;
  transition: background 0.18s var(--ease), color 0.18s var(--ease),
              border-color 0.18s var(--ease);
}
.btn .arw { transition: transform 0.22s var(--ease); }
.btn:hover .arw { transform: translateX(4px); }
.btn:active { transform: translateY(1px); }

.btn-signal { background: var(--signal); color: #17100b; }
.btn-signal:hover { background: var(--signal-hi); }
html[data-theme='light'] .btn-signal { color: #fff; }
html[data-theme='light'] .btn-signal:hover { background: var(--signal-hi); }

.btn-line { border-color: var(--rule-2); color: var(--bone); }
.btn-line:hover { border-color: var(--signal); color: var(--signal); }


/* ── Navigation ──────────────────────────────────────────────────────────── */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--nav-h);
  z-index: 100;
  display: flex;
  align-items: center;
  gap: var(--s5);
  padding-inline: var(--gut);
  border-bottom: 1px solid transparent;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.nav.scrolled {
  background: var(--void);
  border-bottom-color: var(--rule);
}
.nav-logo { display: flex; align-items: center; gap: 0.55rem; }
.nav-logo img { width: 22px; height: 22px; }
html[data-theme='light'] .nav-logo img { filter: invert(1) saturate(0.9); }
.nav-logo span {
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 118%;
  font-size: 1rem;
  letter-spacing: 0.02em;
}

.nav-links { display: flex; align-items: center; gap: 0.15rem; margin-left: auto; }
.nav-links > li > a {
  position: relative;
  border-radius: var(--r-xs);
  display: flex;
  align-items: center;
  height: 40px;
  gap: 0.35rem;
  padding-inline: 0.7rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash);
  transition: color 0.18s;
}
.nav-links > li > a::after {
  content: '';
  position: absolute;
  left: 0.7rem;
  right: 0.7rem;
  bottom: 8px;
  height: 1px;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.24s var(--ease);
}
.nav-links > li > a:hover { color: var(--bone); }
.nav-links > li > a:hover::after,
.nav-links > li > a.active::after { transform: scaleX(1); }
.nav-links > li > a.active { color: var(--signal); }

.nav-right { display: flex; align-items: center; gap: var(--s3); }
.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  height: 36px;
  padding-inline: 0.95rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-sm);
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: border-color 0.18s, color 0.18s;
}
.nav-cta:hover { border-color: var(--discord); color: var(--discord-ink); }
html[data-theme='light'] .nav-cta:hover { color: var(--discord); }

/* Theme switch — blocky, matches the material system */
.theme-toggle {
  position: relative;
  width: 44px;
  height: 24px;
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  flex-shrink: 0;
}
.theme-toggle:hover { border-color: var(--ash); }
.theme-toggle-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--signal);
  transition: transform 0.28s var(--ease), background 0.28s;
}
html[data-theme='light'] .theme-toggle-knob { transform: translateX(20px); }

/* Hamburger */
.nav-burger {
  display: none;
  width: 40px;
  height: 40px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.nav-burger span {
  width: 18px;
  height: 1.5px;
  background: var(--bone);
  transition: transform 0.26s var(--ease), opacity 0.2s;
}
.nav-burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

@media (max-width: 420px) { .nav-cta { display: none; } }
@media (max-width: 860px) {
  .nav-burger { display: flex; order: 3; }
  .nav-right { margin-left: auto; }
  .nav-links {
    position: fixed;
    top: var(--nav-h);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    padding: var(--s2) var(--gut) var(--s5);
    background: var(--void);
    border-bottom: 1px solid var(--rule);
    transform: translateY(-101%);
    visibility: hidden;
    transition: transform 0.3s var(--ease), visibility 0s linear 0.3s;
  }
  .nav-links.open {
    transform: none;
    visibility: visible;
    transition: transform 0.3s var(--ease), visibility 0s;
  }
  .nav-links > li > a {
    height: 50px;
    padding-inline: 0;
    font-size: 0.75rem;
    border-bottom: 1px solid var(--rule);
  }
  .nav-links > li > a::after { left: 0; right: 0; bottom: -1px; }
}

/* ── Ambient ground ──────────────────────────────────────────────────────── */
.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.bg::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 90% 45% at 50% -10%,
    rgba(238, 107, 31, 0.10), transparent 70%);
}
html[data-theme='light'] .bg::before {
  background: radial-gradient(ellipse 90% 45% at 50% -10%,
    rgba(179, 67, 5, 0.06), transparent 70%);
}
.bg::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.024;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── Reveal ──────────────────────────────────────────────────────────────── */
.rv {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.rv.in { opacity: 1; transform: none; }
.rv.d1 { transition-delay: 0.08s; }
.rv.d2 { transition-delay: 0.16s; }
.rv.d3 { transition-delay: 0.24s; }

/* ═══ HERO ═══════════════════════════════════════════════════════════════ */
.hero { padding-top: calc(var(--nav-h) + clamp(3rem, 9vh, 6rem)); }

/* One orchestrated load sequence, ending with the road drawing itself out
   toward the border. Nothing else on the page animates on load. */
@keyframes rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.hero-eyebrow,
.hero .display,
.hero-lower > * {
  opacity: 0;
  animation: rise 0.7s var(--ease) forwards;
}
.hero-eyebrow { animation-delay: 0.05s; }
.hero .display { animation-delay: 0.16s; }
.hero-lower > *:first-child { animation-delay: 0.3s; }
.hero-lower > *:nth-child(2) { animation-delay: 0.42s; }
.road { transform: scaleX(0); animation: draw 1s var(--ease) forwards 0.7s; }
.road-label { opacity: 0; animation: rise 0.5s var(--ease) forwards 1.3s; }

.hero-eyebrow {
  display: flex;
  align-items: center;
  gap: var(--s3);
  color: var(--ash-dim);
  margin-bottom: var(--s5);
}
.hero-eyebrow b { color: var(--signal); font-weight: 500; }

.display .row {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2rem);
}
/* The wordmark's last line runs out into a road heading for the border —
   the clan's whole job, stated in one graphic device. */
.road {
  flex: 1;
  height: 1px;
  min-width: 40px;
  background: var(--rule-2);
  transform-origin: left;
}
.road-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash-dim);
  white-space: nowrap;
  font-stretch: normal;
}
@media (max-width: 640px) { .road-label { display: none; } }

.hero-lower {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: end;
  margin-top: clamp(2rem, 5vw, 3.5rem);
}
@media (max-width: 900px) {
  .hero-lower { grid-template-columns: 1fr; align-items: stretch; }
}
.hero-thesis {
  font-size: clamp(1.125rem, 1.9vw, 1.375rem);
  line-height: 1.55;
  color: var(--ash);
  max-width: 34ch;
  text-wrap: pretty;
}
.hero-thesis strong { color: var(--bone); font-weight: 500; }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }

/* Survey plate — the live numbers, read like an instrument, not a badge row */
.plate { border: 1px solid var(--rule-2); border-radius: var(--r); background: var(--basalt); overflow: hidden; }
.plate-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--rule-2);
  color: var(--ash-dim);
}
.plate-live { display: flex; align-items: center; gap: 0.45rem; color: var(--ash); }
.plate-live::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--signal); }

@media (max-width: 520px) {
  .plate-head { flex-direction: column; align-items: flex-start; gap: 0.3rem; }
}
.plate-grid { display: grid; grid-template-columns: 1fr 1fr; }
.plate-cell { padding: 0.95rem 0.9rem 1rem; border-top: 1px solid var(--rule); }
.plate-cell:nth-child(-n + 2) { border-top: none; }
.plate-cell:nth-child(odd) { border-right: 1px solid var(--rule); }
.plate-cell .num {
  display: block;
  font-size: clamp(1.5rem, 3vw, 1.9rem);
  line-height: 1;
  color: var(--bone);
}
.plate-cell .num.on { color: var(--signal); }
.plate-cell .k { display: block; margin-top: 0.4rem; color: var(--ash-dim); }

/* ═══ ABOUT — the record ══════════════════════════════════════════════════ */
/* Facts hug the left edge, prose hugs the right, and the air collects between
   them — so a 62ch measure inside a 1400px shell reads as a spread, not as a
   column with a hole beside it. */
.record {
  display: grid;
  grid-template-columns: minmax(0, 250px) minmax(0, 62ch);
  justify-content: space-between;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}
@media (max-width: 820px) { .record { grid-template-columns: 1fr; } }

.mark { width: 84px; margin-bottom: var(--s4); opacity: 0.9; }
html[data-theme='light'] .mark { filter: invert(1) saturate(0.9); }

.facts { border-top: 1px solid var(--rule); }
.facts div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s4);
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--rule);
}
.facts dt {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
  white-space: nowrap;
}
.facts dd {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.01em;
  text-align: right;
  color: var(--bone);
}
.record-prose { font-size: 1.125rem; line-height: 1.72; max-width: 62ch; }
.record-prose p + p { margin-top: var(--s5); }
.record-prose .h2 { margin-bottom: var(--s5); }

/* ═══ HISTORY — milepost log ══════════════════════════════════════════════ */
.log {
  position: relative;
  --date-w: 150px;
  --rail-w: 22px;
  --rail-gap: clamp(1.25rem, 3vw, 2.5rem);
}
/* The rail is that same five-lane highway stood on end, running unbroken
   behind every entry. Its centreline fills as you read down: progress along
   the road is progress through the history. */
  .log-rail {
  position: absolute;
  top: 0.5rem;
  bottom: 0;
  left: calc(var(--date-w) + var(--rail-gap) + var(--rail-w) / 2);
  width: 1px;
  background: var(--rule-2);
}
/* ...and it draws itself as you read down. */
.log-rail::after {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(var(--fill, 0) * 100%);
  background: var(--signal);
}

.log-row {
  position: relative;
  display: grid;
  grid-template-columns: var(--date-w) var(--rail-w) minmax(0, 1fr);
  column-gap: var(--rail-gap);
  padding-bottom: var(--s8);
}
.log-row:last-child { padding-bottom: 0; }
.log-date {
  grid-column: 1;
  position: relative;
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--signal);
  text-align: right;
  padding-top: 0.25rem;
}
.log-date::after {
  content: '';
  position: absolute;
  left: 100%;
  top: 0.85rem;
  width: calc(var(--rail-gap) + var(--rail-w) / 2);
  height: 1px;
  background: var(--rule-2);
  transition: background 0.35s var(--ease);
}
.log-row.seen .log-date::after { background: var(--signal); }
.log-body { grid-column: 3; }
.log-body .h3 { margin-bottom: var(--s2); }
.log-body p { color: var(--ash); max-width: 56ch; text-wrap: pretty; }

/* On a wide screen the timeline gets a longer date column and a longer measure,
   so it spreads instead of hugging the left third. */
@media (min-width: 1200px) {
  .log { --date-w: 260px; }
  .log-body p { max-width: 64ch; }
}

@media (max-width: 700px) {
  /* Pull the rail to the left edge by cancelling the date column out of the
     offset both the rail and the markers are computed from. */
  .log { --date-w: calc(-1 * var(--rail-gap)); --rail-gap: var(--s4); }
  .log-row { grid-template-columns: var(--rail-w) minmax(0, 1fr); padding-bottom: var(--s7); }
  .log-date { grid-column: 2; text-align: left; padding-top: 0; margin-bottom: var(--s2); }
  .log-date::after { display: none; }
  .log-body { grid-column: 2; }
}

/* ═══ NETWORK — the map ══════════════════════════════════════════════════ */
/* The map is a foreign object — a bright technical drawing in someone else's
   palette. Reading text beside it rather than under it keeps it to half the
   column, which is what stops it shouting; the .plate frame makes it a
   documented figure and the pulled-back saturation lets it meet the page. */
.net {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}
.net-text .head-title { margin-bottom: var(--s4); }
.net-note {
  margin-top: var(--s4);
  color: var(--ash);
  max-width: 46ch;
  text-wrap: pretty;
}
.net-text .facts { margin-top: var(--s5); }

/* One column from iPad portrait down. */
@media (max-width: 900px) {
  .net { grid-template-columns: 1fr; }
  .net-note, .net-text .lede { max-width: 60ch; }
}

.map { padding: 0; }
.map-open {
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
}
.map-open img {
  display: block;
  width: 100%;
  height: auto;
  filter: saturate(0.82) brightness(0.96);
  transition: filter 0.4s var(--ease);
}
.map-open:hover img,
.map-open:focus-visible img { filter: saturate(1) brightness(1); }

.map-caption {
  padding: 0.75rem var(--s4);
  border-top: 1px solid var(--rule);
  color: var(--ash-dim);
}

/* Enlarged map — native <dialog>, so Esc and the backdrop come free. The image
   keeps a 900px floor so "enlarge" still means something on a phone; the
   container pans instead of shrinking the map to illegibility. */
.zoom {
  /* 131vh = 94vh × the map's 1.4 aspect, so on a wide screen the whole map
     fits without scrolling; on a narrow one 96vw wins and it pans instead. */
  width: min(2800px, 96vw, 131vh);
  max-width: none;
  max-height: 94vh;
  inset: 0;
  margin: auto;
  padding: 0;
  border: 1px solid var(--rule-2);
  border-radius: var(--r);
  background: var(--basalt);
  color: var(--bone);
  overflow: hidden;
}
.zoom::backdrop { background: rgba(0, 0, 0, 0.82); }
.zoom-scroll { overflow: auto; max-height: 94vh; overscroll-behavior: contain; }
.zoom-scroll img { display: block; width: 100%; min-width: 900px; height: auto; }
.zoom-close {
  position: absolute;
  top: var(--s3);
  right: var(--s3);
  z-index: 1;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-sm);
  background: var(--void);
  color: var(--bone);
  cursor: pointer;
}
.zoom-close:hover { border-color: var(--signal-line); color: var(--signal); }

/* Same dialog for every other image, but sized to the picture rather than the
   map's pan floor. fit-content is what makes it hug the image — with a stretched
   width the picture sat off to one side. `inset: 0; margin: auto` from .zoom
   then centres the result. */
.lightbox {
  width: fit-content;
  height: fit-content;
  max-width: 94vw;
  max-height: 92vh;
}
.lightbox img {
  display: block;
  width: auto;
  height: auto;
  /* Under the dialog's own cap, so the border never crops the picture. */
  max-width: min(1600px, 92vw);
  max-height: 88vh;
}
img[role='button'] { cursor: zoom-in; }

/* ═══ STANDARD — the spec ═════════════════════════════════════════════════ */
/* ponytail: no cross-section drawing. The headline states the width and the
   six reasons carry the rest; a diagram of five stacked bands added nothing. */
.spec-lede { margin-block: var(--s6) var(--s5); }

/* Six reasons, ruled and set in two columns — no boxes, no repeated cards */
.why { columns: 2; column-gap: clamp(2rem, 5vw, 4.5rem); border-top: 1px solid var(--rule); }
@media (max-width: 700px) { .why { columns: 1; } }
.why-row { break-inside: avoid; padding: var(--s4) 0; border-bottom: 1px solid var(--rule); }
.why-row dt {
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 106%;
  font-size: 0.8125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bone);
  margin-bottom: 0.3rem;
}
.why-row dd { color: var(--ash); font-size: 1rem; line-height: 1.6; max-width: 46ch; }

/* ═══ TOOLING — two spec sheets, side by side ═══════════════════════════ */
/* Each tool is a named thing with an author and a date, so it is written up the
   way the rest of the page writes up facts: a titled header over a hairline,
   prose, then a ruled .facts table. No new table component. */
.tools {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
  margin-top: var(--s7);
}
@media (max-width: 820px) { .tools { grid-template-columns: 1fr; } }

.tool {
  display: flex;
  flex-direction: column;
  padding: var(--s5);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--basalt);
  transition: border-color 0.35s var(--ease);
}
.tool:hover { border-color: var(--rule-2); }

.tool-head {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: var(--s4);
  align-items: center;
  padding-bottom: var(--s4);
  margin-bottom: var(--s4);
  border-bottom: 1px solid var(--rule-2);
}
.tool img { width: 56px; height: 56px; border-radius: var(--r-sm); }
.tool-mark { background: none; padding: 4px; }
html[data-theme='light'] .tool-mark { filter: invert(1) saturate(0.9); }
.tool-kind { margin-top: 0.3rem; color: var(--ash-dim); }
/* The description takes the slack so both .facts tables sit on the same line. */
.tool > p { flex: 1; color: var(--ash); font-size: 1rem; }
.tool .facts { margin-top: var(--s5); }

/* ═══ ALLIANCE — an archived record, set in past tense ══════════════════ */
.archive {
  display: grid;
  grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  align-items: start;
  opacity: 0.92;
}
@media (max-width: 780px) { .archive { grid-template-columns: 1fr; } }
.archive-name { color: var(--ash); margin-bottom: var(--s3); }
.archive-plate {
  display: inline-block;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-xs);
  font-family: var(--mono);
  font-size: 0.5625rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
.archive p { color: var(--ash); max-width: 64ch; }
.archive p + p { margin-top: var(--s4); }
.archive-tally {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--s4);
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--rule);
}
.archive-tally .num { display: block; font-size: 1.35rem; color: var(--ash); line-height: 1; }
.archive-tally .k {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash-dim);
}

/* Alliance register: name and the date it was signed. Two columns, ruled. */
.reg {
  columns: 2;
  column-gap: clamp(2rem, 5vw, 4.5rem);
  border-top: 1px solid var(--rule);
  margin-bottom: var(--s8);
}
@media (max-width: 620px) { .reg { columns: 1; } }
.reg li {
  break-inside: avoid;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s4);
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
.reg .n {
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 106%;
  font-size: 0.9375rem;
  letter-spacing: 0.015em;
  color: var(--bone);
}
.reg .d {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash-dim);
  white-space: nowrap;
}
.reg li.closed .n { color: var(--ash); }
.reg li.closed .d { color: var(--signal); }

/* ═══ ROSTER ═════════════════════════════════════════════════════════════ */
.leads {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--rule-2);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--s7);
}
@media (max-width: 760px) { .leads { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.lead {
  padding: var(--s4);
  border-left: 1px solid var(--rule);
}
.lead:first-child { border-left: none; padding-left: 0; }
@media (max-width: 760px) {
  .lead:nth-child(odd) { border-left: none; padding-left: 0; }
  .lead:nth-child(-n + 2) { border-bottom: 1px solid var(--rule); }
}
.lead .h3 { color: var(--bone); transition: color 0.18s; }
a.lead:hover .h3 { color: var(--signal); }
.lead .r {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.3rem;
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
.lead .r::before { content: ''; width: 6px; height: 6px; background: var(--signal); }

/* The crew render — the one photographic thing on the site, so it gets the whole
   screen. Cropped to a band with the focus low, because the top half of the
   source is empty stage. Hairlines top and bottom tie it to the seams. */
/* No hairlines any more — the edges are feathered, so a hard rule across them
   would fight the fade. */
.crew { margin-block: var(--s6) var(--s7); }
/* Half width, centred, edges feathered into the page.
   The crop is 2.8/1 rather than the tightest-possible 3.36 on purpose: the six
   figures need source rows 1312–3609 of 4340, and the looser box leaves ~230
   rows of empty stage above the crown and below the feet for the top and bottom
   fades to land in. Fade the artwork itself and the end figures dissolve. */
.crew img {
  width: 50%;
  margin-inline: auto;
  height: auto;   /* or the height attribute wins and aspect-ratio never applies */
  aspect-ratio: 2.8;
  object-fit: cover;
  object-position: 50% 68%;
  /* Sides stop at 4%: figure 1 starts at 2% of the source width and figure 6 ends
     at 98%, so a longer ramp would dissolve the end figures — the crowned one
     included. Top and bottom can afford 10%, that is the empty stage. */
  mask-image:
    linear-gradient(to right, transparent, #000 4%, #000 96%, transparent),
    linear-gradient(to bottom, transparent, #000 10%, #000 90%, transparent);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
/* Narrow screens get the full width and the whole render: at half width the six
   figures would be unreadable, and cropping to a taller box cuts the outer two —
   the crown is on the far right. */
@media (max-width: 760px) { .crew img { width: 100%; aspect-ratio: auto; } }
.crew figcaption { padding-top: 0.8rem; color: var(--ash-dim); }

.roster { columns: 4; column-gap: clamp(1.5rem, 4vw, 3rem); }
@media (min-width: 1200px) { .roster { columns: 5; } }
@media (max-width: 900px) { .roster { columns: 3; } }
@media (max-width: 620px) { .roster { columns: 2; } }
.roster li { break-inside: avoid; }
.roster a, .roster span {
  display: block;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--ash);
  transition: color 0.16s var(--ease), transform 0.16s var(--ease);
}
.roster a:hover { color: var(--signal); transform: translateX(4px); }
.roster a.former { color: var(--ash-dim); }
.roster a.former:hover { color: var(--signal); }
.roster-note .former { color: var(--ash-dim); }
.roster span { color: var(--ash-dim); }
.roster-note { margin-top: var(--s5); color: var(--ash-dim); }

/* ═══ JOIN ═══════════════════════════════════════════════════════════════ */
.join { background: var(--basalt); border-block: 1px solid var(--rule); }
.join-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s6);
}
.join-inner .h2 { max-width: 20ch; }
.join-inner p { color: var(--ash); max-width: 40ch; margin-top: var(--s3); }

/* ═══ FOOTER ═════════════════════════════════════════════════════════════ */
/* ponytail: text only. The crew render moved up to the roster, where it means
   something; the footer does not need a second copy of it. */
.foot { padding-block: var(--s8) var(--s6); text-align: center; }
.foot-lines { display: flex; flex-direction: column; gap: 0.6rem; }
.foot-lines p {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash-dim);
}
.foot-lines b { color: var(--ash); font-weight: 500; }
.foot-lines a { color: var(--ash); transition: color 0.18s; }
.foot-lines a:hover { color: var(--signal); }
.foot-sig { margin-top: var(--s5); font-size: 0.5625rem !important; opacity: 0.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   PLAYER PROFILES
   Same system, no parallel one: the sections reuse .head / .h2 / .prose / .why /
   .facts, and the skin viewer is a .plate like the hero's telemetry.
   ═══════════════════════════════════════════════════════════════════════════ */
.pf { padding-top: calc(var(--nav-h) + var(--s7)); }

.pf-crumb {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  color: var(--ash-dim);
  margin-bottom: var(--s6);
}
.pf-crumb a { color: var(--ash); transition: color 0.18s; }
.pf-crumb a:hover { color: var(--signal); }
.pf-crumb b { color: var(--signal); font-weight: 500; }

.pf-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 252px;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
@media (max-width: 820px) {
  .pf-head { grid-template-columns: 1fr; }
  .pf-plate { order: -1; max-width: 300px; position: static; }
}

.pf-name {
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 116%;
  font-size: clamp(1.9rem, 5.4vw, 3.9rem);
  line-height: 0.88;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  overflow-wrap: break-word;
  margin-bottom: var(--s4);
}
.pf-roles { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: var(--s5); }
.pf-role {
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-xs);
  font-family: var(--mono);
  font-size: 0.5625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash);
}
.pf-role.lead { border-color: var(--signal-line); color: var(--signal); }
.pf-role.dev { border-color: var(--discord-line); color: var(--discord-ink); }
/* Past tense, visually — same treatment as the alliance archive. */
.pf-role.former { color: var(--ash-dim); }
.pf-name-former { color: var(--ash); }
.pf-head .facts { margin-top: var(--s6); max-width: 34rem; }
.pf-bio {
  color: var(--ash);
  font-size: 1.0625rem;
  line-height: 1.75;
  max-width: 56ch;
  text-wrap: pretty;
}

.pf-plate { position: sticky; top: calc(var(--nav-h) + var(--s4)); }
.plate .facts { border-top-color: var(--rule-2); }
.plate .facts div { padding-inline: 0.9rem; }
#skin-canvas { border-radius: var(--r-sm); margin: var(--s4) auto var(--s2); cursor: grab; touch-action: none; }
#skin-canvas:active { cursor: grabbing; }
.skin-hint { text-align: center; color: var(--ash-dim); padding-bottom: var(--s4); }

.pf-body { max-width: 760px; }

/* Portfolio grid. Art is the content, so the frames stay out of its way:
   a hairline, a caption, and nothing else. */
.art-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--s5);
}
.art-item { display: flex; flex-direction: column; gap: 0.6rem; }
.art-item img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: var(--basalt);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 0.75rem;
  transition: border-color 0.2s var(--ease);
}
.art-item:hover img { border-color: var(--rule-2); }
.art-item figcaption {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash);
  line-height: 1.5;
}
.art-item figcaption span { display: block; color: var(--ash-dim); }
.pf-body .head { margin-bottom: var(--s5); }
.pf-prose { font-size: 1.0625rem; line-height: 1.75; }
