:root {
  color-scheme: dark;
  --surface-0:      #0a0e14;
  --surface-1:      #111722;
  --surface-2:      #19212e;
  --border:         #242f3e;
  --text-primary:   #eef3f8;
  --text-secondary: #9db0c2;
  --text-muted:     #647890;
  --series-1:       #4d9fff;
  --card-yellow:    #f5c518;
  --card-red:       #ff5a52;
  --accent:         #c9f24e;
  --accent-ink:     #0a0e14;
  /* The loading overlay's referee character. Tokens like everything else, so
     both themes own their values: the navy kit is lifted a step on the dark
     surface and deepened on the light one; skin and hair do not invert with
     the theme, because people don't. */
  --lo-skin:        #e2b48c;
  --lo-hair:        #2b2119;
  --lo-kit:         #252d45;
  --lo-kit-shade:   #181e31;
  --lo-collar:      #cdd7e1;
  --lo-boot:        #39415a;
}
:root[data-theme="light"] {
  color-scheme: light;
  --surface-0:      #eef0f3;
  --surface-1:      #ffffff;
  --surface-2:      #e4e8ee;
  --border:         #d5dae2;
  --text-primary:   #0d1420;
  --text-secondary: #46586c;
  --text-muted:     #7b8a9b;
  --series-1:       #2a78d6;
  --card-yellow:    #d99a00;
  --card-red:       #dd3d36;
  --accent:         #3f7d00;
  --accent-ink:     #ffffff;
  --lo-skin:        #e2b48c;
  --lo-hair:        #2b2119;
  --lo-kit:         #1e2438;
  --lo-kit-shade:   #131727;
  --lo-collar:      #f2f5f8;
  --lo-boot:        #2a3147;
}

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--surface-0); color: var(--text-primary);
  font: 14px/1.5 'Barlow', ui-sans-serif, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--series-1); } a:hover { color: var(--accent); }
.hidden { display: none !important; }
.sub { color: var(--text-secondary); font-size: 12.5px; }
.thin { color: var(--text-muted); font-style: italic; }
.spacer { flex: 1; }
.cond { font-family: 'Barlow Condensed', 'Barlow', sans-serif; }

/* ---- header / tabs ---- */
header.top {
  position: sticky; top: 0; z-index: 20; background: var(--surface-0);
  border-bottom: 1px solid var(--border); padding: 0 24px; height: 58px;
  display: flex; align-items: center; gap: 18px;
}
.brand { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 22px; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; }
.brand b { color: var(--accent); }
nav#tabs { display: flex; gap: 4px; }
.tabbtn {
  font-family: 'Barlow Condensed'; font-weight: 600; font-size: 16px; letter-spacing: .06em; text-transform: uppercase;
  background: none; border: none; color: var(--text-secondary); padding: 6px 14px; border-radius: 8px; cursor: pointer;
}
.tabbtn:hover { color: var(--text-primary); }
.tabbtn.on { background: var(--accent); color: var(--accent-ink); }

button, select {
  font: inherit; font-size: 13px; color: var(--text-primary);
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 12px; cursor: pointer;
}
button:hover, select:hover { background: var(--surface-2); }

.wrap { max-width: 1120px; margin: 0 auto; padding: 20px 20px 80px; }
.banner {
  background: var(--surface-1); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 8px; padding: 10px 14px; font-size: 13px; color: var(--text-secondary); margin-bottom: 16px;
}
.season-strip { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 4px 0 20px; }
.stitle { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 32px; text-transform: uppercase; letter-spacing: .03em; line-height: 1; }
h2.sec { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 26px; text-transform: uppercase; letter-spacing: .03em; margin: 0 0 12px; }

