/* OldNation shared design system — tokens, base, and common components used by every page.
   Palette and typography now match the approved dashboard design pack
   (oldnation-homepage-handoff/tokens.css) exactly, applied site-wide so every page shares
   one true set of colours/fonts rather than the dashboard homepage looking different from
   the rest of the site. */
/* Fonts are loaded via <link rel="preconnect"> + <link rel="stylesheet"> in each page's <head>,
   not via @import here — an @import inside a stylesheet can only be discovered after the
   stylesheet itself has been fetched and parsed, serializing what should be a parallel fetch
   and delaying first text paint on every page. Keep the two loading paths in sync: the font
   families/weights referenced below (--font-display/--font-body) must match the family/weight
   list in the <link> tag exactly. */

:root{
  --bg:#06131F;
  --surface:#081827;
  --surface-2:#0A1E30;
  --surface-3:#0D2439;
  --line:#20394F;
  --line-soft:rgba(148,178,203,.16);
  --ink:#F3F5F7;
  --ink-2:#B0C0CF;
  /* Was rgba(145,167,187,.65), which measured 3.45-3.84:1 against every surface it sits on —
     under the 4.5:1 floor for the micro-labels, empty states and footer that are its whole job.
     Flattening the alpha to a solid step keeps the three-tier ink ramp (17.4 / 7.2 / 5.0:1 on
     --surface) while every tier now passes AA, including on the lightest surface, --surface-3. */
  --ink-3:#91A7BB;
  --gold:#E1AD28;
  --gold-hi:#F2BD32;
  --gold-dim:#B98A1E;
  --navy-ink:#0B1A2C;
  --teal:#2FA8C7;
  --good:#20A970;
  --bad:#B74949;
  /* Result hues are legible as a fill but not as text: --good on its own 18% wash measures
     4.34:1 and --bad measures 2.81:1. These are the same hues lifted until the *text* passes,
     so a fill and a label can share a colour family without sharing a value. Use --good/--bad
     for fills, borders and bars; --good-text/--bad-text whenever the hue becomes type. */
  --good-text:#3FBF87;
  --bad-text:#E07A72;
  /* Grade band hues. These are referenced from grading.js's GRADE_SCALE, not from CSS in any
     one page, so a grep of the stylesheets says "unused" and lies — deleting them silently
     breaks every grade colour the engine renders. They lived in five page :root blocks with
     identical values; one definition here is the only version that cannot drift.
     S=teal, A=--good, B=blue, C=--gold, D=orange, E=--bad. */
  /* Blue was #5C8FCF, which cleared 4.5:1 on the darker table rows but fell to 4.18:1 on the
     lightest one — a band that passes on some rows and not others is not passing. Lifted until
     it clears on every surface it lands on, and it reads better on a gold fill too. */
  --grade-blue:#7FA9DC; --grade-orange:#D98A3D; --grade-teal:#2FB8A6;
  --shadow:0 14px 34px -14px rgba(0,0,0,.8);
  --shadow-lg:0 24px 60px -20px rgba(0,0,0,.85);
  --nav-bg:rgba(5,17,29,.92);

  --font-display:"Barlow Condensed","Archivo Black","Arial Black","Segoe UI",Impact,sans-serif;
  --font-body:"Inter","Segoe UI Variable Text","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif;

  /* ---------- type roles ----------
     The site had 36 distinct font sizes, 84 of them below 11px and down to 7px. Almost all of
     the small ones were one role wearing six sizes: an uppercase, wide-tracked micro-label in
     --ink-3. These tokens name the roles so a label is a label everywhere instead of a number
     picked per component.

     --fs-label is a floor, not a suggestion: no text carrying meaning goes below it. Purely
     decorative marks (a glyph inside a badge disc) are the only exception.

     --ls-label drops the tracking from the .12-.2em these labels used to carry. That is not
     cosmetic: going 9px -> 11px at .16em widens a label by ~22%, which is enough to wrap the
     tightest stat grids. At .1em the same label grows ~12% instead, so the size increase fits
     the layouts it lands in. Wide tracking was compensating for the size; with a real size it
     is no longer needed. */
  --fs-label:11px;   --ls-label:.1em;
  --fs-micro:12px;   /* dense secondary text that is not a label — captions, meta lines */
  --fs-body-sm:13px; /* table cells and compact rows */
  --fs-body:15px;    /* default body, set on <body> below */
  --fs-data-sm:16px; /* inline numerals in dense rows */
  --fs-data:22px;    /* stat numerals — display face, read as scorelines */
  --fs-headline:14px; --ls-headline:.03em; /* card and panel headers */

  --r-sm:6px; --r-md:10px; --r-lg:14px; --r-xl:20px; --r-pill:999px;
  --ease:cubic-bezier(.2,.8,.2,1);
  color-scheme:dark;
}
*{box-sizing:border-box;}
[hidden]{display:none !important;}
button,input,select{font:inherit;color:inherit;}
body{
  margin:0;
  background:
    radial-gradient(900px 500px at 88% 4%, color-mix(in srgb, var(--gold) 10%, transparent), transparent 62%),
    radial-gradient(700px 420px at 6% 96%, color-mix(in srgb, var(--gold) 7%, transparent), transparent 60%),
    var(--bg);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:var(--fs-body);line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:0 12px 48px;}
