/* Phase A: dark analysis workspace, readable type, stable identity assets.
   Colour lives in tokens.css. */

html { background: var(--surface-base); }
body {
  color: var(--text-primary);
  background:
    var(--gradient-page-glow),
    var(--surface-base);
  font-size: 16px;
  line-height: 1.5;
}
::selection { color: var(--text-on-accent); background: var(--brand-primary); }
:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; }

.site-masthead {
  color: var(--text-primary);
  background: color-mix(in srgb, var(--surface-raised) 96%, transparent);
  border-bottom-color: var(--border-subtle);
  backdrop-filter: blur(14px);
}
.site-masthead .brand strong { color: var(--text-primary); }
.site-masthead .brand small,
.site-masthead .main-nav a { color: var(--text-secondary); }
.site-masthead .main-nav a:hover,
.site-masthead .main-nav a.active { color: var(--text-on-accent); }
.site-masthead .data-status { color: var(--text-secondary); border-color: var(--border-strong); }
.site-masthead .data-status span { background: var(--success-surface); }

/* Display headlines must wrap rather than push the page wider than the
   viewport. German runs 20-35% longer than English and compounds into single
   long words, so this is load-bearing once the site is localised.
   Scoped deliberately: `overflow-wrap` on every heading would collapse the
   min-content width of headings inside auto-sized grid tracks (.player-card
   h3 breaks to one character per line). Hyphenation belongs on body copy with
   a correct lang attribute, and is set in Phase 3, not here. */
.home-statement h1,
.page-heading h1,
.competition-lab-header h1,
.editorial-heading h2,
.lockup-team strong { overflow-wrap: break-word; hyphens: auto; }

h1 { font-size: clamp(48px, 5vw, 64px); line-height: .95; }
h2 { font-size: clamp(28px, 2.4vw, 40px); line-height: 1; }
h3 { font-size: 20px; }
p { line-height: 1.6; }
small { font-size: 12px; }
.page-heading { min-height: 240px; border-color: var(--border-subtle); }
.page-heading h1 { max-width: 950px; font-size: clamp(48px, 5vw, 64px); }
.page-heading p,
.home-statement > p { color: var(--text-secondary); font-size: 16px; }
.home-statement h1 { margin-top: 18px; font-size: clamp(48px, 5.3vw, 68px); line-height: .94; }
.home-statement h1 em { color: var(--brand-accent); }

/* Functional labels never drop below 12px.
   The wordmark is deliberately NOT in this list: it is a logo, not a label,
   and the 12px floor overflowed its 60x34 box so it rendered clipped as
   "ROTBLA". Logotypes are exempt from minimum text size. */
.site-masthead .brand small, .eyebrow, .section-head > span, .issue-line,
.statement-links a, .feature-label, .feature-data > span, .feature-cta,
.tape-title span, .tape-result small, .tape-result i,
.editorial-heading > span, .editorial-heading > a, .brief-score span,
.season-brief dt, .rule-link, .ways-grid span, .ways-grid b,
.competition-ledger i, .competition-ledger span, .control, .archive-rule,
.lab-record span, .form-point i, .form-point span, .formation-ledger-row,
.leader-head, .leader-row, .leader-row i, .competition-records article > div,
.competition-records dt, .opponent-head, .opponent-row, .match-index,
.lockup-team span, .lockup-score small, .lockup-team small, .lockup-score span,
.match-source-line, .fact-strip i, .fact-strip small, .analysis-tabs .tab,
.pipeline-hero span, .pipeline-hero small, .pipeline-state p,
.pipeline-flow .editorial-heading > b, .conflict-register .editorial-heading > b,
.flow-grid i, .flow-grid p, .source-register-head, .source-register-row,
.conflict-register article p, .conflict-severity,
.coverage-detail .editorial-heading p, .brand small, .kpi small, .kpi em,
.match-date, .match-xg, .result-pill, .tier-pill, .availability-pill,
.competition-label, .match-meta span, .fact small, .panel-title span,
.stat-group h4, .formation-player > span, .bench span, .data-table th,
.player-card .country, .player-card-stats small, .injury-badge,
.transfer-direction, footer { font-size: 12px; }

