/* components.css: the library from the Design Check, stripped back.

   DECISIONS.md 2026-09-19: no box around everything, no uppercase monospace as
   the default voice, no status mark on every row, one idea per screen on a
   phone. Sections are separated by space and a heading. Monospace is for the
   opening titles and for numbers, never for a label or a sentence.

   No element on the site carries a style attribute, so the CSP needs no
   'unsafe-inline' for styles. Anything that would have been an inline width is
   drawn as SVG instead, where a width is an attribute and not a style.
   Mobile first: the desktop grids arrive at 900px. */

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
}

a { color: var(--red-ink); text-decoration: none }
a:hover { color: var(--ink); text-decoration: underline }
a:focus-visible, button:focus-visible, select:focus-visible, input:focus-visible,
textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 2px;
}

h1, h2, h3, p, ul, ol, pre { margin: 0 }
ul, ol { padding: 0; list-style: none }

.wrap { width: 100%; max-width: var(--content); margin: 0 auto; padding: 0 var(--gutter) }
/* The quiet voice: the body font, smaller and greyer. Not a second typeface. */
.meta { display: block; color: var(--muted); font-size: 14px; line-height: 1.5 }
.num { text-align: right; font-family: var(--data); font-variant-numeric: tabular-nums }
.note { color: var(--muted); font-size: 15px; line-height: 1.6 }
/* Anything a stranger typed. The cap at the source boundary stops the long
   ones; this stops a single unbroken token opening the page sideways. */
.note, .strap, .banner__text, .srv__note, .wcard__reason, .bestwar__moment,
.roster__title, .record__custom, .result__head, .moments li, .searchline,
.snippet, .empty, main p, main li, .h1 { overflow-wrap: anywhere }
.empty { color: var(--muted); font-size: 15px; padding: 16px 0 }
.ok { color: var(--ink) }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: -9999px; top: 0; background: var(--surface);
  padding: 12px 16px; z-index: 60;
}
.skip:focus { left: 0 }

/* ---------- Head matter ---------- */
.h1 {
  font-family: var(--display); font-weight: 900; line-height: 1.02;
  font-size: clamp(28px, 7vw, 42px); margin: 6px 0 4px;
  overflow-wrap: anywhere; hyphens: auto;
}
.h2 { font-family: var(--display); font-weight: 700; font-size: 21px; line-height: 1.15 }
.h3 { font-family: var(--display); font-weight: 700; font-size: 17px; line-height: 1.2 }
.kicker { color: var(--muted); font-size: 14px }
.searchline { color: var(--muted); font-size: 14px; line-height: 1.55; margin: 8px 0 }
.strap { font-size: 17px; line-height: 1.55; color: var(--ink); max-width: 36ch }

/* ---------- Header, breadcrumbs, footer ---------- */
/* The bar is the wordmark, the Menu button and Join in. The panel drops out of
   the bar full width, so no list of links ever scrolls sideways and none of
   them wraps out of reach (DECISIONS.md, 2026-09-19). */
.topbar { border-bottom: 1px solid var(--divider); position: relative }
.topbar__inner {
  min-height: var(--bar); display: flex; align-items: center;
  justify-content: space-between; gap: 10px;
}
.brand { display: inline-flex; align-items: baseline; gap: 6px; padding: 8px 0; color: var(--ink); flex: 0 0 auto }
.brand:hover { text-decoration: none }
.brand__28 { font-family: var(--display); font-weight: 900; font-size: 24px; color: var(--red-fill) }

.brand__name { font-family: var(--display); font-weight: 900; font-size: 20px; text-transform: uppercase; letter-spacing: 0.02em }

