/* FUTBL — design system
   ===========================================================================
   Three independent layers. Keeping them apart is the whole architecture:

     1  FUTBL CONSTANTS  brand, status, spacing, radius, motion, type.
                         Identical in every theme, for every tournament.

     2  APPEARANCE       light | dark, selected by [data-theme] on <html>.
                         Light is the default. Only token VALUES change here —
                         no component is redesigned between themes.

     3  TOURNAMENT       primary, accent, hero artwork and overlay, written
                         inline on <html> from the database.

   Dark mode is not Maso Cup mode. A blue-and-white tournament must work in
   both appearances, so components read semantic tokens (--surface-1,
   --text-primary) and never a literal colour or a tournament colour for
   anything a reader depends on.
   =========================================================================== */

:root{
  /* ---- 1. FUTBL constants ---- */
  /* The FUTBL brand board, verbatim. Slate is a NEUTRAL, not a text colour:
     it measures 4.44:1 on the ice background and 3.70:1 on dark surfaces, so
     the text inks below are derived from it rather than set to it. */
  --futbl-deep-teal:#064E52;
  --futbl-mint:#96DFCC;
  --futbl-near-black:#0B0D0E;
  --futbl-ice:#EDF8F5;
  --futbl-slate:#687477;
  --futbl-black:var(--futbl-near-black);
  --brand-gold:#D4AF37;
  --brand-red:#E30613;

  --live:#E30613;
  --success:#168A4A;
  --warning:#D99400;
  --info:#356AE6;
  --error:#D92D20;

  --space-1:4px;  --space-2:8px;  --space-3:12px; --space-4:16px;
  --space-5:20px; --space-6:24px; --space-8:32px; --space-10:40px; --space-12:48px;
  --gutter:16px;

  --radius-sm:8px; --radius-md:12px; --radius-lg:16px; --radius-xl:20px; --radius-pill:999px;

  --motion-fast:120ms; --motion-default:180ms; --motion-slow:280ms;

  --font-ui:'Inter',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  /* The scale from the design sheet, named so a heading picks a step rather
     than inventing a size: H1 28 Bold, H2 22 SemiBold, H3 18 SemiBold,
     body 14 Regular, caption 12 Medium. */
  --fs-display:28px; --lh-display:34px;
  --fs-title:22px;   --lh-title:28px;
  --fs-head:18px;    --lh-head:24px;
  --fs-lead:16px;    --lh-lead:22px;
  --fs-body:14px;    --lh-body:20px;
  --fs-caption:12px; --lh-caption:16px;
  /* Four weights. 650 and 750 were indistinguishable from their neighbours at
     these sizes, so they were three decisions pretending to be one system. */
  --fw-reg:400; --fw-med:500; --fw-semi:600; --fw-bold:700;
  /* Condensed faces belong inside tournament artwork, never in the interface. */
  --font-display:'Inter',system-ui,sans-serif;

  --nav-h:64px;
  --hero-h:196px;

  /* ---- 3. tournament defaults ----
     Overwritten inline per tournament; these are Maso Cup's. */
  --tour-primary:#D60012;
  --tour-accent:#F5B51B;
  --hero-x:50%;
  --hero-y:50%;
  --hero-overlay:.10;

  /* Tournament colour is decoration. Where it has to carry SMALL TEXT it is
     mixed toward the current foreground first, so a pale tournament colour can
     never make a label unreadable. The literal is the fallback. */
  --tour-ink:#D60012;
  /* 68%, not the raw colour: as small text the tournament primary lands at
     4.3:1 on the sheet surface, which sits lighter than the page. Mixing
     toward the foreground lifts it in dark and deepens it in light from one
     rule, and keeps working whatever colour a tournament sets. */
  --tour-ink:color-mix(in srgb, var(--tour-primary) 68%, var(--text-primary));
  /* Accent as TEXT. Raw gold is 1.82:1 on white; mixed 55% toward the
     foreground it is 4.87:1 in light and 12.9:1 in dark, from one rule. */
  --tour-accent-ink:#8E6C1A;
  --tour-accent-ink:color-mix(in srgb, var(--tour-accent) 55%, var(--text-primary));
  /* Live as TEXT. Raw #E30613 is 3.81:1 on a dark card; mixed 75% toward
     the foreground it clears AA in both appearances (4.71 / 7.37). The
     dot and the rail keep the pure colour — those are fills. */
  --live-ink:#E8424D;
  --live-ink:color-mix(in srgb, var(--live) 75%, var(--text-primary));
  /* Result badges. Mixed toward --text-primary like the others, so the same
     ratio darkens them on a light page and lightens them on a dark one. */
  --success-ink:#0F6F3B;
  --success-ink:color-mix(in srgb, var(--success) 76%, var(--text-primary));
  --error-ink:#B3241A;
  --error-ink:color-mix(in srgb, var(--error) 76%, var(--text-primary));
}

/* ---- 2. appearance: light (default) ---- */
:root,
[data-theme="light"]{
  /* White, as the board draws it. Ice mint is an ACCENT in the palette, not
     the page: used at full strength as the ground it tinted every screen
     green. It survives as the hover and fill tone below. */
  --background:#FFFFFF;
  --surface-1:#FFFFFF;
  --surface-2:#F2F8F6;
  --surface-3:#E7F1EE;
  --surface-hover:#F2F8F6;

  --text-primary:#0B0D0E;
  --text-secondary:#3E4C4F;
  /* Slate darkened to #5E6C6F: the brand value itself is 4.44:1 on the ice
     background, just under AA for the 12px metadata this token carries. */
  --text-tertiary:#5E6C6F;
  --text-disabled:#9DACAF;

  /* Cards sit on the same white as the page, so the border is what separates
     them. Faintly mint rather than neutral grey, so the brand still reads. */
  --border:#DDE7E4;
  --border-subtle:#EAF1EF;
  --border-strong:#C4D6D1;
  --overlay:rgba(11,13,14,.06);

  /* Product accent. Deep teal reads at 8.7:1 on the ice ground; mint is a
     FILL only here (1.4:1 as ink), carrying near-black text. */
  --accent:var(--futbl-deep-teal);
  --accent-ink:var(--futbl-deep-teal);
  --accent-fill:var(--futbl-mint);
  --on-accent-fill:var(--futbl-near-black);

  --shadow-card:0 1px 2px rgba(16,24,40,.04), 0 4px 12px rgba(16,24,40,.05);
  --shadow-pop:0 6px 12px rgba(16,24,40,.06), 0 18px 44px rgba(16,24,40,.14);
  --on-brand:#FFFFFF;
  --scrim:rgba(255,255,255,.72);
  /* A mono-white sponsor knockout is invisible on white, so it is inverted in
     light mode only. */
  --knockout-filter:invert(1);
  --crest-halo:rgba(17,19,24,.10);
}

[data-theme="dark"]{
  /* #1A1D23 is the dark ground named in the design, and it is deliberately a
     blue-grey charcoal rather than a black: the near-black this replaced read
     as "off", and flat black gives the cards nothing to sit against. Surfaces
     step UP from it so elevation reads the same way it does in light. */
  --background:#0B0D0E;
  --surface-1:#14181A;
  --surface-2:#1B2124;
  --surface-3:#232B2E;
  --surface-hover:#1B2124;

  --text-primary:#FFFFFF;
  --text-secondary:#AFBDBF;
  /* Slate lightened to #7C8A8D: the brand value is 3.70:1 on surface-1, well
     under AA for metadata. */
  --text-tertiary:#7C8A8D;
  --text-disabled:#5B686B;

  --border:#232B2E;
  --border-subtle:#1A2022;
  /* Brand slate, used where an edge should actually show. */
  --border-strong:var(--futbl-slate);

  /* Mint is the accent on dark, at 12.7:1. */
  --accent:var(--futbl-mint);
  --accent-ink:var(--futbl-mint);
  --accent-fill:var(--futbl-mint);
  --on-accent-fill:var(--futbl-near-black);

  /* The accent inks are mixed against --text-primary, so lifting the ground to
     #1A1D23 cost them contrast: at the shared ratios they measured 4.12 and
     3.98 on surface-1, both under the AA floor for the 13px labels they carry.
     More white in the mix, only in dark. */
  --tour-ink:color-mix(in srgb, var(--tour-primary) 52%, var(--text-primary));
  --live-ink:color-mix(in srgb, var(--live) 56%, var(--text-primary));
  /* Same reason: the W/D/L badges sit on a tinted plate that is itself dark,
     so the shared ratio left the letter at 4.24:1. */
  --success-ink:color-mix(in srgb, var(--success) 48%, var(--text-primary));
  --error-ink:color-mix(in srgb, var(--error) 52%, var(--text-primary));
  --overlay:rgba(255,255,255,.04);

  --shadow-card:0 1px 2px rgba(0,0,0,.28), 0 8px 24px rgba(0,0,0,.18);
  --shadow-pop:0 6px 12px rgba(0,0,0,.45), 0 20px 48px rgba(0,0,0,.55);
  /* The accent is mint here, and white on mint is 1.53:1. */
  --on-brand:var(--futbl-near-black);
  --scrim:rgba(26,29,35,.72);
  --knockout-filter:none;
  --crest-halo:rgba(255,255,255,.10);
}

/* ---- aliases ----
   The components were written against the previous names. Mapping them here
   means every rule below inherits light/dark for free, without a rewrite that
   would risk the layout while the appearance work is in flight. New rules
   should use the semantic names above. */
:root{
  --bg:var(--background);
  --card:var(--surface-1);
  --card-2:var(--surface-2);
  --surface:var(--surface-1);
  --text-muted:var(--text-tertiary);
  --ink:var(--text-primary); --ink-2:var(--text-secondary); --mute:var(--text-tertiary);
  --line:var(--border); --line-2:var(--border-strong);

  /* These used to alias the TOURNAMENT colour, which is why the entire product
     turned red for Maso Cup. They now carry the FUTBL accent; the tournament
     keeps the hero, so a second competition changes the artwork and not the
     whole interface. */
  --brand-primary:var(--accent);
  --brand-accent:var(--accent-fill);
  --brand-ink:var(--accent-ink);
  --red:var(--accent); --sun:var(--accent-fill);
  --red-soft:color-mix(in srgb, var(--accent) 12%, transparent);
  --sun-tint:color-mix(in srgb, var(--accent-fill) 16%, transparent);
  --on-sun:var(--on-accent-fill); --on-accent:var(--on-brand);
  --on-accent-2:rgba(255,255,255,.85); --on-accent-3:rgba(255,255,255,.72);
  --on-live:#FFFFFF; --on-live-2:rgba(255,255,255,.75);
  --on-media:#FFFFFF; --on-media-2:rgba(255,255,255,.92); --on-media-3:rgba(255,255,255,.68);
  --media-sun:#FFD98A;

  --s-1:var(--space-1); --s-2:var(--space-2); --s-3:var(--space-3); --s-4:var(--space-4);
  --s-5:var(--space-6); --s-6:var(--space-8); --s-7:var(--space-12);
  --r-btn:10px; --r-card:var(--radius-lg); --r-pill:var(--radius-pill);
  --r-hero:var(--radius-xl); --r-sheet:var(--radius-xl); --r:var(--radius-lg); --r-s:10px;
  --shadow:var(--shadow-card);

  --body:var(--font-ui); --mono:var(--font-ui); --display:var(--font-display);
  --chrome:color-mix(in srgb, var(--background) 86%, transparent);
  --header-bg:var(--background);
  --header-fade:linear-gradient(180deg,var(--background) 0%,transparent 100%);

  /* Films used to be white-on-dark. They now follow the foreground so the same
     rule reads on either appearance. */
  --film-1:var(--overlay);
  --film-2:var(--surface-2);
  --film-3:var(--surface-3);
  --film-4:var(--surface-3);
  --film-5:var(--border-strong);

  --field:var(--surface-1);
  --field-hi:var(--surface-1);
  --field-line:var(--border-strong);
  --field-line-hi:var(--text-tertiary);
  --field-solid:var(--surface-2);
  --focus-ring:color-mix(in srgb, var(--accent) 26%, transparent);
  --picker-filter:none;
  --toast:var(--surface-1);
  --toast-line:var(--border-strong);
  --crest-halo-xl:var(--crest-halo);
}

/* ---- Cup ----
   A third appearance, not a tournament setting: the cup's own red, gold, white
   and black, chosen from the More screen like Light and Dark.

   Two things have to move that do not move between Light and Dark. Red is the
   PAGE here, so --live cannot also be red or the live dot disappears into the
   background; it becomes gold. And the error ink cannot be red for the same
   reason. Everything else is the usual surface ladder, stepped in red. */
[data-theme="cup"]{
  --background:#7E010C;
  --surface-1:#96040F;
  --surface-2:#A80A15;
  --surface-3:#B9101B;
  --surface-hover:#A80A15;

  --text-primary:#FFFFFF;
  --text-secondary:#F6DDDF;
  --text-tertiary:#EAC4C7;
  --text-disabled:#C4898E;

  --border:rgba(255,255,255,.18);
  --border-subtle:rgba(255,255,255,.10);
  --border-strong:rgba(255,255,255,.34);
  --overlay:rgba(255,255,255,.07);

  --shadow-card:0 1px 2px rgba(0,0,0,.30), 0 8px 24px rgba(0,0,0,.26);
  --shadow-pop:0 6px 12px rgba(0,0,0,.44), 0 20px 48px rgba(0,0,0,.54);
  --scrim:rgba(126,1,12,.78);
  /* A mono-white sponsor knockout already reads on red. */
  --knockout-filter:none;
  --picker-filter:invert(1) brightness(1.7);

  /* Gold is the accent. The lighter gold is the TEXT weight of it: #F5B51B
     measures 4.23:1 on surface-2, under AA for the 12px labels it carries. */
  --accent:#F5B51B;
  --accent-ink:#FFD166;
  --accent-fill:#F5B51B;
  --on-accent-fill:#2A0206;
  --on-brand:#2A0206;

  /* Red cannot mean "live" on a red page. */
  --live:#FFD166;
  --live-ink:#FFD166;
  --on-live:#2A0206;
  --success-ink:#9DE8BC;
  --error-ink:#FFC2C6;
  --tour-ink:#FFD166;
  --tour-accent-ink:#FFD166;
}
/* The date/time picker glyphs ship dark, which suits a light field and
   disappears on a dark one. */