/* ---- filters ---- */
.filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.pillrow { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.pillrow.rail { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }

/* The week strip (2026-09-03): arrows at both ends, the pills in a fading
   scroller between them. #weekRail is the flex frame; .wk-scroll owns the
   overflow so the fade masks the strip and never the arrows. */
#weekRail { overflow: visible; flex: 1; min-width: 0; align-items: center; gap: 4px; padding-bottom: 0; }
.wk-scroll {
  position: relative; display: flex; gap: 6px; align-items: center;
  flex: 1; min-width: 0; overflow-x: auto; padding: 3px 26px;
  scroll-behavior: smooth; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 26px, #000 calc(100% - 26px), transparent);
  mask-image: linear-gradient(to right, transparent, #000 26px, #000 calc(100% - 26px), transparent);
}
.wk-scroll::-webkit-scrollbar { display: none; }
.wk-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 10px; }
.wk-scroll .pill { flex: none; }
.wk-arrow {
  flex: none; width: 30px; height: 30px; padding: 0; border-radius: 999px;
  font-size: 16px; line-height: 1; color: var(--text-secondary);
}
.wk-arrow:hover { color: var(--accent); }
/* Under 640px the strip yields to a compact select between the same arrows —
   the native picker is the right control for 34 rounds on a phone. */
.wk-select { display: none; flex: 1; min-width: 0; }
@media (max-width: 639px) {
  .wk-scroll { display: none; }
  .wk-select { display: block; }
}
.flabel { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); flex: none; }
.pill {
  font-family: 'Barlow Condensed'; font-weight: 600; font-size: 14px; letter-spacing: .05em; text-transform: uppercase;
  border-radius: 999px; padding: 5px 14px; flex: none;
  background: var(--surface-1); border: 1px solid var(--border); color: var(--text-secondary);
}
.pill.on, .pill[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
/* A division the season has no data for stays visible but inert — the title
   attribute says why (e.g. "3. Lig arşivi 2026-27'den itibaren"). */
.pill:disabled { opacity: .4; cursor: not-allowed; }

/* ---- match list ---- */
.wkhead { display: flex; align-items: baseline; gap: 10px; margin: 18px 0 10px; }
.wkhead .wk { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 21px; text-transform: uppercase; letter-spacing: .05em; color: var(--accent); }
.wkhead .rule { flex: 1; border-bottom: 1px solid var(--border); }
.mrow { background: var(--surface-1); border: 1px solid var(--border); border-radius: 10px; margin-bottom: 8px; overflow: hidden; }
.mhead { display: grid; grid-template-columns: 76px 1fr auto; align-items: center; gap: 14px; padding: 12px 16px; cursor: pointer; }
.mhead:hover { background: var(--surface-2); }
.when { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; line-height: 1.3; }
.mmid { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.teams { font-weight: 600; font-size: 15px; }
.score {
  font-family: 'Barlow Condensed'; font-weight: 700; font-size: 17px; letter-spacing: .06em;
  background: var(--surface-2); border-radius: 6px; padding: 1px 10px; font-variant-numeric: tabular-nums;
}
.ht { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.flag {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--accent); border: 1px solid var(--accent); border-radius: 999px; padding: 1px 8px;
}
.mright { display: flex; align-items: center; gap: 10px; }
/* The beIN özet chip — rendered by highlightChip() and by nothing else, so
   this is the ONLY place its look is decided. Sized at the .ht halftime
   text's 11px: it sits immediately after the score box in every view and
   must never compete with the score. The dead state keeps the text visible —
   "there was an özet and it is gone" is information — but struck through and
   muted so nobody tries to click it. */
.hlchip {
  position: relative; display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap;
  color: var(--series-1); text-decoration: none;
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 8px;
}
.hlchip:hover { color: var(--accent); border-color: var(--accent); }
.hlchip .hlplay { font-size: 8px; line-height: 1; }
/* The chip is ~19px tall by design; the finger still gets ≥32px. An invisible
   pseudo-element grows the hit area of the link itself — no layout impact,
   and it travels with the chip into every view that renders one. */
.hlchip::after { content: ''; position: absolute; left: -4px; right: -4px; top: -7px; bottom: -7px; }
/* The expanded detail's both-fences line: the only place both cuts link, for
   the viewer the locale guess missed. Muted prose with quiet links. */
.hlalts { margin-top: 8px; }
.hlalts a { color: var(--series-1); text-decoration: none; }
.hlalts a:hover { color: var(--accent); text-decoration: underline; }
/* The coverage number carries the per-fence pair in its tooltip. */
.hlcov { cursor: help; }
.mini { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.swatch { width: 8px; height: 11px; border-radius: 2px; display: inline-block; flex: none; }
.swatch.y { background: var(--card-yellow); }
.swatch.r { background: var(--card-red); }
.swatch.y2 { background: linear-gradient(135deg, var(--card-yellow) 50%, var(--card-red) 50%); }
/* There is deliberately NO .swatch.g. The goal marker was a blue dot the same
   shape as the card swatches beside it, so a goal read as a third colour of
   card; .gicon replaced it everywhere. The rule is removed rather than left
   unused, because a dead selector is an invitation to render against it. */

/* A ball. Sized against the card swatches so the timeline's rows still align,
   and greyed for an own goal — which TFF lists under the scorer's club, the
   opposite of the side it counted for, so the row also says so in words. */
.gicon { width: 12px; font-size: 11px; line-height: 1; display: inline-block; flex: none; text-align: center; filter: grayscale(0); }
.gicon.own { opacity: .55; filter: grayscale(1); }

/* Group identity for divisions that have groups: 2. Lig Kırmızı/Beyaz and the
   numbered 3. Lig groups. Two clubs in the same division that never meet is
   not a footnote — it decides what a table means. */
.gtag {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-secondary); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; white-space: nowrap;
}
.gtags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }

/* The personal rating, beside a score it does not enter. */
.note-line {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 10px 0 2px; padding: 8px 10px;
  background: var(--surface-2); border: 1px dashed var(--border); border-radius: 8px;
}
.note-line .num { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* The review queue's coverage strip: what the two columns are actually over. */
.qstatus { margin-bottom: 4px; }
.reflink { background: none; border: none; color: var(--series-1); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; padding: 0; }
.reflink:hover { color: var(--accent); background: none; }
/* The VAR hakemi beside the referee — same link, quieter voice: the crew's
   second name must never read louder than the first. */
.reflink.varlink { font-weight: 400; font-size: 11.5px; color: var(--text-secondary); white-space: nowrap; }
.reflink.varlink:hover { color: var(--accent); }
/* HakemTakipScore on the collapsed card, from the compact index — a number
   with a border so it reads as a measurement, not a goal count. */
.mini.hts {
  font-size: 11px; font-weight: 600; color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 999px; padding: 2px 7px;
  cursor: help;
}
/* The facts gate's "no score, and here is why" state — the tooltip carries
   the reason, the dash keeps the chip's footprint so rows stay aligned. */
.mini.hts.unscored { color: var(--text-muted); border-style: dashed; }
.chev { color: var(--text-muted); font-size: 10px; }
.mbody { border-top: 1px solid var(--border); padding: 14px 16px; background: var(--surface-2); }

.crew { display: flex; flex-wrap: wrap; gap: 6px 10px; }
.role {
  display: inline-flex; align-items: baseline; gap: 6px;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 6px; padding: 4px 9px; font-size: 12.5px;
}
.role .k { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.role.main { border-color: var(--accent); }
.role.pending { opacity: .55; font-style: italic; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 999px; padding: 2px 10px; color: var(--text-secondary);
}
.num { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text-primary); }

details.cardlist { margin-top: 10px; }
details.cardlist > summary { cursor: pointer; font-size: 12.5px; color: var(--text-secondary); }
.who { display: flex; flex-direction: column; gap: 3px; margin: 8px 0 2px; }
.wrow { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.wrow .min { min-width: 38px; text-align: right; font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: 11.5px; }
.wrow .sub { font-size: 11.5px; }

/* ---- decision book + discussion (Phase 5) ---- *
 *
 *  Two measures that must never read as one. The decision book is a bordered
 *  block like the comments; tartışma yoğunluğu is a single line above it with
 *  its own label, so the eye never groups a verdict with a volume.
 */
.dbook { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 10px; }
.dlist { display: flex; flex-direction: column; gap: 4px; margin: 6px 0 2px; }
.drow { display: flex; align-items: center; gap: 8px; font-size: 12.5px; flex-wrap: wrap; }
.drow .min { min-width: 38px; text-align: right; font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: 11.5px; }
.drow .dtype { font-weight: 600; }
.drow .sub, .drow .dnote { font-size: 11.5px; }
.drow .dnote { flex-basis: 100%; padding-left: 46px; color: var(--text-muted); }
.verdict { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; border: 1px solid var(--border); letter-spacing: .03em; }
.v-hatali { color: var(--card-red); border-color: var(--card-red); }
.v-dogru { color: var(--accent); border-color: var(--accent); }
.v-tartismali { color: var(--card-yellow); border-color: var(--card-yellow); }
.v-none { color: var(--text-muted); font-style: italic; }
.del-decision { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 14px; line-height: 1; padding: 0 4px; }
.del-decision:hover { color: var(--card-red); }
.decision-form { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; align-items: center; }
.decision-form input, .decision-form select {
  font: inherit; font-size: 12px; padding: 5px 8px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface-1); color: var(--text-primary);
}
.decision-form .d-minute { width: 60px; }
.decision-form .d-note { flex: 1; min-width: 150px; }
/* The dış kayıt form reuses the decision form's clothes; only widths differ. */
.eflag-form .ef-minute { width: 60px; }
.eflag-form .ef-match { max-width: 320px; }
.eflag-form .ef-url { flex: 1; min-width: 180px; }
.eflag-form label { display: inline-flex; align-items: center; gap: 4px; }
.add-decision {
  background: var(--surface-1); border: 1px solid var(--accent); color: var(--accent); border-radius: 8px;
  padding: 6px 14px; font-family: 'Barlow Condensed'; font-weight: 700; font-size: 13px;
  letter-spacing: .05em; text-transform: uppercase; cursor: pointer;
}
.add-decision:hover { background: var(--accent); color: var(--accent-ink); }

.discussion { display: flex; align-items: baseline; gap: 8px; margin-top: 12px; font-size: 12.5px; flex-wrap: wrap; }
.discussion .dlabel { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.discussion .sub { font-size: 11.5px; }
.discussion.flagged .num { color: var(--card-yellow); }

/* Career hero on the profile — one big number, and its coverage beneath it. */
.career-hero { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.career-hero .v { font-family: 'Barlow Condensed'; font-size: 40px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.career-hero .k { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.career-hero .sub { flex-basis: 100%; }

.cmts { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 10px; }
.cmt-h { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); margin-bottom: 6px; }
.note { background: var(--surface-1); border-radius: 8px; padding: 7px 11px; margin: 6px 0; font-size: 13px; }
.note time { display: block; font-size: 10.5px; color: var(--text-muted); margin-bottom: 2px; }
.note-form { display: flex; gap: 8px; margin-top: 8px; }
.note-form textarea {
  flex: 1; font: inherit; font-size: 13px; padding: 7px 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface-1); color: var(--text-primary);
  resize: vertical; min-height: 36px;
}
.add-note {
  background: var(--accent); border: none; color: var(--accent-ink); border-radius: 8px; padding: 7px 16px;
  font-family: 'Barlow Condensed'; font-weight: 700; font-size: 14px; letter-spacing: .05em; text-transform: uppercase;
}

/* ---- panels / charts (shared with v1 renderers) ---- */
.panel { background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px; padding: 18px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.chart-title { font-size: 15px; font-weight: 700; margin: 0 0 2px; }
.chart-sub { font-size: 12px; color: var(--text-secondary); margin: 0 0 14px; }
.bars { display: grid; gap: 7px; }
.bar-row, .div-row { display: grid; grid-template-columns: 140px 1fr 48px; align-items: center; gap: 10px; }
.bar-name { font-size: 12px; color: var(--text-secondary); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-track { position: relative; height: 13px; }
.bar-fill { height: 13px; background: var(--accent); border-radius: 0 4px 4px 0; min-width: 2px; transition: width .25s ease; }
.bar-row:hover .bar-fill { filter: brightness(1.12); }
.bar-val { font-size: 12px; font-variant-numeric: tabular-nums; font-weight: 600; }
.div-track { position: relative; height: 13px; background: var(--surface-2); border-radius: 3px; }
.div-mid { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px; background: var(--text-muted); opacity: .55; }
.div-fill { position: absolute; top: 2px; bottom: 2px; border-radius: 2px; }
.div-fill.home { background: var(--series-1); }
.div-fill.away { background: var(--card-yellow); }
.div-val { font-size: 11.5px; font-variant-numeric: tabular-nums; text-align: right; color: var(--text-secondary); }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.kpi { background: var(--surface-1); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.kpi .v { font-family: 'Barlow Condensed'; font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }
.kpi .k { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); margin-top: 2px; }
.kpi .n2 { font-size: 11.5px; color: var(--text-secondary); margin-top: 4px; }

table { border-collapse: collapse; width: 100%; font-size: 13px; }
th, td { text-align: left; padding: 6px 9px; border-bottom: 1px solid var(--border); }
th { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); font-weight: 600; }
td.n, th.n { text-align: right; font-variant-numeric: tabular-nums; }
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable:hover { color: var(--text-secondary); }
th.sortable[aria-sort] { color: var(--text-primary); }
th.sortable .arrow { opacity: .45; font-size: 9px; }
td .sub { font-size: 12px; }

.heat-scroll { overflow-x: auto; }
.heat { border-collapse: collapse; font-size: 12px; }
.heat th, .heat td { border: 1px solid var(--border); padding: 0; }
.heat th { position: sticky; top: 0; background: var(--surface-1); z-index: 1; }
.heat th.rowhead { position: sticky; left: 0; z-index: 2; text-align: right; padding: 4px 8px; white-space: nowrap; }
.heat td.cell { width: 26px; height: 24px; text-align: center; font-variant-numeric: tabular-nums; }
.heat .vert { writing-mode: vertical-rl; transform: rotate(180deg); padding: 6px 2px; font-weight: 600; font-size: 10.5px; }
#heatSide { margin-bottom: 8px; }
/* A cell that answers hover also answers a tap — phones have no hover. */
.heat td.cell[data-n] { cursor: pointer; }

.trend { width: 100%; height: 180px; display: block; }
.trend .grid { stroke: var(--border); stroke-width: 1; }
.trend .ref { stroke: var(--accent); stroke-width: 2.5; fill: none; }
.trend .avg { stroke: var(--text-muted); stroke-width: 1.5; fill: none; stroke-dasharray: 4 3; }
.trend .dot { fill: var(--accent); }
.trend text { fill: var(--text-muted); font-size: 10px; }
.legend { display: flex; gap: 14px; font-size: 11.5px; color: var(--text-secondary); margin-top: 6px; }
.legend i { display: inline-block; width: 16px; height: 2px; vertical-align: middle; margin-right: 5px; }
.legend i.ref { background: var(--accent); }
.legend i.avg { background: var(--text-muted); }

.tiermix { display: flex; gap: 2px; width: 120px; height: 10px; border-radius: 2px; overflow: hidden; }
.tiermix .seg { display: block; height: 100%; }
.tiermix .t1 { background: var(--accent); }
.tiermix .t2 { background: var(--series-1); }
.tiermix .t3 { background: var(--card-yellow); }
.tiermix .t4 { background: var(--text-muted); }
tr.benched td:first-child::after { content: ' ▲'; color: #e69138; }
.benched-key { color: #e69138; font-weight: 600; }
#tiers table td, #tiers table th { padding: 4px 8px; }

.comp-row { display: grid; grid-template-columns: 118px 1fr 72px; align-items: center; gap: 10px; margin-top: 6px; }
.comp-name { font-size: 12px; color: var(--text-secondary); text-align: right; }
.comp-track { height: 11px; background: var(--surface-2); border-radius: 3px; position: relative; overflow: hidden; }
.comp-fill { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: var(--accent); }
/* A component with no value has no track at all: the label and "veri yok" run
   together on one tight line, so an absent measurement takes less room than a
   real one instead of the same room drawn in hatching. */
.comp-row.empty { grid-template-columns: 118px 1fr; gap: 10px; margin-top: 3px; }
.comp-row.empty .comp-val { text-align: left; }
.comp-val { font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--text-secondary); text-align: right; }
.formula { font-size: 11px; color: var(--text-muted); margin-top: 12px; line-height: 1.55; }

/* ---- nasıl hesaplanır / records ---- */
.howto-link { color: var(--accent); text-decoration: none; border-bottom: 1px dotted currentColor; cursor: pointer; white-space: nowrap; }
.howto-link:hover { border-bottom-style: solid; }
.howto-p { font-size: 13px; line-height: 1.65; color: var(--text-secondary); margin-top: 10px; }
.howto-p code { font-size: 12px; }
.howto-table { width: 100%; border-collapse: collapse; margin-top: 10px; }
.howto-table th { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--border); }
.howto-table td { font-size: 13px; color: var(--text-secondary); padding: 7px 8px; border-bottom: 1px solid var(--border); vertical-align: top; }
.howto-table td strong { color: var(--text-primary); }
.howto-table td.n, .howto-table th.n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The disclaimer panel reads as a caution without shouting. */
.panel.warn { border-left: 3px solid var(--accent); }
/* Neutral by default: a difference is a description, not a verdict, so it is
   only tinted once it is large enough to be worth a second look. */
.delta { font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.delta.up { color: var(--series-1); }
.delta.down { color: var(--text-muted); }
tr.teamref { cursor: pointer; }
tr.teamref:hover td { background: var(--surface-2); }
.score-hero { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.score-hero .v { font-family: 'Barlow Condensed'; font-size: 32px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.score-hero .k { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); }
.badge { display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: .04em; padding: 1px 6px; border-radius: 4px; border: 1px solid var(--border); color: var(--text-secondary); }
.badge.fifa { border-color: var(--series-1); color: var(--series-1); }
.badge.ust { border-color: var(--accent); color: var(--accent); }
.badge.acc { border-color: var(--accent); color: var(--accent); }

/* ---- referee grid / ranking / profile ---- */
.refgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.refcard { background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px; padding: 16px; cursor: pointer; }
.refcard:hover { border-color: var(--accent); }
.rc-top { display: flex; justify-content: space-between; align-items: baseline; }
.rc-name { font-weight: 700; font-size: 15px; }
.rc-score { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 26px; color: var(--accent); font-variant-numeric: tabular-nums; }
.rc-badges { display: flex; gap: 6px; margin-top: 8px; align-items: center; flex-wrap: wrap; }

.top3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 14px; }
.topcard { background: var(--surface-1); border: 1px solid var(--border); border-radius: 14px; padding: 18px; cursor: pointer; }
.topcard:hover, .topcard.first { border-color: var(--accent); }
.tc-row { display: flex; justify-content: space-between; align-items: flex-start; }
.tc-rank, .tc-score { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 34px; line-height: 1; font-variant-numeric: tabular-nums; }
.tc-rank { color: var(--accent); }
.tc-name { font-weight: 700; font-size: 16px; margin-top: 10px; }
.ranklist { background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.rankrow { display: grid; grid-template-columns: 36px 1fr 180px 56px; align-items: center; gap: 12px; padding: 10px 16px; border-bottom: 1px solid var(--border); cursor: pointer; }
.rankrow:last-child { border-bottom: none; }
.rankrow:hover { background: var(--surface-2); }
.rankrow .rk { color: var(--text-muted); font-variant-numeric: tabular-nums; font-weight: 600; }
.rankrow .rn { font-weight: 600; }
.rankrow .rv { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.rank-bar { height: 8px; background: var(--surface-2); border-radius: 2px; position: relative; overflow: hidden; display: block; }
.rank-bar i { position: absolute; inset: 0 auto 0 0; background: var(--accent); border-radius: 2px; }

.profhero { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; }
.ph-left { flex: 1; min-width: 220px; }
.ph-name { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 38px; text-transform: uppercase; letter-spacing: .02em; line-height: 1.1; }
.ph-score { text-align: center; }
.ph-score .v { font-family: 'Barlow Condensed'; font-weight: 700; font-size: 62px; color: var(--accent); line-height: 1; font-variant-numeric: tabular-nums; }
.ph-score .k { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); margin-top: 2px; }

#tip {
  position: fixed; pointer-events: none; opacity: 0; transition: opacity .1s;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 11px; font-size: 12px; box-shadow: 0 6px 20px rgba(0,0,0,.3); z-index: 50;
  color: var(--text-primary); max-width: 260px;
  /* data-tip content is plain text; a multi-line tip (Katkı components)
     keeps its line breaks without anyone building markup for it. */
  white-space: pre-line;
}
#tip b { display: block; margin-bottom: 3px; }
#tip .muted { color: var(--text-secondary); }
footer { margin-top: 44px; font-size: 11.5px; color: var(--text-muted); border-top: 1px solid var(--border); padding-top: 16px; }

@media (max-width: 680px) {
  header.top { height: auto; flex-wrap: wrap; padding: 10px 14px; row-gap: 8px; }
  nav#tabs { order: 3; width: 100%; overflow-x: auto; }
  .mhead { grid-template-columns: 1fr; row-gap: 6px; }
  .grid2 { grid-template-columns: 1fr; }
  .top3 { grid-template-columns: 1fr; }
  .rankrow { grid-template-columns: 30px 1fr 50px; }
  .rankrow .rank-bar { display: none; }
  .bar-row, .div-row { grid-template-columns: 104px 1fr 44px; }
  .comp-row { grid-template-columns: 96px 1fr 64px; }
  /* The narrow override above sets three columns; the empty row has two, and
     without this it would inherit a phantom third and reopen the gap. */
  .comp-row.empty { grid-template-columns: 96px 1fr; }
  .howto-table { font-size: 12px; }
  .howto-table td:last-child { font-size: 11.5px; }
}

/* ------------------------------------------------------------------ *
 *  Layout utilities.
 *
 *  These replace the handful of style="" attributes that used to sit on
 *  the markup. They are named for what they do to the layout, not for
 *  the value they happen to carry, so changing the spacing is one edit
 *  here rather than a hunt through index.html.
 * ------------------------------------------------------------------ */
.gap-top { margin-top: 12px; }
.gap-top-lg { margin-top: 14px; }

/* A panel that breaks out of the two-column grid and runs full width. */
.span-all { grid-column: 1 / -1; }

/* A control sitting inside a line of prose — the table toggle, the trend
   picker — rather than on its own row. */
.inline-ctl { margin-left: 6px; }

/* The draft contribution score's caveat: visibly a warning, not a footnote. */
.warnline { border-left: 2px solid var(--card-yellow); padding-left: 10px; }

/* The name column takes whatever width the numbers leave behind, so full
   names render on ONE line at desktop widths — no ellipsis budget. Every
   other column sits at its natural nowrap width. Where the viewport genuinely
   cannot give the name a line (a phone), the span wraps at WORD boundaries to
   at most two lines; the full name rides the #tip only in that clamped case
   (data-tip-overflow, gated at hover time on the actual overflow).

   The cell CONTENT is a flex row (.pline): avatar fixed, name flexible with
   min-width:0, so a two-line name wraps BESIDE the avatar — vertically
   centred, never dropped under it. The flex lives on an inner wrapper, NOT
   on the td: a table-cell turned flex container loses its width:100% slack
   absorption (measured in Chrome — the column collapsed to its floor at
   1280px). The 44px in the floor is the 36px table avatar plus its gap; the
   24ch minimum belongs to the name text itself. */
#playerStats th, #playerStats td { white-space: nowrap; }
.roster-sec th, .roster-sec td { white-space: nowrap; }
#playerStats td.pname, .roster-sec td.pcell {
  width: 100%; min-width: calc(24ch + 44px);
  white-space: normal;
}
.pline { display: flex; align-items: center; }
.pname-t {
  flex: 1 1 auto; min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: normal;   /* between words only — never a mid-word cut */
}

/* ---- §photos: avatars, initials tiles, the lightbox ---- */
.avatar {
  width: 48px; height: 48px; border-radius: 50%; object-fit: cover;
  vertical-align: middle; margin-right: 8px; flex: none;
  background: var(--surface-2); border: 1px solid var(--border);
}
img.avatar[data-photo] { cursor: zoom-in; }
.avatar.init {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 700; letter-spacing: .02em; user-select: none;
  color: var(--text-secondary);
  background: color-mix(in srgb, hsl(var(--ah, 200) 45% 45%) 22%, var(--surface-2));
}
.avatar.lg { width: 72px; height: 72px; }
.avatar.lg.init { font-size: 22px; }
/* Table rows are dense: 36px there, while the base 48px stays for the match
   card's crew line and the .lg 72px for the profile hero. */
#playerStats .avatar, .roster-sec .avatar { width: 36px; height: 36px; }
#playerStats .avatar.init, .roster-sec .avatar.init { font-size: 12px; }

#lightbox {
  position: fixed; inset: 0; z-index: 70;      /* above overlays and #tip */
  display: grid; place-items: center; padding: 24px;
  background: rgba(0, 0, 0, .72);
}
#lightbox[hidden] { display: none; }
.lb-fig { position: relative; margin: 0; max-width: min(520px, 94vw); text-align: center; }
.lb-fig img {
  max-width: 100%; max-height: 72vh; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface-1);
}
.lb-fig figcaption { margin-top: 10px; color: #fff; font-size: 13px; }
.lb-fig figcaption b { display: block; font-size: 16px; margin-bottom: 4px; }
.lb-fig figcaption a { color: rgba(255, 255, 255, .8); text-decoration: underline; }
.lb-close {
  position: absolute; top: -14px; right: -14px; width: 32px; height: 32px;
  border-radius: 50%; border: 1px solid var(--border); cursor: pointer;
  background: var(--surface-1); color: var(--text-primary); font-size: 18px; line-height: 1;
}

/* The Oyuncular methodology, collapsed under the intro paragraph. */
details.method { margin: -4px 0 16px; }
details.method > summary { cursor: pointer; font-size: 12.5px; color: var(--accent); user-select: none; }
details.method > .method-body { margin-top: 6px; padding: 0 0 4px 12px; border-left: 2px solid var(--border); }
details.method .howto-p { font-size: 12px; margin-top: 8px; }

/* ---- score component detail (§Phase 9) ----
   The raw figures behind a 0-100, on hover where hover exists and on tap
   everywhere. Two delivery mechanisms, one piece of markup: a phone has no
   hover at all, and this page is mostly read on one. */
.comp-item { position: relative; }
.comp-item[data-comp] .comp-row { cursor: pointer; }
.comp-item[data-comp] .comp-row:hover .comp-name { color: var(--text-primary); }
.comp-detail {
  display: none; position: absolute; z-index: 30; left: 0; right: 0; top: 100%;
  margin-top: 4px; padding: 10px 12px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
@media (hover: hover) { .comp-item:hover .comp-detail { display: block; } }
.comp-item.open .comp-detail { display: block; }
.cd-head {
  font-family: 'Barlow Condensed'; font-weight: 700; font-size: 14px;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: 6px;
}
.cd-row { display: flex; justify-content: space-between; gap: 12px; font-size: 12px; padding: 2px 0; }
.cd-k { color: var(--text-secondary); }
.cd-v { font-variant-numeric: tabular-nums; white-space: nowrap; }
.cd-row.missing .cd-v { color: var(--text-muted); }
.cd-map {
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border);
  font-size: 11.5px; color: var(--text-secondary);
}

/* Sub-measures of a component, on the methodology page. Rendered from
   SCORE_MODEL so a component that gains an input describes itself here. */
.howto-subs { margin: 6px 0 0; padding-left: 18px; }
.howto-subs li { font-size: 12px; color: var(--text-muted); margin-bottom: 3px; }

/* A club name is a link wherever it appears. Styled as text, not as a button:
   a match card full of buttons reads as a form. */
.teamlink {
  background: none; border: none; padding: 0; font: inherit; cursor: pointer;
  color: inherit; text-align: inherit; border-bottom: 1px dotted transparent;
}
.teamlink:hover { background: none; color: var(--accent); border-bottom-color: currentColor; }
.teamlink.teams { font-weight: 600; font-size: 15px; }
tr.teamrow { cursor: pointer; }

/* Club crests. A fixed box sized by --crest, so a missing or still-loading
   file cannot shift the layout; when the image fails, the initials chip is
   revealed in the same box — never the browser's broken-image icon. */
.crest {
  position: relative; display: inline-block; flex: none;
  width: var(--crest, 20px); height: var(--crest, 20px);
  margin-right: 6px; vertical-align: middle;
}
.crest img { width: 100%; height: 100%; object-fit: contain; display: block; }
.crest .chip {
  display: none; position: absolute; inset: 0; border-radius: 50%;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text-secondary); font-weight: 600; line-height: 1;
  font-size: calc(var(--crest, 20px) * 0.4);
  align-items: center; justify-content: center;
}
.crest.miss img { display: none; }
.crest.miss .chip { display: flex; }

/* ------------------------------------------------------------------ *
 *  Season standings (puan durumu).
 *
 *  One DOM order, two layouts: on a phone the panel sits full-width ABOVE
 *  the match list (it is first in the wrapper), on a desktop the wrapper
 *  becomes a grid and the panel moves to a sticky side column on the right.
 *  The honours line under the season subtitle wraps onto its own row via
 *  flex-basis — the strip is already flex-wrap.
 * ------------------------------------------------------------------ */
.season-strip .honours { flex-basis: 100%; }
.season-strip .honours strong { color: var(--text-primary); }

#matchesWrap.with-standings { display: flex; flex-direction: column; gap: 12px; }
@media (min-width: 900px) {
  #matchesWrap.with-standings {
    display: grid; grid-template-columns: minmax(0, 1fr) 320px;
    gap: 14px; align-items: start;
  }
  #matchesWrap.with-standings .standings-panel {
    order: 2; position: sticky; top: 10px;
    max-height: calc(100vh - 20px); overflow-y: auto;
  }
}

.st-panel { padding: 12px 14px; }
.st-panel .chart-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 4px; }
.st-meta { margin: 0 0 6px; }
.st-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.st-table th {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted); font-weight: 600; text-align: right; padding: 2px 4px;
}
.st-table td { padding: 3px 4px; text-align: right; border-top: 1px solid var(--border); white-space: nowrap; }
.st-table .st-pos { color: var(--text-muted); width: 2ch; }
.st-table .st-team { text-align: left; max-width: 0; width: 99%; overflow: hidden; text-overflow: ellipsis; }
.st-table .st-team .teamlink { font-size: 12px; white-space: nowrap; }
.st-table .st-pts { font-weight: 700; }
.st-table tr.on td { background: var(--surface-2); }
/* A deduction is part of the row, not hidden in it. */
.st-ded { color: var(--accent); font-weight: 600; margin-left: 3px; cursor: help; }
/* Only rendered when the verification script recorded real diffs. */
.st-badge {
  font-size: 11px; font-weight: 600; color: var(--accent);
  border: 1px solid var(--accent); border-radius: 999px; padding: 1px 8px; cursor: help;
}
.st-note { margin: 6px 0 0; }