a{color:var(--gold);text-decoration:none;transition:color .15s var(--ease);}
a:hover{color:var(--gold-hi);}
:is(button,input,select,a,[tabindex]):focus-visible{outline:2px solid var(--gold);outline-offset:2px;}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  background:var(--surface-2);border:1px solid var(--line);
  color:var(--ink);padding:9px 13px;border-radius:var(--r-md);
  cursor:pointer;white-space:nowrap;text-decoration:none;font:inherit;
  transition:background .15s var(--ease),border-color .15s var(--ease),transform .12s var(--ease),box-shadow .15s var(--ease);
}
.btn:hover{background:var(--line-soft);border-color:var(--ink-3);text-decoration:none;transform:translateY(-1px);}
.btn:active{transform:translateY(0) scale(.97);}
.btn.primary{background:var(--gold);border-color:var(--gold);color:var(--navy-ink);font-weight:750;}
.btn.primary:hover{background:var(--gold-hi);box-shadow:0 8px 22px -10px color-mix(in srgb, var(--gold) 55%, transparent);}
.btn.sm{padding:7px 11px;font-size:13px;}
.btn.tiny{padding:5px 9px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;}
.btn:disabled{opacity:.55;cursor:default;transform:none !important;box-shadow:none;}

/* ---------- cards ---------- */
.card{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--shadow);overflow:hidden;
  margin-bottom:14px;
}
.card h2{
  margin:0;padding:12px 14px;font-family:var(--font-display);font-weight:800;
  text-transform:uppercase;font-size:var(--fs-headline);letter-spacing:var(--ls-headline);
  border-bottom:1px solid var(--line);color:var(--ink);
  display:flex;align-items:center;gap:10px;
}
.card h2 .sub{
  margin-left:auto;font-family:var(--font-body);font-weight:400;
  text-transform:none;letter-spacing:0;font-size:12px;color:var(--ink-3);
}
.card.hoverable{transition:border-color .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease);}
.card.hoverable:hover{border-color:var(--gold-dim);transform:translateY(-3px);box-shadow:var(--shadow-lg);}

.badge{
  display:inline-block;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;font-weight:800;
  padding:3px 8px;border-radius:999px;
}
.badge.w{background:rgba(63,191,135,.18);color:var(--good-text);}
.badge.d{background:rgba(159,176,198,.18);color:var(--ink-2);}
.badge.l{background:rgba(217,105,95,.18);color:var(--bad-text);}
.badge.friendly{background:transparent;border:1px solid var(--line);color:var(--ink-2);}

/* ---------- artwork icons ----------
   Supplied as white PNGs, drawn as a mask so they take colour from `background` and can be
   recoloured per context rather than needing a variant file per tint. Size is set by the
   consumer; these only carry the artwork + a sensible default. */
.icon-fixtures,.icon-build-lineup,.icon-player-stats,.icon-form{
  display:inline-block;width:15px;height:15px;flex:none;background:var(--ink);
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
}
.icon-fixtures{-webkit-mask-image:url("icon-fixtures.webp");mask-image:url("icon-fixtures.webp");}
.icon-build-lineup{-webkit-mask-image:url("icon-build-lineup.webp");mask-image:url("icon-build-lineup.webp");}
.icon-player-stats{-webkit-mask-image:url("icon-player-stats.webp");mask-image:url("icon-player-stats.webp");}
.icon-form{-webkit-mask-image:url("icon-form.webp");mask-image:url("icon-form.webp");}