[data-theme="dark"]{ --picker-filter:invert(1) brightness(1.7); }

/* The select chevron is drawn by us, so it needs a colour per appearance. */
:root{--chev:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235F6672' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>")}
[data-theme="dark"]{--chev:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A8AFB9' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>")}

*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%;background:var(--bg)}
body{
  font-family:var(--font-ui);font-size:14px;line-height:20px;font-weight:400;
  color:var(--text-primary);background:var(--bg);min-height:100vh;
  padding-bottom:calc(var(--nav-h) + var(--space-8) + env(safe-area-inset-bottom));
  -webkit-font-smoothing:antialiased;
}
body.admin{padding-bottom:var(--s-6)}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input,select{font:inherit;color:var(--text-primary)}
/* Digits line up in every column they appear in. */
.score,.mc-val,td,th,.pos,.ds-n,.stat b,.mc-clock{font-variant-numeric:tabular-nums}
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible{
  outline:2px solid var(--brand-accent);outline-offset:2px;border-radius:var(--r-btn)}
.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}

.wrap{max-width:720px;margin:0 auto;padding:0 var(--gutter)}
/* Every screen starts the same distance below the bar. Before this the gap was
   whatever the first block happened to carry: pages opening on a .sec inherited
   24px from its margin, while Teams, Bracket, Team Profile and Match Centre
   opened flush against the bar. The first child's own top margin is zeroed so
   the two never stack. The home hero is outside <main>, so it stays full bleed. */
main > .wrap{padding-top:var(--space-5)}
main > .wrap > :first-child{margin-top:0}

/* ---- type scale ---- */
.t-display{font-family:var(--font-display);font-size:var(--fs-display);line-height:var(--lh-display);font-weight:var(--fw-bold);
  text-transform:uppercase;letter-spacing:.01em}
.t-title{font-size:var(--fs-title);line-height:var(--lh-title);font-weight:var(--fw-bold);letter-spacing:-.02em}
.t-section{font-size:18px;line-height:24px;font-weight:700;letter-spacing:-.01em}
.t-team{font-size:16px;line-height:22px;font-weight:600;letter-spacing:-.005em}
.t-meta{font-size:12px;line-height:16px;font-weight:500;color:var(--text-secondary)}
.t-label{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:var(--fw-bold);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-muted)}
/* A label introducing a card needs air between the two, or it reads as part of
   the card's own chrome. Scoped to h3 so the group label inside a .sec row on
   the Tables screen -- an h2 in a flex header -- is left alone. */
h3.t-label{margin-bottom:var(--space-3)}

/* ---- section heading ---- */
.sec{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-3);
  margin:var(--s-6) 0 var(--s-4)}
.sec:first-child{margin-top:var(--s-5)}
.sec h2{font-size:var(--fs-head);line-height:var(--lh-head);font-weight:var(--fw-semi);letter-spacing:-.015em}
.sec a,.sec small{font-size:var(--fs-body);line-height:var(--lh-body);font-weight:var(--fw-med);color:var(--text-muted)}

/* =========================================================================
   APP BAR — the platform's chrome, above the tournament's. Sits on the shell
   colour, never on a tournament colour.
   ========================================================================= */
.appbar{position:sticky;top:0;z-index:30;background:var(--bg);
  border-bottom:1px solid var(--border)}
.appbar .wrap{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);height:56px}
/* The platform lockup. Sized by HEIGHT so it sits on the bar's optical centre
   whatever the artwork's aspect ratio turns out to be. */
.ab-mark{flex:none;display:inline-flex;align-items:center}
.ab-mark img{height:20px;width:auto;display:block}
/* Three grounds, three lockups: teal on white, mint on near-black, plain white
   on the cup red. A filter cannot do this: the mark is not monochrome. */
.ab-mark .on-dark,.ab-mark .on-cup{display:none}
[data-theme="dark"] .ab-mark .on-light{display:none}
[data-theme="dark"] .ab-mark .on-dark{display:block}
[data-theme="cup"] .ab-mark .on-light{display:none}
[data-theme="cup"] .ab-mark .on-cup{display:block}
.ab-title{flex:1;min-width:0;display:inline-flex;align-items:center;justify-content:center;
  gap:6px;font-size:15px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--text-primary);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.ab-title svg{width:16px;height:16px;flex:none;stroke:var(--text-muted);fill:none;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round}
.ab-actions{flex:none;display:flex;align-items:center;gap:var(--s-1)}
.ab-btn{position:relative;width:38px;height:38px;border-radius:var(--r-pill);
  display:flex;align-items:center;justify-content:center;color:var(--text-secondary)}
.ab-btn svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.ab-btn:hover{background:var(--surface-2);color:var(--text-primary)}
.ab-btn[aria-pressed=true]{color:var(--accent-ink)}
/* The pip says alerts are armed — the one piece of state worth a dot. */
.ab-pip{position:absolute;top:7px;right:8px;width:7px;height:7px;border-radius:50%;
  background:var(--brand-primary);border:2px solid var(--bg)}

/* =========================================================================
   HERO — the tournament's own artwork, full bleed. The single gradient in the
   product exists here, to hold type over it.
   ========================================================================= */
.hero{background:var(--surface-1);border-bottom:1px solid var(--border)}
.hero-art{position:relative;height:var(--hero-h);overflow:hidden;background:var(--surface-2)}
.hero-art picture{display:block;height:100%}
/* The admin sets the crop: --hero-x / --hero-y come from the tournament. */
.hero-img{width:100%;height:100%;object-fit:cover;
  object-position:var(--hero-x,50%) var(--hero-y,50%)}
/* A flat veil at the configured strength — separate from any gradient, so the
   admin's overlay slider means one predictable thing. */
.hero-veil{position:absolute;inset:0;pointer-events:none;
  background:var(--futbl-black);opacity:var(--hero-overlay,.1)}
.hero-body{padding:var(--space-4) var(--gutter);display:flex;flex-direction:column;gap:10px}
.hero-facts{display:flex;flex-direction:column;gap:7px}
.hf{display:inline-flex;align-items:center;gap:9px;font-size:var(--fs-body);font-weight:var(--fw-semi);
  letter-spacing:0;color:var(--text-secondary)}
.hf svg{width:15px;height:15px;flex:none;stroke:var(--accent-ink);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.hero-live{align-self:flex-start;display:inline-flex;align-items:center;gap:9px;
  font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--text-primary)}

/* =========================================================================
   MATCH ROW — one component, three states.
   A list, not a stack of outlined boxes: rows share one surface and are
   separated by a hairline, which is what makes twenty-seven fixtures read as
   a fixture list. Live is marked by its indicator and a thin accent down the
   edge; the surface never turns red. The score is the hero.
   ========================================================================= */
.mlist{display:flex;flex-direction:column;gap:var(--space-3);margin-bottom:var(--space-5)}
.match{position:relative;display:flex;flex-direction:column;gap:10px;
  padding:var(--space-4);background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-lg);transition:border-color var(--motion-default),
  background var(--motion-default)}
/* No accent bar on a live row. The reference marks live with the indicator and
   the score alone; the extra vertical rule sat hard against the card edge and
   read as a stray border rather than as meaning. */
/* A live card keeps the ordinary border. In the reference, live is carried
   by the indicator, the word and the red score — not by the card's edge.
   Status is still never colour alone: the dot is paired with "Live". */

.mr-top{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);
  min-height:17px}
.mr-state{display:inline-flex;align-items:center;gap:7px;font-size:var(--fs-caption);line-height:var(--lh-caption);
  font-weight:var(--fw-semi);letter-spacing:-.005em;color:var(--text-tertiary)}
.match.sched .mr-state{color:var(--text-primary);font-weight:700}
.match.live .mr-state{color:var(--live-ink)}
.mr-clock{font-size:var(--fs-caption);font-weight:var(--fw-bold);color:var(--live-ink);font-variant-numeric:tabular-nums}
.dot{width:7px;height:7px;border-radius:50%;background:var(--live);flex:none;
  animation:pulse 2s ease-in-out infinite}
@keyframes pulse{50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){.dot{animation:none}}

.mr-rows{display:flex;flex-direction:column;gap:10px}
.mr-row{display:grid;grid-template-columns:28px 1fr auto;align-items:center;gap:var(--space-3)}
.mr-row .crest{width:28px;height:28px;object-fit:contain;flex:none}
.mr-name{font-size:16px;line-height:22px;font-weight:600;letter-spacing:-.005em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-primary)}
.mr-val{font-size:var(--fs-title);line-height:var(--lh-title);font-weight:var(--fw-bold);letter-spacing:-.02em;
  color:var(--text-primary);min-width:20px;text-align:right;font-variant-numeric:tabular-nums}
/* Deliberately NOT coloured. Red was marking live state, the leading score,
   the active tab and every link at once; when one colour means everything it
   stops meaning anything. The dot carries "live", the weight carries "ahead". */
.match.live .mr-row:not(.lost) .mr-val{color:var(--text-primary)}
.match.final .mr-row.lost .mr-name,
.match.final .mr-row.lost .mr-val{color:var(--text-tertiary)}
.mr-meta{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:var(--fw-med);color:var(--text-tertiary)}
.mr-fav,.mc-fav{color:var(--accent-ink)}
.match.mine{background:color-mix(in srgb, var(--accent-fill) 7%, var(--surface-1))}

/* =========================================================================
   HOME — a doorway per block.
   ========================================================================= */
.sec h2 .dot{margin-right:9px;vertical-align:middle}
.chev-i{display:inline-block;width:7px;height:7px;flex:none;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(-45deg);opacity:.7}
.panel{display:grid;grid-template-columns:1fr auto;align-items:center;gap:var(--space-3);
  padding:var(--space-4);background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-lg);margin-bottom:var(--space-4)}
.panel-k{grid-column:1;font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.09em;
  text-transform:uppercase;color:var(--text-tertiary)}
.panel b{grid-column:1;font-size:16px;font-weight:var(--fw-semi);letter-spacing:-.01em;margin-top:2px}
.panel small{grid-column:1;font-size:var(--fs-caption);font-weight:var(--fw-med);color:var(--text-tertiary);margin-top:2px}
.panel .chev-i{grid-column:2;grid-row:1 / span 3;color:var(--text-tertiary)}
.tbl-more{display:flex;align-items:center;justify-content:flex-end;gap:8px;
  padding-top:var(--space-3);margin-top:var(--space-2);border-top:1px solid var(--border-subtle);
  font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--accent-ink)}

/* =========================================================================
   FILTERS — two jobs, two controls.

   Competition is NAVIGATION: it changes the URL, so it reads as a segmented
   control, one row, always visible, the way a tab set does.

   Day and the refinements act on the rendered list. They sit apart, hold their
   own state, and the bar tells you how many matches survived and offers a way
   back once anything is on. Mixing the two in one row of identical chips was
   the clutter.
   ========================================================================= */
.f-comps{display:flex;gap:var(--s-1);overflow-x:auto;scrollbar-width:none;
  margin:0 calc(var(--gutter) * -1) var(--s-3);padding:0 var(--gutter);
  -webkit-overflow-scrolling:touch;scroll-snap-type:x proximity}
.f-comps::-webkit-scrollbar{display:none}
.seg{flex:none;scroll-snap-align:start;display:inline-flex;align-items:center;
  height:34px;padding:0 var(--s-3);border-radius:var(--r-btn);
  font-size:14px;font-weight:600;letter-spacing:-.005em;white-space:nowrap;
  color:var(--text-secondary);transition:color .16s,background .16s}
.seg:hover{color:var(--text-primary)}
.seg[aria-selected=true]{background:var(--surface-2);color:var(--text-primary);font-weight:var(--fw-semi)}

/* Day: a light segmented row, not a card. */
/* The day strip: a big date, a small weekday, a rule under the selected one —
   not a filled block, which at this size shouts louder than the fixtures do. */
.dates{display:flex;gap:var(--space-2);overflow-x:auto;scrollbar-width:none;
  margin:0 calc(var(--gutter) * -1) var(--space-4);padding:0 var(--gutter);
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch}
.dates::-webkit-scrollbar{display:none}
.ds{position:relative;flex:none;scroll-snap-align:start;
  display:flex;flex-direction:column;align-items:center;gap:1px;min-width:64px;
  padding:var(--space-2) var(--space-3) 10px;background:none}
.ds-d{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-tertiary)}
.ds-n{font-size:var(--fs-title);line-height:var(--lh-title);font-weight:var(--fw-bold);letter-spacing:-.02em;
  color:var(--text-secondary);font-variant-numeric:tabular-nums}
.ds-c{font-size:var(--fs-caption);font-weight:var(--fw-med);color:var(--text-tertiary)}
.ds:hover .ds-n{color:var(--text-primary)}
.ds[aria-pressed=true] .ds-n{color:var(--text-primary)}
.ds[aria-pressed=true] .ds-d{color:var(--accent-ink)}
.ds[aria-pressed=true]::after{content:"";position:absolute;left:var(--space-2);
  right:var(--space-2);bottom:0;height:3px;border-radius:3px 3px 0 0;
  background:var(--accent)}

/* =========================================================================
   DAY HEADING — sentence case. "Friday 18 September" is language;
   "FRIDAY 18 SEP" is a database field.
   ========================================================================= */
.day{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-3);
  margin:var(--s-6) 0 var(--s-3)}
/* A day divider is a label, not a heading. At 19px/700 it was one pixel
   from .sec h2 and the two read as the same level, which flattened the page. */
.day h3{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:var(--fw-bold);
  letter-spacing:.08em;text-transform:uppercase;color:var(--text-tertiary)}
.day span{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:var(--fw-med);color:var(--text-tertiary)}

/* =========================================================================
   TABLES
   ========================================================================= */
.tbl-wrap{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--r-card);padding:var(--s-2) var(--s-4) var(--s-3);overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:var(--fs-body)}
th{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-muted);text-align:right;padding:var(--s-2) 5px;white-space:nowrap}
td{padding:10px 5px;text-align:right;border-top:1px solid var(--border);
  color:var(--text-secondary);font-size:var(--fs-caption);font-weight:var(--fw-med)}
th:first-child,td:first-child{text-align:left;padding-left:0}
td:first-child{color:var(--text-primary);font-weight:600;font-size:14px;
  display:flex;align-items:center;gap:var(--s-2)}