.main-nav a { font-size: 14px; }
.control, button, select, input { font-size: 14px; }
.control, .tab, button { min-height: 44px; }
.text-link, .rule-link { color: var(--text-primary); border-color: var(--border-subtle); }
.eyebrow { color: var(--brand-accent); }

/* Surfaces and structural lines. */
.home-lead, .result-tape, .ways-grid, .competition-records, .flow-grid,
.squad-grid, .fact-strip, .competition-ledger > a, .lab-record,
.season-scope, .form-sequence, .page-heading, .editorial-heading, .archive-rule,
.opponent-head, .opponent-row, .leader-head, .leader-row,
.formation-ledger-row, .source-register-head, .source-register-row,
.conflict-clear, .match-ledger, .match-row, .player-card,
.flow-grid article, .transfer-row { border-color: var(--border-subtle); }
.home-lead, .result-tape, .ways-grid > a,
.competition-records article, .flow-grid article { background: var(--surface-raised); }
.ways-grid > a:hover { background: var(--surface-overlay); }
.card {
  background: var(--surface-raised);
  border: 1px solid var(--border-subtle);
  box-shadow: var(--elevation-card);
}
.card-pad { padding: 24px; }
.panel-title { border-color: var(--border-subtle); }
.panel-title h3 { font-size: 20px; }
.section-head { border-color: var(--border-subtle); }
.section-head > span, .issue-line, .match-date, .match-xg,
.brief-score span, .season-brief dt, .competition-ledger i,
.competition-ledger span, .archive-rule, .lab-record span,
.form-point span, .formation-ledger-row > span, .leader-head,
.leader-row i, .competition-records article > div, .competition-records dt,
.opponent-head, .match-index, .fact-strip i, .fact-strip small,
.panel-title span, .stat-label, .stat-group h4, .shot-item small,
.heatmap-button small, .commentary-item small, .player-card .country,
.player-card-stats small, .transfer-route, .pipeline-hero span,
.pipeline-hero small, .pipeline-state p, .flow-grid p,
.source-register-head, .conflict-register article p,
.coverage-detail .editorial-heading p, footer { color: var(--text-secondary); }

.home-lead { min-height: 520px; }
.home-statement { padding: 38px 44px; }
.issue-line { margin-bottom: 42px; }
.statement-links a { border-color: var(--border-subtle); }
.last-match-feature {
  background: var(--gradient-feature);
}
.feature-score { padding-top: 32px; }
.feature-score > div { position: relative; }
.feature-score strong { font-size: clamp(76px, 8vw, 120px); }
.feature-score small { min-height: 34px; font-size: 14px; }
.feature-data > span { font-size: 12px; }
.result-tape, .tape-result { background: var(--surface-raised); }
.tape-title { background: var(--surface-overlay); }
.tape-result { border-color: var(--border-subtle); }
.tape-result.draw i { color: var(--warning-ink); }
.brief-score, .season-brief dl > div { border-color: var(--border-subtle); }