.menu { flex: 0 0 auto; order: 3 }
.topbar__right { margin-left: auto; order: 2 }
.topbar .btn { min-height: var(--tap); padding: 0 14px; font-size: 15px }
.menu__btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); min-width: var(--tap); padding: 0 12px;
  border: 1px solid var(--edge); color: var(--ink); font-size: 15px;
  cursor: pointer; list-style: none; user-select: none;
}
.menu__btn::-webkit-details-marker { display: none }
.menu__icon { width: 16px; height: 16px; fill: currentColor; flex: 0 0 auto }
.menu__panel {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 20;
  background: var(--surface); border-bottom: 1px solid var(--border);
  padding: 8px var(--gutter) 16px; display: flex; flex-direction: column; gap: 12px;
}
.menu__controls { display: flex; flex-wrap: wrap; gap: 12px 24px; padding-top: 8px; border-top: 1px solid var(--divider) }
.nav { display: flex; flex-direction: column; min-width: 0 }
.nav__link {
  display: flex; align-items: center; min-height: var(--tap); padding: 0 4px;
  color: var(--ink); font-size: 17px; border-bottom: 1px solid var(--divider);
}
.nav__link--on { color: var(--ink); border-left: 3px solid var(--red-fill); padding-left: 10px }

/* From 720px the panel is the bar: menu.js holds the details open, the button
   hides itself and the links lie down in a row. With modules off the button
   stays, and opening it lays the same row out under the wordmark. */
@media (min-width: 720px) {
  .menu { flex: 1 1 auto; min-width: 0; order: 0 }
  .topbar__right { margin-left: 0; order: 0 }
  .menu[open] > .menu__btn { display: none }
  .menu[open] > .menu__panel {
    position: static; z-index: auto; background: none; border: 0; padding: 0;
    flex-direction: row; align-items: center; gap: 0;
  }
  .menu[open] .nav { flex-direction: row; gap: 2px }
  .menu[open] .nav__link {
    min-height: var(--bar); padding: 0 10px; color: var(--muted); font-size: 16px;
    border-bottom: 2px solid transparent; border-left: 0; white-space: nowrap;
  }
  .menu[open] .nav__link--on { color: var(--ink); border-bottom-color: var(--red-fill); padding-left: 10px }
  .menu[open] .menu__controls { display: none }
}
.crumbs-strip { border-bottom: 1px solid var(--divider) }
.crumbs__list { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px 0 }
.crumbs__item { display: inline-flex; align-items: center; font-size: 14px; color: var(--muted) }
.crumbs__item + .crumbs__item::before { content: ">"; color: var(--muted2); margin-right: 4px }
.crumbs__item a {
  display: inline-flex; align-items: center; min-height: var(--tap); min-width: var(--tap);
  color: var(--muted);
}

main { display: block; padding: 8px 0 48px }
.foot { border-top: 1px solid var(--divider); margin-top: 40px }
.foot__inner { padding: 20px var(--gutter); display: flex; flex-direction: column; gap: 14px }
.foot__line { font-size: 14px; color: var(--muted2) }
.foot__nav { display: flex; flex-wrap: wrap; gap: 2px }
.foot__nav a {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 10px 0 0;
  margin-right: 10px; font-size: 15px; color: var(--muted);
}
.foot__controls { display: flex; flex-wrap: wrap; gap: 16px 28px }
/* One visible set of switches: the menu has them on a phone, the footer on a
   wide screen, so a reader never meets the same control twice. */
@media (max-width: 719px) {
  .foot__controls { display: none }
}
.foot__replay { align-self: flex-start }
.switch { display: flex; align-items: center; flex-wrap: wrap; gap: 4px }
.switch__label { color: var(--muted2); font-size: 14px; margin-right: 4px }
/* A short label ("Yes") is still a 44px target: the minimum is on the width as
   well as the height, or the button shrinks to fit the word. */
.switch__btn {
  min-height: var(--tap); min-width: var(--tap); padding: 0 10px;
  border: 1px solid var(--edge);
  background: transparent; color: var(--muted); font-family: var(--body);
  font-size: 15px; cursor: pointer;
}
.switch__btn[aria-pressed="true"] { background: var(--raised); color: var(--ink) }

/* ---------- Buttons, fields ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 18px; border: 1px solid var(--red-deep);
  background: var(--red-fill); color: var(--red-fill-ink); font-family: var(--body);
  font-weight: 500; font-size: 16px; cursor: pointer;
}
.btn:hover { text-decoration: none; color: var(--red-fill-ink) }
.btn--quiet { background: transparent; border-color: var(--edge); color: var(--ink) }
.btn--warn { background: transparent; border-color: var(--amber-border); color: var(--amber-ink) }
.btn--big { min-height: 54px; padding: 0 24px; font-size: 17px }
.field { display: flex; flex-direction: column; gap: 4px; min-width: 150px }
.field__label { color: var(--muted); font-size: 14px }
.select, .input {
  min-height: var(--tap); padding: 0 10px; background: var(--surface);
  border: 1px solid var(--edge); color: var(--ink); font-family: var(--body); font-size: 16px;
}
.input--area { min-height: 96px; padding: 10px; line-height: 1.5 }
.check { display: flex; align-items: center; gap: 8px; min-height: var(--tap) }
.check input { width: 24px; height: 24px }

/* ---------- Flags, chips, pills, banners ---------- */
/* A flag is drawn only when the state is NOT the ordinary one. A confirmed row
   carries nothing, because a mark on every line is wallpaper. */