td:first-child .crest{width:22px;height:22px;object-fit:contain;flex:none}
td.pts{font-weight:700;color:var(--text-primary);font-size:15px;padding-right:0}
th:last-child{padding-right:0}
.pos{display:inline-block;width:14px;color:var(--text-muted);font-size:12px;font-weight:600}
/* Qualification is a 2px rule on the position, not a tinted row. */
tr.q td:first-child{box-shadow:inset 2px 0 0 var(--success);padding-left:var(--s-2)}
tr[data-clubrow].fav td:first-child::after{content:"★";color:var(--brand-accent);font-size:10px}

/* =========================================================================
   BRACKET
   A round is a column; the columns pan sideways. Each round is centred against
   its neighbour so a final sits level with the semis that feed it, and a
   connector shows which tie leads where.
   ========================================================================= */
/* ---- select ----
   A native <select> popup is drawn by the operating system. It ignores the
   page radius, spacing, hover state and accent -- and on some platforms the
   colours too -- so no amount of CSS on `option` makes the open list match the
   product. The native element is therefore kept as the source of truth (it
   holds the value and submits with the form) while the list the user actually
   SEES is ours, built from the same tokens as everything else.

   With JS off none of that exists and the native select is the whole control,
   which is why it is still fully styled here. */
.sel{position:relative;display:block;width:100%;min-width:0}
.sel select,
.admin select,
.picker select{
  appearance:none;-webkit-appearance:none;width:100%;height:44px;
  padding:0 40px 0 var(--space-4);border-radius:var(--radius-md);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-primary);
  font-family:var(--font-ui);font-size:14.5px;font-weight:600;letter-spacing:-.005em;
  cursor:pointer;text-overflow:ellipsis;
  transition:border-color var(--motion-default),background var(--motion-default)}
.sel select:hover,.admin select:hover,.picker select:hover{border-color:var(--border-strong)}
.sel select:focus,.admin select:focus,.picker select:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring)}
/* Only reached without JS, where the OS draws the list: it does not inherit the
   page, so both colours are stated and the ground must be OPAQUE or the options
   render white-on-white. */
.sel option,.admin option,.picker option,
.sel optgroup,.admin optgroup,.picker optgroup{
  background-color:var(--surface-1);color:var(--text-primary);font-weight:600}

/* Fallback chevron. Once enhanced the trigger draws its own -- which can rotate
   -- so every container-drawn one is switched off. */
.sel::after,.picker::after{content:"";position:absolute;right:16px;top:50%;
  width:8px;height:8px;margin-top:-6px;pointer-events:none;
  border-right:2px solid var(--text-tertiary);border-bottom:2px solid var(--text-tertiary);
  transform:rotate(45deg);border-radius:1px}
.sel-on::after,
.picker:has(.sel-on)::after,
.admin .fld:has(.sel-on)::after,
.admin .dt-bar label:has(.sel-on)::after{display:none}
.sel-on select{display:none}

/* ---- the trigger ---- */
.sel-btn{display:flex;align-items:center;width:100%;height:44px;
  padding:0 var(--space-3) 0 var(--space-4);border-radius:var(--radius-md);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-primary);
  font-family:var(--font-ui);font-size:14.5px;font-weight:600;letter-spacing:-.005em;
  cursor:pointer;text-align:left;
  transition:border-color var(--motion-default),background var(--motion-default),
    box-shadow var(--motion-default)}
.sel-cur{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sel-chev{flex:none;width:8px;height:8px;margin:0 6px 0 var(--space-3);
  border-right:2px solid var(--text-tertiary);border-bottom:2px solid var(--text-tertiary);
  border-radius:1px;transform:translateY(-2px) rotate(45deg);
  transition:transform var(--motion-default)}
.sel-btn:hover{border-color:var(--border-strong);background:var(--surface-hover)}
.sel-btn:focus-visible,.sel-btn[aria-expanded="true"]{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring)}
.sel-btn[aria-expanded="true"] .sel-chev{transform:translateY(1px) rotate(225deg)}

/* ---- the list ---- */
.sel-list{position:absolute;z-index:60;top:calc(100% + 6px);left:0;
  min-width:100%;max-width:min(340px,92vw);box-sizing:border-box;
  margin:0;padding:var(--space-2);list-style:none;
  background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-pop);
  max-height:min(320px,56vh);overflow-y:auto;overscroll-behavior:contain;
  animation:selIn var(--motion-fast) ease-out}
/* Flipped above the trigger when there is no room below. */
.sel-list[data-flip="up"]{top:auto;bottom:calc(100% + 6px)}
@keyframes selIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

.sel-opt{display:grid;grid-template-columns:1fr 12px;align-items:center;gap:var(--space-3);
  width:100%;min-height:40px;padding:0 var(--space-3);
  border:0;background:none;border-radius:var(--radius-sm);
  font-family:var(--font-ui);font-size:14.5px;font-weight:600;letter-spacing:-.005em;
  color:var(--text-primary);text-align:left;cursor:pointer}
.sel-opt + .sel-opt{margin-top:2px}
.sel-opt > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Pointer hover and the keyboard cursor are deliberately the SAME state: two
   highlights moving independently is how these lists get confusing. */
.sel-opt:hover,.sel-opt.is-cursor{background:var(--surface-hover)}
.sel-opt:focus{outline:none}
/* The label stays on --text-primary rather than the accent. Tournament colours
   are set by the organiser, and an accent dark enough to read here is not one
   we can guarantee; the tint and the tick carry the accent instead, and both
   are graphics, which need 3:1 rather than 4.5:1. */
.sel-opt[aria-selected="true"]{color:var(--text-primary);
  background:color-mix(in srgb, var(--accent) 8%, transparent)}
.sel-opt[aria-selected="true"] i{border-color:var(--accent-ink)}
.sel-opt[aria-selected="true"]:hover,.sel-opt[aria-selected="true"].is-cursor{
  background:color-mix(in srgb, var(--accent) 14%, transparent)}
/* The tick is the only thing that says "this is the current value", so it is
   drawn rather than left to colour alone. */
.sel-opt i{display:none;width:6px;height:10px;justify-self:center;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:translateY(-2px) rotate(45deg)}
.sel-opt[aria-selected="true"] i{display:block}

.sel-sm .sel-btn{height:38px;font-size:var(--fs-body);padding:0 var(--space-2) 0 var(--space-3)}
.sel-sm select{height:38px;font-size:var(--fs-body);padding:0 34px 0 var(--space-3)}
.sel-sm::after{right:13px}
.picker{position:relative;display:block;margin-bottom:var(--space-4)}
.picker svg{display:none}

@media (prefers-reduced-motion:reduce){
  .sel-list{animation:none}
  .sel-chev{transition:none}
}

/* A phone shows one 246px column and a sliver of the next, so the rounds stack
   instead: read down, exactly the order results happen in. Columns return from
   720px where there is room to see the shape of the draw. */
.bracket{display:flex;flex-direction:column;gap:var(--space-5)}
.br-round{display:flex;flex-direction:column;min-width:0}
.br-round > h3{padding:0 0 var(--space-3);
  font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-tertiary)}
.br-ties{display:flex;flex-direction:column;gap:var(--space-3)}

.br-tie{position:relative;display:flex;flex-direction:column;gap:10px;
  padding:var(--space-3) var(--space-4);background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--radius-md);
  transition:border-color var(--motion-default),background var(--motion-default)}
.br-tie:hover{background:var(--surface-hover);border-color:var(--border-strong)}
.br-side{display:grid;grid-template-columns:24px 1fr auto;align-items:center;gap:10px}
.br-side .crest{width:24px;height:24px;object-fit:contain}
/* A placeholder is a slot, not a team: a neutral square reads as "waiting"
   where a dashed circle read as a broken image. */
.br-dot{width:24px;height:24px;border-radius:var(--radius-sm);background:var(--surface-3)}
.br-side b{font-size:var(--fs-body);font-weight:var(--fw-semi);letter-spacing:-.005em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.br-side s{text-decoration:none;font-size:var(--fs-head);font-weight:var(--fw-bold);
  font-variant-numeric:tabular-nums}
.br-side.tbd b{color:var(--text-tertiary);font-weight:500}
.br-side.out b,.br-side.out s{color:var(--text-tertiary)}
.br-meta{display:inline-flex;align-items:center;gap:7px;padding-top:var(--space-2);
  border-top:1px solid var(--border-subtle);
  font-size:var(--fs-caption);font-weight:var(--fw-med);color:var(--text-tertiary)}
.br-tie.is-live .br-meta{color:var(--live-ink)}
/* Stacked, the join between rounds is a short vertical line, which is the same
   statement the horizontal connector makes when there is room for columns. */
.br-round:not(:last-child)::after{content:"";width:2px;height:var(--space-4);
  margin:var(--space-3) auto calc(var(--space-5) * -1 + var(--space-2));
  background:var(--border-strong);border-radius:2px}

@media (min-width:720px){
  .bracket{flex-direction:row;gap:var(--space-6);overflow-x:auto;scrollbar-width:none;
    align-items:stretch;margin:0 calc(var(--gutter) * -1);
    padding:0 var(--gutter) var(--space-4)}
  .bracket::-webkit-scrollbar{display:none}
  .br-round{flex:0 0 250px}
  .br-round > h3{position:sticky;top:0;z-index:1;background:var(--background)}
  /* space-around is what puts a single final level with the two semis. */
  .br-ties{flex:1;justify-content:space-around;gap:var(--space-4)}
  .br-round:not(:last-child)::after{display:none}
  .br-round:not(:last-child) .br-tie::after{content:"";position:absolute;
    left:100%;top:50%;width:var(--space-6);height:2px;background:var(--border-strong)}
}

.br-champ{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4);
  border-radius:var(--radius-md);background:var(--surface-1);
  border:1px solid color-mix(in srgb, var(--accent-fill) 46%, var(--border))}
.br-champ .crest{width:40px;height:40px;object-fit:contain;flex:none}
.br-champ span{display:block;font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.09em;
  text-transform:uppercase;color:var(--accent-ink)}
.br-champ b{display:block;font-size:16px;font-weight:700;letter-spacing:-.01em;margin-top:2px}

/* =========================================================================
   TEAMS
   ========================================================================= */
.team{display:flex;align-items:center;gap:var(--s-3);background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--r-card);
  padding:var(--s-3) var(--s-4);margin-bottom:var(--s-2)}
.team-link{display:flex;align-items:center;gap:var(--s-3);flex:1;min-width:0}
.team .crest{width:36px;height:36px;object-fit:contain;flex:none}
.team .n b{display:block;font-size:16px;line-height:22px;font-weight:600;letter-spacing:-.005em}
.team .n span{display:block;font-size:12px;line-height:16px;color:var(--text-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.follow{flex:none;height:32px;padding:0 var(--s-3);border-radius:var(--r-pill);
  border:1px solid var(--border-strong);color:var(--text-secondary);
  font-size:12px;font-weight:var(--fw-semi);white-space:nowrap;transition:all .16s}
.follow[aria-pressed=true]{background:var(--brand-accent);border-color:var(--brand-accent);
  color:var(--on-sun)}

.team-hero{display:flex;align-items:center;gap:var(--s-4);padding:var(--s-5) var(--s-4);
  border-radius:var(--r-card);border:1px solid var(--border);background:var(--surface-1);
  margin-bottom:var(--s-4);position:relative;overflow:hidden}
.team-hero .crest{width:64px;height:64px;object-fit:contain;flex:none;position:relative;z-index:1}
.team-hero > div{min-width:0;position:relative;z-index:1}
.team-hero h2{font-size:24px;line-height:30px;font-weight:700;letter-spacing:-.02em;
  margin-bottom:var(--s-2);overflow-wrap:anywhere}
/* A single flat wash of the club's colour, at low opacity. No gradient. */
.team-wash{position:absolute;inset:0;opacity:.14;pointer-events:none}
.statline{display:flex;gap:var(--s-2);margin-bottom:var(--s-4)}
.stat{flex:1;background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--r-btn);padding:var(--s-3) var(--s-2);text-align:center}
.stat b{display:block;font-size:var(--fs-title);line-height:var(--lh-title);font-weight:var(--fw-bold)}
.stat span{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:var(--fw-bold);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-muted)}

/* =========================================================================
   SPONSORS — quiet by default, colour on interaction. Below the football.
   ========================================================================= */
.sponsors{display:flex;gap:var(--s-5);overflow-x:auto;scrollbar-width:none;align-items:center;
  margin:0 calc(var(--gutter) * -1);padding:var(--s-2) var(--gutter) var(--s-4);
  -webkit-overflow-scrolling:touch}
.sponsors::-webkit-scrollbar{display:none}
.sp-item{flex:none;height:34px;display:flex;align-items:center;justify-content:center}
.sp-item img{height:100%;width:auto;max-width:132px;object-fit:contain;
  opacity:.42;transition:opacity .18s,filter .18s}
.sp-item:hover img,.sp-item:focus-visible img{opacity:1}

/* ---- sponsor artwork ----
   A "none" plate means the file is a mono-white knockout: it carries no ground
   of its own, so on a light page it is white on near-white and simply does not
   appear. --knockout-filter inverts it to dark ink in light and leaves it alone
   in dark -- which is what that token was added for and was never wired to. */
.plate-none img{filter:var(--knockout-filter)}
/* A light-plate file has its own white ground baked in, so it needs that ground
   back under it once the page goes dark. */
[data-theme="dark"] .plate-light img{background:#FFF;border-radius:4px}

/* ---- major partners, home ----
   The strip elsewhere is deliberately a quiet backdrop. These are the partners
   the organiser put on the front page, so they are full strength and on their
   own plates rather than floating at 42%. */
.majors{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-2);
  margin-bottom:var(--space-2)}
.mj-item{display:flex;align-items:center;justify-content:center;height:64px;
  padding:var(--space-3);background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--radius-md);
  transition:border-color var(--motion-default),background var(--motion-default)}
a.mj-item:hover{border-color:var(--border-strong);background:var(--surface-hover)}
.mj-item img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.mj-item .sp-word{font-size:var(--fs-caption);line-height:var(--lh-caption);text-align:center}
@media (min-width:600px){.majors{grid-template-columns:repeat(4,1fr)}}

