/*
 * VANTAGE — field control audience display.
 *
 * The world is the Tournament Manager screen projected in every competition gym: scale is the
 * message, blocks not cards, hairlines not shadows, everything tabular, status is a state.
 * Specifically the RANKINGS screen, never the match screen — the match screen's red/blue alliance
 * blocks would turn red into an encoding of alliance, and red here is a brand accent with exactly
 * three jobs: live, primary action, rank 1.
 *
 * See DESIGN.md at the project root. Two layers live here: the document layer (/docs/*, /privacy)
 * and the display layer under `body.display`, scoped so it cannot leak into a doc.
 */

:root {
  color-scheme: dark;

  --ground: #050507;
  --panel: #0b0b0e;
  --panel-hi: #101015;
  --rule: #1e1e24;
  --rule-strong: #2c2c35;

  --ink-display: #ededf1;
  --ink-strong: #d2d2d9;
  --ink: #a6a6ae;
  --label: #8a8a93;
  --label-dim: #787880;

  --accent: #e11d23;
  --accent-hot: #f4363c;

  /* Aliases kept so the document layer's existing rules keep resolving. */
  --bg: var(--ground);
  --bright: var(--ink-display);
  --white: #fff;
  --dim: var(--label);
  --line: var(--rule);

  --hair: 1px;
  --sp-xs: 4px;
  --sp-sm: 8px;
  --sp-md: 16px;
  --sp-lg: 24px;
  --sp-xl: 40px;
  --sp-xxl: 64px;
  --sp-band: 96px;

  --face: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding: 4rem 1.5rem 6rem;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--face);
  font-size: 0.95rem;
  font-weight: 400;
  line-height: 1.7;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* Browser surfaces belong to the design too. */
::selection { background: var(--accent); color: #fff; }
:focus-visible { outline: 2px solid var(--ink-display); outline-offset: 2px; }
a { text-underline-offset: 0.22em; text-decoration-thickness: 1px; }
* { scrollbar-color: var(--rule-strong) var(--ground); scrollbar-width: thin; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: var(--ground); }
*::-webkit-scrollbar-thumb { background: var(--rule-strong); border: 3px solid var(--ground); }
*::-webkit-scrollbar-thumb:hover { background: #3c3c47; }

/* ======================================================================== DOCUMENT LAYER */

main { max-width: 46rem; margin: 0 auto; }

h1 {
  font-family: var(--face);
  font-size: 2.1rem;
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: -0.02em;
  color: var(--white);
  margin: 0 0 0.4rem;
}

h2 {
  font-family: var(--face);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--label);
  margin: 3.2rem 0 0.9rem;
}

h3 {
  font-family: var(--face);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-display);
  margin: 2rem 0 0.4rem;
}

.tag { color: var(--label); font-size: 0.68rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; margin: 0 0 2.5rem; }
.updated { color: var(--label); font-size: 0.8rem; margin: 0 0 2rem; }

a { color: var(--white); }
ul { padding-left: 1.1rem; }
li { margin: 0.5rem 0; }
strong { color: var(--ink-display); font-weight: 600; }
hr { border: none; border-top: var(--hair) solid var(--rule); margin: 3.5rem 0; }
.foot { color: var(--label); font-size: 0.82rem; }