/* ------------------------------------------------------------------ *
 *  Loading feedback. Two patterns, both pure CSS animation:
 *
 *  .skel — shimmer placeholder bars for in-tab loads. The renderer lays
 *  them out at the real column widths, so the table does not reflow when
 *  data replaces them. The shimmer is a background-position sweep: one
 *  keyframe rule, no JS timer, and prefers-reduced-motion below freezes
 *  it to a plain grey bar.
 *
 *  .load-overlay — the full-page card for boot and a season switch,
 *  when there is nothing underneath worth interacting with. The ball
 *  rolls into the net on a 2 s loop; every colour is a theme token so
 *  the scene survives the light theme without a second drawing.
 * ------------------------------------------------------------------ */
.skel {
  display: inline-block; height: 12px; max-width: 100%; border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--border) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: skel-shimmer 1.4s linear infinite;
}
.skelrow { padding: 6px 0; }
/* background-position 200% → -200% at background-size 200% walks the
   highlight fully off-screen left, across, and off-screen right. */
@keyframes skel-shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.load-overlay {
  position: fixed; inset: 0; z-index: 60;  /* above #tip's 50 */
  display: flex; align-items: center; justify-content: center;
  background: rgba(6, 10, 16, .55); padding: 24px;
}
/* display:flex would beat the [hidden] attribute's UA display:none. */
.load-overlay[hidden] { display: none; }
.load-card {
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px;
  padding: 22px 26px 18px; width: min(320px, 100%);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  box-shadow: 0 12px 40px rgba(0,0,0,.4); text-align: center;
}
.load-label { font-size: 13px; color: var(--text-secondary); }