/* The Sponsors page itself: a quiet wall, not a carousel. */
.sp-wall{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));
  gap:var(--s-5) var(--s-4);align-items:center;padding:var(--s-2) 0}
/* On the Partners page the sponsors are the subject rather than the backdrop,
   so they sit at a higher rest opacity than the home strip. Still monochrome —
   colour is still the reward for interacting. */
.sp-wall .sp-item{height:44px;width:100%}
.sp-wall .sp-item img{max-width:100%;opacity:.72}
.sp-tier{margin:var(--s-6) 0 var(--s-3)}

/* =========================================================================
   BOTTOM NAVIGATION — Matches · Tables · Bracket · Teams
   ========================================================================= */
nav.tabbar{position:fixed;bottom:0;left:0;right:0;z-index:20;
  background:var(--chrome);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border-top:1px solid var(--border);padding-bottom:env(safe-area-inset-bottom)}
nav.tabbar .wrap{display:flex;height:var(--nav-h);padding:0;align-items:stretch}
/* Sentence case at a readable size, not uppercase micro-type.
   Letterspaced capitals are a utility-bar convention; every app people
   actually compare this to labels its bottom bar the way a person would
   write it, and it reads faster at 11px than SMALL CAPS do. */
nav.tabbar a{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:4px;color:var(--text-muted);font-size:11px;line-height:13px;
  font-weight:var(--fw-med);letter-spacing:0;transition:color .16s}
nav.tabbar svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;transition:stroke-width .16s}
/* Colour carries the active state, with the icon drawn a touch heavier. A rule
   under the tab belongs to a top tab strip; on a bottom bar it reads as a
   stray underline against the screen edge. */
nav.tabbar a[aria-current=page]{color:var(--brand-ink);font-weight:var(--fw-semi)}
nav.tabbar a[aria-current=page] svg{stroke-width:2.2}

/* ---- footer ---- */
/* ---- empty state ---- */
.empty{text-align:center;padding:var(--s-7) var(--s-4);color:var(--text-muted)}
.empty b{display:block;font-size:16px;font-weight:600;color:var(--text-secondary);
  margin-bottom:var(--s-1)}
.note{font-size:12px;line-height:18px;color:var(--text-muted);margin:var(--s-4) 0}

/* ---- buttons ---- */
.btn{display:inline-flex;align-items:center;justify-content:center;height:44px;
  padding:0 var(--s-5);border-radius:var(--r-btn);font-size:14px;font-weight:var(--fw-semi);
  background:var(--brand-accent);color:var(--on-sun);border:1px solid var(--brand-accent);
  white-space:nowrap;transition:filter .16s}
.btn:hover{filter:brightness(1.06)}
.btn:active{transform:translateY(1px)}
.btn.sm{height:36px;padding:0 var(--s-4);font-size:var(--fs-body)}
.btn.ghost{background:transparent;border-color:var(--border-strong);color:var(--text-secondary);filter:none}
.btn.ghost:hover{border-color:var(--brand-primary);color:var(--text-primary);background:var(--red-soft)}
.btn.quiet{background:transparent;border-color:var(--border-strong);color:var(--text-secondary);filter:none}
.btn.quiet:hover{border-color:var(--brand-accent);color:var(--text-primary)}
form.dirty .btn.quiet{background:var(--brand-accent);border-color:var(--brand-accent);color:var(--on-sun)}

.cta{background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-card);
  padding:var(--s-4)}
.cta b{display:block;font-size:18px;line-height:24px;font-weight:700;margin-bottom:var(--s-1)}
.cta p{font-size:var(--fs-body);line-height:var(--lh-body);color:var(--text-secondary);margin-bottom:var(--s-4)}

.flash{background:var(--sun-tint);border:1px solid rgba(245,181,27,.3);border-radius:var(--r-btn);
  padding:var(--s-3) var(--s-4);font-size:var(--fs-body);font-weight:var(--fw-med);margin-bottom:var(--s-3)}

/* ---- poster (About) ---- */
.poster{display:block;border-radius:var(--r-card);overflow:hidden;border:1px solid var(--border)}
.poster img{width:100%;height:auto}

/* =========================================================================
   LIVE ALERTS
   ========================================================================= */
.toasts{position:fixed;z-index:40;display:flex;flex-direction:column;gap:var(--s-2);
  left:var(--gutter);right:var(--gutter);
  bottom:calc(var(--nav-h) + var(--s-3) + env(safe-area-inset-bottom));pointer-events:none}
.toast{pointer-events:auto;display:flex;align-items:center;gap:var(--s-3);
  padding:var(--s-3);border-radius:var(--r-btn);color:var(--text-primary);
  background:var(--toast);border:1px solid var(--toast-line);
  box-shadow:var(--shadow-card);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  animation:toast-in .22s cubic-bezier(.2,.8,.3,1) both}
.toast.out{animation:toast-out .18s ease-in both}
.toast-tag{flex:none;align-self:flex-start;font-size:10px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;padding:4px 7px;border-radius:var(--r-pill);
  background:var(--film-3);color:var(--text-secondary);white-space:nowrap}
.toast-goal .toast-tag{background:var(--live);color:#fff}
.toast-full .toast-tag{background:var(--brand-accent);color:var(--on-sun)}
.toast-body{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px}
.toast-body b{font-size:var(--fs-body);font-weight:var(--fw-semi);line-height:var(--lh-body);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.toast-body span{font-size:var(--fs-caption);font-weight:var(--fw-med);color:var(--text-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.toast-x{flex:none;width:24px;height:24px;border-radius:50%;font-size:16px;line-height:1;
  color:var(--text-muted);display:flex;align-items:center;justify-content:center}
.toast-x:hover{background:var(--film-3);color:var(--text-primary)}
@keyframes toast-in{from{opacity:0;transform:translateY(10px) scale(.98)}}
@keyframes toast-out{to{opacity:0;transform:translateY(6px) scale(.98)}}
.match.flash-in{animation:flash-in 1.4s ease-out both}
@keyframes flash-in{0%,50%{border-color:var(--brand-accent)}100%{border-color:var(--border)}}
@media (prefers-reduced-motion:reduce){
  .toast,.toast.out,.match.flash-in{animation:none}
  .toast.out{opacity:0}
}

/* =========================================================================
   BREAKPOINTS — the layout is mobile-first; wider screens only get more room.
   ========================================================================= */
@media (min-width:560px){
  :root{--hero-h:240px}
  .mc-row{grid-template-columns:44px 1fr auto}
  .mc-row .crest{width:44px;height:44px}
  .match{grid-template-columns:1fr 132px}
}
@media (min-width:760px){
  /* --nav-h drives the bar's height AND the clearance body reserves for it,
     so overriding it here keeps the two in step at this width. */
  :root{--gutter:24px; --nav-h:56px}
  nav.tabbar .wrap{height:var(--nav-h)}
  nav.tabbar a{flex-direction:row;gap:var(--s-2);font-size:var(--fs-body);font-weight:var(--fw-semi)}
  .sponsors{gap:var(--s-6)}
}
@media (max-width:359px){
  .match{grid-template-columns:1fr 92px}
  .mc-row{grid-template-columns:32px 1fr auto;gap:var(--s-2)}
  .mc-row .crest{width:32px;height:32px}
  .mc-val{font-size:23px;line-height:26px}
  .mc-name{font-size:15px}
  .ds{min-width:92px}
}

/* ===== carried over: organiser ===== */
/* The public wrap is 720px, which suits a reading column but crushes a
   five-column score row. max-width only binds on wide screens, so this needs
   no breakpoint. */
.admin .wrap{max-width:1180px}

/* ---- organiser ----
   The same shell as the app: near-black, charcoal surfaces, Inter, the 8px
   scale. An organiser entering results on a phone at the ground is using the
   same product as the supporter watching them, and it should feel like it. */

.adminbar{position:sticky;top:0;z-index:30;background:var(--bg);
  border-bottom:1px solid var(--border)}
.adminbar .wrap{display:flex;align-items:center;gap:var(--s-4);min-height:58px;
  flex-wrap:wrap;padding-top:var(--s-2);padding-bottom:var(--s-2)}
.adminbar b{flex:none;display:inline-flex;align-items:center;gap:9px;white-space:nowrap;
  font-family:var(--font-ui);font-size:14px;font-weight:700;letter-spacing:-.01em;
  text-transform:none;color:var(--text-primary)}
.adminbar b::before{content:"";width:8px;height:8px;border-radius:var(--r-pill);
  background:var(--brand-accent);flex:none}
.admin-nav{display:flex;gap:var(--s-1);overflow-x:auto;flex:1;scrollbar-width:none}
.admin-nav::-webkit-scrollbar{display:none}
.admin-nav a{padding:0 var(--s-3);height:34px;display:inline-flex;align-items:center;
  border-radius:var(--r-btn);font-size:14px;font-weight:600;letter-spacing:-.005em;
  white-space:nowrap;color:var(--text-secondary);transition:background .16s,color .16s}
.admin-nav a:hover{color:var(--text-primary);background:var(--surface-2)}
.admin-nav a[aria-current=page]{background:var(--surface-2);color:var(--text-primary);font-weight:var(--fw-semi)}
.admin-right{font-size:13px;color:var(--text-muted);white-space:nowrap}
.admin-right a{font-weight:600;color:var(--text-secondary)}
.admin-right a:hover{color:var(--brand-accent)}

/* Page heading. */
.admin .sec,.admin .h{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s-3);margin:var(--s-6) 0 var(--s-4)}
.admin .h h2,.admin .sec h2{font-family:var(--font-ui);font-size:22px;line-height:28px;
  font-weight:700;letter-spacing:-.02em;text-transform:none}
.admin .h h3,.admin .sec h3{font-family:var(--font-ui);font-size:17px;line-height:22px;
  font-weight:700;letter-spacing:-.01em;text-transform:none}
.admin .h small{font-size:13px;font-weight:500;color:var(--text-muted);
  letter-spacing:0;text-transform:none}
.admin main .wrap{padding-top:var(--s-2);padding-bottom:var(--s-7)}

/* Rows. One surface, a hairline, generous padding — no nesting. */
.card{background:var(--surface-1);border:1px solid var(--border);border-radius:var(--r-card);
  padding:var(--s-4);margin-bottom:var(--s-3)}
.result-row,.club-row{padding:var(--s-4);margin-bottom:var(--s-3);
  transition:background .14s,box-shadow .14s}
.result-row:focus-within,.club-row:focus-within,.sp-row:focus-within{background:var(--surface-2)}
form.dirty.card{box-shadow:inset 3px 0 0 var(--brand-accent)}
.rr-meta{font-size:12.5px;color:var(--text-muted);font-weight:500;letter-spacing:.01em;
  text-transform:none;margin-bottom:var(--s-3)}
.rr-meta b{color:var(--text-secondary);font-weight:var(--fw-semi)}

/* ---- the control system ----
   Scoped to .admin so the public site's chips and inputs are untouched. */
/* Same shape as the app's fields — height, radius, border and focus all come
   from the shared tokens, so a dropdown in the organiser and a dropdown in the
   app are recognisably the same control. */
.admin input:where(:not([type=color]):not([type=file]):not([type=radio]):not([type=checkbox])),
.admin select,
.admin textarea{
  height:44px;width:100%;min-width:0;box-sizing:border-box;
  border:1px solid var(--border);border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text-primary);
  padding:0 var(--space-4);font-family:var(--font-ui);font-size:14.5px;font-weight:600;
  letter-spacing:-.005em;
  transition:border-color var(--motion-default),background var(--motion-default),
  box-shadow var(--motion-default)}
.admin input:hover:not(:focus),.admin select:hover:not(:focus){
  border-color:var(--border-strong)}
.admin input:focus,.admin select:focus,.admin textarea:focus{
  outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--focus-ring)}
.admin ::placeholder{color:var(--mute);opacity:1;font-weight:500}

/* Native select chrome differs on every OS, so the arrow is drawn here and the
   browser's is removed. --chev carries a themed stroke colour. */
.admin select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:40px}
/* Drawn once, in the shared component, so every dropdown carries the same mark. */
.admin .fld,.admin .dt-bar label{position:relative}
.admin .fld:has(select)::after,.admin .dt-bar label:has(select)::after{
  content:"";position:absolute;right:16px;bottom:15px;width:8px;height:8px;
  pointer-events:none;border-right:2px solid var(--text-tertiary);
  border-bottom:2px solid var(--text-tertiary);transform:rotate(45deg);border-radius:1px}
/* The calendar/clock buttons ship as dark glyphs; invert them on dark grounds. */
.admin input[type=date]::-webkit-calendar-picker-indicator,
.admin input[type=time]::-webkit-calendar-picker-indicator{
  filter:var(--picker-filter);opacity:.6;cursor:pointer;transition:opacity .14s}
.admin input[type=date]:hover::-webkit-calendar-picker-indicator,
.admin input[type=time]:hover::-webkit-calendar-picker-indicator{opacity:1}

/* Colour well: the default control is a bevelled OS swatch with its own
   padding, so the wrapper and swatch are both restyled to match the fields. */
.admin input[type=color]{width:46px;height:44px;flex:none;padding:0;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface-1)}
.admin input[type=color]:hover{border-color:var(--field-line-hi)}
.admin input[type=color]::-webkit-color-swatch-wrapper{padding:4px}
.admin input[type=color]::-webkit-color-swatch{border:0;border-radius:8px}
.admin input[type=color]::-moz-color-swatch{border:0;border-radius:8px}

/* File picker: a real control, not a bare browser button. */
.upload{position:relative;display:inline-flex;align-items:center;gap:7px;height:44px;padding:0 14px;
  border:1px dashed var(--border-strong);border-radius:var(--radius-md);font-size:11.5px;font-weight:var(--fw-bold);
  color:var(--ink-2);cursor:pointer;white-space:nowrap;transition:border-color .14s,background .14s,color .14s}
.upload:hover{border-color:var(--sun);color:var(--ink);background:var(--field)}
.upload:focus-within{border-color:var(--sun);box-shadow:0 0 0 3px var(--focus-ring)}
.upload input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%}

/* ---- buttons ----
   Three weights. Gold is reserved for the one primary action on a page; the
   per-row Save is quiet until its row is actually edited, so a 27-row list is
   not 27 gold buttons competing with each other. */