code, pre { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.84rem; }
pre {
  background: var(--panel);
  border: var(--hair) solid var(--rule);
  padding: 1rem 1.1rem;
  overflow-x: auto;
  color: #c8c8cf;
  line-height: 1.6;
}
code { color: #d8d8de; }

.scroll { overflow-x: auto; }

table { border-collapse: collapse; width: 100%; font-size: 0.88rem; margin: 0.5rem 0; }
th, td { text-align: left; padding: 0.5rem 0.9rem 0.5rem 0; border-bottom: var(--hair) solid var(--rule); white-space: nowrap; }
th { color: var(--label); font-weight: 600; font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; }
td.n { font-variant-numeric: tabular-nums; }
.win { color: var(--white); }

.note {
  border-left: var(--hair) solid var(--rule-strong);
  padding: 0.2rem 0 0.2rem 1.1rem;
  margin: 1.4rem 0;
  color: #96969c;
}

.links { margin-top: 2.5rem; display: flex; gap: 1.6rem; flex-wrap: wrap; font-size: 0.9rem; }

.docnav {
  display: flex; gap: 1.4rem; flex-wrap: wrap;
  margin: 0 0 2.5rem; padding: 0 0 1.2rem;
  border-bottom: var(--hair) solid var(--rule);
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
}
.docnav a { color: var(--label); text-decoration: none; }
.docnav a:hover { color: var(--ink); }
.docnav a[aria-current="page"] { color: var(--white); }
.docnav span { color: var(--label-dim); }

.doclist { list-style: none; padding: 0; }
.doclist li { margin: 0 0 1.6rem; }
.doclist a { font-size: 1.05rem; font-weight: 600; text-decoration: none; }
.doclist p { margin: 0.2rem 0 0; color: var(--label); font-size: 0.9rem; }

math { font-size: 1.05rem; display: block; margin: 1.1rem 0; color: var(--ink-display); }
math[display="inline"] { display: inline; margin: 0; font-size: 1em; }
.where { margin: -0.4rem 0 1.2rem; font-size: 0.86rem; color: var(--label); }
.where dt { display: inline; font-variant-numeric: tabular-nums; color: var(--ink); }
.where dd { display: inline; margin: 0 0 0 0.4rem; }
.where div { margin: 0.15rem 0; }

/* `TM` only: the registered symbol is reserved for a federally registered mark. */
.tm { font-size: 0.42em; vertical-align: super; letter-spacing: 0; margin-left: 0.1em; }


/* ========================================================================= DISPLAY LAYER */

body.display { padding: 0; overflow-x: hidden; }
body.display main { max-width: none; margin: 0; }
.display h1, .display h2, .display h3 { margin: 0; }

/* Full bleed: a projected display runs to the edges, it is not a centred column. */
.bleed { padding-inline: var(--sp-lg); }
@media (min-width: 900px) { .bleed { padding-inline: var(--sp-xl); } }

.label {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--label);
  font-variant-numeric: tabular-nums;
}

.statement {
  font-size: clamp(1.6rem, 3.2vw, 2.5rem);
  font-weight: 600;
  font-stretch: 90%;
  line-height: 1.08;
  letter-spacing: -0.025em;
  color: var(--ink-display);
  text-wrap: balance;
  max-width: 18ch;
}

.prose { max-width: 62ch; color: var(--ink); line-height: 1.62; }

/* ---- Header band ---------------------------------------------------------------------- */

.band-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 80;
  height: 46px;
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  background: var(--ground);
  border-bottom: var(--hair) solid var(--rule);
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-display);
  text-decoration: none;
  flex-shrink: 0;
}
.mark svg { width: 14px; height: 14px; display: block; color: var(--accent); }

.season { color: var(--label-dim); flex-shrink: 0; }
@media (max-width: 800px) { .season { display: none; } }

.head-nav { margin-left: auto; display: flex; align-items: center; gap: var(--sp-lg); min-width: 0; }
.head-nav a { color: var(--label); text-decoration: none; transition: color 0.18s var(--ease); }
.head-nav a:hover { color: var(--ink-display); }

/* The text links plus the action overran the bar on a phone and clipped the action itself, which
   is the one thing in the header that must always be whole. Below 640 the action is the nav. */
@media (max-width: 640px) {
  .head-nav a:not(.act) { display: none; }
  .head-nav { gap: var(--sp-md); }
}

/* ---- Actions -------------------------------------------------------------------------- */