.flag {
  display: inline-flex; align-items: center; color: var(--muted);
  font-size: 13px; white-space: nowrap;
}
.flag--warn { color: var(--amber-ink) }
.flag--ok, .flag--you { color: var(--ink) }
.chip { display: inline-flex; align-items: center; color: var(--muted); font-size: 14px }
.chips { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 }

.pill {
  display: inline-flex; align-items: center; gap: 7px; min-height: 24px;
  font-size: 14px; white-space: nowrap; color: var(--muted);
}
.pill__dot { width: 8px; height: 8px; background: currentColor; flex: 0 0 auto }
.pill--live { color: var(--ink); text-shadow: var(--glow) }
.pill--live .pill__dot { animation: livePulse 1.4s steps(1) infinite }
.pill--stale, .pill--provisional { color: var(--amber-ink) }
.pill--stale .pill__dot { background: transparent; border: 1.5px solid currentColor }
.pill--offline { color: var(--muted) }
.pill--offline .pill__dot { background: var(--edge) }
.pill--rejected { color: var(--red-ink) }

.banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  padding: 12px 0 12px 14px; margin: 12px 0; border-left: 3px solid var(--border);
}
.banner__text { flex: 1 1 200px; font-size: 15px; line-height: 1.5 }
.banner--stale { border-left-color: var(--amber-border); color: var(--amber-text) }
.banner--provisional { border-left-color: var(--demo-border) }

/* ---------- Rank and honours ---------- */
.rank { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); font-size: 14px }
.rank--compact { font-size: 13px }
.rank__short { color: var(--ink) }
.rank--muted .rank__short { color: var(--muted) }
.ranktitle { display: inline-flex; align-items: center; gap: 6px; color: var(--amber-ink) }
.ranktitle__name { color: var(--ink); font-size: 15px }
.ranktitle--muted, .ranktitle--muted .ranktitle__name { color: var(--muted) }
.rank-tile {
  display: flex; align-items: center; gap: 12px; color: var(--amber-ink); min-width: 120px;
}
.rank-tile__text { display: flex; flex-direction: column; gap: 1px }
.rank-tile__label { color: var(--muted); font-size: 14px }
.rank-tile__name { font-family: var(--display); font-weight: 700; font-size: 22px; color: var(--ink) }

.honour { display: flex; align-items: center; gap: 10px; color: var(--amber-ink) }
.honour--unearned { color: var(--muted2) }
.honour__hit { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; flex: 0 0 auto }
.honour-row { display: flex; flex-wrap: wrap; gap: 4px }
.honour-row__item { color: var(--amber-ink) }

/* ---------- Faction marks ---------- */
.fmark {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--data); font-weight: 700; color: var(--lonestar-ink); flex: 0 0 auto;
}
.fmark--14 { width: 16px; height: 16px; font-size: 9px }
.fmark--16 { width: 16px; height: 16px; font-size: 9px }
.fmark--20 { width: 20px; height: 20px; font-size: 10px }
.fmark--22 { width: 22px; height: 22px; font-size: 11px }
.fmark--28 { width: 28px; height: 28px; font-size: 13px }
.fmark--lonestar { background: var(--lonestar); color: var(--lonestar-ink) }
.fmark--valkyra { background: var(--valkyra); color: var(--valkyra-ink) }
.fmark--manticore { background: var(--manticore); color: var(--manticore-ink) }
.fmark--triangle { clip-path: polygon(50% 0, 100% 100%, 0 100%); align-items: flex-end }
.fmark--diamond { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%) }
.fmark--circle { border-radius: 50% }
.fchip--large {
  display: inline-flex; align-items: center; gap: 8px; min-height: 28px;
  font-family: var(--display); font-weight: 700; font-size: 17px;
}
.fbar { display: block; width: 100%; height: 6px; background: var(--raised) }
.fbar--muted { opacity: 0.5 }
.sbar { display: block; width: 100%; height: 8px; background: var(--raised) }
.fbar__lonestar { fill: var(--bar-1) }
.fbar__valkyra { fill: var(--bar-2) }
.fbar__manticore { fill: var(--bar-3) }
.fbar__turnout { fill: var(--ink) }