.match-row:hover { color: var(--text-primary); background: var(--surface-sunken); }
.match-ledger .match-row:hover { color: var(--interactive-active); background: var(--surface-raised); }
.match-teams { font-size: 14px; }
.match-teams > span { display: flex; align-items: center; gap: 8px; min-width: 0; }
.match-teams b { overflow: hidden; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
.match-date strong, .match-xg strong { color: var(--text-primary); }
.result-pill.draw { color: var(--warning-ink); background: var(--warning-surface); }
.tier-pill.full { color: var(--success-on-subtle); background: var(--success-subtle); }
.tier-pill.advanced { color: var(--info-on-subtle); background: var(--info-subtle); }
.tier-pill.standard { color: var(--warning-on-subtle); background: var(--warning-subtle); }
.tier-pill.basic { color: var(--danger-on-subtle); background: var(--danger-subtle); }

.control {
  min-width: 180px;
  padding: 11px 36px 11px 12px;
  color: var(--text-primary);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
}
.control:focus { border-color: var(--focus-ring); box-shadow: 0 0 0 3px var(--focus-glow); }
.lab-record > div { border-color: var(--border-subtle); }
.form-point { min-width: 92px; }
.form-point span { max-width: 86px; }
.formation-ledger-row > div { background: var(--surface-overlay); }
.competition-records article { border-color: var(--border-subtle); }

.match-masthead {
  background: var(--gradient-match-masthead);
}
.match-lockup { min-height: 380px; }
.lockup-team { display: flex; flex-direction: column; align-items: flex-start; }
.lockup-team.away { align-items: flex-end; }
.lockup-team strong { margin: 14px 0; font-size: clamp(38px, 4vw, 64px); }
.lockup-score strong { font-size: 78px; }
.match-source-line { padding: 10px 18px; }

/* --- The fact strip -------------------------------------------------------
   It is welded to the masthead (no top border, same block), so it has to speak
   in the masthead's voice. It was the one key/value tile row on the site whose
   value had been left at the 12px label floor in the body face: label and
   value came out the same size, under a 92px score, and read as a caption band
   rather than as the match's facts. Same two-step lockup the other tile rows
   use (.lab-record, .pipeline-hero, .competition-ledger) — lettered label,
   value in the display face, uppercase like the team names right above it —
   sized for a text value in a sixth of the page rather than for a figure. */
.fact-strip > div { border-color: var(--border-subtle); }
.fact-strip strong {
  font: 800 clamp(16px, 1.32vw, 21px)/1.15 var(--font-display);
  letter-spacing: -.01em;
  text-transform: uppercase;
}
/* --- The match tab bar travels with the reader ----------------------------
   Eight tabs at the top of a page that runs to several screens meant scrolling
   all the way back up to change what you were looking at. It sticks under the
   masthead instead, the same way the site nav does, so the match is switchable
   from wherever you are in it.
   It needs its own opaque background: transparent was fine while nothing ever
   passed behind it. `--masthead-height` is measured, not assumed — the bar
   reflows to two rows below 820px. */
.analysis-tabs {
  position: sticky;
  top: var(--masthead-height);
  z-index: 14;
  background: var(--surface-base);
  border-color: var(--border-subtle);
}
.analysis-tabs .tab { color: var(--text-secondary); border-color: var(--border-strong); }
.analysis-tabs .tab:hover, .analysis-tabs .tab.active { color: var(--text-on-accent); background: var(--surface-overlay); }
/* --- The section index ----------------------------------------------------
   A rail for a tab that runs to several screens: what is in it, in order, one
   click from each, marking the section the reader is in. Used by the analysis
   and by the on-ball tab; each of those decides where it sits, because the
   column it can spare is not the same on both.
   Wide screens get a sticky column; narrow ones get the same list as a
   scrollable strip, where a 232px column would leave the content too thin. */
.section-index {
  min-width: 0;
  padding: 2px 0 var(--space-2);
}
.section-index-title {
  margin: 0 0 var(--space-3);
  color: var(--text-muted);
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
}
.section-index ol {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.section-index button {
  width: 100%;
  /* The app's floor for anything operable, kept here too rather than tightened
     to fit more of the list on screen. */
  min-height: 44px;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: var(--space-2);
  align-items: baseline;
  padding: 9px 10px;
  text-align: left;
  color: var(--text-secondary);
  background: transparent;
  border: 0;
  border-left: 2px solid var(--border-subtle);
  font-size: 13.5px; line-height: 1.35;
}
.section-index button i {
  color: var(--text-muted);
  font-size: 11px; font-style: normal; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: .08em;
}
.section-index button:hover {
  color: var(--text-primary);
  background: var(--surface-raised);
}
/* The same accent rule the analysis lede carries, so "you are here" reads as
   part of the page rather than as a control. */
.section-index button.is-current {
  color: var(--text-on-accent);
  background: var(--surface-raised);
  border-left-color: var(--brand-accent);
  font-weight: 700;
}
.section-index button.is-current i { color: var(--brand-accent); }

@media (max-width: 1119px) {
  .section-index ol {
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    gap: var(--space-1);
    overflow-x: auto;
    padding-bottom: var(--space-2);
  }
  .section-index button {
    grid-template-columns: auto auto;
    align-items: center;
    border-left: 0;
    border-bottom: 2px solid var(--border-subtle);
    white-space: nowrap;
  }
  .section-index button.is-current { border-bottom-color: var(--brand-accent); }
}

/* Opening a tab from the foot of another one scrolls back to the top of the
   content; this is what keeps that landing clear of the two sticky bars. */
#match-tab-content { scroll-margin-top: calc(var(--masthead-height) + 56px); }
.coverage-note { color: var(--warning-on-subtle); background: var(--warning-subtle); border-left-color: var(--warning-surface); }

.stat-row { font-size: 14px; }
.stat-bar { background: var(--surface-overlay); }
.momentum line { stroke: var(--border-subtle); }
.pitch { background: var(--pitch-surface); border-color: var(--pitch-border); }
.shot-list { padding: 24px; }
.shot-item { grid-template-columns: 44px 34px minmax(0, 1fr) auto; align-items: center; border-color: var(--border-subtle); font-size: 14px; }
.xg-chip { background: var(--surface-overlay); }
.goal-frame { fill: var(--surface-sunken); stroke: var(--text-primary); }
.goal-mouth line { stroke: var(--text-primary); }

.formation-pitch { background: linear-gradient(var(--pitch-surface-alt) 50%, var(--pitch-surface-alt) 50%); }
.formation-player { width: 104px; }
.formation-player > span { margin-top: 5px; line-height: 1.15; }
.formation-face { position: relative; width: 44px; height: 44px; margin: 0 auto; }
.formation-face b {
  position: absolute; right: -5px; bottom: -3px; min-width: 21px; height: 21px;
  display: grid; place-items: center; color: var(--text-on-accent); background: var(--brand-primary);
  border: 2px solid var(--text-on-accent); border-radius: 50%; font-size: 12px;
}
.formation-card.away .formation-face b { background: var(--brand-secondary); }
.bench span { color: var(--text-secondary); background: var(--surface-overlay); }

.table-scroll { overflow: auto; scrollbar-color: var(--border-subtle) var(--surface-raised); }

/* --- The frame around a table too wide for the screen ---------------------
   A plain overflow box puts its scrollbar at the foot of the whole table,
   which on 25 rows is below the fold: the reader had to scroll the page down
   to find the bar, drag it right, then scroll back up to the row he wanted —
   by which time the column heading had gone too. Capping the height gives the
   table a viewport of its own, so its bar and its sticky heading are on screen
   together, and the page above the table stops moving when a filter changes
   the number of rows. */
/* Grid and flex items default to min-width:auto, so an unconstrained frame
   grows to its widest column and pushes the whole page sideways instead of
   scrolling inside itself — the far-right columns then cannot be reached at
   all. Both halves need the cap: the frame is the item, the scroller is what
   the table is measured against. */
.table-frame { position: relative; min-width: 0; max-width: 100%; }
.table-frame-scroll {
  min-width: 0; max-width: 100%;
  max-height: min(74vh, 780px); overflow: auto; overscroll-behavior-x: contain;
  scrollbar-width: auto; scrollbar-color: var(--border-strong) var(--surface-sunken);
}
.table-frame-scroll:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
/* WebKit hides the bar until it moves, which is the whole problem. */
.table-frame-scroll::-webkit-scrollbar { width: 13px; height: 13px; }
.table-frame-scroll::-webkit-scrollbar-track { background: var(--surface-sunken); }
.table-frame-scroll::-webkit-scrollbar-thumb { background: var(--border-strong); border: 3px solid var(--surface-sunken); border-radius: var(--radius-round); }
.table-frame-scroll::-webkit-scrollbar-thumb:hover { background: var(--interactive-disabled); }

/* The bar says there is more only to someone who already looked for it. These
   say it where the reader's eye is: at the edge the columns run off. Clear of
   the vertical bar, and clear of the sticky player column at the other side,
   which is the one thing on the row that is never cut and never worth
   covering. */
.table-nudges {
  position: absolute; top: 50%; right: 24px; z-index: 6; display: none; gap: 4px; margin-top: -23px;
}
.table-frame.can-scroll .table-nudges { display: flex; }
.table-nudge {
  width: 34px; height: 46px; display: grid; place-items: center; padding: 0;
  color: var(--text-primary); background: var(--surface-overlay);
  border: 1px solid var(--border-strong); border-radius: var(--radius-control);
  box-shadow: var(--elevation-chip); font-size: 22px; line-height: 1;
}
.table-nudge:hover:not(:disabled) { color: var(--text-on-accent); background: var(--brand-primary); border-color: var(--brand-primary); }
.table-nudge:disabled { color: var(--interactive-disabled); border-color: var(--border-subtle); box-shadow: none; }
/* A fade at the cut edge, so it reads as more-to-come rather than finished.
   Only that edge: the left of the frame is the sticky column, which does not
   scroll and has nothing behind it to hint at. */
.table-frame.can-scroll::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 0; z-index: 4; width: 52px;
  background: linear-gradient(to left, var(--surface-base), transparent); pointer-events: none;
}
.table-frame.at-end::after { content: none; }

/* --- Column comparison ----------------------------------------------------
   Where the number sits inside its own column. A second reading of a figure
   that is printed in the cell either way, so nothing here is the only carrier
   of anything — see Design.md 1.7. The wash goes on the cell, never on the
   sticky name column, which has to stay one flat plate as it slides over the
   rest. */
td.compare-good-1 { background: var(--compare-good-1); }
td.compare-good-2 { background: var(--compare-good-2); }
td.compare-poor-1 { background: var(--compare-poor-1); }
td.compare-poor-2 { background: var(--compare-poor-2); }
td.compare-flat-1 { background: var(--compare-flat-1); }
td.compare-flat-2 { background: var(--compare-flat-2); }

.compare-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0; color: var(--text-secondary); font-size: 12px; }
.compare-swatches { display: inline-flex; align-items: center; gap: 5px; }
.compare-swatches i { width: 22px; height: 12px; border: 1px solid var(--border-subtle); }
.compare-legend .compare-good-1 { background: var(--compare-good-1); }
.compare-legend .compare-good-2 { background: var(--compare-good-2); }
.compare-legend .compare-poor-1 { background: var(--compare-poor-1); }
.compare-legend .compare-poor-2 { background: var(--compare-poor-2); }
.compare-legend .compare-mid { background: var(--surface-raised); }