/* The stage: showLoading() injects exactly ONE scene (plus its escalation
   overlay) here, so seven scenes never mean seven DOM trees. Position:
   relative so the VAR/board overlays can sit on the scene. Each scene keeps
   its own natural size — the figures draw on tall canvases so faces,
   whistles, flags and board digits survive the 390px card. */
.load-stage { position: relative; display: flex; justify-content: center; }
.lo-scene-goal { width: 180px; height: 72px; }
.lo-refsvg, .lo-lines { width: 140px; height: 182px; }   /* 200×260 */
.lo-whistlesvg { width: 168px; height: 126px; }          /* 200×150 */
.lo-coinsvg { width: 150px; height: 197px; }             /* 160×210 */
.lo-pensvg { width: 190px; height: 114px; }              /* 200×120 */
.load-fact { font-size: 11.5px; color: var(--text-muted); }
.lo-ground { stroke: var(--border); stroke-width: 2; }
.lo-frame { stroke: var(--text-secondary); stroke-width: 2.5; fill: none; }
.lo-net { stroke: var(--border); stroke-width: 1; fill: none; }
.lo-ball-c { fill: var(--text-primary); }
.lo-ball-p { stroke: var(--surface-1); stroke-width: 1.6; fill: none; }
.lo-ball-pent { fill: var(--surface-1); }