.btn{display:inline-flex;align-items:center;justify-content:center;height:44px;padding:0 18px;
  border-radius:var(--radius-md);font-weight:var(--fw-bold);font-size:13px;line-height:1;white-space:nowrap;
  background:var(--sun);color:var(--on-sun);text-decoration:none;text-align:center;
  border:1px solid var(--sun);cursor:pointer;transition:filter .14s,background .14s,border-color .14s,color .14s}
.btn:hover{filter:brightness(1.08)}
.btn:active{transform:translateY(1px)}
.btn.sm{height:36px;padding:0 var(--s-4);font-size:13px;border-radius:var(--r-btn)}
.btn.ghost{background:transparent;border:1px solid var(--field-line-hi);color:var(--ink-2);filter:none}
.btn.ghost:hover{border-color:var(--red);color:var(--ink);background:var(--red-soft)}
.btn.quiet{background:transparent;border:1px solid var(--field-line-hi);color:var(--ink-2);filter:none}
.btn.quiet:hover{border-color:var(--sun);color:var(--ink)}
/* Lit by admin.js the moment anything in the row changes. */
form.dirty .btn.quiet{background:var(--sun);border-color:var(--sun);color:var(--on-sun)}
form.dirty .btn.quiet:hover{filter:brightness(1.08)}

/* ---- rows ---- */
.result-row,.club-row,.sp-row{padding:13px 14px;transition:background .14s,box-shadow .14s}
.result-row:focus-within,.club-row:focus-within,.sp-row:focus-within{background:var(--card-2)}
form.dirty.card{box-shadow:var(--shadow),inset 3px 0 0 var(--sun)}
.rr-meta{font-size:10px;color:var(--mute);font-weight:800;text-transform:uppercase;
  letter-spacing:.09em;margin-bottom:10px}
.rr-meta b{color:var(--ink-2)}
.rr-grid{display:grid;grid-template-columns:1fr 56px auto 56px 1fr;gap:var(--s-3);align-items:center}
.rr-club .crest,.club-grid .crest{width:28px;height:28px}
/* 'Scheduled' needs 70px and the auto track gave it 72 — two pixels is not
   headroom, it is luck. The drawn chevron reserves 34px on the right. */
.admin .rr-grid select[name=status],
.admin .rr-grid .sel:has(select[name=status]){min-width:148px}
.rr-club{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;
  letter-spacing:-.005em;min-width:0;white-space:nowrap;overflow:hidden}
.rr-club.rr-away{justify-content:flex-end;text-align:right}
/* Scores are the one place a bigger, centred numeral beats the shared field. */
.admin .rr-grid input[name=hs],.admin .rr-grid input[name=as]{
  text-align:center;padding:0 4px;font-size:22px;font-weight:var(--fw-bold);letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
.rr-fixture{grid-template-columns:minmax(140px,1.4fr) minmax(112px,1fr) 104px auto}
.admin .rr-fixture input{text-align:left;font-family:var(--body);font-size:var(--fs-body);font-weight:600}
.result-row .btn{margin-top:10px}
.rr-fixture .btn{margin-top:0}

/* ---- clubs ---- */
.club-grid{display:grid;grid-template-columns:auto 1fr 68px 46px auto auto auto;gap:9px;align-items:center}
.admin .club-grid .w-s{text-align:center;padding:0 4px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}

/* ---- sponsors ----
   Eight controls in one row left every field too narrow to read, and laying
   all twenty-nine out flat made a fifteen-thousand-pixel page. Each sponsor is
   now a collapsed summary that opens into a properly sized form. */
.sp-row{padding:0 !important;overflow:hidden}
.sp-det{width:100%}
.sp-sum{display:flex;align-items:center;gap:var(--s-4);padding:var(--s-3) var(--s-4);
  cursor:pointer;list-style:none;transition:background .14s}
.sp-sum::-webkit-details-marker{display:none}
.sp-sum:hover{background:var(--surface-2)}
.sp-sum-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.sp-sum-t b{font-size:15px;font-weight:var(--fw-semi);letter-spacing:-.005em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sp-sum-t > span{font-size:12px;font-weight:500;color:var(--text-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sp-chev{width:18px;height:18px;flex:none;stroke:var(--text-muted);fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .18s}
.sp-det[open] .sp-chev{transform:rotate(180deg)}
.sp-det[open] .sp-sum{border-bottom:1px solid var(--border);background:var(--surface-2)}

.sp-grid{padding:var(--s-4)}
.sp-fields{display:flex;flex-direction:column;gap:var(--s-3);min-width:0}
.sp-line{display:flex;flex-wrap:wrap;gap:var(--s-3);align-items:flex-end}
/* Every control carries a visible label. An aria-label alone tells a screen
   reader what a field is but leaves everyone else guessing. */
.fld{display:flex;flex-direction:column;gap:5px;min-width:150px;margin:0}
.fld > span{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-muted)}
.fld-s{min-width:88px;flex:0 0 88px}
.fld-grow{flex:1 1 240px}
.sp-foot{justify-content:space-between;align-items:center;
  padding-top:var(--s-3);border-top:1px solid var(--border);margin-top:var(--s-1)}
.chk{display:inline-flex;align-items:center;gap:9px;cursor:pointer;margin:0;
  font-size:13px;font-weight:600;color:var(--text-secondary);text-transform:none;letter-spacing:0}
.admin .chk input{width:18px;height:18px;flex:none;accent-color:var(--brand-accent);cursor:pointer}
.chk:hover{color:var(--text-primary)}
/* The ground comes from the sponsor's own plate class, exactly as on the
   public page — a hardcoded white plate hid every mono-white knockout. */
.sp-preview{width:84px;height:52px;flex:none;border-radius:var(--r-btn);
  border:1px solid var(--border);display:flex;align-items:center;justify-content:center;
  padding:6px;background:var(--field-solid)}
.sp-preview img{max-width:100%;max-height:100%;object-fit:contain}
.sp-preview.plate-light{background:#FFF;border-color:transparent}
.sp-preview.plate-dark{background:rgba(0,0,0,.4)}
.sp-word{font-size:11px;font-weight:700;color:var(--text-muted);letter-spacing:.06em;
  text-transform:uppercase}
.sp-actions{display:flex;gap:var(--s-2);flex:none}
.sec-h{margin:var(--s-6) 0 var(--s-3)}
.sec-h h3{font-family:var(--font-ui);font-size:18px;font-weight:700;letter-spacing:-.01em}

@media (max-width:559px){
  .sp-foot{flex-direction:column;align-items:stretch;gap:var(--s-3)}
  .sp-actions .btn{flex:1}
}

/* ---- settings ---- */
.settings label,.settings-label{display:block;font-size:11px;font-weight:var(--fw-bold);text-transform:uppercase;
  letter-spacing:.09em;color:var(--mute);margin-bottom:16px}
.settings label input{margin-top:7px;font-weight:500;text-transform:none;letter-spacing:0}

/* ---- sign-in ---- */
.pin{max-width:380px;margin:11vh auto 0;text-align:center;padding:30px 24px}
.pin .disp{font-size:22px;display:block;margin-bottom:6px}
.pin p{font-size:12.5px;color:var(--ink-2);margin-bottom:18px;line-height:1.5}
.admin .pin input{height:50px;margin-bottom:12px;text-align:center;letter-spacing:.12em;font-size:15px}
.pin .btn{width:100%}


/* ===== carried over: admin-phones ===== */
@media (max-width:559px){
  .rr-grid{grid-template-columns:1fr 62px;
    grid-template-areas:"home hs" "away as" "status status"}
  .rr-grid>.rr-club{grid-area:home}
  /* row-reverse puts the crest first to match the home row; with it, flex-end
     is the left edge. */
  .rr-grid>.rr-club.rr-away{grid-area:away;justify-content:flex-end;text-align:left;flex-direction:row-reverse}
  .rr-grid>input[name=hs]{grid-area:hs}
  .rr-grid>input[name=as]{grid-area:as}
  .rr-grid>select,.rr-grid>.sel{grid-area:status;width:100%}
  .rr-club{font-size:14px}
  /* The fixture row shares .rr-grid, so undo the score-entry areas on its own
     children (same specificity as the rules above, but later in the file). */
  .rr-fixture{grid-template-columns:1fr 1fr;grid-template-areas:none}
  .rr-fixture>input,.rr-fixture>select,.rr-fixture>.sel,.rr-fixture>.btn{grid-area:auto}
  .rr-fixture>select,.rr-fixture>.sel{width:100%;grid-column:1}
  .rr-fixture>.btn{grid-column:2}
  .sp-grid{grid-template-columns:auto 1fr}
  .sp-grid input[name=name]{grid-column:span 1}
  .sp-grid input[name=url],.sp-grid input[name=blurb],.sp-actions{grid-column:span 2}
  .sp-actions .btn{flex:1}
}





/* ---- organiser: tournament colours ---- */
.tcolours{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-4);margin-bottom:var(--s-4)}
.tcol{display:flex;align-items:center;gap:var(--s-2);margin:0}
.tcol span{font-size:11px;font-weight:var(--fw-bold);letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted)}
.tcol-note{flex:1 1 100%;font-size:11.5px;line-height:16px;color:var(--text-muted);
  text-transform:none;letter-spacing:0;font-weight:500}

/* ---- appearance picker + settings rows ---- */
.appearance{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-2);
  margin-bottom:var(--space-3)}
.apx{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  min-height:76px;padding:var(--space-3);border-radius:var(--radius-md);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-secondary);
  font-size:13px;font-weight:600;transition:border-color var(--motion-default),
  color var(--motion-default),background var(--motion-default)}
.apx svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.apx:hover{color:var(--text-primary)}
.apx[aria-checked=true]{border-color:var(--accent);color:var(--text-primary);
  box-shadow:inset 0 0 0 1px var(--accent)}

/* One row pattern for every setting: label, description, control. */
.rowlink{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);
  width:100%;text-align:left;padding:var(--space-3) var(--space-4);margin-bottom:var(--space-2);
  background:var(--surface-1);border:1px solid var(--border);border-radius:var(--radius-md)}
.rowlink b{display:block;font-size:15px;font-weight:600;letter-spacing:-.005em}
.rowlink small{display:block;font-size:12.5px;font-weight:500;color:var(--text-tertiary);margin-top:2px}
.rowlink .chev{width:8px;height:8px;flex:none;border-right:2px solid var(--text-tertiary);
  border-bottom:2px solid var(--text-tertiary);transform:rotate(-45deg)}
/* A switch, so alerts state is not carried by colour alone. */
.rowlink .sw{position:relative;width:44px;height:26px;flex:none;border-radius:var(--radius-pill);
  background:var(--surface-3);transition:background var(--motion-default)}
.rowlink .sw::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;
  border-radius:50%;background:var(--surface-1);box-shadow:var(--shadow-card);
  transition:transform var(--motion-default)}
.rowlink[aria-pressed=true] .sw{background:var(--success)}
.rowlink[aria-pressed=true] .sw::after{transform:translateX(18px)}
@media (prefers-reduced-motion:reduce){.rowlink .sw,.rowlink .sw::after{transition:none}}

/* ---- organiser: branding ---- */
.bsec{margin:var(--space-6) 0 var(--space-3);padding-bottom:var(--space-2);
  border-bottom:1px solid var(--border)}
.bsec h3{font-family:var(--font-ui);font-size:15px;font-weight:700;letter-spacing:-.01em}
.fld-note{flex:1 1 100%;font-size:12px;line-height:17px;color:var(--text-tertiary);
  font-weight:500;letter-spacing:0;text-transform:none}
.uprow{display:flex;flex-wrap:wrap;gap:var(--space-4)}
.upcell{flex:1 1 300px;display:flex;flex-direction:column;gap:var(--space-2);align-items:flex-start}
.uplab{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-tertiary)}
.upframe{width:100%;aspect-ratio:16/5;border-radius:var(--radius-md);overflow:hidden;
  background:var(--surface-2);border:1px solid var(--border);
  display:flex;align-items:center;justify-content:center}
.upframe-m{aspect-ratio:2/1;max-width:220px}
.upframe img{width:100%;height:100%;object-fit:cover}
.upframe span{font-size:12.5px;color:var(--text-tertiary);font-weight:500}
/* A range needs a visible track and a large enough thumb to hit on a phone. */
.rng{-webkit-appearance:none;appearance:none;width:100%;height:28px;background:none;padding:0;
  border:0;cursor:pointer}
.rng::-webkit-slider-runnable-track{height:6px;border-radius:var(--radius-pill);
  background:var(--surface-3)}
.rng::-moz-range-track{height:6px;border-radius:var(--radius-pill);background:var(--surface-3)}
.rng::-webkit-slider-thumb{-webkit-appearance:none;width:22px;height:22px;border-radius:50%;
  margin-top:-8px;background:var(--accent);border:2px solid var(--surface-1);
  box-shadow:var(--shadow-card)}
.rng::-moz-range-thumb{width:22px;height:22px;border-radius:50%;border:2px solid var(--surface-1);
  background:var(--accent);box-shadow:var(--shadow-card)}
.rng:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:var(--radius-pill)}

/* Both appearances side by side: the point of two overlay sliders is seeing
   both results at once. */
.bprev{display:flex;flex-wrap:wrap;gap:var(--space-4)}
.bprev-phone{flex:1 1 260px;max-width:340px;border-radius:var(--radius-lg);overflow:hidden;
  border:1px solid var(--border);background:var(--background)}
.bprev-lab{display:block;padding:8px var(--space-3);font-size:var(--fs-caption);font-weight:var(--fw-bold);
  letter-spacing:.09em;text-transform:uppercase;color:var(--text-tertiary);
  background:var(--surface-1);border-bottom:1px solid var(--border)}
.bprev-art{position:relative;height:120px;overflow:hidden;background:var(--surface-2)}
.bprev-art img{width:100%;height:100%;object-fit:cover;
  object-position:var(--hero-x,50%) var(--hero-y,50%)}
.bprev-veil{position:absolute;inset:0;background:var(--futbl-black);opacity:var(--hero-overlay,.1)}
.bprev-body{display:flex;align-items:center;gap:9px;padding:var(--space-3)}
.bprev-body i{width:8px;height:8px;border-radius:50%;background:var(--live);flex:none}
.bprev-body b{font-size:13px;font-weight:600;color:var(--text-primary)}