.data-table { min-width: 680px; font-size: 14px; font-variant-numeric: tabular-nums; }
.data-table th { color: var(--text-secondary); background: var(--surface-sunken); }
.data-table td { border-color: var(--border-subtle); }
.table-player { display: flex; align-items: center; gap: 10px; min-width: 190px; }
.table-player > span:last-child { display: grid; gap: 2px; }
.table-player small { display: block; color: var(--text-secondary); font-size: 12px; }
.heatmap-list { border-color: var(--border-subtle); }
.heatmap-button { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; align-items: center; gap: 10px; color: var(--text-primary); border-color: var(--border-subtle); font-size: 14px; }
.heatmap-button:hover, .heatmap-button.active { color: var(--text-on-accent); background: var(--surface-overlay); }
.commentary-item { border-color: var(--border-subtle); }
.commentary-item p { font-size: 14px; }
.event-row { grid-template-columns: 50px 34px 26px minmax(0, 1fr); align-items: center; }
.event-icon { width: 32px; height: 32px; display: inline-grid; place-items: center; color: var(--text-primary); background: var(--surface-overlay); border: 1px solid var(--border-subtle); }
.event-icon svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.event-icon.card svg { stroke: none; }
.event-icon.yellow-card svg { fill: var(--warning-surface); }
.event-icon.red-card svg { fill: var(--brand-primary); }