/* ---------- Sections and grids ---------- */
/* A band is a section: air above it and a heading, and no border anywhere. */
.band { margin: 28px 0 }
.bands { align-items: start }
.grid { display: grid; gap: 14px; grid-template-columns: 1fr }
.shead { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 10px }
.shead__link {
  display: inline-flex; align-items: center; min-height: var(--tap); min-width: var(--tap);
  font-size: 15px;
}
.strip { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 32px; color: var(--muted2) }
.hero { padding: 4px 0 0 }
.hero__cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px }
.club__date { font-family: var(--display); font-weight: 900; font-size: 26px }
.club__count { margin: 10px 0 }
.club__big { font-family: var(--display); font-weight: 900; font-size: 30px; color: var(--red-ink) }

/* ---------- Cards that are still cards ---------- */
/* A server, a clan and a war are separate objects in a grid, so each keeps one
   hairline to say where it ends. Nothing inside them is boxed again. */
.scard { display: flex; flex-direction: column; gap: 8px; padding: 12px 0; color: var(--ink) }
.scard + .scard { border-top: 1px solid var(--divider) }
.scard:hover { text-decoration: none }
.scard__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap }
.scard__name { font-family: var(--display); font-weight: 700; font-size: 20px; line-height: 1.1 }
.scard__meta { color: var(--muted); margin-top: 2px }

.ccard { display: flex; gap: 12px; padding: 12px 0; color: var(--ink) }
.ccard + .ccard { border-top: 1px solid var(--divider) }
.ccard__name { font-family: var(--display); font-weight: 900; font-size: 19px; line-height: 1.1 }
.ccard__meta { color: var(--muted) }
.wcard { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; color: var(--ink) }
.wcard + .wcard { border-top: 1px solid var(--divider) }
.wcard__top { display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap }
.wcard__head { font-family: var(--display); font-weight: 700; font-size: 18px }
.wcard__meta { color: var(--muted) }
.wcard__scores { display: flex; gap: 12px; flex-wrap: wrap }
.wcard__score { display: inline-flex; align-items: center; gap: 4px }
.wcard__reason { font-size: 14px; color: var(--muted) }

/* ---------- Ladder rows ---------- */
.ladder { display: block }
/* The rowgroups exist for assistive technology; they must not become a box. */
.ladder [role="rowgroup"] { display: contents }
.ladder--desktop { display: none }
.ladder--mobile.grid { display: grid }
.lrow { display: grid; gap: 10px; padding: 8px 0; align-items: center; border-bottom: 1px solid var(--divider) }
.lrow--head { color: var(--muted); font-size: 14px; border-bottom-color: var(--border) }
.lrow__pos { font-family: var(--data); font-weight: 700; font-size: 15px; color: var(--muted) }
.lrow--hidden .lrow__pos { color: var(--muted2) }
.lrow__name { min-width: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap }
.lrow__score { font-family: var(--data); font-weight: 700; font-size: 17px; color: var(--ink) }
.lrow--hidden .lrow__score { color: var(--muted) }
.lrow--you { box-shadow: inset 3px 0 0 var(--ink) }
/* A name is a link and a link is a target: 44px tall even though the type is
   16px, which is the rule the design states for a 16px glyph. */