/* ---------- competition lockups ----------
   The supplied label PNGs are 2048x512 canvases whose icon+text artwork occupies a
   1361x322 (l1b) / 1261x322 (l5) box at offset 89,95 — the rest is transparent padding,
   and the leading icon disc is the first 322x322 of that. Scaling the background by
   --comp-h/322 and shifting it by that offset crops to just the artwork, so the element's
   box hugs the lockup and drives layout correctly. Doing it here rather than re-cutting the
   files keeps the supplied assets authoritative.

   --comp-h is the artwork height. The baked-in text only holds up around 28px+, so use the
   full lockup where there's room and `.disc` (icon only, name via aria-label/title) in
   tight rows. */
.comp-badge{
  --comp-h:30px;
  display:inline-block;height:var(--comp-h);flex:none;
  background-repeat:no-repeat;
  background-size:calc(var(--comp-h) * 6.3602) calc(var(--comp-h) * 1.5901);
  background-position:calc(var(--comp-h) * -0.2764) calc(var(--comp-h) * -0.2950);
}
.comp-badge.l1b{background-image:url("uk-league-one-b-label-640x160.png");}
.comp-badge.l5{background-image:url("eu-league-five-label-640x160.png");}
.comp-badge.l1b:not(.disc){width:calc(var(--comp-h) * 4.2267);}
.comp-badge.l5:not(.disc){width:calc(var(--comp-h) * 3.9153);}
.comp-badge.disc{width:var(--comp-h);}

/* League Five playoffs. The competition is still League Five, so the badge keeps that artwork
   and the surrounding treatment does the work of marking the fixture out — inventing a second
   label image would not match the set and there is no playoff artwork to match anyway. */
.comp-badge.l5po{background-image:url("eu-league-five-label-640x160.png");}
.comp-badge.l5po:not(.disc){width:calc(var(--comp-h) * 3.9153);}

/* Gold on --navy-ink rather than gold-on-dark type: the same pairing the primary buttons use,
   and it clears AA comfortably where gold text on a dark surface would not. */
.playoff-chip{
  display:inline-flex;align-items:center;flex:none;white-space:nowrap;
  background:var(--gold);color:var(--navy-ink);
  font-family:var(--font-display);font-weight:700;
  font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;
  padding:2px 8px;border-radius:999px;line-height:1.5;
}
/* A fixture that only happens if the previous one is won. Outlined rather than filled so it
   reads as provisional next to the solid chip on the tie that is actually scheduled. */
.playoff-chip.conditional{
  background:transparent;color:var(--gold);
  box-shadow:inset 0 0 0 1px var(--gold-dim);
}
.is-playoff{
  border-color:var(--gold-dim) !important;
  background-image:linear-gradient(90deg,rgba(225,173,40,.10),transparent 62%);
}

.empty{padding:22px 14px;text-align:center;color:var(--ink-3);}
.hint{font-size:12px;color:var(--ink-3);margin:8px 0 0;}
.hint.err{color:var(--bad);}
.hint.ok{color:var(--good);}

label.fld{display:flex;flex-direction:column;gap:5px;font-size:var(--fs-label);
  letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--ink-3);font-weight:700;}
input[type=text],input[type=password],input[type=search],input[type=date],input[type=time],input[type=number],select{
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:9px 10px;font-size:16px;width:100%;
  line-height:1.4;box-sizing:border-box;color:var(--ink);
  transition:border-color .15s var(--ease);
}
input:focus,select:focus{border-color:var(--gold-dim);}
input::placeholder{color:var(--ink-3);}

/* Visually hidden, still in the accessibility tree. For structure a screen reader needs and
   the visual design deliberately does not show — the homepage has no visible page title by
   design (the Match Centre leads), but it still needs an <h1>. Not display:none, which would
   remove it from the tree entirely and defeat the point. */
.vh{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;
}

/* Panel titles are real headings so the page can be navigated by structure. Every one of these
   classes already sets its own font-size and weight, so the reset is margin ONLY — an earlier
   version added font-size:inherit here and, being one specificity step above the panel classes,
   silently overrode all of them and pushed three titles from 12-13px up to the 15px body size.
   Promoting a div to h2 must be a semantic change with no visual one. */
:is(h1,h2,h3):is(.mc-label,.lbl,.lrb-label,.insights-title,.fp-kicker){ margin:0; }

/* Skip link, injected by nav.js as the first focusable element on every page. Off-screen
   rather than display:none, because a hidden element cannot receive focus — it has to be
   reachable by Tab and only then become visible. Sits above the sticky nav's z-index:30. */