/* The ball needs its own box as the rotation origin, or it orbits the
   SVG's 0,0 instead of rolling. */
.lo-ball {
  animation: lo-roll 2s linear infinite;
  transform-box: fill-box; transform-origin: center;
}
.lo-netg { animation: lo-net-bulge 2s linear infinite; }

/* 120 px of travel against a 56 px circumference is ~2 turns, so ~700deg
   reads as rolling rather than sliding. The hold from 64% is the ball
   sitting in the net before the loop resets behind a fade. */
@keyframes lo-roll {
  0%   { transform: translateX(0) rotate(0deg); opacity: 1; }
  58%  { transform: translateX(120px) rotate(680deg); opacity: 1; }
  64%  { transform: translateX(126px) rotate(700deg); }
  86%  { transform: translateX(126px) rotate(700deg); opacity: 1; }
  94%  { transform: translateX(126px) rotate(700deg); opacity: 0; }
  100% { transform: translateX(0) rotate(0deg); opacity: 0; }
}
@keyframes lo-net-bulge {
  0%, 57% { transform: translateX(0); }
  63%     { transform: translateX(3px); }
  72%, 100% { transform: translateX(0); }
}

/* ---------------- the referee scene (red / yellow card) ----------------
   A flat-illustration character: tube limbs with round joins, two tones per
   garment for volume, kit details that read at 140px. One figure, both
   cards: the SVG's data-card attribute picks the fill from the SAME tokens
   the match rows' swatches use, so the overlay can never drift from the
   colours the data wears. Every colour is a theme token. */