.name {
  display: inline-flex; align-items: center; min-height: var(--tap); max-width: 100%;
  font-weight: 500; font-size: 16px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.name--hidden { color: var(--muted); font-style: italic }

/* On a phone the whole row is the target and it carries four things: the
   place, the name, the rank in small text and one number. */
.mrow {
  display: grid; grid-template-columns: 26px minmax(0, 1fr) auto; gap: 12px;
  align-items: center; padding: 6px 0; min-height: 60px;
  border-bottom: 1px solid var(--divider); color: var(--ink);
}
.mrow:hover { text-decoration: none }
.mrow--you { box-shadow: inset 3px 0 0 var(--ink) }
.mrow__pos { font-family: var(--data); font-weight: 700; color: var(--muted) }
.mrow__body { min-width: 0; display: block }
.mrow__top { display: flex; align-items: center; gap: 8px; min-width: 0 }
.mrow__top .name { flex: 0 1 auto; min-width: 0; min-height: 0 }
.mrow__tag { flex: 0 0 auto; color: var(--muted); font-size: 14px }
.mrow__meta { display: flex; align-items: center; gap: 4px 12px; flex-wrap: wrap; color: var(--muted); font-size: 14px }
.mrow__rank { color: var(--muted) }
.mrow__score { font-family: var(--data); font-weight: 700; font-size: 18px }

.crow {
  display: grid; grid-template-columns: 26px auto minmax(0, 1fr) auto; gap: 10px;
  align-items: center; padding: 6px 0; min-height: 52px;
  border-bottom: 1px solid var(--divider); color: var(--ink);
}
.crow:hover { text-decoration: none }
.crow__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
/* Only where the whole row is the link: a mini ladder on a server page
   still has its own name link, and that one is a 44px target. */
a.crow .crow__name .name { min-height: 0 }
.crow__flag { grid-column: 3 / -1 }
.srow { display: grid; grid-template-columns: 22px minmax(0, 1fr) 2fr auto; gap: 10px; align-items: center; padding: 8px 0 }
.srow__name {
  font-size: 16px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.srow__bar { min-width: 60px }
.srow__won { display: none; color: var(--muted); white-space: nowrap }

.tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: 12px 0 }
.tabs__tab {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 12px;
  color: var(--muted); font-size: 16px; border-bottom: 2px solid transparent;
}
.tabs__tab--on { color: var(--ink); border-bottom-color: var(--red-fill) }
.filters-box { margin: 10px 0 }
.filters-box__head {
  min-height: var(--tap); padding: 10px 0; color: var(--muted);
  font-size: 15px; cursor: pointer;
}
.filters { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin: 8px 0 16px }
.seg { display: flex; flex-wrap: wrap; gap: 4px }
.seg__item {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 12px;
  border: 1px solid var(--edge); color: var(--muted); font-size: 15px;
}
.seg__item--on { background: var(--raised); color: var(--ink) }
.pager { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 0; flex-wrap: wrap }
.ladder-layout { display: grid; gap: 16px; grid-template-columns: 1fr }
.side { min-width: 0 }

/* ---------- Record, clan, server, war ---------- */
.record { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-start; padding: 4px 0 }
.record__id { min-width: 0; flex: 1 1 260px }
.record__titles { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin: 6px 0 }
.record__clan { display: inline-flex; align-items: center; gap: 8px; color: var(--ink) }
.record__custom { font-style: italic; color: var(--muted) }
.record__meta { display: flex; flex-wrap: wrap; gap: 4px 16px; color: var(--muted) }
.record__plays { display: inline-flex; align-items: center; gap: 6px }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 18px 24px; margin: 20px 0 }
.stat__label { color: var(--muted); font-size: 14px }
.stat__value { font-family: var(--display); font-weight: 900; font-size: 32px; line-height: 1 }
.stat__note { font-size: 13px }
.bestwars { display: flex; flex-direction: column; gap: 14px }
.bestwar { border-bottom: 1px solid var(--divider); padding-bottom: 12px }
.bestwar__moment { font-size: 16px }
.warline { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; color: var(--muted); margin-top: 4px }
.warline__score { display: inline-flex; align-items: center; gap: 4px }
.result a, .warline a { color: var(--red-ink) }
.caps { display: grid; grid-template-columns: repeat(14, 1fr); gap: 4px; max-width: 420px }
.cap { height: 16px; border: 1px solid var(--edge); background: var(--bg) }
.cap--on { background: var(--amber-ink); border-color: var(--amber-chip-border) }
.cap--today { outline: 1px solid var(--ink) }
.moments { display: flex; flex-direction: column; gap: 8px; font-size: 16px }