/* Locally cached team and player identity. */
.identity-image { position: relative; flex: none; display: inline-grid; place-items: center; overflow: hidden; }
.identity-image picture { position: relative; z-index: 1; display: block; width: 100%; height: 100%; }
.identity-image img { display: block; width: 100%; height: 100%; object-fit: contain; }
.identity-fallback { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-secondary); background: var(--surface-overlay); border: 1px solid var(--border-subtle); font: 800 12px/1 Arial, sans-serif; }
.team-identity { width: 36px; height: 36px; }
.team-identity.compact, .team-identity.tiny { width: 24px; height: 24px; }
.team-identity.small { width: 32px; height: 32px; }
.feature-score > div:last-child .feature-logo { margin-left: auto; }
/* A transparent crest may never sit directly on a gradient (Design.md 3.5).
   These two are the only such placements: the match masthead and the home
   feature panel. Provider crests may not be recoloured or knocked out, so the
   background is treated instead — here with the lockup plate of §3.5b, which
   the spec prefers over a scrim wherever the layout has room for it.

   The declared width/height is the PLATE. `box-sizing: border-box` means the
   padding insets the crest, so padding is the clear space of §3.7: it stays at
   ~30% of the crest's height, the ratio §3.5b sets (12px at a 40px mark). */
.team-identity.masthead-logo,
.team-identity.feature-logo {
  background: var(--surface-inverse);
  border-radius: var(--radius-round);
  box-shadow: var(--elevation-chip);
}
.team-identity.feature-logo {
  width: 64px; height: 64px; padding: 12px;
  margin-bottom: 10px;
}
.team-identity.masthead-logo {
  width: 104px; height: 104px; padding: 20px;
  margin-bottom: 18px;
}
.player-identity { width: 40px; height: 40px; background: var(--surface-overlay); border: 1px solid var(--border-subtle); border-radius: 50%; }
.player-identity img { object-fit: cover; object-position: center top; }
.player-identity.tiny { width: 28px; height: 28px; }
.player-identity.small { width: 34px; height: 34px; }
.player-identity.formation { width: 44px; height: 44px; border: 2px solid var(--text-on-accent); }
.player-identity.card-photo { width: 128px; height: 148px; border: 0; border-radius: 0; background: transparent; }
.team-heading, .team-pair, .leader-player { display: flex; align-items: center; gap: 9px; }
.team-pair { flex-wrap: wrap; justify-content: flex-end; }
.leader-player { min-width: 0; }
.leader-player > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.player-card { min-height: 280px; color: var(--text-primary); background: var(--surface-raised); }
.player-card-photo { position: absolute; z-index: 0; top: 12px; right: 10px; opacity: .9; }
.player-card > :not(.player-card-photo) { position: relative; z-index: 1; }
.player-card h3 { max-width: 63%; font-size: 24px; }
.player-card-stats { border-color: var(--border-subtle); }
.player-card-stats div { background: transparent; }
.injury-badge { color: var(--danger-on-subtle); background: var(--danger-subtle); }
.transfer-row { background: var(--surface-raised); }
.pipeline-hero { background: var(--surface-raised); }
.coverage-matrix.card { border-color: var(--border-subtle); }
.dot-no { background: var(--interactive-disabled); }
footer { background: var(--surface-raised); border-color: var(--border-subtle); }