/* =========================================================================
   MATCH CENTRE
   Room around a large score. No card behind every piece of information —
   whitespace and one hairline do the separating.
   ========================================================================= */
.ab-back{flex:none;width:38px;height:38px;margin-left:-9px;border-radius:var(--radius-pill);
  display:flex;align-items:center;justify-content:center;color:var(--text-primary)}
.ab-back svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.ab-back:hover{background:var(--surface-2)}
.ab-mid{flex:1;min-width:0;text-align:center;font-size:15px;font-weight:var(--fw-semi);
  letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.mhead{padding:var(--space-6) 0 var(--space-5);text-align:center}
.mhead-k{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-tertiary)}
.mhead-p{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-tertiary);margin-top:3px}
.mhead-score{display:grid;grid-template-columns:1fr auto 1fr;align-items:start;
  gap:var(--space-3);margin-top:var(--space-5)}
.ms-side{display:flex;flex-direction:column;align-items:center;gap:10px;min-width:0}
.ms-side .crest{width:56px;height:56px;object-fit:contain}
.ms-side b{font-size:14px;font-weight:var(--fw-semi);line-height:18px;letter-spacing:-.005em;
  overflow-wrap:anywhere}
.ms-mid{display:flex;flex-direction:column;align-items:center;gap:10px;padding-top:6px}
.ms-num{display:flex;align-items:baseline;gap:10px;font-size:40px;line-height:42px;
  font-weight:var(--fw-bold);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.ms-num i{font-style:normal;font-size:26px;color:var(--text-tertiary);font-weight:600}
.ms-kick{font-size:28px;line-height:32px;font-weight:var(--fw-bold);letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
.ms-state{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;font-weight:var(--fw-semi);
  color:var(--text-tertiary);white-space:nowrap}
.ms-state.live{color:var(--live-ink)}
.ms-state em{font-style:normal;font-variant-numeric:tabular-nums}

/* Tabs: a rule under the selected one, nothing else. */
.tabs{display:flex;gap:var(--space-5);border-bottom:1px solid var(--border);
  margin-bottom:var(--space-5);overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tab{position:relative;flex:none;padding:0 0 var(--space-3);font-size:14px;font-weight:600;
  letter-spacing:-.005em;color:var(--text-tertiary);white-space:nowrap;
  transition:color var(--motion-default)}
.tab:hover{color:var(--text-secondary)}
.tab[aria-selected=true]{color:var(--accent-ink);font-weight:var(--fw-semi)}
.tab[aria-selected=true]::after{content:"";position:absolute;left:0;right:0;bottom:-1px;
  height:2px;border-radius:2px 2px 0 0;background:var(--accent)}

/* Key/value list, not a table: two columns of text need no grid lines. */
.kv{display:flex;flex-direction:column;background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}
.kv > div{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-4);
  padding:var(--space-3) var(--space-4);border-top:1px solid var(--border-subtle)}
.kv > div:first-child{border-top:0}
.kv dt{font-size:var(--fs-body);font-weight:500;color:var(--text-tertiary)}
.kv dd{font-size:14px;font-weight:600;letter-spacing:-.005em;text-align:right}

/* The whole row opens the match; the chevron says so. */
.match{cursor:pointer}
.mr-open{position:absolute;inset:0;z-index:1}
.match:hover{background:var(--surface-hover)}
.mr-meta{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
.mr-meta .chev-i{color:var(--text-tertiary)}

/* =========================================================================
   FILTERS — quick chips inline, everything else in a bottom sheet.
   ========================================================================= */
.qbar{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-3)}
.qchips{display:flex;gap:var(--space-2);overflow-x:auto;scrollbar-width:none;flex:1;
  padding:2px 0;-webkit-overflow-scrolling:touch;scroll-snap-type:x proximity}
/* If a row ever does overflow it fades out rather than guillotining a word
   mid-letter, which read as broken instead of scrollable. Applied only when
   there are enough chips to overflow, so the common case stays crisp. */
.qchips:has(> :nth-child(4)){
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
  mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent)}
.qchips::-webkit-scrollbar{display:none}
.qc{flex:none;scroll-snap-align:start;display:inline-flex;align-items:center;gap:7px;
  height:36px;padding:0 var(--space-4);border-radius:var(--radius-pill);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-secondary);
  font-size:var(--fs-body);font-weight:600;letter-spacing:-.005em;white-space:nowrap;
  transition:background var(--motion-default),color var(--motion-default),
  border-color var(--motion-default)}
.qc:hover{color:var(--text-primary);border-color:var(--border-strong)}
.qc[aria-pressed=true]{background:var(--accent);border-color:var(--accent);
  color:var(--on-brand)}
.qc[aria-pressed=true] .dot{background:var(--on-brand)}
/* The filter button carries the count, so the number of active filters is
   readable without opening anything. */
.qfilt{position:relative;flex:none;width:38px;height:38px;border-radius:var(--radius-md);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-secondary);
  display:flex;align-items:center;justify-content:center}
.qfilt:hover{color:var(--text-primary);border-color:var(--border-strong)}
.qfilt svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round}
.qfilt-n{position:absolute;top:-6px;right:-6px;min-width:18px;height:18px;padding:0 5px;
  border-radius:var(--radius-pill);background:var(--accent);color:var(--on-brand);
  font-size:var(--fs-caption);font-weight:var(--fw-bold);display:flex;align-items:center;justify-content:center}

/* Active filters: every one removable, which is what makes filtering feel
   reversible rather than a state you have to hunt your way out of. */
.active-f{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-bottom:var(--space-3)}
.af{display:inline-flex;align-items:center;gap:7px;height:30px;padding:0 10px 0 12px;
  border-radius:var(--radius-pill);background:var(--surface-2);color:var(--text-primary);
  font-size:12.5px;font-weight:600}
.af i{font-style:normal;font-size:15px;line-height:1;color:var(--text-tertiary)}
.af:hover i{color:var(--text-primary)}
.af-all{height:30px;padding:0 6px;font-size:12.5px;font-weight:var(--fw-semi);color:var(--accent-ink)}
.fcount-line{font-size:var(--fs-caption);font-weight:var(--fw-med);color:var(--text-tertiary);
  margin-bottom:var(--space-3)}

.sheet-scrim{position:fixed;inset:0;z-index:40;background:rgba(9,11,14,.45);
  opacity:0;transition:opacity var(--motion-default)}
.sheet-scrim.open{opacity:1}
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:41;max-height:86vh;
  display:flex;flex-direction:column;background:var(--surface-1);
  border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl);
  box-shadow:0 -8px 40px rgba(0,0,0,.28);
  transform:translateY(100%);transition:transform var(--motion-slow) cubic-bezier(.2,.8,.25,1);
  padding-bottom:env(safe-area-inset-bottom)}
.sheet.open{transform:translateY(0)}
@media (prefers-reduced-motion:reduce){
  .sheet{transition:none}.sheet-scrim{transition:none}
}
.sheet-grab{width:38px;height:4px;border-radius:var(--radius-pill);background:var(--border-strong);
  margin:10px auto 0}
.sheet-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);
  padding:var(--space-3) var(--gutter) var(--space-3)}
.sheet-head h2{font-size:var(--fs-head);font-weight:var(--fw-semi);letter-spacing:-.02em}
.sheet-reset{font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--accent-ink)}
.sheet-body{flex:1;overflow-y:auto;padding:0 var(--gutter) var(--space-4);
  -webkit-overflow-scrolling:touch}
.fgrp{margin-bottom:var(--space-8)}
.fgrp h3{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-tertiary);margin-bottom:var(--space-4)}
.fopts{display:flex;flex-wrap:wrap;gap:var(--space-3)}
/* Soft by default: an inactive option is a filled chip, not an outlined
   button, so a sheet of them does not read as a wall of borders. */
.fo{display:inline-flex;align-items:center;gap:7px;min-height:42px;padding:0 var(--space-4);
  border-radius:var(--radius-md);background:var(--surface-2);border:1px solid transparent;
  color:var(--text-secondary);font-size:14px;font-weight:600;letter-spacing:-.005em;
  transition:background var(--motion-default),color var(--motion-default)}
.fo:hover{color:var(--text-primary)}
.fo[aria-pressed=true]{background:var(--accent);color:var(--on-brand)}
.fo[aria-pressed=true] .dot{background:var(--on-brand)}
.frange{display:flex;gap:var(--space-3)}
.sheet-foot{padding:var(--space-3) var(--gutter) var(--space-4);
  border-top:1px solid var(--border);background:var(--surface-1)}
.btn-full{width:100%;height:50px;font-size:var(--fs-lead);font-weight:var(--fw-bold);background:var(--accent);
  border-color:var(--accent);color:var(--on-brand)}
.sheet .fld > span{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.09em;
  text-transform:uppercase;color:var(--text-tertiary);margin-bottom:var(--space-2);display:block}
.sheet .fld input{width:100%;height:44px;padding:0 12px;border-radius:var(--radius-md);
  border:1px solid var(--border);background:var(--surface-1);color:var(--text-primary);
  font-size:14px;font-weight:600}
.sheet .fld input:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--focus-ring)}

/* ---- organiser: dashboard ----
   A worklist, not an ornament. Every line under "Needs attention" is computed
   from the data and links to the screen that clears it. */
.dash-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-4);
  margin:var(--space-5) 0 var(--space-5);flex-wrap:wrap}
.dash-head h2{font-family:var(--font-ui);font-size:24px;line-height:30px;font-weight:700;
  letter-spacing:-.02em;text-transform:none}
.dash-head p{font-size:var(--fs-body);color:var(--text-tertiary);margin-top:3px}

.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:var(--space-3);margin-bottom:var(--space-5)}
.stat-c{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);padding:var(--space-4)}
.stat-c b{display:flex;align-items:center;gap:9px;font-size:30px;line-height:34px;
  font-weight:var(--fw-bold);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.stat-c span{display:block;font-size:var(--fs-body);font-weight:600;margin-top:4px}
.stat-c small{display:block;font-size:12px;color:var(--text-tertiary);margin-top:2px}
.stat-c.is-live b{color:var(--live-ink)}

.dash-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:var(--space-4);align-items:start}
.card-h{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);
  margin-bottom:var(--space-3);font-family:var(--font-ui);text-transform:none;letter-spacing:0}
.card-h h3{font-size:16px;font-weight:700;letter-spacing:-.01em}
.card-h a{font-size:13px;font-weight:var(--fw-semi);color:var(--accent-ink)}
.pill-n{min-width:22px;height:22px;padding:0 7px;border-radius:var(--radius-pill);
  background:var(--warning);color:#111318;font-size:12px;font-weight:700;
  display:inline-flex;align-items:center;justify-content:center}

.dm{padding:var(--space-3) 0;border-top:1px solid var(--border-subtle)}
.dm:first-of-type{border-top:0;padding-top:0}
.dm-k{display:block;font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--text-tertiary);margin-bottom:var(--space-2)}
.dm-r{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);
  padding:3px 0}
.dm-r span{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dm-r .crest{width:24px;height:24px;object-fit:contain;flex:none}
.dm-r b{font-size:17px;font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}

.todo{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:var(--space-3);
  padding:var(--space-3) 0;border-top:1px solid var(--border-subtle)}
.todo:first-of-type{border-top:0}
.todo i{width:9px;height:9px;border-radius:50%;background:var(--warning)}
.todo-bad i{background:var(--live)}
.todo b{display:block;font-size:14px;font-weight:var(--fw-semi);letter-spacing:-.005em}
.todo small{display:block;font-size:12.5px;color:var(--text-tertiary);margin-top:2px}
.todo em{font-style:normal;font-size:13px;font-weight:var(--fw-semi);color:var(--accent-ink);white-space:nowrap}
.todo:hover em{text-decoration:underline;text-underline-offset:3px}

/* ---- organiser: data table ----
   An enterprise table, not a card per record. Sticky header, aligned numerics,
   a status word that never relies on its colour. */
.dt-bar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--space-3);
  margin-bottom:var(--space-4)}
.dt-search{position:relative;flex:1 1 260px;margin:0}
.dt-search svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;stroke:var(--text-tertiary);fill:none;stroke-width:2;
  stroke-linecap:round;pointer-events:none}
.admin .dt-search input{padding-left:38px}
.dt-wrap{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);overflow:auto;max-height:70vh}
table.dt{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fs-body)}
table.dt th{position:sticky;top:0;z-index:1;background:var(--surface-2);
  padding:11px var(--space-3);text-align:left;white-space:nowrap;cursor:pointer;
  font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-tertiary);border-bottom:1px solid var(--border);user-select:none}
table.dt th:hover{color:var(--text-primary)}
table.dt th:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.dt-arrow{display:inline-block;width:0;height:0;margin-left:6px;vertical-align:middle;
  border-left:4px solid transparent;border-right:4px solid transparent;opacity:0}
th[aria-sort=ascending] .dt-arrow{opacity:1;border-bottom:5px solid currentColor}
th[aria-sort=descending] .dt-arrow{opacity:1;border-top:5px solid currentColor}
table.dt td{padding:11px var(--space-3);border-bottom:1px solid var(--border-subtle);
  vertical-align:middle;color:var(--text-secondary)}
table.dt tbody tr:last-child td{border-bottom:0}
table.dt tbody tr:hover td{background:var(--surface-hover)}
table.dt td:nth-child(4),table.dt td:nth-child(5){color:var(--text-primary);font-weight:600}
table.dt td:nth-child(1),table.dt td:nth-child(2),table.dt td:nth-child(6){
  font-variant-numeric:tabular-nums;white-space:nowrap}
table.dt td small{display:block;font-size:11.5px;color:var(--text-tertiary);margin-top:1px}
.dt-score{margin-left:9px;font-size:var(--fs-body);font-weight:var(--fw-bold);color:var(--text-primary);
  font-variant-numeric:tabular-nums}
.dt-act a{font-weight:var(--fw-semi);color:var(--accent-ink)}
.dt-act a:hover{text-decoration:underline;text-underline-offset:3px}

.badge{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;
  border-radius:var(--radius-pill);font-size:11.5px;font-weight:var(--fw-semi);white-space:nowrap}