.clanhead { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-start; padding: 4px 0 }
.clanhead__tag { color: var(--muted) }
.roster { display: flex; flex-direction: column }
.roster__row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 4px 10px;
  align-items: center; padding: 6px 0; border-bottom: 1px solid var(--divider);
}
.roster__row > :nth-child(3), .roster__row > :nth-child(4) { grid-column: 1 / -1 }
.roster__row > :nth-child(5) { grid-column: 3; grid-row: 1; text-align: right }
.roster__row > :nth-child(6) { display: none }
.roster__name { min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap }
.roster__title { font-style: italic; color: var(--muted); font-size: 14px }
.results { display: flex; flex-direction: column; gap: 12px }
.result { display: grid; gap: 4px; padding-bottom: 12px; border-bottom: 1px solid var(--divider) }
.result__cash { color: var(--ink) }
.roster--head { display: none }
.result__head { font-weight: 500 }
.result__points { color: var(--ink) }
.bhonours { display: flex; flex-direction: column; gap: 8px }
.bhonour__name { font-family: var(--display); font-weight: 700 }
.turnouts { display: flex; flex-direction: column; gap: 10px }
.turnout { display: grid; grid-template-columns: 70px minmax(0, 1fr) 56px; gap: 10px; align-items: center }

.serverhead { padding: 4px 0 }
.serverhead__pills { display: flex; gap: 6px 16px; flex-wrap: wrap; align-items: center }
.asof { padding: 8px 0 }
.asof__head { color: var(--muted); font-size: 14px }
.asof__count { font-family: var(--display); font-weight: 900; font-size: 40px; line-height: 1 }
.asof__slots { font-size: 20px; color: var(--muted) }
.asof__map { color: var(--muted); font-size: 14px }
.splitline { display: flex; gap: 4px 14px; flex-wrap: wrap; color: var(--muted) }
.history { display: flex; flex-direction: column }
/* .history sets a display of its own, so the desktop switch has to be said
   again with it, or a phone gets the cards and the grid. */
.history.ladder--desktop { display: none }
.history__row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; padding: 10px 0; border-bottom: 1px solid var(--divider) }
.history__scores { display: flex; gap: 12px; flex-wrap: wrap }

.steps { display: flex; flex-direction: column; gap: 28px }
.step { display: flex; flex-direction: column; gap: 10px; align-items: flex-start }
.step__number { color: var(--muted2) }
.plan { border-top: 1px solid var(--divider); padding: 14px 0; display: flex; flex-direction: column; gap: 8px; align-items: flex-start }
.plan__price { font-family: var(--display); font-weight: 900; font-size: 26px }
.plan__lines { display: flex; flex-direction: column; gap: 4px; color: var(--muted); font-size: 15px }
.snippet { overflow-x: auto; background: var(--surface); padding: 10px; font-family: var(--data); font-size: 12px }
.report { display: flex; flex-direction: column; gap: 12px; align-items: flex-start }
.notice { padding: 40px 0; display: flex; flex-direction: column; gap: 10px; align-items: flex-start }

/* Links that sit on their own in a row, a cell or a meta line are targets. */
.lrow a, .crow, .mrow, .srow a, .roster__row a, .history__row a, .warline a,
.result a, .record__meta a, .record__clan, .strip a, .splitline a, .turnout a {
  display: inline-flex; align-items: center; min-height: var(--tap); min-width: var(--tap);
}
.crow, .mrow { display: grid }

/* ---------- For anyone who missed all of this ---------- */
/* The strip and the explainers are always in the markup and shown only when
   the reader asked for them, so a page cached for everyone still works. */
.oldschool, .explain { display: none }
:root[data-crew="new"] .oldschool { display: block; margin: 32px 0 }
:root[data-crew="new"] .explain { display: flex }
.oldschool__cards { margin-top: 12px }
.oldcard { border-left: 3px solid var(--border); padding: 2px 0 2px 12px }
.oldcard p { color: var(--muted); font-size: 15px; margin-top: 2px }
.explain {
  align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0;
  border-left: 3px solid var(--edge); padding: 4px 0 4px 12px;
}
.explain__text { color: var(--muted); font-size: 15px; flex: 1 1 200px }
.explain__close {
  min-height: var(--tap); padding: 0 12px; border: 1px solid var(--edge);
  background: transparent; color: var(--ink); font-family: var(--body);
  font-size: 15px; cursor: pointer;
}