.skip-link{
  position:absolute;left:12px;top:-64px;z-index:40;
  padding:10px 14px;border-radius:var(--r-sm);
  background:var(--gold);color:var(--navy-ink);
  font-weight:750;font-size:var(--fs-body-sm);
  transition:top .15s var(--ease);
}
.skip-link:focus{top:12px;color:var(--navy-ink);}

/* ---------- shared top nav ---------- */
/* #site-nav (the bare id) gets the same look before nav.js has even run: the placeholder div
   ships empty in every page's initial HTML, and nav.js (which builds the actual links and adds
   the .site-nav class) only runs once the rest of the page has parsed, since it's the first
   script at the end of <body>. Without this, every navigation showed a blank strip that popped
   in and shoved the page down once JS caught up — styling the id directly, plus a min-height
   matching the real rendered bar (measured: ~75.5px desktop/tablet, ~61px at the 900px mobile
   breakpoint below), makes the bar correct from first paint with no JS dependency. */
.site-nav,#site-nav{
  position:sticky;top:0;z-index:30;
  min-height:75.5px;
  background:var(--nav-bg);backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
  border-bottom:1px solid var(--line-soft);
}
/* Matches the widest page content (.sq-wrap/.fx-wrap run to 1540px, 1880px at 1800px+) so
   the nav's left edge lines up with the page below it instead of sitting narrower/centered
   in the full-bleed bar. */
.site-nav .inner{
  max-width:1440px;margin:0 auto;padding:16px 20px;
  display:flex;align-items:center;gap:8px;
}
@media (min-width:1800px){ .site-nav .inner{max-width:1440px;} }
.site-nav .brand{display:flex;align-items:center;gap:11px;flex:none;margin-right:16px;}
.site-nav .brand img{width:40px;height:40px;object-fit:contain;}
.site-nav .brand b{
  font-family:var(--font-display);font-weight:800;text-transform:uppercase;
  font-size:19px;letter-spacing:.01em;color:var(--ink);
}
.site-nav .brand b em{font-style:normal;color:var(--gold);}
.site-nav .links{display:flex;gap:3px;overflow-x:auto;scrollbar-width:none;}
.site-nav .links::-webkit-scrollbar{display:none;}
.site-nav .links a{
  position:relative;flex:none;padding:10px 15px;border-radius:var(--r-sm);
  font-size:15px;font-weight:600;color:var(--ink-2);white-space:nowrap;
  transition:color .15s var(--ease),background .15s var(--ease);
}
.site-nav .links a:hover{color:var(--ink);background:var(--surface-2);}
.site-nav .links a.active{color:var(--gold);}
.site-nav .links a.active::after{
  content:"";position:absolute;left:12px;right:12px;bottom:1px;height:2px;
  background:var(--gold);border-radius:2px;
}
/* The one nav item styled as a real button rather than a plain link — Lineup Generator is
   an action, not just another destination. Own colour (not .active's gold-on-transparent,
   which would vanish against a gold fill) and no underline/accent-bar — a filled button
   doesn't need a second "you are here" marker. */
.site-nav .links a.nav-cta{background:var(--gold);color:var(--navy-ink);font-weight:750;}
.site-nav .links a.nav-cta:hover{background:var(--gold-hi);color:var(--navy-ink);}
.site-nav .links a.nav-cta.active{color:var(--navy-ink);}
.site-nav .links a.nav-cta.active::after{display:none;}
.nav-toggle{
  display:none;align-items:center;justify-content:center;
  width:40px;height:40px;flex:none;margin-left:auto;
  background:none;border:1px solid var(--line);border-radius:var(--r-sm);color:var(--ink);
}
.nav-toggle svg{width:19px;height:19px;}
.nav-toggle:hover{background:var(--surface-2);}
/* The full nav (wordmark + every link in nav.js's LINKS array, at normal size) measures
   831px end to end as of 6 links (Home/Fixtures/League Table/Squad/Player Stats/Lineup
   Generator — the longer labels/CTA button pushed this up from 660px) — below that the
   links row starts clipping, silently hiding destinations behind a scrollbar-less overflow
   rather than wrapping or shrinking gracefully. Shrinking link text/padding to fit narrower
   still runs out of room well before 320px without going past a readable/tappable size, so
   instead the links collapse into a toggled dropdown below 900px (nearly 70px clear of the
   831px crossover, so there's no dead zone in between) — replacing the old hidden-scrollbar
   strip that left destinations unreachable. Icon-only brand + tighter nav padding are kept
   regardless — "Home" already exists as its own link, so the wordmark is pure decoration,
   and the shorter bar also helps short phone viewports (was 76px — over 13% of a 320x568
   screen).
   MAINTENANCE: adding/renaming a link changes the 831px figure — reload the site at ~900px,
   open dev tools and check `document.querySelector('.site-nav .links').scrollWidth` against
   `.site-nav .inner`'s content-box width; bump this breakpoint if it now clips. */