.act {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 13px 22px;
  border: var(--hair) solid transparent;
  border-radius: 0;
  font-family: var(--face);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease), color 0.18s var(--ease);
}
.act svg { width: 14px; height: 14px; flex-shrink: 0; }
.act-primary { background: var(--accent); color: #fff; }
.act-primary:hover { background: var(--accent-hot); }
.act-secondary { color: var(--ink-strong); border-color: var(--rule-strong); }
.act-secondary:hover { border-color: var(--ink); color: var(--ink-display); }
.act-sm { padding: 9px 14px; }

/* ---- Viewport one: the display -------------------------------------------------------- */

.screen {
  min-height: 100dvh;
  padding-top: 46px;
  display: flex;
  flex-direction: column;
}

.strip {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  min-height: 42px;
  padding-block: var(--sp-sm);
  border-bottom: var(--hair) solid var(--rule);
  flex-wrap: wrap;
}

.metric {
  display: flex;
  gap: var(--sp-md);
  background: none;
  border: 0;
  padding: 0;
}
.metric button {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 3px 0;
  margin: 0;
  cursor: pointer;
  font-family: var(--face);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--label);
  transition: color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.metric button:hover { color: var(--ink); }
.metric button[aria-selected="true"] { color: var(--ink-display); border-bottom-color: var(--ink-display); }

.strip-right { margin-left: auto; display: flex; align-items: center; gap: var(--sp-md); flex-wrap: wrap; }

/* A square, not a circle: circles are a UI habit, this world is orthogonal. */
.live {
  width: 6px; height: 6px;
  background: var(--label-dim);
  flex-shrink: 0;
  display: inline-block;
}
.live.on { background: var(--accent); animation: beat 1s steps(1, end) infinite; }
@keyframes beat { 0%, 60% { opacity: 1; } 61%, 100% { opacity: 0.25; } }

/* ---- The board ------------------------------------------------------------------------ */

.board { flex: 1; display: flex; flex-direction: column; list-style: none; margin: 0; padding: 0; }

.brow {
  flex: 1;
  min-height: 62px;
  margin: 0;
  display: flex;
  border-bottom: var(--hair) solid var(--rule);
}
.blink {
  flex: 1;
  display: grid;
  grid-template-columns: 3.2ch 1fr auto;
  align-items: center;
  gap: 2px var(--sp-md);
  padding-block: var(--sp-md);
  text-decoration: none;
  color: inherit;
  transition: background 0.18s var(--ease);
}
a.blink:hover { background: var(--panel); }
a.blink:focus-visible { outline: 2px solid var(--accent-hot); outline-offset: -2px; }

.brk {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--label-dim);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.brow.lead .brk { color: var(--accent-hot); }

.bteam,
.bval {
  font-size: clamp(1.7rem, 5vw, 3.4rem);
  font-weight: 600;
  font-stretch: 84%;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink-display);
  font-variant-numeric: tabular-nums;
}
.bval { text-align: right; }
.brow.lead .bteam, .brow.lead .bval { color: #fff; }

.bmeta {
  grid-column: 2 / -1;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--label-dim);
  margin-top: 2px;
}

/* Rows past the third are height the small screen does not have. */
@media (max-width: 720px) { .brow:nth-child(n + 4) { display: none; } }

.brow.skel .bteam, .brow.skel .bval { color: transparent; background: var(--panel-hi); }
.brow.skel .bteam { width: 5.5ch; }
.brow.skel .bval { width: 4ch; }

/* ---- The offer, bottom of the first viewport ------------------------------------------ */

.offer {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-xl);
  flex-wrap: wrap;
  padding-block: var(--sp-lg) var(--sp-xl);
  border-top: var(--hair) solid var(--rule-strong);
}
.offer-copy { max-width: 46ch; }
.offer .prose { margin: var(--sp-md) 0 0; font-size: 0.92rem; }
.offer-acts { display: flex; gap: var(--sp-sm); flex-wrap: wrap; }

/* ---- Sections ------------------------------------------------------------------------- */

.section { border-top: var(--hair) solid var(--rule); padding-block: var(--sp-band); }
.section-head { display: flex; align-items: baseline; gap: var(--sp-md); margin-bottom: var(--sp-xl); flex-wrap: wrap; }
.section-head h2 {
  font-size: clamp(1.5rem, 3vw, 2.2rem);
  font-weight: 700;
  font-stretch: 86%;
  letter-spacing: -0.025em;
  color: var(--ink-display);
  text-transform: none;
  margin: 0;
}

/* **Screenshots, presented as screenshots.** They were in a device frame with a working tab bar,
   which invited a tap and then did nothing - no scrolling, no opening a team, nothing. A control
   that answers once and then refuses reads as broken software. Pictures that admit to being
   pictures do not make a promise they cannot keep. */