/* ---------- The intro strip, and how it works ---------- */
/* Two lines at the top of a page that needs one: what it is, what to do.
   Always served, taken away by intro.js only once the reader says so. */
.intro {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 4px 16px; margin: 12px 0 4px; padding: 10px 0 10px 12px;
  border-left: 3px solid var(--red-fill);
}
.intro__lines { min-width: 0; flex: 1 1 240px }
.intro__what { font-size: 16px; line-height: 1.5 }
.intro__todo { color: var(--muted); font-size: 15px; line-height: 1.5 }
.intro__links { display: flex; align-items: center; gap: 4px 10px; flex: 0 0 auto }
.intro__more {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 4px;
  font-size: 15px;
}
.intro__close {
  min-height: var(--tap); padding: 0 12px; border: 1px solid var(--edge);
  background: transparent; color: var(--muted); font-family: var(--body);
  font-size: 15px; cursor: pointer;
}
.intro__close:hover { color: var(--ink) }

/* One scene per screen on a phone: a heading, a sentence, the thing itself,
   and the rest folded away behind one control. */
.scenes { display: flex; flex-direction: column; gap: 36px; margin: 20px 0 8px }
.scene { display: flex; flex-direction: column; gap: 10px; min-width: 0 }
.scene__line { font-size: 18px; line-height: 1.5; max-width: 40ch }
.scene__show { min-width: 0 }
.scene__caption { color: var(--muted2) }
.scene__art { position: relative; overflow: hidden; background: var(--hero-bg); min-height: 200px }
.scene__art .art__img, .scene__art .shapes { display: block; width: 100%; height: 100%; object-fit: cover }
.scene__wash {
  position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(180deg, rgba(15, 13, 12, 0) 40%, rgba(15, 13, 12, 0.55) 100%);
}
.more { border-top: 1px solid var(--divider) }
.more__head {
  display: flex; align-items: center; min-height: var(--tap);
  color: var(--red-ink); font-size: 15px; cursor: pointer;
}
.more__body { display: flex; flex-direction: column; gap: 8px; padding-bottom: 10px; max-width: 56ch }
.more__body p { color: var(--muted); font-size: 16px; line-height: 1.6 }