.lo-face, .lo-hand, .lo-neck { fill: var(--lo-skin); }
.lo-hair-f, .lo-eye { fill: var(--lo-hair); }
.lo-mouth { stroke: var(--lo-hair); stroke-width: 1.4; stroke-linecap: round; fill: none; }
.lo-shirt { fill: var(--lo-kit); }
.lo-shade { fill: var(--lo-kit-shade); }
.lo-collar-f { fill: var(--lo-collar); }
.lo-limb { stroke: var(--lo-skin); stroke-linecap: round; stroke-linejoin: round; fill: none; }
.lo-sleeve { stroke: var(--lo-kit); stroke-linecap: round; fill: none; }
.lo-sleeve-shade { stroke: var(--lo-kit-shade); }
.lo-sock { stroke: var(--lo-kit-shade); stroke-linecap: round; fill: none; }
.lo-sock-trim { stroke: var(--lo-collar); stroke-linecap: round; fill: none; }
.lo-boot-f { fill: var(--lo-boot); }
.lo-lanyard { stroke: var(--lo-collar); stroke-width: 1.3; fill: none; }
.lo-whistle { fill: var(--accent); }
.lo-card { fill: var(--card-red); }
.lo-refsvg[data-card="red"] .lo-card { fill: var(--card-red); }
.lo-refsvg[data-card="yellow"] .lo-card { fill: var(--card-yellow); }

/* One 3s timeline shared by every part, so the loop can never desync:
   0–40%   walk in — scale from small with a two-beat bob; the legs swing
           from the hips with the knee bending on the forward leg, the arms
           swing lightly on the OPPOSITE beats
   40–46%  the right arm rotates up shoulder-first
   42–49%  …the elbow bends after it, and the palm turns to the viewer
   47–55%  the card pops at the raised hand
   55–68%  the card alone glides to centre and scales to fill the scene
   68–88%  hold (0.6s), 88–96% fade, reset. */
.lo-ref {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: lo-ref-walk 3s ease-in-out infinite;
}
.lo-legL  { transform-box: view-box; transform-origin: 92px 150px;  animation: lo-swing-a 3s ease-in-out infinite; }
.lo-legR  { transform-box: view-box; transform-origin: 108px 150px; animation: lo-swing-b 3s ease-in-out infinite; }
.lo-calfL { transform-box: view-box; transform-origin: 92px 196px;  animation: lo-knee-a 3s ease-in-out infinite; }
.lo-calfR { transform-box: view-box; transform-origin: 108px 196px; animation: lo-knee-b 3s ease-in-out infinite; }
.lo-armL  { transform-box: view-box; transform-origin: 79px 72px;   animation: lo-swing-b 3s ease-in-out infinite; }
.lo-arm   { transform-box: view-box; transform-origin: 121px 72px;  animation: lo-arm-raise 3s ease infinite; }
.lo-forearm { transform-box: view-box; transform-origin: 125px 98px; animation: lo-elbow 3s ease infinite; }
.lo-hand  { transform-box: fill-box; transform-origin: center; animation: lo-palm 3s ease infinite; }
.lo-card {
  opacity: 0; transform-box: fill-box; transform-origin: center;
  animation: lo-card-show 3s ease infinite;
}
@keyframes lo-ref-walk {
  0%        { transform: translateY(0) scale(.35); }
  10%       { transform: translateY(-4px) scale(.5); }
  20%       { transform: translateY(-1px) scale(.64); }
  30%       { transform: translateY(-4px) scale(.82); }
  40%, 100% { transform: translateY(0) scale(1); }
}
@keyframes lo-swing-a {
  0%, 20%, 40%, 100% { transform: rotate(0deg); }
  10% { transform: rotate(10deg); }
  30% { transform: rotate(-8deg); }
}
@keyframes lo-swing-b {
  0%, 20%, 40%, 100% { transform: rotate(0deg); }
  10% { transform: rotate(-8deg); }
  30% { transform: rotate(10deg); }
}
@keyframes lo-knee-a {
  0%, 20%, 40%, 100% { transform: rotate(0deg); }
  12% { transform: rotate(14deg); }
}
@keyframes lo-knee-b {
  0%, 20%, 40%, 100% { transform: rotate(0deg); }
  32% { transform: rotate(14deg); }
}
@keyframes lo-arm-raise {
  0%, 20%, 40% { transform: rotate(0deg); }
  10% { transform: rotate(10deg); }
  30% { transform: rotate(-8deg); }
  46%, 100% { transform: rotate(-150deg); }
}
@keyframes lo-elbow {
  0%, 42%   { transform: rotate(0deg); }
  49%, 100% { transform: rotate(-20deg); }
}
@keyframes lo-palm {
  0%, 45%   { transform: scaleX(.45); }
  50%, 100% { transform: scaleX(1); }
}
@keyframes lo-card-show {
  0%, 47%   { opacity: 0; transform: none; }
  50%, 55%  { opacity: 1; transform: none; }
  68%, 88%  { opacity: 1; transform: translate(-39px, 117px) scale(8); }
  96%, 100% { opacity: 0; transform: translate(-39px, 117px) scale(8); }
}