@media (max-width: 820px) {
  .site-masthead .main-nav a { font-size: 13px; }
  .page { width: calc(100% - 28px); }
  .page-heading { min-height: 250px; }
  .page-heading h1, .home-statement h1 { font-size: clamp(38px, 11vw, 44px); }
  .home-statement { padding: 28px 22px 34px; }
  .last-match-feature { min-height: 420px; }
  .feature-score strong { font-size: 76px; }
  .match-lockup { min-height: 400px; grid-template-columns: 1fr 104px 1fr; }
  /* Plate and clear space shrink together — see the §3.5b note above. */
  .team-identity.masthead-logo { width: 76px; height: 76px; padding: 14px; }
  .lockup-team strong { font-size: 30px; }
  .lockup-score strong { font-size: 52px; }
  .card-pad, .shot-list { padding: 18px; }
  .squad-grid { border-color: var(--border-subtle); }
  /* On a phone the sticky name column leaves about a column and a half of the
     screen, and the pair would sit on nearly all of it. A finger drags the
     table sideways anyway; the bar and the fade still say there is more. */
  .table-frame.can-scroll .table-nudges { display: none; }
}

@media (max-width: 520px) {
  .site-masthead .brand strong { font-size: 14px; }
  .site-masthead .main-nav { gap: 22px; }
  .site-masthead .main-nav a { font-size: 13px; }
  .issue-line { margin-bottom: 30px; }
  .feature-score small { font-size: 12px; }
  .feature-score strong { font-size: 66px; }
  .match-ledger .match-row { grid-template-columns: 66px minmax(0, 1fr) 42px 32px; gap: 8px; }
  .match-teams b { font-size: 13px; }
  .match-teams .team-identity { width: 20px; height: 20px; }
  .match-lockup { padding: 24px 10px; }
  .team-identity.masthead-logo { width: 64px; height: 64px; padding: 12px; }
  .lockup-team strong { font-size: 24px; }
  .match-source-line { font-size: 12px; }
  .player-card { border-color: var(--border-subtle); }
  .source-register-row { font-size: 12px; }
}