.clubcard { position: relative; overflow: hidden; min-height: 260px; display: flex; align-items: flex-end }
.clubcard__media { position: absolute; inset: 0; background: var(--hero-bg) }
.clubcard__media .art__img, .clubcard__media .shapes {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
.clubcard__body { position: relative; z-index: 3; width: 100%; padding: 20px 16px 16px; color: var(--hero-ink) }
.clubcard__when { font-family: var(--display); font-weight: 700; font-size: 20px }
.clubcard__where { color: var(--hero-muted); font-size: 15px }
.clubcard .bignum__value { color: var(--hero-ink) }
.clubcard .bignum__label { color: var(--hero-muted) }

.mission__line { max-width: 60ch }

.doors {
  position: fixed; inset: 0; z-index: 55; background: var(--bg); color: var(--ink);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.doors[hidden] { display: none }
.doors__inner { width: 100%; max-width: 420px; display: flex; flex-direction: column; gap: 14px }
.doors__head { font-family: var(--display); font-weight: 900; font-size: 26px }
.doors__line { font-size: 18px; line-height: 1.5 }
.doors__note { color: var(--muted); font-size: 15px }

/* ---------- The opening titles ---------- */
.intercept {
  position: fixed; inset: 0; z-index: 50; background: #161311; color: #ECE7DF;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  cursor: pointer; overflow: hidden; transition: opacity 0.42s ease-out;
}
.intercept[hidden] { display: none }
/* On the way out it stops taking input at once, even while it fades. */
.intercept--out { opacity: 0; pointer-events: none }
.intercept__inner { width: 100%; max-width: 640px; display: flex; flex-direction: column; gap: 18px }
.mono { font-family: var(--data); font-size: 12px; letter-spacing: 0.08em }
.intercept__skip { position: absolute; top: 14px; right: 14px }
.intercept__counter { position: absolute; top: 24px; left: 16px; color: #9A9184; letter-spacing: 0.25em }
.intercept__kicker { color: #FF8A84; letter-spacing: 0.3em; text-transform: uppercase }
.intercept__stage { min-height: 150px; font-family: var(--data); font-size: 15px; line-height: 2; letter-spacing: 0.1em }
.intercept__line { min-height: 30px }
.intercept__caret { display: inline-block; width: 8px; height: 16px; background: #E5484D; margin-left: 3px; animation: caretBlink 0.7s steps(1) infinite }
.intercept__sub { color: #5FD0BF; letter-spacing: 0.14em; margin-top: 10px; animation: fadeUp 0.4s ease-out both }
.intercept__stamp { font-family: var(--display); font-weight: 900; text-transform: uppercase; line-height: 0.86; animation: stampIn 0.38s cubic-bezier(0.2, 0.9, 0.3, 1) both }
.intercept__big { font-size: clamp(64px, 22vw, 128px); color: #E5484D; line-height: 0.85 }
.intercept__mid { font-size: clamp(30px, 10vw, 60px) }
.intercept__title { display: inline-flex; align-items: baseline; gap: 10px }
.intercept__prompt { position: absolute; bottom: 24px; left: 0; right: 0; text-align: center; color: #FF8A84; letter-spacing: 0.25em; text-transform: uppercase }
.widget { padding: 0 }
.widget__card { display: flex; flex-direction: column; gap: 6px; padding: 10px; color: var(--ink) }
.widget__name { font-family: var(--display); font-weight: 700; font-size: 18px }
.widget__foot { color: var(--muted) }

@media (prefers-reduced-motion: reduce) {
  .pill--live .pill__dot, .intercept__caret, .intercept__stamp, .intercept__sub {
    animation: none;
  }
  * { transition: none !important }
}

/* ---------- Desktop ---------- */
@media (min-width: 700px) {
  .wrap { padding: 0 var(--gutter-wide) }
  .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)) }
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)) }
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)) }
  .history__row { grid-template-columns: 92px minmax(0, 1fr) 150px 110px; align-items: center }
  .roster__row { grid-template-columns: 96px minmax(0, 1fr) 170px minmax(0, 1fr) 70px 70px }
  .roster__row > :nth-child(3), .roster__row > :nth-child(4),
  .roster__row > :nth-child(5), .roster__row > :nth-child(6) { grid-column: auto; grid-row: auto }
  .srow__won { display: block }
  /* The 260px sidebar has no room for the wars line or a second column. */
  .side .srow { grid-template-columns: 22px minmax(0, 1fr) auto }
  .side .srow__bar, .side .srow__won { display: none }
  .result { grid-template-columns: 24px minmax(0, 1fr) 90px; align-items: center }
  /* 36ch is the measure for a phone; it breaks one word onto a line here. */
  .strap { max-width: 52ch }
  .scene__art, .clubcard { max-width: 560px }
}

@media (min-width: 900px) {
  .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)) }
  .grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)) }
  /* The war line is a row of its own, so an id, a server and three scores do
     not stack one word per line beside the headline. */
  .result { grid-template-columns: 24px minmax(0, 1fr) 90px; column-gap: 12px }
  .result .warline { grid-column: 2 / -1; flex-wrap: nowrap; white-space: nowrap; overflow: hidden }
  .roster--head { display: grid; grid-template-columns: 96px minmax(0, 1fr) 170px minmax(0, 1fr) 70px 70px; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); color: var(--muted); font-size: 14px }
  .ladder--desktop { display: block }
  .history.ladder--desktop { display: flex }
  .ladder--mobile, .ladder--mobile.grid { display: none }
  .lrow { grid-template-columns: 44px minmax(0, 1fr) 150px 64px 60px 90px 96px 120px; padding: 0 4px; min-height: 48px }
  .ladder-layout { grid-template-columns: minmax(0, 1fr) 260px }
  .side .lrow { grid-template-columns: 40px minmax(0, 1fr) 90px 44px 44px 56px 64px 90px }
  .h1 { font-size: clamp(34px, 3.4vw, 46px) }
}

/* A roster line names its own number on a phone, where there is no column
   header to hang it on. The header carries it from 700px up. */
.roster__unit { color: var(--muted); font-size: 13px }
@media (min-width: 700px) {
  .roster__row > :nth-child(6) { display: block; text-align: right }
  .roster__unit { display: none }
}