.shelf {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: 6px;
  /* The row scrolls inside itself; the page never scrolls sideways. */
  scrollbar-width: thin;
}
.shelf-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(210px, 1fr);
  gap: var(--sp-md, 20px);
}
.shot-card {
  margin: 0;
  scroll-snap-align: start;
  min-width: 0;
}
.shot-card img {
  display: block;
  width: 100%;
  height: auto;
  /* The one curve in this world, and it is a physical fact rather than a style: an iPhone screen
     has round corners, so a picture of one that is hard-cornered is the wrong picture. Small on
     purpose - the 12-16px card radius is the category default this page refuses. */
  border-radius: 6px;
  border: var(--hair) solid #1c1c22;
  background: #000;
}
.shot-card figcaption {
  margin-top: 12px;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-display, #e6e6ea);
}
@media (max-width: 720px) {
  .shelf-track { grid-auto-columns: minmax(180px, 78vw); }
}

/* Marquee. The shelf is the window and .shelf-track is what moves, so everything above stays the
   no-JS layout: a scrollable, snapping grid. `.js-marquee` is added only once GSAP is running. */
.shelf.js-marquee {
  display: block;
  overflow: hidden;
  scroll-snap-type: none;
}
.shelf.js-marquee .shelf-track {
  display: flex;
  gap: var(--sp-md, 20px);
  width: max-content;
  will-change: transform;
}
.shelf.js-marquee .shot-card { width: var(--shot-w, 240px); flex: 0 0 auto; }
@media (max-width: 720px) {
  .shelf.js-marquee .shot-card { width: var(--shot-w, 180px); }
}
/* A figure the marquee cloned is decoration for a screen reader - the real five are already in
   the accessibility tree, and announcing ten screenshots for an app with five screens is a lie. */
.shot-card[aria-hidden="true"] { pointer-events: none; }

/* ---- Data table (the rating comparison) ----------------------------------------------- */

.data { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.data th, .data td {
  text-align: right;
  padding: var(--sp-md) var(--sp-md) var(--sp-md) 0;
  border-bottom: var(--hair) solid var(--rule);
  white-space: nowrap;
  font-size: 0.95rem;
}
.data th:first-child, .data td:first-child { text-align: left; padding-left: 0; }
.data th {
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--label); border-bottom-color: var(--rule-strong);
}
.data td { color: var(--ink); }
/* Two signals that must not be confused: weight says "this row is ours", the rule beneath a
   figure says "best in this column". Bold-plus-white for both made a reader unable to tell which
   claim was being made. */
.data tr.mine td { color: var(--ink-display); font-weight: 600; }
/* A cell in our own row that we do not win. The row's weight is a claim of ownership, not of
   victory, and it has to be droppable for the one column where the honest answer is "they won". */
.data tr.mine td.lost { color: var(--ink); font-weight: 400; }

.data td.best {
  color: #fff;
  text-decoration: underline;
  text-decoration-color: var(--rule-strong);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.42em;
}
@media (max-width: 560px) {
  .data th, .data td { padding-right: 6px; font-size: 0.8rem; }
  .data th { font-size: 0.58rem; letter-spacing: 0.1em; }
  .data th:last-child, .data td:last-child { padding-right: 0; }
}
.data-legend { display: flex; gap: var(--sp-lg); flex-wrap: wrap; margin-top: var(--sp-md); }

/* ---- Spec rows: what replaces a feature card grid -------------------------------------- */

.spec { border-top: var(--hair) solid var(--rule-strong); }
.spec-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-xs) var(--sp-xl);
  padding-block: var(--sp-lg);
  border-bottom: var(--hair) solid var(--rule);
}
@media (min-width: 760px) { .spec-row { grid-template-columns: 15rem minmax(0, 1fr); gap: var(--sp-xl); } }
.spec-row p { margin: 0; color: var(--ink); max-width: 62ch; }
.spec-row .label { padding-top: 0.32rem; }

/* ---- Close + footer ------------------------------------------------------------------- */

.close { border-top: var(--hair) solid var(--rule-strong); padding-block: var(--sp-band); }
.close .statement { max-width: 22ch; }
.close .offer-acts { margin-top: var(--sp-lg); }