/* Language switcher. Language names, not flags — flags mean countries. */
.masthead-end { display: flex; align-items: center; gap: var(--space-4); margin-left: auto; }
.lang-switcher { display: flex; align-items: center; gap: 1px; background: var(--border-subtle); border: 1px solid var(--border-strong); }
.lang-option {
  min-height: 32px;
  padding: 6px var(--space-2);
  display: grid;
  place-items: center;
  color: var(--text-secondary);
  background: var(--surface-raised);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .06em;
}
.lang-option abbr { text-decoration: none; border: 0; }
.lang-option:hover { color: var(--text-on-accent); background: var(--surface-overlay); }
.lang-option.active,
.lang-option[aria-current="true"] { color: var(--text-on-accent); background: var(--brand-primary); }
.site-masthead .data-status { margin-left: 0; }

@media (max-width: 1100px) {
  .masthead-end { gap: var(--space-3); }
}
@media (max-width: 820px) {
  /* The switcher stays visible on mobile; the data-status link is what drops. */
  .masthead-end { margin-left: auto; }
  .site-masthead .data-status { display: none; }
  .lang-option { min-height: 30px; padding: 5px 7px; }
}

/* Text expansion: German runs 20-35% longer and compounds into single long
   words ("Gegentore", "Wettbewerbslabor"). These labels sit in narrow grid
   tracks that are already allowed to shrink to zero, so the only thing left
   to give is the word itself. `anywhere` is safe here precisely because the
   tracks are minmax(0,1fr) — there is no auto track left to collapse. */
.brief-score span,
.lab-record span,
.season-brief dt,
.feature-data > span,
.competition-records dt,
.ways-grid span,
.ways-grid b,
.statement-links a { overflow-wrap: anywhere; hyphens: auto; }

/* Section-card headings: "Kader und Verfügbarkeit" is wider than the card at
   320px, and the card is already min-width:0. */
.ways-grid h3,
.flow-grid strong,
.competition-records article > strong { overflow-wrap: break-word; hyphens: auto; }

/* The initials plate is a fallback, not a backdrop. Crest artwork is rarely
   square, so once the image loads its transparent margins would otherwise
   show the plate as a dark box behind the mark. */
.identity-image.has-image .identity-fallback { display: none; }