/* The figure's chest badge takes the referee's initials on profile loads. */
.lo-badge-txt {
  fill: var(--lo-kit); font: 700 6.5px 'Barlow Condensed', sans-serif;
  text-anchor: middle; letter-spacing: .02em;
}
.lo-badge-big { font-size: 12px; }

/* ------------- the linesman: jog the line, raise the flag -------------
   Side view. The jog is a treadmill: the touchline dashes scroll under the
   scissoring legs, then everything stops and the flag goes straight up —
   offside. 3.5s loop; the flag is two tones from the card tokens. */
.lo-touch { stroke: var(--border); stroke-width: 2.5; stroke-dasharray: 16 12; animation: lo-touch-scroll 3.5s linear infinite; }
.lo-pole { stroke: var(--text-secondary); stroke-width: 2.5; stroke-linecap: round; }
.lo-flag-a { fill: var(--card-yellow); }
.lo-flag-b { fill: var(--card-red); }
.lo-kit2 { fill: var(--lo-collar); }
.lo-coin-c { fill: var(--card-yellow); stroke: var(--lo-kit-shade); stroke-width: 1.5; }
.lo-coin-l { stroke: var(--lo-kit-shade); stroke-width: 1.2; }
.lo-jog { transform-box: fill-box; transform-origin: 50% 100%; animation: lo-jog-bob 3.5s ease-in-out infinite; }
.lo-jlegF  { transform-box: view-box; transform-origin: 98px 150px;  animation: lo-jog-a 3.5s ease-in-out infinite; }
.lo-jlegB  { transform-box: view-box; transform-origin: 104px 150px; animation: lo-jog-b 3.5s ease-in-out infinite; }
.lo-jcalfF { transform-box: view-box; transform-origin: 98px 196px;  animation: lo-jog-kneeF 3.5s ease-in-out infinite; }
.lo-jcalfB { transform-box: view-box; transform-origin: 104px 196px; animation: lo-jog-kneeB 3.5s ease-in-out infinite; }
.lo-jarm   { transform-box: view-box; transform-origin: 97px 72px;   animation: lo-jog-b 3.5s ease-in-out infinite; }
.lo-flagarm { transform-box: view-box; transform-origin: 110px 73px; animation: lo-flag-raise 3.5s ease infinite; }
@keyframes lo-touch-scroll { 0% { stroke-dashoffset: 0; } 52%, 100% { stroke-dashoffset: -112px; } }
@keyframes lo-jog-bob {
  0%, 14%, 28%, 42%, 100% { transform: translateY(0); }
  7%, 21%, 35%, 49% { transform: translateY(-4px); }
  52% { transform: translateY(0); }
}
@keyframes lo-jog-a {
  0%, 28%, 52%, 100% { transform: rotate(0deg); }
  12% { transform: rotate(20deg); }
  40% { transform: rotate(-16deg); }
}
@keyframes lo-jog-b {
  0%, 28%, 52%, 100% { transform: rotate(0deg); }
  12% { transform: rotate(-16deg); }
  40% { transform: rotate(20deg); }
}
@keyframes lo-jog-kneeF {
  0%, 28%, 52%, 100% { transform: rotate(0deg); }
  40% { transform: rotate(24deg); }
}
@keyframes lo-jog-kneeB {
  0%, 28%, 52%, 100% { transform: rotate(0deg); }
  12% { transform: rotate(24deg); }
}
@keyframes lo-flag-raise {
  0%, 12%, 28%, 40%, 55% { transform: rotate(0deg); }
  20% { transform: rotate(6deg); }
  46% { transform: rotate(6deg); }
  64%, 100% { transform: rotate(-175deg); }
}

/* --------------- the whistle close-up: three short bursts --------------
   ~2s loop: pip, pip, pip. The arcs expand from the whistle's mouth; the
   head gives a small push on each burst. */
.lo-burst path { stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; fill: none; }
.lo-burst { opacity: 0; transform-box: view-box; transform-origin: 120px 77px; }
.lo-b1 { animation: lo-burst 2s ease-out infinite; }
.lo-b2 { animation: lo-burst 2s ease-out .5s infinite; }
.lo-b3 { animation: lo-burst 2s ease-out 1s infinite; }
.lo-wshead { transform-box: fill-box; transform-origin: 50% 90%; animation: lo-blow 2s ease-in-out infinite; }
@keyframes lo-burst {
  0%, 4% { opacity: 0; transform: scale(.55); }
  10% { opacity: 1; transform: scale(.85); }
  22% { opacity: 0; transform: scale(1.15); }
  23%, 100% { opacity: 0; transform: scale(.55); }
}
@keyframes lo-blow {
  0%, 4%, 29%, 54%, 100% { transform: scale(1); }
  8% { transform: scale(1.03, .97); }
  33% { transform: scale(1.03, .97); }
  58% { transform: scale(1.03, .97); }
}

/* ------------------- the toss: coin up, coin caught -------------------
   The spin is a scaleY illusion — a disc seen edge-on and face-on in
   turn — riding a translate parabola from the palm and back. */
.lo-coin { transform-box: fill-box; transform-origin: center; animation: lo-toss 3.2s ease-in-out infinite; }
@keyframes lo-toss {
  0%, 8% { transform: translateY(0) scaleY(1); }
  16% { transform: translateY(-38px) scaleY(.15); }
  24% { transform: translateY(-64px) scaleY(1); }
  32% { transform: translateY(-74px) scaleY(.15); }
  40% { transform: translateY(-64px) scaleY(1); }
  48% { transform: translateY(-34px) scaleY(.15); }
  56% { transform: translateY(-2px) scaleY(1); }
  60% { transform: translateY(-6px) scaleY(1); }
  64%, 100% { transform: translateY(0) scaleY(1); }
}

/* ------------- the penalty: keeper one way, ball the other ------------- */
/* The inner ball reuses the goal scene's classes for its fills — but NOT
   its roll: here the .lo-shot group owns the motion, and the inherited
   lo-roll once launched the ball clean off the canvas. */
.lo-pensvg .lo-ball { animation: none; }
.lo-shot { transform-box: fill-box; transform-origin: center; animation: lo-pen-shot 3s ease-in infinite; }
.lo-keeper { transform-box: view-box; transform-origin: 156px 88px; animation: lo-pen-dive 3s ease-in-out infinite; }
.lo-netg2 { animation: lo-pen-bulge 3s linear infinite; }
@keyframes lo-pen-shot {
  0%, 30% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  52% { transform: translate(120px, -4px) rotate(560deg); }
  86% { transform: translate(120px, -4px) rotate(560deg); opacity: 1; }
  94%, 100% { transform: translate(120px, -4px) rotate(560deg); opacity: 0; }
}
@keyframes lo-pen-dive {
  0%, 32% { transform: rotate(0deg) translate(0, 0); }
  52% { transform: rotate(-58deg) translate(-14px, 8px); }
  86% { transform: rotate(-58deg) translate(-14px, 8px); }
  96%, 100% { transform: rotate(0deg) translate(0, 0); }
}
@keyframes lo-pen-bulge {
  0%, 50% { transform: translateX(0); }
  56% { transform: translateX(4px); }
  66%, 100% { transform: translateX(0); }
}