.site-foot { border-top: var(--hair) solid var(--rule); padding-block: var(--sp-xl); color: var(--label); font-size: 0.84rem; }
.site-foot a { color: var(--ink); text-decoration: none; }
.site-foot a:hover { color: #fff; text-decoration: underline; }
.foot-links { display: flex; flex-wrap: wrap; gap: var(--sp-lg); margin-bottom: var(--sp-lg); }
.foot-fine { max-width: 68ch; line-height: 1.6; margin: 0; }

/* ---- Motion: one authored moment, from an already-visible default ---------------------- */

/* Four sections fading up identically was one entrance repeated, which the page did not earn and
   which left a visitor on slow wifi looking at blank bands. What arrives now is the hairline that
   separates the section, drawn left to right the way a display draws its own rules - additive to a
   page that is already readable, and absent entirely when motion never loads. */
.rule-draw {
  position: absolute;
  inset: -1px 0 auto 0;
  height: 1px;
  background: var(--rule-strong);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.section, .close { position: relative; }
.js .section, .js .close { border-top-color: transparent; }

@media (prefers-reduced-motion: reduce) {
  .enter, .enter.in { opacity: 1; transform: none; transition: none; }
  .js .section, .js .close { border-top-color: var(--rule-strong); }
  .rule-draw { display: none; }
  .shelf-track { transform: none !important; }
  .live.on { animation: none; }
  * { scroll-behavior: auto !important; }
}

/* Progressive disclosure. The audit-tier material - exact parameters, the validation battery, the
   reproduction commands - matters enormously to the few people who want to check the model and not
   at all to a team wondering what their number means. Folding it keeps both readers served without
   removing anything. */
details {
  border-top: 1px solid var(--line);
  margin: 2.4rem 0 0;
  padding-top: 1rem;
}
details summary {
  font-family: var(--face);
  font-size: 0.68rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--dim);
  cursor: pointer;
  list-style: none;
}
details summary::-webkit-details-marker { display: none; }
details summary::before { content: "+ "; color: var(--dim); }
details[open] summary::before { content: "\2212 "; }
details summary:hover { color: var(--ink); }

/* ---- The full board and the team page -------------------------------------------------
   Operate surfaces, not the landing page. DESIGN.md specifies a "board row, dense" for exactly
   this: the same structure as the display row, at body scale, for a list somebody scans rather
   than reads across a gym. No fluid type here - these are read at a desk at a fixed size. */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.tools {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  flex-wrap: wrap;
  padding-block: var(--sp-md);
  border-bottom: var(--hair) solid var(--rule);
}
.tools input[type="search"] {
  flex: 1 1 18rem;
  min-width: 0;
  background: var(--panel);
  border: var(--hair) solid var(--rule-strong);
  border-radius: 0;
  color: var(--ink-display);
  font: inherit;
  font-size: 0.95rem;
  padding: 10px 12px;
  -webkit-appearance: none;
  appearance: none;
}
.tools input[type="search"]::placeholder { color: var(--label); }
.tools input[type="search"]:focus-visible {
  outline: 2px solid var(--accent-hot);
  outline-offset: -2px;
  border-color: var(--accent-hot);
}
.tools #shown { margin-left: auto; }

/* The column headings for the dense list. A board whose columns are unnamed is a table pretending
   not to be one, and this world labels every region. */
.denseHead {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) auto;
  gap: var(--sp-md);
  padding: var(--sp-md) 0 var(--sp-sm);
  border-bottom: var(--hair) solid var(--rule-strong);
}
.denseHead .numHead { text-align: right; }

.dense { list-style: none; margin: 0; padding: 0; }
.drow { border-bottom: var(--hair) solid var(--rule); }
.drow.lead .drk { color: var(--accent-hot); }

.dlink {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) auto;
  grid-template-areas: "rank who value" ".    meta meta";
  gap: 1px var(--sp-md);
  align-items: baseline;
  padding: 10px 0;
  text-decoration: none;
  color: inherit;
}
a.dlink:hover { background: var(--panel); }
a.dlink:focus-visible { outline: 2px solid var(--accent-hot); outline-offset: -2px; }