@media (max-width:900px){
  .site-nav,#site-nav{min-height:61px;}
  .site-nav .inner{padding:10px 16px;}
  .site-nav .brand{gap:0;margin-right:12px;}
  .site-nav .brand b{display:none;}
  .site-nav .brand img{width:28px;height:28px;}
  .nav-toggle{display:inline-flex;}
  .site-nav .links{
    display:none;flex-direction:column;gap:0;
    position:absolute;top:100%;left:0;right:0;
    background:var(--nav-bg);backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
    border-bottom:1px solid var(--line-soft);
    padding:6px 16px 12px;overflow-x:visible;
  }
  .site-nav .links.open{display:flex;}
  .site-nav .links a{width:100%;padding:13px 10px;text-align:left;}
  /* A bottom underline reads oddly on a full-width stacked row — a left accent bar is the
     more natural "current page" marker for a vertical list. */
  .site-nav .links a.active::after{left:0;top:8px;bottom:8px;right:auto;width:3px;height:auto;}
}
.page-head{padding:20px 0 14px;}
.page-head h1{
  margin:0;font-family:var(--font-display);font-weight:800;
  font-size:clamp(21px,5.6vw,30px);line-height:1;letter-spacing:.01em;
  text-transform:uppercase;color:var(--ink);
}
.page-head h1 em{font-style:normal;color:var(--gold);}

/* ---------- wide desktop (large monitors, e.g. 2560px) ----------
   Everything above is sized in px, tuned against a ~1440-1600px viewport, and every page
   caps its content width well short of a big monitor's full canvas — so past that cap, extra
   screen just becomes empty navy instead of the page looking any bigger. Rather than a
   site-wide rem rewrite (a much bigger, riskier change), this tier widens the content column
   and bumps the small set of most visually load-bearing elements per page, so large screens
   read as deliberately spacious rather than the same layout floating in dead space. */
@media (min-width:1800px){
  .wrap{max-width:1400px;}
  .page-head h1{font-size:38px;}
}

/* ---------- footer ---------- */
.foot{margin-top:20px;padding-top:14px;border-top:1px solid var(--line-soft);text-align:center;}
.foot .slogan{
  font-family:var(--font-display);font-weight:800;text-transform:uppercase;
  color:var(--gold);font-size:clamp(12px,3vw,15px);letter-spacing:.02em;
}
.foot .est{margin-top:4px;font-size:var(--fs-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--ink-3);font-weight:700;}

/* ---------- cross-document page transitions ----------
   Native View Transitions for plain multi-page navigation — no JS, no framework. Chromium
   browsers get a real cross-fade between pages; everything else just navigates normally. */
@view-transition{ navigation:auto; }
::view-transition-old(root){ animation:on-fade-out .16s var(--ease) both; }
::view-transition-new(root){ animation:on-fade-in .22s var(--ease) both; }
@keyframes on-fade-out{ to{ opacity:0; transform:translateY(-6px); } }
@keyframes on-fade-in{ from{ opacity:0; transform:translateY(6px); } }

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{transition-duration:.001ms !important;animation-duration:.001ms !important;}
  ::view-transition-old(root),::view-transition-new(root){animation:none !important;}
}

/* Page load failure. Deliberately a card in the content area rather than a toast: a toast that
   auto-dismisses leaves the reader back at a blank page with no way to retry. */
.load-fail{
  display:grid;justify-items:start;gap:10px;
  margin:18px 0;padding:18px 20px;
  border:1px solid var(--line);border-radius:var(--r-lg);
  background:linear-gradient(180deg,var(--surface-2),var(--surface));
  box-shadow:var(--shadow);
}
.load-fail-title{
  margin:0;font-family:var(--font-display);font-weight:800;
  font-size:var(--fs-headline);letter-spacing:var(--ls-headline);
  text-transform:uppercase;color:var(--ink);
}
.load-fail-body{margin:0;color:var(--ink-2);font-size:var(--fs-body-sm);max-width:52ch;}