/* The easter egg: a tap on the ball kicks it into the net immediately and
   it stays there — pure delight, no functional effect. The class dies with
   the scene, which is re-injected on the next showLoading call. */
.lo-ball.kicked { animation: lo-kick .5s ease-out forwards; }
.lo-shot .lo-ball.kicked { animation: none; }
.lo-shot:has(.lo-ball.kicked) { animation: lo-kick-pen .45s ease-out forwards; }
@keyframes lo-kick { to { transform: translateX(126px) rotate(700deg); } }
@keyframes lo-kick-pen { to { transform: translate(120px, -4px) rotate(560deg); } }

/* --------------------- escalation: VAR and the board -------------------
   Hidden until showLoading sets data-state="esc" on the card at 8s. The
   VAR mime draws its rectangle once (dashoffset), the hands part to the
   corners, the caption fades in; the board rises lit and its +N ticks via
   data-extra, exactly the way boards keep finding more time. */
.lo-esc { display: none; position: absolute; }
.lo-var { top: -6px; left: 50%; margin-left: -60px; width: 120px; height: 60px; }
.lo-board { right: -8px; bottom: -4px; width: 108px; height: 90px; }
.load-card[data-state="esc"][data-esc="var"] .lo-var { display: block; }
.load-card[data-state="esc"][data-esc="board"] .lo-board { display: block; animation: lo-board-rise .6s ease both; }
.lo-var-rect {
  fill: none; stroke: var(--accent); stroke-width: 3; stroke-linejoin: round;
  stroke-dasharray: 192; stroke-dashoffset: 192; animation: lo-var-draw 1.1s ease-out .1s both;
}
.lo-var-txt {
  fill: var(--accent); font: 700 17px 'Barlow Condensed', sans-serif;
  text-anchor: middle; letter-spacing: .12em; opacity: 0; animation: lo-var-cap .4s ease 1.1s both;
}
.lo-var-hand { fill: var(--lo-skin); animation: lo-var-handspread 1.1s ease-out .1s both; }
.lo-var-hand2 { animation-name: lo-var-handspread2; }
@keyframes lo-var-draw { from { stroke-dashoffset: 192; } to { stroke-dashoffset: 0; } }
@keyframes lo-var-cap { from { opacity: 0; } to { opacity: 1; } }
@keyframes lo-var-handspread { from { transform: translate(34px, 22px); } to { transform: translate(0, 0); } }
@keyframes lo-var-handspread2 { from { transform: translate(-34px, -22px); } to { transform: translate(0, 0); } }
.lo-board-panel { fill: var(--surface-2); stroke: var(--accent); stroke-width: 3; }
.lo-board-grip { fill: var(--text-muted); }
.lo-board-num {
  fill: var(--accent); font: 700 34px 'Barlow Condensed', sans-serif;
  text-anchor: middle; display: none;
}
.load-card:not([data-extra]) .lo-bnum1, .load-card[data-extra="1"] .lo-bnum1 { display: block; }
.load-card[data-extra="2"] .lo-bnum2 { display: block; }
.load-card[data-extra="3"] .lo-bnum3 { display: block; }
@keyframes lo-board-rise { from { transform: translateY(46px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* While a full load is in flight (showLoading adds this class): the cursor
   itself says "working" wherever it happens to be. The themed ball comes
   first; a browser that cannot use it falls back to the native progress
   cursor. Static PNG on purpose — browsers do not animate cursor images. */
body.is-loading, body.is-loading * {
  cursor: url('img/ball-cursor.png') 16 16, progress !important;
}

/* Acknowledgement inside the header: the label flips to the chosen season
   immediately, with this spinner beside it until data arrives. */
.mini-spin {
  display: inline-block; width: 12px; height: 12px; vertical-align: -1px;
  border: 2px solid var(--border); border-top-color: var(--accent);
  border-radius: 50%; animation: mini-spin .8s linear infinite;
}
@keyframes mini-spin { to { transform: rotate(360deg); } }

/* Static FINAL frames, not first frames: the ball sits in the net, the
   referee stands at full size holding the card up at the hand. The card,
   the label, and the timed messages still appear, because the feedback is
   the point and only the motion was the problem. */
@media (prefers-reduced-motion: reduce) {
  .skel, .mini-spin, .lo-netg, .lo-ref,
  .lo-legL, .lo-legR, .lo-calfL, .lo-calfR, .lo-armL { animation: none; }
  /* goal & penalty: the ball IN the net, the keeper already down */
  .lo-ball, .lo-ball.kicked { animation: none; transform: translateX(126px); }
  .lo-shot .lo-ball, .lo-shot .lo-ball.kicked { transform: none; }
  .lo-shot { animation: none; transform: translate(120px, -4px); }
  .lo-keeper { animation: none; transform: rotate(-58deg) translate(-14px, 8px); }
  .lo-netg2 { animation: none; }
  /* referee: full size, arm up, card shown */
  .lo-arm { animation: none; transform: rotate(-150deg); }
  .lo-forearm { animation: none; transform: rotate(-20deg); }
  .lo-hand { animation: none; }
  .lo-card { animation: none; opacity: 1; }
  /* linesman: stopped on the line, flag straight up */
  .lo-jog, .lo-jlegF, .lo-jlegB, .lo-jcalfF, .lo-jcalfB, .lo-jarm, .lo-touch { animation: none; }
  .lo-flagarm { animation: none; transform: rotate(-175deg); }
  /* whistle: bursts visible, held */
  .lo-wshead { animation: none; }
  .lo-burst { animation: none; opacity: 1; transform: none; }
  /* toss: the coin already caught on the palm */
  .lo-coin { animation: none; }
  /* escalation: the VAR rectangle fully drawn, the board already up */
  .lo-var-rect { animation: none; stroke-dashoffset: 0; }
  .lo-var-txt { animation: none; opacity: 1; }
  .lo-var-hand { animation: none; }
  .load-card[data-state="esc"][data-esc="board"] .lo-board { animation: none; }
}

/* §officials — roster-driven Hakemler tab: collapsible tier sections. */
.roster-sec { background: var(--surface-1); border: 1px solid var(--border); border-radius: 12px; margin-top: 10px; }
.roster-sec > summary { cursor: pointer; padding: 12px 16px; font-weight: 700; font-size: 14px; display: flex; align-items: center; gap: 10px; list-style: none; user-select: none; }
.roster-sec > summary::-webkit-details-marker { display: none; }
.roster-sec > summary::before { content: '▸'; color: var(--text-muted); transition: transform .15s; }
.roster-sec[open] > summary::before { transform: rotate(90deg); }
.roster-sec .cnt { font-size: 11px; font-weight: 600; color: var(--text-secondary); background: var(--surface-2); border-radius: 10px; padding: 1px 8px; }
/* Wide table scrolls inside the section; the page never scrolls sideways. */
.roster-sec .sec-body { overflow-x: auto; padding: 0 8px 8px; }
.roster-sec tr.rowlink { cursor: pointer; }
.roster-sec tr.rowlink:hover td { background: var(--surface-2); }
.rtag { font-size: 10px; color: var(--text-muted); border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; margin-left: 6px; white-space: nowrap; }
.rtag.warn { color: var(--card-yellow); border-color: var(--card-yellow); }