.badge-idle{background:var(--surface-3);color:var(--text-secondary)}
/* The tint lifts the badge's ground, which drops the ink below AA against it.
   These use the shared *-ink tokens rather than re-deriving a mix: those are
   already tuned per appearance, and the private mix here measured 3.32:1 on
   the cup red because it had no idea the page had changed underneath it. */
.badge-live{background:color-mix(in srgb, var(--live) 14%, var(--surface-1));
  color:var(--live-ink)}
.badge-done{background:color-mix(in srgb, var(--success) 14%, var(--surface-1));
  color:var(--success-ink)}

.dt-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--space-3);margin-top:var(--space-3);font-size:13px;color:var(--text-tertiary)}
.dt-pages{display:flex;gap:4px}
.dt-page{min-width:32px;height:32px;padding:0 8px;border-radius:var(--radius-sm);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-secondary);
  font-size:13px;font-weight:var(--fw-semi)}
.dt-page:hover:not(:disabled){color:var(--text-primary);border-color:var(--border-strong)}
.dt-page.on{background:var(--accent);border-color:var(--accent);color:var(--on-brand)}
.dt-page:disabled{opacity:.4;cursor:default}


/* ---- 06 Teams ----
   A search field, then one section per competition. Rows are separated by a
   rule rather than boxed as cards: eight crests in eight cards is a lot of
   chrome for a list whose only job is to be scanned. */
.srch{position:relative;display:block;margin-bottom:var(--space-4)}
.srch svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);
  width:17px;height:17px;stroke:var(--text-tertiary);fill:none;stroke-width:2;
  stroke-linecap:round;pointer-events:none}
.srch input{width:100%;height:44px;box-sizing:border-box;padding:0 var(--space-4) 0 40px;
  border:1px solid var(--border);border-radius:var(--radius-md);
  background:var(--surface-1);color:var(--text-primary);
  font-family:var(--font-ui);font-size:14.5px;font-weight:500;
  transition:border-color var(--motion-default)}
.srch input::placeholder{color:var(--text-tertiary);font-weight:500}
.srch input:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--focus-ring)}
.srch input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}

.sec-sm{margin:var(--space-5) 0 var(--space-2)}
.sec-sm h3{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-tertiary)}
.tlist{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);overflow:hidden}
.trow{display:flex;align-items:center;gap:var(--space-2);padding-right:var(--space-3)}
.trow + .trow{border-top:1px solid var(--border-subtle)}
.trow-link{flex:1;min-width:0;display:flex;align-items:center;gap:var(--space-3);
  padding:var(--space-3) var(--space-4);color:var(--text-primary)}
.trow-link .crest{width:30px;height:30px;flex:none}
.trow-link b{flex:1;min-width:0;font-size:var(--fs-lead);font-weight:var(--fw-semi);letter-spacing:-.01em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.trow:hover{background:var(--surface-hover)}

/* ---- 07 Team Profile ---- */
.tp-hero{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);
  padding:var(--space-4) 0 var(--space-6);text-align:center}
.tp-hero .crest{width:76px;height:76px;margin-bottom:var(--space-1)}
.tp-hero h1{font-size:var(--fs-display);line-height:var(--lh-display);font-weight:var(--fw-bold);letter-spacing:-.02em;
  text-transform:uppercase}
.tp-hero p{font-size:var(--fs-body);font-weight:var(--fw-med);color:var(--text-secondary)}
.tp-hero .follow{margin-top:var(--space-2)}

/* Three figures on one plate, divided rather than boxed separately -- they are
   one statement about the club, not three unrelated cards. */
.tp-stats{display:grid;grid-template-columns:repeat(3,1fr);
  background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);margin-bottom:var(--space-5)}
.tp-stats span{display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:var(--space-4) var(--space-2)}
.tp-stats span + span{border-left:1px solid var(--border-subtle)}
.tp-stats b{font-size:var(--fs-title);font-weight:var(--fw-bold);letter-spacing:-.02em;
  font-variant-numeric:tabular-nums}
.tp-stats small{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-tertiary)}

.tp-next{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:var(--space-3);padding:var(--space-4);background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--radius-md);
  margin-bottom:var(--space-5);transition:border-color var(--motion-default)}
.tp-next:hover{border-color:var(--border-strong)}
.tp-side{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0}
.tp-side .crest{width:34px;height:34px}
.tp-side b{font-size:var(--fs-caption);font-weight:var(--fw-semi);text-align:center;line-height:var(--lh-caption)}
.tp-v{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-tertiary)}
.tp-next small{grid-column:1/-1;padding-top:var(--space-3);text-align:center;
  border-top:1px solid var(--border-subtle);
  font-size:var(--fs-caption);font-weight:var(--fw-med);color:var(--text-secondary)}

.tp-res{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);overflow:hidden;margin-bottom:var(--space-5)}
.tp-r{display:grid;grid-template-columns:24px 1fr auto 1fr;align-items:center;
  gap:var(--space-3);padding:var(--space-3) var(--space-4);color:var(--text-primary)}
.tp-r + .tp-r{border-top:1px solid var(--border-subtle)}
.tp-r:hover{background:var(--surface-hover)}
/* The letter carries the result; the colour only reinforces it, which is why
   the badge is never colour alone. */
.tp-b{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;font-style:normal;font-size:var(--fs-caption);font-weight:var(--fw-bold);
  background:var(--surface-3);color:var(--text-secondary)}
.tp-w{background:color-mix(in srgb, var(--success) 18%, transparent);color:var(--success-ink)}
.tp-l{background:color-mix(in srgb, var(--error) 16%, transparent);color:var(--error-ink)}
.tp-t{font-size:var(--fs-body);font-weight:var(--fw-semi);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.tp-right{text-align:right}
.tp-r b{font-size:var(--fs-body);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;
  white-space:nowrap}

/* ---- 04 Tables: the qualification line ---- */
.qline td{padding:0 !important;border:0 !important}
.qline span{display:flex;align-items:center;gap:var(--space-2);
  padding:var(--space-2) 0;
  font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-tertiary);white-space:nowrap}
.qline span::before,.qline span::after{content:"";flex:1;height:1px;
  background:repeating-linear-gradient(to right,var(--border-strong) 0 4px,transparent 4px 8px)}
/* W/D/L are detail: a phone shows played, goal difference and points, which is
   what the design puts on the narrow screen. */
@media (max-width:479px){.col-wide{display:none}}


/* ---- supporter sign-up ----
   A short, single-column form. Nothing else is on these screens because the
   only thing being asked is a name and a number, and every extra control is
   another reason to abandon it. */
.auth{max-width:420px;margin:0 auto;padding-top:var(--space-2)}
.auth h2{font-size:var(--fs-title);line-height:var(--lh-title);font-weight:var(--fw-bold);
  letter-spacing:-.02em;margin-bottom:var(--space-2)}
.auth-sub{font-size:var(--fs-body);line-height:var(--lh-body);color:var(--text-secondary);
  margin-bottom:var(--space-5)}
.auth-err{display:flex;gap:var(--space-2);padding:var(--space-3) var(--space-4);
  margin-bottom:var(--space-4);border-radius:var(--radius-md);
  background:color-mix(in srgb, var(--error) 12%, transparent);
  border:1px solid color-mix(in srgb, var(--error) 34%, transparent);
  color:var(--error-ink);font-size:var(--fs-body);font-weight:var(--fw-med)}
.auth-form{display:flex;flex-direction:column;gap:var(--space-4)}
.auth-form .fld{display:flex;flex-direction:column;gap:6px}
.auth-form .fld > span{font-size:var(--fs-caption);font-weight:var(--fw-bold);
  letter-spacing:.06em;text-transform:uppercase;color:var(--text-tertiary)}
.auth-form input{height:48px;box-sizing:border-box;width:100%;
  padding:0 var(--space-4);border-radius:var(--radius-md);
  background:var(--surface-1);border:1px solid var(--border);color:var(--text-primary);
  font-family:var(--font-ui);font-size:var(--fs-lead);font-weight:var(--fw-med);
  transition:border-color var(--motion-default),box-shadow var(--motion-default)}
.auth-form input::placeholder{color:var(--text-tertiary);font-weight:var(--fw-reg)}
.auth-form input:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--focus-ring)}
/* The code field is the whole point of its screen, so it is set large and
   spaced like the digits it holds. */
.auth-form input.otp{height:60px;text-align:center;font-size:26px;font-weight:var(--fw-bold);
  letter-spacing:.34em;text-indent:.34em;font-variant-numeric:tabular-nums}
.auth .chk{display:flex;align-items:flex-start;gap:var(--space-3);
  font-size:var(--fs-body);line-height:var(--lh-body);color:var(--text-secondary)}
.auth .chk input{width:20px;height:20px;flex:none;margin-top:1px;
  accent-color:var(--accent);cursor:pointer}
.auth-alt{margin-top:var(--space-4);text-align:center}
.linkbtn{font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--accent-ink);
  text-decoration:underline;text-underline-offset:3px}
/* The privacy line is not fine print in the legal sense: it is the answer to
   "why do you want my number", so it is legible rather than tucked away. */
.auth-fine{margin-top:var(--space-5);padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle);
  font-size:var(--fs-caption);line-height:18px;color:var(--text-tertiary)}
.auth-fine a{color:var(--accent-ink);text-decoration:underline;text-underline-offset:2px}

/* ---- the account row on More ---- */
.acct{display:flex;align-items:center;gap:var(--space-3);
  padding:var(--space-4);margin-bottom:var(--space-2);
  background:var(--surface-1);border:1px solid var(--border);border-radius:var(--radius-md)}
.acct-badge{flex:none;width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-fill);color:var(--on-accent-fill);
  font-size:var(--fs-lead);font-weight:var(--fw-bold)}
.acct-who{display:flex;flex-direction:column;min-width:0}
.acct-who b{font-size:var(--fs-lead);font-weight:var(--fw-semi);letter-spacing:-.01em}
.acct-who small{font-size:var(--fs-caption);color:var(--text-tertiary);
  font-variant-numeric:tabular-nums}
.rowlink-danger b{color:var(--error-ink)}


/* ---- 01 Welcome ----
   Its own page rather than a screen inside the tab shell: there is no bottom
   nav here because there is nowhere yet to navigate to. */
.welcome{min-height:100vh;min-height:100dvh;display:flex;align-items:center;
  padding:var(--space-8) 0 var(--space-10)}
.welcome .wrap{max-width:440px}
.wc-mark img{height:26px;width:auto;display:block}
.wc-mark .on-dark,.wc-mark .on-cup{display:none}
[data-theme="dark"] .wc-mark .on-light{display:none}
[data-theme="dark"] .wc-mark .on-dark{display:block}
[data-theme="cup"] .wc-mark .on-light{display:none}
[data-theme="cup"] .wc-mark .on-cup{display:block}
.wc-h{margin-top:var(--space-8);font-size:40px;line-height:44px;
  font-weight:var(--fw-bold);letter-spacing:-.03em;color:var(--text-primary)}
.wc-h span{color:var(--accent-ink)}
.wc-sub{margin-top:var(--space-3);font-size:var(--fs-lead);line-height:24px;
  color:var(--text-secondary)}
.wc-list{list-style:none;margin:var(--space-6) 0 var(--space-6);
  display:flex;flex-direction:column;gap:var(--space-3)}
.wc-list li{display:flex;align-items:center;gap:var(--space-3);
  font-size:var(--fs-body);font-weight:var(--fw-med);color:var(--text-secondary)}
.wc-i{flex:none;width:18px;height:18px;border-radius:50%;
  background:color-mix(in srgb, var(--accent) 14%, transparent);position:relative}
.wc-i::after{content:"";position:absolute;left:6px;top:4px;width:4px;height:8px;
  border-right:2px solid var(--accent-ink);border-bottom:2px solid var(--accent-ink);
  transform:rotate(45deg)}

/* The tournament card: real artwork, real counts, no stock imagery. */
/* The artwork is set inline per tournament; this is only the ground it falls
   back to while the image loads or if there is none. */
.wc-card{position:relative;display:flex;align-items:flex-end;gap:var(--space-3);
  min-height:186px;padding:var(--space-5) var(--space-4) var(--space-4);overflow:hidden;
  border-radius:var(--radius-lg);border:1px solid var(--border);
  background-color:var(--surface-3);color:var(--on-media);
  background-size:cover;background-position:center}
.wc-card-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.wc-card b{font-size:var(--fs-head);line-height:22px;font-weight:var(--fw-bold);
  letter-spacing:-.015em;color:#fff}
.wc-card small{font-size:var(--fs-caption);color:rgba(255,255,255,.86)}
.wc-card em{font-style:normal;font-size:var(--fs-caption);font-weight:var(--fw-semi);
  color:rgba(255,255,255,.7)}
.wc-go{flex:none;width:9px;height:9px;margin-bottom:4px;
  border-right:2px solid #fff;border-top:2px solid #fff;transform:rotate(45deg)}
.wc-cta{margin-top:var(--space-5)}
.wc-fine{margin-top:var(--space-3);text-align:center;
  font-size:var(--fs-caption);color:var(--text-tertiary)}


/* ---- next match ----
   The one card on the home screen that earns real estate: who, when, where and
   how long until it. Deliberately on the raised surface with the crests large,
   because everything else on this screen is a list row. */
.nm{display:flex;flex-direction:column;align-items:center;gap:var(--space-3);
  padding:var(--space-5) var(--space-4);margin-bottom:var(--space-5);
  background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-lg);text-align:center;
  transition:border-color var(--motion-default)}
.nm:hover{border-color:var(--border-strong)}
.nm-stage{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-tertiary)}
.nm-teams{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:var(--space-3);width:100%}
.nm-side{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);min-width:0}
.nm-side .crest{width:46px;height:46px}
.nm-side b{font-size:var(--fs-body);font-weight:var(--fw-semi);line-height:18px}
.nm-vs{font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-tertiary)}
.nm-when{font-size:var(--fs-lead);font-weight:var(--fw-semi);letter-spacing:-.01em}
.nm-where{font-size:var(--fs-caption);color:var(--text-tertiary)}
/* Three figures, evenly divided, so the eye reads them as one clock. */
.nm-count{display:grid;grid-template-columns:repeat(3,1fr);width:100%;
  margin-top:var(--space-2);padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle)}