.drk {
  grid-area: rank;
  font-variant-numeric: tabular-nums;
  color: var(--label);
  font-size: 0.9rem;
}
.dwho { grid-area: who; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--sp-sm); }
.dteam {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ink-display);
  font-variant-numeric: tabular-nums;
}
.dname { font-size: 0.95rem; color: var(--ink-strong); min-width: 0; }
.dplace { font-size: 0.8rem; color: var(--label); }
.dval {
  grid-area: value;
  text-align: right;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink-display);
  font-variant-numeric: tabular-nums;
}
.dmeta { grid-area: meta; font-size: 0.78rem; color: var(--label); font-variant-numeric: tabular-nums; }

.drow.skel { opacity: 0.35; }

@media (max-width: 560px) {
  .denseHead, .dlink { grid-template-columns: 2.4rem minmax(0, 1fr) auto; gap: 2px var(--sp-sm); }
  .dname { font-size: 0.88rem; }
}

/* ---- Team page ------------------------------------------------------------------------ */

.teamhead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-md) var(--sp-lg);
  padding-block: var(--sp-xl) var(--sp-lg);
  border-bottom: var(--hair) solid var(--rule-strong);
}
/* A team number arrives from the URL. `/team/<3000 characters>` is a 200, and without this the
   header pushed the document to 63,000px wide - a shareable link that defaces the page. */
.teamhead h1 { margin: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; min-width: 0; }
.teamwho { min-width: 0; }
.teamwho p { margin: 0; }
.teamwho .statement { font-size: 1.4rem; }
.teamwho .label + .label { margin-top: 2px; }

/* Call things out at full size rather than describing them - the same discipline as the display
   board, applied to one team. */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--sp-lg);
  padding-block: var(--sp-lg) var(--sp-xl);
}
.figure { display: flex; flex-direction: column; gap: var(--sp-xs); }
.figure-v {
  font-size: clamp(2rem, 5vw, 3rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink-display);
  font-variant-numeric: tabular-nums;
}

.teamhead + #body .section-head { margin-top: var(--sp-xl); }

/* ---- VP trend chart -------------------------------------------------------------------
   Hand-built SVG, one polyline. No colour: red is live, the primary action and rank 1, and a
   data series is none of those. Depth is a hairline, the same as everywhere else here. */

#chart { padding-block: var(--sp-lg); }
.vpchart { display: block; width: 100%; height: 190px; margin-bottom: var(--sp-md); }
.vpchart .grid { stroke: var(--rule); stroke-width: 1; }
.vpchart .avg { stroke: var(--rule-strong); stroke-width: 1; stroke-dasharray: 4 4; }
.vpchart .series { fill: none; stroke: var(--ink-display); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.vpchart .dot { fill: var(--ink-display); }
.vpchart .axis {
  fill: var(--label);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.dmore { display: block; padding: var(--sp-md) 0; color: var(--label); }
.copyright { color: var(--label-dim); }
.site-foot .copyright { margin-top: var(--sp-sm); }

/* ---- Loading ---------------------------------------------------------------------------
   A hairline that draws in from the left and retracts to the right, under the status strip.
   Same device as the section rules: this world's idea of "working" is a display drawing itself,
   not a spinner borrowed from somebody else's design system. No colour - red is live, the primary
   action and rank 1, and "still loading" is none of those. No gradient, so no shimmer. */

.strip { position: relative; }
.strip.is-loading::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--rule-strong);
  transform: scaleX(0);
  transform-origin: 0 50%;
  animation: strip-sweep 1.15s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

@keyframes strip-sweep {
  0%     { transform: scaleX(0); transform-origin: 0 50%; }
  48%    { transform: scaleX(1); transform-origin: 0 50%; }
  52%    { transform: scaleX(1); transform-origin: 100% 50%; }
  100%   { transform: scaleX(0); transform-origin: 100% 50%; }
}

/* Skeleton rows breathe rather than sit at a dead opacity, so a slow board looks like it is
   working instead of like it has finished badly. */
.skel, .drow.skel { animation: skel-breathe 1.6s ease-in-out infinite; }
@keyframes skel-breathe { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.22; } }

@media (prefers-reduced-motion: reduce) {
  /* The state still has to be legible: a full-width rule that does not move says "loading"
     just as well, and losing it entirely would remove information rather than motion. */
  .strip.is-loading::after { animation: none; transform: scaleX(1); }
  .skel, .drow.skel { animation: none; opacity: 0.4; }
}