.nm-count > span{display:flex;flex-direction:column;align-items:center;gap:2px}
.nm-count > span + span{border-left:1px solid var(--border-subtle)}
.nm-count b{font-size:var(--fs-title);font-weight:var(--fw-bold);letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--accent-ink)}
.nm-count small{font-size:10px;font-weight:var(--fw-bold);letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-tertiary)}

/* ---- latest result ---- */
.lr{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);overflow:hidden;margin-bottom:var(--space-5)}
.lr-k{display:block;padding:var(--space-3) var(--space-4) 0;
  font-size:var(--fs-caption);font-weight:var(--fw-bold);letter-spacing:.08em;
  text-transform:uppercase;color:var(--text-tertiary)}
.lr-row{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:var(--space-3);padding:var(--space-3) var(--space-4)}
.lr-t{display:flex;align-items:center;gap:var(--space-2);min-width:0}
.lr-t .crest{width:24px;height:24px;flex:none}
.lr-t b{font-size:var(--fs-body);font-weight:var(--fw-semi);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lr-away{justify-content:flex-end;text-align:right}
.lr-s{font-size:var(--fs-head);font-weight:var(--fw-bold);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.lr-s i{font-style:normal;margin:0 4px;color:var(--text-tertiary)}
.lr-all{display:flex;align-items:center;justify-content:flex-end;gap:6px;
  padding:var(--space-3) var(--space-4);border-top:1px solid var(--border-subtle);
  font-size:var(--fs-body);font-weight:var(--fw-semi);color:var(--accent-ink)}


/* ---- 02 Tournament select ---- */
.choose .wrap{max-width:420px}
.ch-h{margin-top:var(--space-6);font-size:var(--fs-display);line-height:var(--lh-display);
  font-weight:var(--fw-bold);letter-spacing:-.02em}
/* Artwork on top, live text beneath: the board bakes the tournament name into
   the image, which cannot be translated, restyled or kept in step with the
   database. The photo carries the mood, the card carries the facts. */
.tc{display:block;margin-top:var(--space-5);overflow:hidden;
  background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-lg);position:relative;
  transition:border-color var(--motion-default)}
.tc:hover{border-color:var(--border-strong)}
/* The image is set inline from the organiser's upload; this only supplies the
   ground it falls back to while that loads. */
.tc-art{display:block;aspect-ratio:193/122;background-color:#0B0D0E;
  background-size:cover;background-position:center;background-repeat:no-repeat}
.tc-body{display:flex;flex-direction:column;gap:3px;
  padding:var(--space-4) 56px var(--space-4) var(--space-4)}
.tc-body b{font-size:var(--fs-head);line-height:22px;font-weight:var(--fw-bold);
  letter-spacing:-.015em;color:var(--text-primary)}
.tc-body small{font-size:var(--fs-caption);font-weight:var(--fw-semi);
  letter-spacing:.06em;text-transform:uppercase;color:var(--accent-ink)}
.tc-go{position:absolute;right:var(--space-4);bottom:var(--space-4);
  width:34px;height:34px;border-radius:50%;background:var(--accent-fill);
  display:flex;align-items:center;justify-content:center}
.tc-go::after{content:"";width:8px;height:8px;margin-left:-2px;
  border-right:2px solid var(--on-accent-fill);border-top:2px solid var(--on-accent-fill);
  transform:rotate(45deg)}
.tc-more{display:flex;align-items:center;justify-content:space-between;
  margin-top:var(--space-3);padding:var(--space-4);
  background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md)}
.tc-more span{display:flex;flex-direction:column;gap:2px}
.tc-more b{font-size:var(--fs-body);font-weight:var(--fw-semi)}
.tc-more small{font-size:var(--fs-caption);color:var(--text-tertiary)}


/* ---- home hub ----
   One list, one row per section, each saying what is behind it. Rows share a
   single plate with hairline dividers rather than six separate cards, so the
   set reads as one menu instead of six competing objects. */
.hub{background:var(--surface-1);border:1px solid var(--border);
  border-radius:var(--radius-md);overflow:hidden;margin-bottom:var(--space-5)}
.hub-row{display:grid;grid-template-columns:24px 1fr 10px;align-items:center;
  gap:var(--space-4);padding:var(--space-4);color:var(--text-primary);
  transition:background var(--motion-default)}
.hub-row + .hub-row{border-top:1px solid var(--border-subtle)}
.hub-row:hover{background:var(--surface-hover)}
.hub-i{width:24px;height:24px;stroke:var(--accent-ink);fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.hub-t{display:flex;flex-direction:column;gap:2px;min-width:0}
.hub-t b{font-size:var(--fs-lead);font-weight:var(--fw-semi);letter-spacing:-.01em}
.hub-t small{font-size:var(--fs-caption);color:var(--text-tertiary);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}


/* ---- next match: one card, or a swipeable track ----
   With a single match the wrapper is inert and the card behaves exactly as
   before. With several it becomes a snap track that bleeds to both edges, so
   the next card peeks and the gesture is discoverable without a hint. */
.nmw{margin-bottom:var(--space-5)}
.nmw .nm{margin-bottom:0}
.nmw-many{display:flex;gap:var(--space-3);overflow-x:auto;scrollbar-width:none;
  scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  margin-left:calc(var(--gutter) * -1);margin-right:calc(var(--gutter) * -1);
  padding:0 var(--gutter) var(--space-2)}
.nmw-many::-webkit-scrollbar{display:none}
/* The snap child is .nmc, the card wrapper; see the vote block below. */
/* The count beside the heading says how many there are before you swipe. */
.t-count{display:inline-flex;align-items:center;justify-content:center;
  min-width:18px;height:18px;padding:0 5px;margin-left:6px;
  border-radius:var(--radius-pill);background:var(--accent-fill);
  color:var(--on-accent-fill);font-size:11px;font-weight:var(--fw-bold);
  letter-spacing:0;vertical-align:1px}


/* ---- organiser: text alerts ---- */
.smstest{display:flex;align-items:flex-end;gap:var(--space-3);margin-bottom:var(--space-4)}
.smstest .fld{margin:0}
.smslog{margin-top:var(--space-2)}
.smslog td{vertical-align:top}
/* The provider's own words, kept small but readable: this is the line that
   explains a failure, so hiding it defeats the point of logging at all. */
.smsdetail{display:block;margin-top:3px;font-size:var(--fs-caption);line-height:16px;
  color:var(--text-tertiary);word-break:break-word}


/* ---- organiser: fixture import ---- */
.fx-bad,.fx-warn{padding:var(--space-3) var(--space-4);margin:var(--space-3) 0;
  border-radius:var(--radius-md);font-size:var(--fs-body);line-height:19px}
.fx-bad{background:color-mix(in srgb, var(--error) 10%, transparent);
  border:1px solid color-mix(in srgb, var(--error) 34%, transparent);color:var(--error-ink)}
/* The destructive warning is the one thing on this screen that must not be
   skimmed, so it gets the accent border rather than another grey note. */
.fx-warn{background:color-mix(in srgb, var(--warning) 12%, transparent);
  border:1px solid color-mix(in srgb, var(--warning) 40%, transparent);
  color:var(--text-primary)}
.fx-bad ul{margin:var(--space-2) 0 0;padding-left:18px}
.fx-bad li{margin-bottom:3px}
.fx-actions{display:flex;align-items:center;gap:var(--space-3);margin-top:var(--space-4)}
.fx-clear{display:flex;align-items:flex-end;gap:var(--space-3)}
.fx-clear .fld{margin:0;max-width:220px}


/* ---- teams: club first, competitions under it ----
   The club is the object; the competitions are facets of it. So one card per
   club with the crest and name reading as the heading, and the competitions
   as a quiet row beneath rather than four more list rows. */
.tclub + .tclub{border-top:1px solid var(--border-subtle)}
.tclub-top{display:flex;align-items:center;gap:var(--space-3)}
.tclub-top{padding-right:var(--space-3)}
.tclub-top .trow-link{flex:1;min-width:0;display:flex;align-items:center;
  gap:var(--space-3);padding:var(--space-3) var(--space-4);color:var(--text-primary)}
.tclub-top .trow-link .crest{width:30px;height:30px;flex:none}
.tclub-id{flex:1;min-width:0;display:flex;flex-direction:column}
.tclub-id b{font-size:15px;font-weight:var(--fw-semi);letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tclub-id small{font-size:var(--fs-caption);color:var(--text-tertiary);margin-top:1px}
.tclub-top .chev-i{color:var(--text-tertiary);flex:none}

/* Indented past the crest so the pills read as belonging to the club above
   them rather than as a new row of their own. */
.tcomps{display:flex;flex-wrap:wrap;gap:var(--space-2);
  padding:0 var(--space-4) var(--space-3) calc(var(--space-4) + 30px + var(--space-3))}
.cfollow{-webkit-appearance:none;appearance:none;cursor:pointer;
  font:inherit;font-size:var(--fs-caption);font-weight:var(--fw-med);
  min-height:30px;padding:0 10px;border-radius:999px;
  background:var(--surface-2);color:var(--text-secondary);
  border:1px solid var(--border);transition:background .15s,color .15s,border-color .15s}
.cfollow[aria-pressed="true"]{background:var(--accent-fill);color:var(--on-accent-fill);
  border-color:transparent;font-weight:var(--fw-semi)}
/* Kept for any future inert state; pills are live controls in every state
   the app currently renders. */
.cfollow:disabled{cursor:default;opacity:.85}
.cfollow:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tcomps-all{flex-basis:100%;font-size:var(--fs-caption);color:var(--text-tertiary)}


/* ---- greeting ---- */
/* A line, not a card: it greets and gets out of the way. */
.greet{display:flex;flex-direction:column;gap:1px;margin:0 0 var(--space-4)}
.greet b{font-size:17px;font-weight:var(--fw-semi);letter-spacing:-.01em;color:var(--text-primary)}
.greet span{font-size:var(--fs-caption);color:var(--text-tertiary)}

/* ---- live hero ----
   A game happening right now is the most important thing on the page, and a
   list row cannot say that. Big crests, big score, running clock. */
/* Several live at once become a swipeable track, matching how simultaneous
   next matches behave. One live match fills the width as a single card. */
.lmw{margin-bottom:var(--space-5)}
.lmw .lm{margin-bottom:0}
.lmw-many{display:flex;gap:var(--space-3);overflow-x:auto;scrollbar-width:none;
  scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  margin-left:calc(var(--gutter) * -1);margin-right:calc(var(--gutter) * -1);
  padding:0 var(--gutter) var(--space-2)}
.lmw-many::-webkit-scrollbar{display:none}
.lmw-many .lm{flex:0 0 86%;scroll-snap-align:center}
@media (min-width:600px){.lmw-many .lm{flex:0 0 46%}}

.lm{display:flex;flex-direction:column;gap:var(--space-4);
  padding:var(--space-4) var(--space-4) var(--space-5);margin-bottom:var(--space-5);
  background:var(--surface-1);border:1px solid var(--border);border-radius:var(--radius-lg);
  transition:border-color var(--motion-default)}
.lm:hover{border-color:var(--border-strong)}
.lm-top{display:flex;align-items:center;gap:6px;font-size:var(--fs-caption);
  font-weight:var(--fw-bold);letter-spacing:.06em;text-transform:uppercase;color:var(--live-ink)}
.lm-top .dot{flex:none}
.lm-comp{margin-left:auto;text-transform:none;letter-spacing:0;
  font-weight:var(--fw-med);color:var(--text-tertiary)}
.lm-body{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:var(--space-3)}
.lm-side{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);min-width:0}
.lm-side .crest{width:52px;height:52px;object-fit:contain}
.lm-side b{font-size:14px;font-weight:var(--fw-semi);text-align:center;line-height:17px}
.lm-score{display:flex;align-items:center;gap:8px}
.lm-score em{font-style:normal;font-size:40px;line-height:1;font-weight:var(--fw-bold);
  letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--text-primary)}
.lm-score i{font-style:normal;font-size:24px;color:var(--text-tertiary)}
.lm-where{font-size:var(--fs-caption);color:var(--text-tertiary);text-align:center}

/* ---- next match card + fan vote ----
   The card is the container now: the match is a link, the vote is buttons, and
   an anchor cannot hold a button. */
.nmc{display:flex;flex-direction:column;background:var(--surface-1);
  border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}
.nmc .nm{background:none;border:0;border-radius:0;margin-bottom:0;width:100%}
.nmw{margin-bottom:var(--space-5)}
.nmw-many .nmc{flex:0 0 86%;scroll-snap-align:center}
@media (min-width:600px){.nmw-many .nmc{flex:0 0 46%}}

.nv{padding:var(--space-4);border-top:1px solid var(--border-subtle)}
.nv-q{display:flex;align-items:baseline;gap:var(--space-2);flex-wrap:wrap;
  font-size:13px;font-weight:var(--fw-semi);color:var(--text-primary);margin-bottom:var(--space-3)}
/* Says plainly what this is. A fabricated probability would be a lie a club
   could reasonably object to; a straw poll labelled as one cannot be. */
.nv-note{font-size:11px;font-weight:var(--fw-reg);color:var(--text-tertiary)}
.nv-btns{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2)}
.nv-b{-webkit-appearance:none;appearance:none;cursor:pointer;font:inherit;
  font-size:13px;font-weight:var(--fw-med);min-height:38px;padding:0 10px;
  border-radius:var(--radius-md);background:var(--surface-2);color:var(--text-secondary);
  border:1px solid var(--border);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:background .15s,color .15s,border-color .15s}
.nv-b[aria-pressed="true"]{background:var(--accent-fill);color:var(--on-accent-fill);
  border-color:transparent;font-weight:var(--fw-semi)}
.nv-b:disabled{cursor:default;opacity:.7}
.nv-b:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.nv-res{margin-top:var(--space-3)}
.nv-bar{height:8px;border-radius:999px;overflow:hidden;background:var(--surface-3)}
/* The away share is the remainder, so only one element has to be sized and the
   two can never add up to something other than the whole bar. */
.nv-bar span{display:block;height:100%;border-radius:999px;background:var(--accent);
  transition:width .25s ease}
.nv-pct{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2);
  margin-top:6px;font-size:var(--fs-caption);font-weight:var(--fw-semi);color:var(--text-secondary)}
.nv-n{font-weight:var(--fw-med);color:var(--text-tertiary)}
.nv-few{margin:var(--space-3) 0 0;font-size:var(--fs-caption);color:var(--text-tertiary)}
