/* ============================================================================
   SUFC FOUNDATIONS — the panel + the type system
   ----------------------------------------------------------------------------
   Goes into style.css, above everything else. Adds tokens and four component
   blocks. Touches NO existing selector except .panel-title, .site-footer and
   the numeral list in §5 — all three deliberately, all three called out in the
   migration notes.

   No build step. No new font family. Plain CSS custom properties.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. TOKENS
   Inert until something consumes them, so this whole block is safe to ship on
   day one against all 47 templates.
   --------------------------------------------------------------------------- */
:root{
  /* -- the two canonical stacks. Nothing else declares a font-family. ------- */
  --font-serif:'Playfair Display','Iowan Old Style',Georgia,'Times New Roman',serif;
  --font-sans:'Source Sans 3','Source Sans Pro',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --font-num:var(--font-sans);
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* -- the scale: 9 steps, replacing 77 values ----------------------------- */
  --fs-micro:0.75rem;   /* 12px — uppercase micro-labels ONLY, never prose    */
  --fs-xs:0.8125rem;    /* 13px — dense table cells, footnotes                */
  --fs-s:0.875rem;      /* 14px — small print, meta lines, table headers      */
  --fs-m:1rem;          /* 16px — body. The default. Never go below on prose. */
  --fs-l:1.125rem;      /* 18px — lede, intro paragraph                       */
  --fs-xl:1.375rem;     /* 22px — h3 / panel title / card title               */
  --fs-2xl:1.75rem;     /* 28px — h2 / section head                           */
  --fs-3xl:clamp(2rem,1.4rem + 2.6vw,2.75rem);   /* h1                        */
  --fs-4xl:clamp(2.25rem,1.5rem + 3.6vw,3.5rem); /* display figures only      */

  /* -- line-heights -------------------------------------------------------- */
  --lh-tight:1.08;      /* display + h1                                       */
  --lh-head:1.22;       /* h2–h4                                              */
  --lh-body:1.65;       /* prose. Older eyes: generous, not fashionable.      */
  --lh-ui:1.35;         /* labels, table cells, buttons                       */

  /* -- weights. NOTE: Source Sans 3 is loaded at 300/400/600 only. --------- */
  --fw-body:400;
  --fw-med:600;         /* strongest sans weight currently loaded             */
  --fw-head:700;        /* Playfair                                           */
  --fw-display:900;     /* Playfair                                           */

  --tracking-label:0.16em;  /* uppercase micro-labels                         */
  --tracking-head:-0.015em; /* Playfair at large sizes needs pulling in       */

  /* -- panel --------------------------------------------------------------- */
  --panel-bg:var(--white,#fff);
  --panel-line:var(--border,#d1d9ee);
  --panel-line-strong:#c8cfe0;
  --panel-radius:6px;
  --panel-shadow:0 1px 2px rgba(0,32,90,.04),0 8px 28px -14px rgba(0,32,90,.22);
  --panel-shadow-lift:0 2px 4px rgba(0,32,90,.06),0 16px 40px -16px rgba(0,32,90,.34);
  --panel-pad:24px;
  --panel-pad-tight:16px;
}
@media (max-width:520px){
  :root{--panel-pad:18px;--panel-pad-tight:14px}
}

/* ---------------------------------------------------------------------------
   2. THE PANEL — one component, four variants.
   Choose: is it clickable? --nav. Does it hold controls? --filter.
   Does it hold a table edge-to-edge? --flush. Otherwise plain .sufc-panel.
   --------------------------------------------------------------------------- */
.sufc-panel{
  background:var(--panel-bg);
  border:1px solid var(--panel-line);
  border-radius:var(--panel-radius);
  box-shadow:var(--panel-shadow);
  padding:var(--panel-pad);
}
.sufc-panel + .sufc-panel{margin-top:var(--panel-pad)}
/* ...but not inside a grid or flex row, where gap already does the spacing.
   Without this the adjacent-sibling margin pushed every card except the
   first down by 24px, so a row of three gallery cards sat in a staircase. */
.sufc-grid > .sufc-panel + .sufc-panel{margin-top:0}

/* -- variant: filter. Controls, not content. Recessed, not raised. --------- */
.sufc-panel--filter{
  background:var(--off-white,#f4f6fb);
  box-shadow:none;
  padding:var(--panel-pad-tight) var(--panel-pad);
}

/* -- variant: flush. Panel holds a full-bleed table or list. --------------- */
.sufc-panel--flush{padding:0;overflow:hidden}
.sufc-panel--flush > .sufc-panel-head{padding:var(--panel-pad-tight) var(--panel-pad)}
.sufc-panel--flush > .sufc-panel-foot{padding:var(--panel-pad-tight) var(--panel-pad)}

/* -- variant: nav. The whole card is the link. ----------------------------- */
.sufc-panel--nav{
  display:flex;flex-direction:column;gap:6px;
  position:relative;min-height:44px;
  color:inherit;text-decoration:none;
  border-top:3px solid var(--royal-blue,#003087);
  transition:box-shadow .15s ease,transform .15s ease,border-color .15s ease;
}
.sufc-panel--nav:hover{box-shadow:var(--panel-shadow-lift);transform:translateY(-2px)}
.sufc-panel--nav:hover .sufc-panel-title{text-decoration:underline;text-underline-offset:3px}
.sufc-panel--nav .sufc-panel-cue{
  margin-top:6px;padding-top:12px;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-size:var(--fs-s);font-weight:var(--fw-med);color:var(--royal-blue,#003087);
}

/* -- panel header row ------------------------------------------------------ */
.sufc-panel-head{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  padding-bottom:12px;margin-bottom:var(--panel-pad-tight);
  border-bottom:1px solid var(--panel-line);
}
.sufc-panel-head-note{margin-left:auto;font-size:var(--fs-s);color:var(--text-light,#6b7280)}

/* -- panel title. Replaces all four definitions of .panel-title. ----------- */
.sufc-panel-title,.panel-title{
  font-family:var(--font-serif);
  font-size:var(--fs-xl);
  font-weight:var(--fw-head);
  line-height:var(--lh-head);
  letter-spacing:var(--tracking-head);
  color:var(--royal-blue,#003087);
  margin:0;
}
/* the gold rule is the brand mark — keep it, but only on section-level titles */
.sufc-panel > .sufc-panel-title:first-child,
.sufc-panel > .panel-title:first-child{
  padding-bottom:8px;margin-bottom:var(--panel-pad-tight);
  border-bottom:2px solid var(--gold-accent,#c8a84b);
  width:fit-content;max-width:100%;
}
/* :first-child on the left-hand side as well, so this beats the gold-rule
   selector above at equal specificity instead of losing to it by one
   pseudo-class. It only ever lost when the title WAS the first child, which
   on /visuals and /data-cleansing it never was — an icon <div> sat in front
   of it. Removing those icons made the title first, and eight nav cards
   silently grew the section-title gold rule this line exists to prevent. */
.sufc-panel--nav .sufc-panel-title,
.sufc-panel--nav > .sufc-panel-title:first-child{border-bottom:none;padding-bottom:0;margin-bottom:2px;font-size:var(--fs-xl)}

/* -- the card header bar ---------------------------------------------------
   The royal-blue rule across the top of a --flush panel: "Top Scorers",
   "Goalkeeper Records", "Record by Day of Year". Fourteen templates each
   declared their own near-copy of it under their own prefix — the same
   fourteen lines the panel refactor found seventeen of. Same fix, same list:
   one rule, the old class names kept as aliases so page CSS and scripts that
   target them still work.

   The fourteen had drifted, and three of them are therefore CHANGED rather
   than merely replaced. Eleven were identical; .gk-card-header and
   .att-table-header had no letter-spacing and now get the other twelve's
   0.02em; .record-card-header had 0.04em and 0.7rem padding and now gets
   0.02em and 0.8rem. None of the three looks like a decision — they look
   like a paste that lost a line — but they were differences, so they are
   named here rather than absorbed silently.

   flex/baseline is .record-card-header's, taken for all of them: several of
   these headers carry a trailing instruction ("Click any row to see the
   individual matches"), which was running on as body text inline. It now
   has a class and sits on the heading's baseline.

   line-height is --lh-body, which is what all fourteen already inherited
   from .sufc-type. Stated rather than inherited so the bar keeps its height
   on a page that has not been typed. */
.sufc-cardhead,
.goals-card-header,.gk-card-header,.att-table-header,.fn-card-header,
.sl-card-header,.gbs-card-header,.gt-card-header,.wdl-card-header,
.dbd-card-header,.app-table-header,.discipline-card-header,
.record-card-header,.sc-card-header{
  display:flex;align-items:baseline;flex-wrap:wrap;
  column-gap:12px;row-gap:2px;
  margin:0;padding:.8rem 1.2rem;
  background:var(--royal-blue,#003087);color:#fff;
  font-family:var(--font-serif);font-size:var(--fs-m);
  font-weight:var(--fw-head);line-height:var(--lh-body);
  letter-spacing:.02em;
}
/* The instruction some of them carry. Sans and italic, so it reads as an
   aside to the heading rather than part of it. */
.sufc-cardhead-note{
  font-family:var(--font-sans);font-size:var(--fs-s);font-weight:var(--fw-body);
  font-style:italic;letter-spacing:0;color:rgba(255,255,255,.82);
}

/* ---------------------------------------------------------------------------
   3. TYPE ROLES
   Element selectors are scoped to .sufc-type so an unmigrated page's stray
   <h3> is never restyled from under it. Add the class to <main> to opt in.
   --------------------------------------------------------------------------- */
/* font-family and font-size only: both are no-ops today (style.css already
   sets the family, and 1rem is the browser default), so this states intent
   without moving anything. line-height moved to .sufc-type — as a bare body
   rule it cascaded into all 47 templates and grew every page: /statistics
   +156px, the home page +180px, pages this same design system had just been
   measured against. Migrated pages get the generous leading; the rest are
   untouched, which is what the rest of this file promises. */
body{font-family:var(--font-sans);font-size:var(--fs-m);-webkit-text-size-adjust:100%}
.sufc-type{line-height:var(--lh-body)}

/* Two strengths, deliberately.
   The CLASS form (.sufc-h1, .sufc-body, …) is an instruction: you asked for
   this role, you get it, and it beats the page's own rules at (0,1,0).
   The ELEMENT form is only a DEFAULT, so it is wrapped in :where() and carries
   no specificity at all — any class the page already puts on that element
   wins. This is not tidiness. Typing <main class="hp"> on the home page put
   `.sufc-type h1` (0,1,1) over `.hp-title` (0,1,0) and turned a white hero
   headline royal blue on a navy photograph, took the gold off the eyebrow,
   and widened the lede from its own measure to 72ch. Three pages on this site
   — the home page, /statistics and /season — carry complete design languages
   of their own, and the type system's job on those pages is to supply what
   they have not said, not to overrule what they have. */
.sufc-h1,:where(.sufc-type h1){font-family:var(--font-serif);font-size:var(--fs-3xl);font-weight:var(--fw-display);line-height:var(--lh-tight);letter-spacing:var(--tracking-head);color:var(--royal-blue,#003087);margin:0}
.sufc-h2,:where(.sufc-type h2){font-family:var(--font-serif);font-size:var(--fs-2xl);font-weight:var(--fw-head);line-height:var(--lh-head);letter-spacing:var(--tracking-head);color:var(--royal-blue,#003087);margin:0}
.sufc-h3,:where(.sufc-type h3){font-family:var(--font-serif);font-size:var(--fs-xl);font-weight:var(--fw-head);line-height:var(--lh-head);color:var(--royal-blue,#003087);margin:0}
.sufc-h4,:where(.sufc-type h4){font-family:var(--font-sans);font-size:var(--fs-m);font-weight:var(--fw-med);line-height:var(--lh-head);color:var(--text-dark,#111827);margin:0}

/* A lede sits beside its heading when there is room and drops beneath it when
   there is not — one flex line with wrapping, so no media query has to guess
   where the break falls. Top-aligned, not baseline: baseline alignment drops
   the lede's first line to sit on the title's baseline, which on a 44px
   Playfair heading pushes it most of a line down the block. The small
   padding-top is optical — the heading's tight 1.08 leading puts its cap very
   near the top of its box, while the lede's 1.5 leaves space above the x-height.
   The residual is half-leading and cannot be cancelled proportionally in CSS:
   it is larger under a 42px h1 than a 22px h2. Tuned by eye against the 42px
   case, which is the one most pages have — an earlier -.3em was measured as
   near-perfect on line boxes and still read as too high, because Playfair's
   cap sits lower in its box than the italic sans does and the boxes are not
   what anyone looks at.

   Short copy only. A page whose intro runs to forty words of instructions
   wants .sufc-body underneath, not this: it will never fit on the line, and
   italic grey at 14px is the wrong voice for something a reader must follow. */
.sufc-pagehead{
  display:flex;flex-wrap:wrap;align-items:flex-start;
  column-gap:14px;row-gap:2px;
  margin-bottom:var(--panel-pad-tight);
}
.sufc-pagehead > .sufc-lede{margin:0;padding-top:.1em}
/* A panel holding nothing but its heading does not need the gap that
   separates a heading from content below it. /onthisday is one. */
.sufc-panel > .sufc-pagehead:only-child{margin-bottom:0}

.sufc-lede{
  font-size:var(--fs-s);
  font-style:italic;
  line-height:1.5;
  /* The deeper gold, not --gold-accent. #c8a84b is a highlight against navy
     and fails badly as small text on white; #8f7420 is the same hue carrying
     enough contrast to read at 14px. This is the colour the eyebrow used. */
  color:#8f7420;
  max-width:62ch;
  text-wrap:pretty;
}
.sufc-body,:where(.sufc-type p){font-size:var(--fs-m);line-height:var(--lh-body);color:var(--text-mid,#374151);max-width:72ch;text-wrap:pretty}
:where(.sufc-type p + p){margin-top:1em}
.sufc-small{font-size:var(--fs-s);line-height:1.5;color:var(--text-light,#6b7280)}
.sufc-label{font-size:var(--fs-micro);font-weight:var(--fw-med);letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-light,#6b7280);line-height:var(--lh-ui)}

.sufc-th,:where(.sufc-type th){font-size:var(--fs-s);font-weight:var(--fw-med);line-height:var(--lh-ui);color:var(--text-mid,#374151);text-align:left}
.sufc-td,:where(.sufc-type td){font-size:var(--fs-xs);line-height:var(--lh-ui);color:var(--text-dark,#111827)}
@media (min-width:768px){.sufc-td,:where(.sufc-type td){font-size:var(--fs-s)}}

/* links — defined so editor-added links never render browser blue */
:where(.sufc-type) a{color:var(--royal-blue,#003087)}
/* The underline is for PROSE, and only prose. As a blanket `.sufc-type a` rule
   it beat every control on the site — (0,1,1) against the (0,1,0) of
   .back-link, .alpha-btn, .sn-back and the rest — so the A–Z buttons, the back
   links and every player name in a 500-row results table all gained an
   underline the moment their page was typed. Scoping it to the prose roles
   keeps the affordance where a reader needs it and leaves controls alone;
   the colour above still applies everywhere, so no link renders browser blue. */
:where(.sufc-type :is(p,li,dd,blockquote)) a,
.sufc-body a,.sufc-lede a,.sufc-small a{
  text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;
}
/* ...except a nav card, where the whole panel is the <a>: the prose-link
   underline was striking through the title, the description and the cue.
   The variant already underlines its title on hover, which is the affordance. */
.sufc-type a.sufc-panel--nav,.sufc-type a.sufc-panel--nav:hover{text-decoration:none;color:inherit}
:where(.sufc-type) a:hover{color:#001f5c}
:where(.sufc-type :is(p,li,dd,blockquote)) a:hover,
.sufc-body a:hover,.sufc-lede a:hover,.sufc-small a:hover{text-decoration-thickness:2px}
:where(a,button,summary,[role=button]):focus-visible{outline:3px solid var(--gold-accent,#c8a84b);outline-offset:2px;border-radius:3px}

/* ---------------------------------------------------------------------------
   4. DISPLAY FIGURE — the one place a number gets to be big.
   Still sans. Size does the work that the serif used to.
   --------------------------------------------------------------------------- */
.sufc-fig{font-family:var(--font-num);font-size:var(--fs-4xl);font-weight:var(--fw-med);line-height:1;letter-spacing:-.02em;font-variant-numeric:tabular-nums lining-nums;color:var(--royal-blue,#003087)}
.sufc-fig-s{font-size:var(--fs-2xl)}

/* ---------------------------------------------------------------------------
   5. THE NUMERAL RULE — safe to ship globally on day one.
   RULE: if it is a number a reader might compare with another number, it is
   sans with tabular figures. Playfair is for words.
   This selector list is the 40 audited serif-numeral rules, minus the seven
   that belong to shipped components (listed separately in the migration notes).
   --------------------------------------------------------------------------- */
/* .pm-stats-header and .stats-card-header were in the delivered list and are
   NOT numerals — both read "Career Statistics at Southend United". They were
   false positives in the audit I supplied, which matched class names on
   "stat". Left on Playfair, where headings belong. */
.sufc-num,
/* The shipped components' figures. Excluded from the first pass because
   changing them looked like a redesign rather than a refactor — but .ss-value
   is the stat strip, which is the most numeric thing on the site and appears
   on /season, /onthisday, /opponent and /h2h. Headings that happen to contain
   digits are deliberately NOT here: "Season 2024/25" and "9 August" are words,
   and Playfair is for words. */
/* The eleven .*-stat-value classes that used to be listed here — .app-,
   .att-, .dbd-, .discipline-, .sc-, .fn-, .gt-, .gk-, .goals-, .gbs-,
   .sl-, .wdl- — are gone. Each was one page's copy of the row of bordered
   summary boxes, and all fifteen of those pages now render .ss-value
   through renderStatStrip, which is already first in this list. */
.ss-value,.ss-score,.sh-fig b,.sh-land-val,.sh-feature-fig b,.sh-card-cue b,.vp-score,
.record-row-value,.hp-otd-year,.hp-otd-score,.hp-total-fig,.hp-card-count{
  font-family:var(--font-num);
  font-variant-numeric:tabular-nums lining-nums;
  font-weight:var(--fw-med);
  letter-spacing:-.01em;
}
/* every table figure aligns, without needing a class per page */
.sufc-type td,.sufc-type th{font-variant-numeric:tabular-nums lining-nums}

/* ---------------------------------------------------------------------------
   6. FOOTER — one footer. Replaces .site-footer and .site-footer.hp.
   Drop the .hp modifier from the three templates that use it; no other markup
   change is needed.
   --------------------------------------------------------------------------- */
.site-footer{
  margin-top:56px;
  background:var(--royal-blue,#003087);
  border-top:3px solid var(--gold-accent,#c8a84b);
  color:rgba(255,255,255,.78);
}
.site-footer .hp-inner,.sufc-footer-inner{
  max-width:1200px;margin:0 auto;padding:22px 24px;
  display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 24px;
  font-size:var(--fs-s);line-height:var(--lh-ui);
}
.site-footer p{margin:0}
/* <strong>, not <b>: that is what all three templates using the name emit. */
.site-footer b,.site-footer strong,.sufc-footer-name{color:#fff;font-weight:var(--fw-med)}
.sufc-footer-meta{margin-left:auto;font-variant-numeric:tabular-nums}
.site-footer a{color:var(--gold-accent,#c8a84b);text-decoration:none;display:inline-block;min-height:44px;line-height:44px}
.site-footer a:hover{text-decoration:underline;text-underline-offset:3px}
@media (max-width:640px){
  .site-footer .hp-inner,.sufc-footer-inner{display:block}
  .sufc-footer-meta{margin:6px 0 0}
  /* 14px, not the delivered 12px: at 12 the link measured 41px and the
     brief sets 44 as the floor. */
  .site-footer a{line-height:1.4;min-height:0;padding:14px 0}
}

/* ---------------------------------------------------------------------------
   7. UTILITY
   --------------------------------------------------------------------------- */
.sufc-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.sufc-grid{display:grid;gap:var(--panel-pad-tight);align-items:start}
.sufc-grid--4{grid-template-columns:repeat(4,minmax(0,1fr))}
.sufc-grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:900px){.sufc-grid--4,.sufc-grid--3{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.sufc-grid--4,.sufc-grid--3{grid-template-columns:minmax(0,1fr)}}

/* =============================================
   SOUTHEND UNITED HISTORY - STYLESHEET
   Royal Blue & White | Classic Football Archive
   ============================================= */

:root {
    --royal-blue: #003087;
    --blue-mid: #004abf;
    --blue-light: #1a5ccc;
    --blue-pale: #e8eef8;
    --white: #ffffff;
    --off-white: #f4f6fb;
    --text-dark: #111827;
    --text-mid: #374151;
    --text-light: #6b7280;
    --border: #d1d9ee;
    --gold-accent: #c8a84b;
    --win: #1a7a3c;
    --draw: #b07a00;
    --loss: #9b1c1c;
    --shadow: 0 4px 24px rgba(0, 48, 135, 0.10);
    --shadow-lg: 0 8px 40px rgba(0, 48, 135, 0.18);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
    font-family: 'Source Sans 3', sans-serif;
    background: var(--off-white);
    color: var(--text-dark);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* ---- HEADER ---- see the redesign block appended at the end of this file ----*/

/* ---- MAIN ---- */
.main-content {
    max-width: 1200px;
    margin: 2rem auto;
    padding: 0 1.5rem;
    flex: 1;
    width: 100%;
}

/* ---- PANEL TITLES ---- */
.panel-title {
    font-family: 'Playfair Display', serif;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--royal-blue);
    margin-bottom: 1.2rem;
    padding-bottom: 0.5rem;
    border-bottom: 2px solid var(--gold-accent);
    display: inline-block;
}

/* ---- FILTERS PANEL ----
   The frame now comes from .sufc-panel, and on the nineteen pages that hold
   nothing but controls, from .sufc-panel--filter. All that is left here is
   the gap between the panel and whatever the page renders under it. */
.filters-panel { margin-bottom: 2rem; }

.filters-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.filter-group { display: flex; flex-direction: column; gap: 0.4rem; }

.filter-group label {
    font-size: var(--fs-micro);
    font-weight: var(--fw-med);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-light);
}

.filter-group select,
.filter-group input[type="text"] {
    /* 44px, not the 37px this used to compute to. Every filter panel on the
       site is built from these two, so every one of them had a sub-target
       control in it; the readership is not one to forgive a 37px hit area. */
    min-height: 44px;
    padding: 0.55rem 0.8rem;
    border: 1.5px solid var(--border);
    border-radius: 7px;
    font-family: var(--font-sans);
    font-size: var(--fs-m);
    color: var(--text-dark);
    background: var(--white);
    transition: border-color 0.2s, box-shadow 0.2s;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23003087' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.8rem center;
    padding-right: 2.2rem;
}

.filter-group input[type="text"] { background-image: none; padding-right: 0.8rem; }

.filter-group select:focus,
.filter-group input[type="text"]:focus {
    outline: none;
    border-color: var(--blue-light);
    box-shadow: 0 0 0 3px rgba(26, 92, 204, 0.15);
}

.filter-actions { display: flex; gap: 1rem; flex-wrap: wrap; }

.btn-primary {
    background: var(--royal-blue);
    color: var(--white);
    border: none;
    /* was 43px tall — one pixel under, on every filter panel on the site */
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.65rem 2rem;
    border-radius: 7px;
    font-family: var(--font-sans);
    font-size: var(--fs-m);
    font-weight: var(--fw-med);
    cursor: pointer;
    transition: background 0.2s, transform 0.1s;
    letter-spacing: 0.04em;
}

.btn-primary:hover { background: var(--blue-light); transform: translateY(-1px); }
.btn-primary:active { transform: translateY(0); }

.btn-secondary {
    background: transparent;
    color: var(--royal-blue);
    border: 1.5px solid var(--royal-blue);
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.65rem 1.5rem;
    border-radius: 7px;
    font-family: var(--font-sans);
    font-size: var(--fs-m);
    font-weight: var(--fw-med);
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
}

.btn-secondary:hover { background: var(--blue-pale); }

/* ---- RESULTS PANEL ----
   Now .sufc-panel. The class stays on the element as the hook these rules
   and the page scripts still target. */
.results-header { display: flex; align-items: baseline; gap: 1rem; margin-bottom: 1.2rem; }
.match-count { font-size: 0.9rem; color: var(--text-light); font-weight: 400; }

/* Filters beside the programme thumbnail on the opponent page. The grid's
   min column is 220px and the thumbnail is a non-shrinking 130px, so with the
   gap they cannot both fit a phone; let the row break instead. */
.opp-filters-row {
    display: flex;
    gap: 1.5rem;
    align-items: flex-start;
}

@media (max-width: 700px) {
    .opp-filters-row { flex-wrap: wrap; gap: 1rem; }
}

/* Played / Won / Drawn / Lost / GF / GA / Diff on the opponent page. Was an
   inline repeat(7,1fr), which squeezed each card to ~50px on a phone and ran
   off-screen; auto-fit lets it fall to 4 and then 3 columns. */
.om-stat-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.75rem;
}

@media (max-width: 700px) {
    .om-stat-grid { grid-template-columns: repeat(4, 1fr); gap: 0.5rem; }
}

@media (max-width: 420px) {
    .om-stat-grid { grid-template-columns: repeat(3, 1fr); }
}

/* auto, not visible: these wrap tables far wider than a phone screen (the
   /onthisday table is 1041px), and with `visible` the overflow escapes the
   wrapper and scrolls the whole document sideways instead of just the table.
   .app-table-card on /appearances already does this correctly. */
.table-wrapper { overflow-x: auto; border-radius: 8px; border: 1px solid var(--border); }

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
thead { background: var(--royal-blue); color: var(--white); }

thead th {
    padding: 0.75rem 0.9rem;
    text-align: left;
    font-weight: 600;
    letter-spacing: 0.05em;
    font-size: 0.8rem;
    text-transform: uppercase;
    white-space: nowrap;
}

tbody tr { border-bottom: 1px solid var(--border); transition: background 0.15s; cursor: pointer; }
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--blue-pale); }
tbody td { padding: 0.65rem 0.9rem; color: var(--text-mid); white-space: nowrap; }
tbody tr:nth-child(even) { background: var(--off-white); }
tbody tr:nth-child(even):hover { background: var(--blue-pale); }

.placeholder-row td {
    text-align: center;
    color: var(--text-light);
    padding: 3rem;
    font-style: italic;
    cursor: default;
}

/* Result badges */
.badge { display: inline-block; padding: 0.2rem 0.6rem; border-radius: 4px; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.05em; }
.badge-W { background: #d1fae5; color: var(--win); }
.badge-D { background: #fef3c7; color: var(--draw); }
.badge-L { background: #fee2e2; color: var(--loss); }
.badge-other { background: var(--blue-pale); color: var(--royal-blue); }

/* ---- SORTABLE COLUMNS ---- */
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable:hover { background: var(--blue-mid); }
th.sort-asc .sort-icon::after  { content: ' ▲'; }
th.sort-desc .sort-icon::after { content: ' ▼'; }
th.sort-asc .sort-icon, th.sort-desc .sort-icon { opacity: 1; }
.sort-icon { opacity: 0.4; font-size: 0.75rem; }

/* ---- MODAL OVERLAY ---- */

/* =============================================
   VINTAGE PROGRAMME MODAL
   ============================================= */

/* Override modal box for vintage look */

/* Close button vintage style */

/* Wrapper */

/* ---- MASTHEAD ---- */

/* ---- THREE COLUMNS ---- */

/* Goalscorers */

/* Players */

/* =============================================
   RECORDS PAGE
   ============================================= */
.records-loading {
    text-align: center;
    padding: 4rem;
    color: var(--text-light);
    font-style: italic;
    font-size: 1rem;
}

.records-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 1.5rem;
    margin-top: 1.5rem;
}

/* .record-card is .sufc-panel--flush; the frame it used to declare here
   would have won on source order over the shared component.

   The header bar that stood here is gone: it was a THIRD definition of the
   same fourteen lines, at --fs-s where every other page used --fs-m, and it
   never rendered — records.html carried its own copy in an inline <style>,
   which comes after this file and won. Deleting the template's copy without
   this one would have silently dropped /records to 14px. See .sufc-cardhead
   in §2. */

.record-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.6rem 1rem;
    border-bottom: 1px solid var(--border);
    gap: 1rem;
    font-size: 0.88rem;
    transition: background 0.15s;
    min-width: 0;
}

.record-row:last-child { border-bottom: none; }

.record-clickable { cursor: pointer; }
.record-clickable:hover { background: var(--blue-pale); }

.record-row-left {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.record-row-rank {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--white);
    background: var(--royal-blue);
    border-radius: 50%;
    width: 1.4rem;
    height: 1.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.record-row-main {
    font-weight: 600;
    color: var(--text-dark);
    white-space: normal;
    word-break: break-word;
    line-height: 1.3;
}

.record-row-sub {
    font-size: 0.78rem;
    color: var(--text-light);
    margin-top: 0.2rem;
    white-space: normal;
    word-break: break-word;
    line-height: 1.3;
}

.record-row-value {
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--royal-blue);
    white-space: nowrap;
    flex-shrink: 0;
}

/* ============================================================================
   BREADCRUMBS
   ----------------------------------------------------------------------------
   Replaces .back-link, .sh-back and .sn-back — 44 hand-written "← Back to …"
   links whose destination was a guess about where the reader had come from.
   With a site-wide search box in the header the guess was wrong most of the
   time. A breadcrumb answers the question a lost reader is actually asking,
   which is where am I, and it is generated from sitemap.py rather than typed
   per page, so it cannot contradict the menu.

   Sits where the back link sat: first child of <main>, same margin below.
   44px rows, because the audience skews older and a 14px crumb with 4px of
   padding is not a target.
   ============================================================================ */
.sufc-crumbs { margin-bottom: var(--panel-pad-tight, 16px); }

.sufc-crumbs ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 0.15rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* min-width:0 so a long player name — "Collin Andeng Ndi", "Freddy Eastwood"
   — can shrink and ellipsise at 320px instead of pushing the page sideways. */
.sufc-crumbs li { display: flex; align-items: center; min-width: 0; }

/* The separator belongs to the crumb it precedes, so it wraps with it rather
   than being orphaned at the end of a line. */
.sufc-crumbs li + li::before {
    content: "\203A";           /* › */
    margin: 0 0.35rem;
    color: var(--text-light, #6b7280);
    font-size: var(--fs-m, 1rem);
    line-height: 1;
}

.sufc-crumbs a,
.sufc-crumbs [aria-current] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 0.15rem;
    font-size: var(--fs-s, 0.875rem);
    line-height: var(--lh-ui, 1.35);
}

.sufc-crumbs a {
    color: var(--royal-blue, #003087);
    font-weight: 600;
    text-decoration: none;
    transition: color 0.15s;
}
.sufc-crumbs a:hover {
    color: var(--blue-light, #0047b3);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.sufc-crumbs a:focus-visible {
    outline: 2px solid var(--royal-blue, #003087);
    outline-offset: 2px;
    border-radius: 3px;
}

/* The page you are on. Not a link, and not shouting — it is the one crumb the
   reader does not need to act on. */
.sufc-crumbs [aria-current] {
    color: var(--text-light, #6b7280);
    font-weight: 400;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

@media print {
    .sufc-crumbs { display: none !important; }
}

@media (max-width: 500px) {
    .records-grid { grid-template-columns: 1fr; }
}

/* ---- MERGED MATCH MODAL ---- */

/* ---- STATISTICS SEARCH PAGE - COLUMN WIDTHS ---- */
#results-table th[data-col="Date"],
#results-table td:nth-child(1) { width: 95px; min-width: 95px; }

#results-table th[data-col="Season"],
#results-table td:nth-child(2) { width: 75px; min-width: 75px; }

#results-table th[data-col="Competition"],
#results-table td:nth-child(3) { white-space: normal; word-wrap: break-word; min-width: 140px; max-width: 220px; vertical-align: top; }

#results-table th[data-col="Opponents"],
#results-table td:nth-child(4) { min-width: 140px; }

#results-table th[data-col="Venue"],
#results-table td:nth-child(5) { width: 90px; min-width: 90px; }

#results-table th[data-col="Score"],
#results-table td:nth-child(6) { width: 65px; min-width: 65px; text-align: center; }

#results-table th[data-col="HT"],
#results-table td:nth-child(7) { width: 60px; min-width: 60px; text-align: center; }

#results-table th[data-col="WDL"],
#results-table td:nth-child(8) { width: 70px; min-width: 70px; text-align: center; }

/* =============================================
   PLAYER BIOGRAPHY POP-UP (pm- classes)
   Used by openPlayerModal() in app.js
   ============================================= */
.pm-top { display:flex; gap:1.2rem; align-items:flex-start; margin-bottom:1.2rem; }
.pm-photo-wrap { flex-shrink:0; width:130px; }
.pm-photo { width:130px; max-height:200px; object-fit:contain; object-position:top; border-radius:8px; border:2px solid var(--border); display:block; }
.pm-info { flex:1; min-width:0; }
.pm-name { font-family:'Playfair Display',serif; font-size:1.4rem; font-weight:900; color:var(--royal-blue); margin:0 0 0.8rem; }
.pm-detail-table { width:100%; border-collapse:collapse; font-size:0.85rem; }
.pm-detail-table td { padding:0.25rem 0.4rem; vertical-align:top; }
.pm-label { font-weight:700; color:var(--text-light); white-space:nowrap; padding-right:0.8rem; width:110px; }
.pm-stats-header { background:var(--royal-blue); color:#fff; font-family:'Playfair Display',serif; font-size:0.9rem; font-weight:700; padding:0.5rem 0.9rem; border-radius:6px 6px 0 0; margin-top:1rem; }
.pm-stats-table { width:100%; border-collapse:collapse; font-size:0.85rem; margin-bottom:1rem; border:1px solid var(--border); border-top:none; }
.pm-stats-table th { background:var(--blue-pale); color:var(--royal-blue); padding:0.4rem 0.8rem; text-align:left; font-size:0.75rem; text-transform:uppercase; letter-spacing:0.07em; }
.pm-stats-table td { padding:0.35rem 0.8rem; border-bottom:1px solid var(--border); }
.pm-stats-table tr:last-child td { border-bottom:none; }
.pm-num { text-align:right; font-weight:600; color:var(--royal-blue); }
.pm-total-row td { background:#f0f4ff; border-top:2px solid var(--royal-blue); }
.pm-friendly-row td { color:var(--text-light); font-style:italic; font-size:0.82rem; }
.pm-bio-text { font-size:0.85rem; line-height:1.6; color:#333; border-top:1px solid var(--border); padding-top:1rem; }
.pm-source { font-size:0.75rem; color:var(--text-light); font-style:italic; }

/* ============================================================================
   SITE HEADER — REDESIGN
   ----------------------------------------------------------------------------
   Replaces the previous .site-header / .header-inner / .header-crest /
   .site-title / .site-subtitle rules and their @media (max-width:700px) block,
   and takes over the .sufc-* search styles that static/js/search.js used to
   inject — they live here now so there is only one copy.

   The About links no longer carry inline styles in the templates, so nothing
   here needs !important.
   ============================================================================ */

/* --- local fallbacks so this block is safe even before :root is parsed ----- */
.site-header {
  --hdr-blue:      var(--royal-blue, #003087);
  --hdr-blue-deep: #001f5c;
  --hdr-blue-lift: #004abf;
  --hdr-gold:      var(--gold-accent, #c8a84b);
  --hdr-white:     var(--white, #ffffff);

  /* The two numbers that set header height. Change these, not the paddings. */
  --hdr-pad-y:     1.125rem;   /* 18px desktop */
  --hdr-control:   44px;       /* control height = minimum tap target */
}

/* --- 1. shell ------------------------------------------------------------- */
.site-header {
  position: relative;   /* containing block for .hdr-nav-panel */
  background: var(--hdr-blue);
  background-image: linear-gradient(135deg, var(--hdr-blue-deep) 0%, var(--hdr-blue) 55%, var(--hdr-blue-lift) 100%);
  color: var(--hdr-white);
  border-bottom: 3px solid var(--hdr-gold);
}

.header-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--hdr-pad-y) 1.5rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  /* Deliberately no flex-wrap: the layout is explicit at every breakpoint
     rather than emergent. Wrapping is what made the old header's height vary
     between pages. */
}

/* --- 2. brand ------------------------------------------------------------- */
.hdr-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
  color: inherit;
  margin-right: auto;
  min-width: 0;
}

/* The crest is an <img> of a white-line SVG, so `color` no longer applies —
   the artwork carries its own paint. object-fit keeps the club badge's
   1.06:1 aspect ratio inside the square box instead of squashing it. */
.hdr-crest { flex: 0 0 auto; width: 40px; height: 40px; display: block; object-fit: contain; }

.hdr-brand-text { display: flex; flex-direction: column; min-width: 0; }

.hdr-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 900;
  font-size: clamp(1.15rem, 2.4vw, 1.5rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--hdr-white);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.hdr-subtitle {
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.72);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- 3. search ------------------------------------------------------------ */
.hdr-search { position: relative; flex: 0 1 340px; min-width: 0; }

.hdr-search input {
  width: 100%;
  height: var(--hdr-control);
  box-sizing: border-box;
  padding: 0 0.75rem 0 2.35rem;
  border: 1px solid rgba(255,255,255,0.38);
  border-radius: 4px;
  background: rgba(255,255,255,0.12);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-opacity='0.75' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6'/%3E%3Cpath d='M20 20l-4.3-4.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 0.7rem center;
  color: var(--hdr-white);
  font-family: inherit;
  font-size: 0.95rem;
  -webkit-appearance: none;
  appearance: none;
}
.hdr-search input::placeholder { color: rgba(255,255,255,0.72); opacity: 1; }
.hdr-search input::-webkit-search-cancel-button { -webkit-appearance: none; }
.hdr-search input:hover { background-color: rgba(255,255,255,0.17); }
.hdr-search input:focus {
  outline: none;
  background-color: rgba(255,255,255,0.2);
  border-color: var(--hdr-gold);
  box-shadow: 0 0 0 3px rgba(200,168,75,0.35);
}

.sufc-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 1000;
  background: #fff;
  color: #111827;
  border: 1px solid rgba(0,48,135,0.18);
  border-top: 3px solid var(--hdr-gold);
  border-radius: 0 0 5px 5px;
  box-shadow: 0 14px 40px rgba(0,20,70,0.35);
  max-height: min(64vh, 428px);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: none;
}
.sufc-results.open { display: block; }

.sufc-group {
  position: sticky;
  top: 0;
  padding: 0.35rem 0.85rem;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--hdr-blue);
  background: #eef2fa;
  border-bottom: 1px solid rgba(0,48,135,0.1);
}

.sufc-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6rem 0.85rem;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  border-bottom: 1px solid #eef0f4;
}
.sufc-item:last-child { border-bottom: none; }
.sufc-item .n { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sufc-item .m { flex: 0 0 auto; color: #6b7280; font-size: 0.78rem; white-space: nowrap; }
.sufc-item:hover,
.sufc-item.active { background: #eef3fb; }
.sufc-item.active { box-shadow: inset 3px 0 0 var(--hdr-gold); }
.sufc-empty { padding: 0.85rem; color: #6b7280; font-size: 0.9rem; }

/* --- 4. the menu ---------------------------------------------------------- */
/* Replaces the <details class="hdr-more"> disclosure, which held two About
   links and nothing else — so the four front-page destinations were reachable
   only from the home page. This is the same slot, the same 44px gold pill and
   the same panel treatment as the search results; what changed is that it now
   opens the whole site rather than two links.

   A real <button aria-expanded> rather than <details>: a disclosure that must
   close on Escape, close on outside click and hand focus back is a button with
   a panel, and <details> only pretended otherwise (header.js was already
   overriding `open` from a matchMedia listener to stop the panel rendering
   290px off-screen on desktop).

   The no-JavaScript path is kept by the `js` class, set on <html> before first
   paint by the global head injection in app.py: without it the button is
   hidden and the panel is a plain band of links under the header. */
.hdr-nav { flex: 0 0 auto; }

.hdr-nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  height: var(--hdr-control);
  min-width: var(--hdr-control);
  padding: 0 0.9rem;
  border: 1px solid rgba(200,168,75,0.7);
  border-radius: 4px;
  background: rgba(255,255,255,0.12);
  color: var(--hdr-gold);
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  cursor: pointer;
  user-select: none;
  -webkit-appearance: none;
  appearance: none;
}
.hdr-nav-btn:hover { background: rgba(255,255,255,0.2); color: #e2c979; }
.hdr-nav-icon { flex: 0 0 auto; }
.hdr-nav-icon--close,
.hdr-nav-btn[aria-expanded="true"] .hdr-nav-icon--open { display: none; }
.hdr-nav-btn[aria-expanded="true"] .hdr-nav-icon--close { display: block; }

/* The panel spans the header rather than hanging off the button. On a phone
   the search box is the header's second row, so a button-anchored panel would
   sit on top of it; and a right-anchored fixed-width panel is the usual way a
   header overflows a 320px viewport. Full-bleed does neither. */
.hdr-nav-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 999;
  background: #fff;
  color: var(--text-dark, #111827);
  border-bottom: 1px solid rgba(0,48,135,0.18);
  border-top: 3px solid var(--hdr-gold);
  box-shadow: 0 14px 40px rgba(0,20,70,0.35);
  max-height: 80vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hdr-nav-list {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0.85rem 1.5rem 1.1rem;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.35rem 1rem;
}

.hdr-nav-link {
  display: block;
  min-height: var(--hdr-control);
  padding: 0.6rem 0.7rem;
  border-radius: 4px;
  border-left: 3px solid transparent;
  text-decoration: none;
  color: inherit;
}
.hdr-nav-link:hover { background: #eef3fb; }
.hdr-nav-link[aria-current="page"] {
  background: #eef3fb;
  border-left-color: var(--hdr-gold);
}

.hdr-nav-label {
  display: block;
  font-family: var(--font-serif, 'Playfair Display', Georgia, serif);
  font-size: var(--fs-l, 1.125rem);
  font-weight: 700;
  line-height: var(--lh-head, 1.22);
  color: var(--hdr-blue);
}
.hdr-nav-blurb {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-s, 0.875rem);
  line-height: 1.4;
  color: var(--text-light, #6b7280);
}

/* Open/closed is CSS keyed on the `js` class, which app.py's global head
   injection sets on <html> before first paint — not a `hidden` attribute set
   by header.js, which is deferred and would therefore let the panel paint open
   for a frame on every page load.

   No JavaScript: no button, and the panel stays a static band of links, which
   is a working site rather than a dead burger. */
html.js .hdr-nav-panel { display: none; }
html.js .hdr-nav-panel.is-open { display: block; }
html:not(.js) .hdr-nav { display: none; }
html:not(.js) .hdr-nav-panel { position: static; box-shadow: none; max-height: none; }

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

.site-header a:focus-visible,
.site-header input:focus-visible,
.site-header button:focus-visible {
  outline: 3px solid var(--hdr-gold);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Inside the white panel the gold ring has too little contrast to find. */
.hdr-nav-panel a:focus-visible {
  outline-color: var(--hdr-blue);
  outline-offset: -2px;
}

/* --- 5. breakpoints ------------------------------------------------------- */
@media (max-width: 1279px) { .hdr-search { flex-basis: 300px; } }

@media (max-width: 1023px) {
  .header-inner { gap: 1rem; padding-left: 1.25rem; padding-right: 1.25rem; }
  .hdr-search { flex-basis: 250px; }
  .hdr-nav-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }
}

@media (max-width: 860px) and (min-width: 768px) {
  .hdr-subtitle { display: none; }
}

@media (max-width: 767px) {
  .site-header { --hdr-pad-y: 0.75rem; }

  .header-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "brand  more"
      "search search";
    column-gap: 0.75rem;
    row-gap: 0.5rem;
    padding-left: 1rem;
    padding-right: 1rem;
  }

  .hdr-brand  { grid-area: brand;  margin-right: 0; }
  .hdr-search { grid-area: search; flex: initial; width: 100%; }
  .hdr-nav    { grid-area: more; }

  .hdr-crest { width: 34px; height: 34px; }
  .hdr-title { font-size: 1.15rem; }
  .hdr-subtitle { font-size: 0.62rem; letter-spacing: 0.1em; }

  /* 16px stops iOS Safari zooming the page when the field takes focus. */
  .hdr-search input { font-size: 1rem; }

  .hdr-nav-list {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    padding: 0.4rem 1rem 0.8rem;
  }
  .hdr-nav-link { border-radius: 0; }
  .hdr-nav-list li + li .hdr-nav-link { border-top: 1px solid #eef0f4; }
}

@media (max-width: 359px) {
  .header-inner { padding-left: 0.75rem; padding-right: 0.75rem; }
  .hdr-crest { width: 30px; height: 30px; }
  .hdr-title { font-size: 1.05rem; }
  .hdr-subtitle { display: none; }
  /* The word would wrap; the burger alone is unambiguous at this width. */
  .hdr-nav-btn { padding: 0 0.65rem; }
  .hdr-nav-btn > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .hdr-nav-list { padding-left: 0.75rem; padding-right: 0.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .site-header * { transition: none !important; }
}

/* ============================================================================
   MATCH DETAIL MODAL — "THE TEAM SHEET"
   ----------------------------------------------------------------------------
   Replaces the previous .modal-overlay / .modal-box (there were two, the
   vintage one and a later "Modal scroll fix" that fought it with !important) /
   .modal-close / #modal-content / all .vp-* / all .merged-* rules, and the
   three contradictory @media blocks at 800/600/500px that targeted
   .vp-columns.

   Structure this expects, built by renderModal:
     .modal-overlay > .modal-box > [ .modal-close, .vp-scroll > .vp-wrap ]
   .modal-box does not scroll; .vp-scroll does. That is what keeps the close
   button pinned and visible without position:fixed or JS.
   ============================================================================ */

.modal-overlay {
  /* Vintage palette, tokenised so the whole programme re-skins from one place.
     Scoped to the modal so nothing else on the site is affected. */
  --vp-paper:      #f5f0e8;
  --vp-paper-deep: #ebe3d3;
  --vp-paper-sink: #e3dac6;
  --vp-edge:       #cfc3a6;
  --vp-ink:        #1a1a1a;
  --vp-ink-mid:    #4a4338;
  --vp-ink-soft:   #7d7566;
  --vp-blue:       var(--royal-blue, #003087);
  --vp-gold:       var(--gold-accent, #c8a84b);
  --vp-booked:     #b06f00;
  --vp-sentoff:    #b81c1c;

  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 18, 58, 0.72);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  box-sizing: border-box;
}

/* --- 1. the box ----------------------------------------------------------- */
.modal-box {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1040px;
  max-height: 92vh;
  overflow: hidden;
  background: var(--vp-paper);
  color: var(--vp-ink);
  border: 1px solid var(--vp-ink);
  border-radius: 0;
  font-family: 'Times New Roman', Times, Georgia, serif;
  box-shadow: 0 32px 90px rgba(0, 10, 34, 0.5);
}

.vp-scroll { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }

#modal-content { padding: 0; }

/* --- 2. close: pinned, 44px, legible on cream ----------------------------- */
.modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 20;
  width: 44px;
  height: 44px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--vp-ink);
  color: var(--vp-paper);
  border: 1px solid var(--vp-ink);
  border-radius: 50%;
  cursor: pointer;
  font: inherit;
  line-height: 1;
  transition: background 0.15s, transform 0.15s;
}
.modal-close:hover { background: #000; transform: scale(1.06); }
.modal-close:focus-visible { outline: 3px solid var(--vp-gold); outline-offset: 3px; }
.modal-close svg { display: block; }

/* --- 3. masthead ---------------------------------------------------------- */
.vp-masthead {
  padding: 22px 60px 18px;
  text-align: center;
  background: linear-gradient(180deg, #fffdf7 0%, var(--vp-paper) 100%);
  border-bottom: 1px solid var(--vp-ink);
}

.vp-kicker {
  font-size: 0.76rem;
  font-style: italic;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--vp-ink-mid);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.vp-kicker::before,
.vp-kicker::after { content: ""; height: 1px; width: 42px; background: var(--vp-edge); }

.vp-fixture {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 900;
  font-size: clamp(1.05rem, 2.6vw, 1.7rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--vp-ink);
  margin: 10px 0 2px;
  text-wrap: balance;
}
/* Set by JS above 46 characters — deterministic, rather than hoping clamp()
   copes with a 52-character opponent name. */
.vp-fixture.is-long { font-size: clamp(0.92rem, 1.9vw, 1.22rem); letter-spacing: 0; }
.vp-vs {
  font-family: 'Times New Roman', Times, serif;
  font-style: italic;
  font-weight: 400;
  text-transform: lowercase;
  color: var(--vp-ink-soft);
  margin: 0 4px;
  font-size: 0.82em;
}

.vp-score {
  font-weight: 900;
  font-size: clamp(2.1rem, 5vw, 3.1rem);
  line-height: 1;
  letter-spacing: 0.06em;
  color: var(--vp-blue);
  font-variant-numeric: tabular-nums;
  margin: 8px 0 6px;
}
/* Non-played or unrecorded: never render prose at 3rem with 0.15em tracking. */
.vp-score.is-none {
  font-family: 'Times New Roman', Times, serif;
  font-size: 1rem;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vp-ink-soft);
}
.vp-ht { font-size: 0.8rem; font-style: italic; color: var(--vp-ink-soft); margin-top: -2px; }

.vp-particulars {
  font-size: 0.86rem;
  font-style: italic;
  color: var(--vp-ink-mid);
  letter-spacing: 0.02em;
  margin-top: 6px;
}
.vp-particulars span { white-space: nowrap; }
.vp-particulars i { font-style: normal; color: var(--vp-edge); margin: 0 4px; }

.vp-stamp {
  display: inline-block;
  margin-top: 10px;
  padding: 4px 14px;
  border: 2px solid var(--vp-sentoff);
  color: var(--vp-sentoff);
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transform: rotate(-2.5deg);
  opacity: 0.85;
}

/* --- 4. body grid --------------------------------------------------------- */
.vp-body {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
}
.vp-body[data-cols="1"] { grid-template-columns: minmax(0, 1fr); }
.vp-col { padding: 20px 24px 24px; min-width: 0; }
.vp-col + .vp-col { border-left: 1px solid var(--vp-ink); }
.vp-body[data-cols="1"] .vp-col + .vp-col { border-left: none; border-top: 1px solid var(--vp-ink); }

.vp-section + .vp-section { margin-top: 22px; }
.vp-section-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: 'Playfair Display', Georgia, serif;
  font-style: italic;
  font-weight: 700;
  font-size: 0.84rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--vp-ink);
  border-bottom: 1px solid var(--vp-ink);
  padding-bottom: 5px;
  margin-bottom: 10px;
}
.vp-section-count {
  margin-left: auto;
  font-family: 'Times New Roman', Times, serif;
  font-style: normal;
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  color: var(--vp-ink-soft);
}

/* --- 5. the team sheet ---------------------------------------------------- */
.vp-player {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 6px 8px 6px 4px;
  margin: 0 -8px 0 -4px;
  border-bottom: 1px dotted var(--vp-edge);
  font-size: 0.95rem;
  line-height: 1.35;
}
.vp-player:last-child { border-bottom: none; }
.vp-num {
  flex: 0 0 20px;
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--vp-blue);
  font-variant-numeric: tabular-nums;
}
.vp-name { min-width: 0; color: var(--vp-ink); }

/* Names stay links, but stop looking like eleven stacked underlines. The row
   is the affordance; the underline appears on hover/focus. */
.vp-name a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.12s, color 0.12s;
}
.vp-player:hover { background: var(--vp-paper-deep); }
.vp-player:hover .vp-name a,
.vp-name a:hover { color: var(--vp-blue); border-bottom-color: var(--vp-gold); }
.vp-name a:focus-visible { outline: 2px solid var(--vp-gold); outline-offset: 2px; border-radius: 2px; }

.vp-note {
  color: var(--vp-ink-soft);
  font-size: 0.82rem;
  font-style: italic;
  white-space: nowrap;
}
.vp-sup { font-size: 0.72em; vertical-align: super; color: var(--vp-ink-soft); }

.vp-partial {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--vp-edge);
  font-size: 0.82rem;
  font-style: italic;
  color: var(--vp-ink-soft);
}

/* --- 6. goalscorers ------------------------------------------------------- */
.vp-scorers { font-size: 0.95rem; }
/* 9+ scorers (there are 22–0 results) go two-up. CSS columns, no JS layout. */
.vp-scorers[data-dense="1"] { columns: 2; column-gap: 22px; }
.vp-scorer {
  break-inside: avoid;
  padding: 5px 0;
  border-bottom: 1px dotted var(--vp-edge);
  line-height: 1.35;
}
.vp-scorer:last-child { border-bottom: none; }
.vp-scorer .vp-min { color: var(--vp-ink-soft); font-size: 0.85rem; }
.vp-scorer.is-og { font-style: italic; color: var(--vp-ink-mid); }
.vp-scorer.is-og .vp-og-tag { font-size: 0.76rem; letter-spacing: 0.06em; text-transform: uppercase; }

/* --- 7. discipline -------------------------------------------------------- */
.vp-cards { display: flex; flex-direction: column; gap: 8px; }
.vp-card-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  font-size: 0.92rem;
  line-height: 1.4;
  border: 1px solid;
  background: #fff;
}
.vp-card-mark { flex: 0 0 12px; width: 12px; height: 17px; border-radius: 1px; margin-top: 2px; }
.vp-card-row.is-booked  { border-color: var(--vp-booked);  background: #fdf6e7; }
.vp-card-row.is-booked  .vp-card-mark { background: var(--vp-booked); }
.vp-card-row.is-sentoff { border-color: var(--vp-sentoff); background: #fdefef; }
.vp-card-row.is-sentoff .vp-card-mark { background: var(--vp-sentoff); }
.vp-card-label {
  display: block;
  font-size: 0.7rem;
  font-style: italic;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 2px;
}
.vp-card-row.is-booked  .vp-card-label { color: var(--vp-booked); }
.vp-card-row.is-sentoff .vp-card-label { color: var(--vp-sentoff); }

/* --- 8. match details ----------------------------------------------------- */
.vp-detail {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px dotted var(--vp-edge);
  font-size: 0.9rem;
  line-height: 1.4;
}
.vp-detail:last-child { border-bottom: none; }
.vp-detail dt {
  font-style: italic;
  font-size: 0.8rem;
  color: var(--vp-ink-mid);
  letter-spacing: 0.03em;
}
.vp-detail dd { margin: 0; color: var(--vp-ink); overflow-wrap: anywhere; }
.vp-detail dd.is-num { font-variant-numeric: tabular-nums; }
.vp-detail dd .vp-approx { font-style: italic; color: var(--vp-ink-soft); font-size: 0.86em; }

/* --- 9. empty / not-recorded states --------------------------------------- */
/* An archive's missing data should read as a printer's note, not a failure. */
.vp-empty {
  text-align: center;
  padding: 22px 20px;
  background: var(--vp-paper-sink);
  border-top: 1px solid var(--vp-edge);
  border-bottom: 1px solid var(--vp-edge);
}
.vp-empty-mark {
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  color: var(--vp-ink-soft);
  margin-bottom: 8px;
}
.vp-empty-head {
  font-family: 'Playfair Display', Georgia, serif;
  font-style: italic;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--vp-ink);
  margin-bottom: 6px;
}
.vp-empty-body {
  font-size: 0.88rem;
  font-style: italic;
  line-height: 1.55;
  color: var(--vp-ink-mid);
  max-width: 46ch;
  margin: 0 auto;
}
.vp-nil {
  font-size: 0.86rem;
  font-style: italic;
  color: var(--vp-ink-soft);
  padding: 4px 0;
}

/* --- 10. foot ------------------------------------------------------------- */
.vp-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 24px;
  border-top: 1px solid var(--vp-ink);
  background: linear-gradient(180deg, var(--vp-paper) 0%, var(--vp-paper-deep) 100%);
  font-size: 0.76rem;
  font-style: italic;
  color: var(--vp-ink-mid);
}
.vp-foot b { font-style: normal; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; font-size: 0.7rem; color: var(--vp-ink-soft); }

/* --- 11. breakpoints ------------------------------------------------------ */
/* One ladder. The old 800/600/500 blocks contradicted each other. */
@media (max-width: 859px) {
  .vp-body { grid-template-columns: minmax(0, 1fr); }
  .vp-col + .vp-col { border-left: none; border-top: 1px solid var(--vp-ink); }
  .vp-scorers[data-dense="1"] { columns: 2; }
}

@media (max-width: 560px) {
  .modal-overlay { padding: 8px; }
  .modal-box { max-height: 94vh; }
  .vp-masthead { padding: 16px 52px 14px; }
  .vp-kicker { font-size: 0.66rem; letter-spacing: 0.16em; }
  .vp-kicker::before, .vp-kicker::after { width: 22px; }
  .vp-fixture { margin: 8px 0 2px; }
  .vp-score { margin: 6px 0 4px; }
  .vp-particulars { font-size: 0.78rem; }
  .vp-particulars i { margin: 0 2px; }
  .vp-col { padding: 16px 16px 20px; }
  .vp-foot { padding: 10px 16px; font-size: 0.72rem; }
  .vp-detail { grid-template-columns: 74px minmax(0, 1fr); gap: 8px; }
  .vp-scorers[data-dense="1"] { columns: 1; }
  /* Sections get a visible band on mobile so the rhythm survives stacking. */
  .vp-section-head {
    background: var(--vp-paper-deep);
    margin: 0 -16px 10px;
    padding: 7px 16px;
    border-bottom: 1px solid var(--vp-ink);
    border-top: 1px solid var(--vp-edge);
  }
  .vp-section + .vp-section { margin-top: 18px; }
}

@media (max-width: 380px) {
  .vp-masthead { padding: 14px 48px 12px; }
  .vp-col { padding: 14px 12px 18px; }
  .vp-section-head { margin-left: -12px; margin-right: -12px; padding-left: 12px; padding-right: 12px; }
  .vp-player { font-size: 0.9rem; gap: 9px; }
  .vp-foot { padding: 9px 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .modal-close, .vp-name a { transition: none; }
}

/* ============================================================================
   HOME PAGE
   ----------------------------------------------------------------------------
   Replaces the inline <style> block that used to live in landing.html
   (.landing-main, .home-card*, .panorama-banner, the unused .memorial-* rules)
   and styles .site-footer, which had no rules at all — which is why it sat at
   left:0 with no padding.

   Namespaced .hp-* so it cannot collide with the rest of the site. The header
   is untouched.
   ============================================================================ */

.hp {
  --hp-blue:      var(--royal-blue, #003087);
  --hp-blue-deep: #001f5c;
  --hp-blue-lift: #004abf;
  --hp-gold:      var(--gold-accent, #c8a84b);
  --hp-gold-deep: #8f7420;

  /* Paper tones, shared with the match programme modal so the two read as one
     system rather than two unrelated visual ideas. */
  --hp-paper:      #f5f0e8;
  --hp-paper-deep: #ebe3d3;
  --hp-edge:       #cfc3a6;
  --hp-ink:        #1a1a1a;
  --hp-ink-mid:    #4a4338;
  --hp-ink-soft:   #7d7566;

  --hp-bg:      #f4f6fb;
  --hp-surface: var(--white, #fff);
  --hp-rule:    #d8dded;
  --hp-text:    #111827;
  --hp-text-mid:#374151;
  --hp-text-soft:#6b7280;

  --hp-win:  #1a7a3c;
  --hp-draw: #b07a00;
  --hp-loss: #9b1c1c;

  background: var(--hp-bg);
}
.hp *, .hp *::before, .hp *::after { box-sizing: border-box; }
.hp h1, .hp h2, .hp h3 { font-family: 'Playfair Display', Georgia, serif; margin: 0; }
.hp p { margin: 0; }
.hp ul, .hp ol { margin: 0; padding: 0; list-style: none; }

.hp a:focus-visible,
.hp button:focus-visible,
.hp input:focus-visible { outline: 3px solid var(--hp-gold); outline-offset: 2px; border-radius: 3px; }

.hp-inner { max-width: 1200px; margin: 0 auto; padding: 0 24px; }

/* --- 1. hero -------------------------------------------------------------- */
/* The panorama finally does a job: it is the ground for the hero rather than a
   322px band of decoration sitting below the navigation.

   It is served from static/img-inline/, not static/img/, and that matters:
   static/img/ is 759MB of gallery photographs, gitignored and listed in
   .dockerignore, so nothing in it exists in the container. This file was
   referenced from there and 404'd in production from the day the home page
   redesign deployed — the hero rendered as the gradient alone, which reads as
   a plain blue band. Locally it looked right, because locally the file is on
   disk.

   Anything a stylesheet or template references must live in img-inline/,
   which the Dockerfile copies. static/img/ is for gallery content the browser
   fetches from S3 via IMG_BASE_URL. */
.hp-hero {
  position: relative;
  background-color: var(--hp-blue-deep);
  background-image: linear-gradient(180deg, rgba(0,20,64,0.82) 0%, rgba(0,20,64,0.9) 100%),
                    url('/static/img-inline/RH_panorama_web.jpg');
  background-size: cover;
  background-position: center 62%;
  border-bottom: 3px solid var(--hp-gold);
  color: #fff;
  overflow: hidden;
}
.hp-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(0deg, rgba(255,255,255,0.035) 0 1px, transparent 1px 4px);
  pointer-events: none;
}
.hp-hero-inner {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 52px 24px 48px;
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr);
  gap: 48px;
  align-items: start;
}


/* Kept on the home page only: against the navy hero the gold reads as a
   flourish, where on a white page it was decoration above a title that
   already said the same thing. */
.hp-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--hp-gold);
  margin-bottom: 20px;
}
.hp-eyebrow::after { content: ""; width: 44px; height: 1px; background: rgba(200,168,75,0.55); }

.hp-h1 {
  font-size: clamp(2rem, 4.4vw, 3.3rem);
  font-weight: 900;
  line-height: 1.03;
  letter-spacing: -0.022em;
  color: #fff;
  margin-bottom: 18px;
  text-wrap: balance;
}
.hp-h1 em { font-style: italic; color: var(--hp-gold); }

.hp-lede {
  font-size: 1.05rem;
  line-height: 1.6;
  color: rgba(255,255,255,0.82);
  max-width: 52ch;
  margin-bottom: 26px;
}

.hp-search { position: relative; max-width: 460px; }
.hp-search-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.62);
  margin-bottom: 8px;
}
.hp-search input {
  width: 100%;
  height: 52px;
  padding: 0 16px 0 46px;
  border: 1px solid rgba(255,255,255,0.4);
  border-radius: 4px;
  background: rgba(255,255,255,0.12);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-opacity='0.8' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='6'/%3E%3Cpath d='M20 20l-4.3-4.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 15px center;
  color: #fff;
  font-family: inherit;
  font-size: 1rem;
  -webkit-appearance: none;
  appearance: none;
}
.hp-search input::placeholder { color: rgba(255,255,255,0.62); opacity: 1; }
.hp-search input::-webkit-search-cancel-button { -webkit-appearance: none; }
.hp-search input:hover { background-color: rgba(255,255,255,0.17); }
.hp-search input:focus {
  outline: none;
  background-color: rgba(255,255,255,0.22);
  border-color: var(--hp-gold);
  box-shadow: 0 0 0 3px rgba(200,168,75,0.32);
}
.hp-search-hint { font-size: 0.8rem; color: rgba(255,255,255,0.55); margin-top: 9px; }

/* Reuses the header's dropdown classes verbatim — same component, same styles. */
.hp-search .sufc-results { top: calc(100% + 6px); }

/* --- 2. on this day ------------------------------------------------------- */
.hp-otd {
  background: var(--hp-paper);
  border: 1px solid var(--hp-edge);
  border-top: 3px solid var(--hp-gold);
  box-shadow: 0 24px 60px -20px rgba(0, 10, 40, 0.6);
  color: var(--hp-ink);
  font-family: 'Times New Roman', Times, Georgia, serif;
  display: flex;
  flex-direction: column;
  min-height: 344px;              /* holds its size through load → data → error */
}
.hp-otd-head {
  padding: 14px 20px 12px;
  border-bottom: 1px solid var(--hp-ink);
  background: linear-gradient(180deg, #fffdf7, var(--hp-paper));
}
.hp-otd-kicker {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.68rem;
  font-style: italic;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--hp-ink-mid);
}
.hp-otd-kicker::after { content: ""; flex: 1; height: 1px; background: var(--hp-edge); }
.hp-otd-date {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.5rem;
  font-weight: 900;
  letter-spacing: -0.015em;
  color: var(--hp-ink);
  margin-top: 4px;
}
.hp-otd-sub { font-size: 0.82rem; font-style: italic; color: var(--hp-ink-soft); margin-top: 2px; }

.hp-otd-list { flex: 1; overflow: hidden; }

.hp-otd-row {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 20px;
  border-bottom: 1px dotted var(--hp-edge);
  background: none;
  border-left: 0; border-right: 0; border-top: 0;
  font: inherit;
  text-align: left;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  min-height: 46px;
  transition: background 0.12s;
}
.hp-otd-row:last-child { border-bottom: none; }
.hp-otd-row:hover { background: var(--hp-paper-deep); }
.hp-otd-year {
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--hp-gold-deep);
  font-variant-numeric: tabular-nums;
}
.hp-otd-fix { min-width: 0; }
.hp-otd-opp { display: block; font-size: 0.95rem; color: var(--hp-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hp-otd-comp { display: block; font-size: 0.76rem; font-style: italic; color: var(--hp-ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hp-otd-score {
  font-weight: 700;
  font-size: 1rem;
  color: var(--hp-blue);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hp-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 3px;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
}
.hp-badge.w { background: #dff0e3; color: var(--hp-win); }
.hp-badge.d { background: #fbedca; color: var(--hp-draw); }
.hp-badge.l { background: #f6dbdb; color: var(--hp-loss); }
.hp-badge.x { background: #e8eaf0; color: var(--hp-ink-soft); }

.hp-otd-foot {
  /* Vertical padding lives on the link, not here, so the link can fill the
     band and reach a 44px target without the band growing. */
  padding: 0 20px;
  border-top: 1px solid var(--hp-ink);
  background: var(--hp-paper-deep);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.82rem;
}
.hp-otd-foot a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--hp-blue);
  font-weight: 600;
  text-decoration: none;
  font-family: 'Source Sans 3', sans-serif;
  min-height: 44px;
}
.hp-otd-foot a:hover { text-decoration: underline; text-underline-offset: 3px; }
.hp-otd-count { font-style: italic; color: var(--hp-ink-soft); }

/* Loading: ruled placeholder rows at the real row height, so nothing moves
   when the data lands. No shimmer — this is an archive, not a feed. */
.hp-otd-skel { padding: 10px 20px; border-bottom: 1px dotted var(--hp-edge); min-height: 46px; display: flex; align-items: center; gap: 12px; }
.hp-otd-skel span { height: 9px; border-radius: 2px; background: var(--hp-paper-deep); display: block; }
.hp-otd-skel span:nth-child(1) { width: 40px; }
.hp-otd-skel span:nth-child(2) { flex: 1; max-width: 190px; }
.hp-otd-skel span:nth-child(3) { width: 34px; margin-left: auto; }

/* Empty and error share one quiet, centred treatment. */
.hp-otd-msg {
  padding: 30px 24px;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1;
}
.hp-otd-msg-mark { font-size: 0.7rem; letter-spacing: 0.28em; color: var(--hp-ink-soft); margin-bottom: 10px; }
.hp-otd-msg-head {
  font-family: 'Playfair Display', Georgia, serif;
  font-style: italic;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.06em;
  color: var(--hp-ink);
  margin-bottom: 6px;
}
.hp-otd-msg-body { font-size: 0.88rem; font-style: italic; line-height: 1.55; color: var(--hp-ink-mid); max-width: 34ch; margin: 0 auto; }

/* --- 3. totals strip ------------------------------------------------------ */
.hp-totals {
  background: var(--hp-surface);
  border-bottom: 1px solid var(--hp-rule);
}
.hp-totals-grid {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}
.hp-total {
  padding: 22px 16px 20px;
  border-right: 1px solid var(--hp-rule);
  text-align: center;
}
.hp-total:last-child { border-right: none; }
.hp-total-fig {
  display: block;
  font-size: clamp(1.5rem, 2.6vw, 2.05rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--hp-blue);
  font-variant-numeric: tabular-nums;
}
.hp-total-cap {
  display: block;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hp-text-soft);
  margin-top: 8px;
}

/* --- 4. the four destinations --------------------------------------------- */
/* The 9px title stagger was caused by the icon sitting BESIDE text of differing
   length. Icon above title, in a fixed-height frame, removes the cause. */
.hp-nav { padding: 44px 0 52px; }
.hp-nav-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 22px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--hp-blue);
}
.hp-nav-head h2 { font-size: 1.35rem; font-weight: 700; color: var(--hp-blue); letter-spacing: -0.01em; }
.hp-nav-head span { margin-left: auto; font-size: 0.85rem; color: var(--hp-text-soft); }

.hp-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }

.hp-card {
  display: flex;
  flex-direction: column;
  padding: 22px 22px 20px;
  background: var(--hp-surface);
  border: 1px solid var(--hp-rule);
  border-top: 3px solid var(--hp-blue);
  border-radius: 4px;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.hp-card:hover {
  background: #fcfdff;
  border-color: var(--hp-blue);
  border-top-color: var(--hp-gold);
  transform: translateY(-2px);
}
.hp-card-icon {
  width: 44px; height: 44px;      /* fixed frame — this is what fixes alignment */
  flex: 0 0 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hp-rule);
  border-radius: 4px;
  color: var(--hp-blue);
  background: #f7f9fd;
  margin-bottom: 16px;
}
.hp-card:hover .hp-card-icon { border-color: var(--hp-gold); color: var(--hp-blue); }
.hp-card-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--hp-blue);
  letter-spacing: -0.01em;
  margin-bottom: 8px;
}
.hp-card-desc { font-size: 0.86rem; line-height: 1.5; color: var(--hp-text-mid); flex: 1; }
.hp-card-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 16px;
  min-height: 24px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--hp-blue);
  transition: gap 0.15s;
}
.hp-card:hover .hp-card-cta { gap: 11px; }
.hp-card-count {
  margin-left: auto;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--hp-text-soft);
  font-variant-numeric: tabular-nums;
}

/* --- 5. footer — had no rules at all, hence left:0 ------------------------- */
.hp-foot-meta { font-size: 0.78rem; color: rgba(255,255,255,0.5); }

/* --- 6. breakpoints ------------------------------------------------------- */
@media (max-width: 1023px) {
  .hp-hero-inner { gap: 32px; padding: 42px 24px 40px; }
  .hp-cards { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 859px) {
  .hp-hero-inner { grid-template-columns: minmax(0, 1fr); gap: 30px; }
  .hp-lede { max-width: none; }
  .hp-search { max-width: none; }
  .hp-otd { min-height: 0; }
}

@media (max-width: 639px) {
  .hp-inner { padding: 0 16px; }
  .hp-hero-inner { padding: 32px 16px 32px; gap: 26px; }
  .hp-totals-grid { padding: 0 16px; grid-template-columns: repeat(2, 1fr); }
  /* With 5 items on a 2-col grid the last one spans, so the row never orphans. */
  .hp-total { border-bottom: 1px solid var(--hp-rule); padding: 16px 12px; }
  .hp-total:nth-child(2n) { border-right: none; }
  .hp-total:last-child { grid-column: 1 / -1; border-right: none; border-bottom: none; }
  .hp-cards { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .hp-nav { padding: 32px 0 38px; }
  .hp-card { padding: 18px 18px 16px; }
  .hp-otd-row { grid-template-columns: 44px minmax(0, 1fr) auto auto; gap: 10px; padding: 10px 16px; }
  .hp-otd-head, .hp-otd-msg { padding-left: 16px; padding-right: 16px; }
  .hp-otd-foot { padding-left: 16px; padding-right: 16px; }
  .hp-otd-skel { padding-left: 16px; padding-right: 16px; }
  .site-footer .hp-inner { flex-direction: column; align-items: flex-start; gap: 8px; }
}

@media (max-width: 359px) {
  .hp-inner { padding: 0 12px; }
  .hp-hero-inner { padding: 26px 12px 28px; }
  .hp-totals-grid { padding: 0 12px; }
  .hp-otd-row { grid-template-columns: 40px minmax(0, 1fr) auto; padding-left: 12px; padding-right: 12px; }
  .hp-otd-row .hp-badge { display: none; }   /* score already carries the result */
  .hp-otd-head, .hp-otd-msg, .hp-otd-skel { padding-left: 12px; padding-right: 12px; }
  .hp-otd-foot { padding-left: 12px; padding-right: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .hp-card, .hp-card-cta, .hp-otd-row { transition: none; }
  .hp-card:hover { transform: none; }
}

/* ============================================================================
   MATCH LIST — one component, eleven callers
   ----------------------------------------------------------------------------
   Appended, not substituted. The delivered block asked for the global `table`,
   `thead th` and `tbody td` rules to be deleted on the grounds that every table
   on the site is a match list. That is not so: .players-table, .scorers-table,
   .discipline-table, .gk-table, .app-table, .att-table and .fn-table have zero
   rules of their own and inherit all their padding, colour and borders from
   those globals. Deleting them would strip seven pages.

   Everything here is .ml-* and beats the element selectors on specificity, so
   the globals can stay for the aggregate tables that still need them.
   ============================================================================ */

/* .ss-strip shares the palette: it sits directly on top of an .ml panel and
   the two have to read as one object. */
/* .apps-match-table is on the player profile: it reuses .ml-c-score and
   .ml-pill for its scoreline, so it needs the same tokens. */
.ml, .ss-strip, .apps-match-table {
  --ml-blue:      var(--royal-blue, #003087);
  --ml-blue-deep: #001f5c;
  --ml-gold:      var(--gold-accent, #c8a84b);
  --ml-gold-deep: #8f7420;

  /* Paper tones, shared with the programme modal and the home page slip. */
  --ml-paper:      #f7f5ef;
  --ml-paper-deep: #efebe0;
  --ml-rule:       #ddd8ca;

  --ml-surface:   var(--white, #fff);
  --ml-line:      #e3e7f0;
  --ml-line-hard: #c8cfe0;
  --ml-text:      #14181f;
  --ml-text-mid:  #414a5a;
  --ml-text-soft: #6b7280;

  --ml-win:  #1a7a3c;
  --ml-draw: #b07a00;
  --ml-loss: #9b1c1c;

  --ml-row: 46px;
}
.ml *, .ml *::before, .ml *::after { box-sizing: border-box; }
.ml-sr { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* --- 1. panel ------------------------------------------------------------- */
.ml-panel { background: var(--ml-surface); border: 1px solid var(--ml-line); border-radius: 6px; overflow: hidden; }

.ml-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  padding: 16px 18px 12px;
  border-bottom: 2px solid var(--ml-blue);
}
.ml-title {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--ml-blue);
  letter-spacing: -0.01em;
  margin: 0;
}
.ml-count { font-size: 0.85rem; color: var(--ml-text-soft); font-variant-numeric: tabular-nums; }
.ml-head-tools { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* Sort control shown only where the table itself cannot carry it (narrow). */
.ml-sortbar { display: none; align-items: center; gap: 8px; padding: 10px 16px; border-bottom: 1px solid var(--ml-line); background: var(--ml-paper); }
.ml-sortbar label { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ml-text-soft); }
.ml-sortbar select {
  flex: 1;
  min-height: 44px;
  padding: 0 34px 0 12px;
  border: 1px solid var(--ml-line-hard);
  border-radius: 4px;
  background: var(--ml-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23003087' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--ml-text);
  -webkit-appearance: none;
  appearance: none;
}

/* --- 2. table ------------------------------------------------------------- */
/* Real <table> semantics at every width. The mobile layout is a column
   selection, not a display:block rewrite — that keeps row/column association
   intact for screen readers, which display:block silently destroys. */
.ml-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ml-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
}
.ml-table caption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.ml-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--ml-blue);
  color: #fff;
  text-align: left;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 0;
  border-bottom: 2px solid var(--ml-gold);
}
/* The button is the whole header cell, so the sort target is 44px tall. */
.ml-th-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-height: 44px;
  padding: 0 12px;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  cursor: pointer;
}
.ml-th-btn:hover { background: rgba(255,255,255,0.1); }
.ml-th-static { display: flex; align-items: center; min-height: 44px; padding: 0 12px; }
.ml-th-num .ml-th-btn, .ml-th-num .ml-th-static { justify-content: flex-end; }

.ml-sort-ind { opacity: 0.35; flex: 0 0 auto; transition: opacity 0.12s; }
.ml-th-btn:hover .ml-sort-ind { opacity: 0.7; }
[aria-sort="ascending"] .ml-sort-ind,
[aria-sort="descending"] .ml-sort-ind { opacity: 1; color: var(--ml-gold); }
[aria-sort="ascending"] .ml-th-btn, [aria-sort="descending"] .ml-th-btn { background: rgba(200,168,75,0.16); }

.ml-table tbody td { padding: 0 12px; height: var(--ml-row); color: var(--ml-text-mid); vertical-align: middle; }
.ml-table tbody tr { border-bottom: 1px solid var(--ml-line); }
.ml-table tbody tr:last-child { border-bottom: none; }
.ml-table tbody tr:nth-child(even) { background: #fafbfd; }
.ml-row { cursor: pointer; }
.ml-row:hover, .ml-row:hover:nth-child(even) { background: #eef3fb; }
.ml-row:focus-visible { outline: 3px solid var(--ml-gold); outline-offset: -3px; background: #eef3fb; }

.ml-c-date, .ml-c-year { font-weight: 600; color: var(--ml-blue); white-space: nowrap; }
.ml-c-season { white-space: nowrap; color: var(--ml-text-soft); }
.ml-c-competition { color: var(--ml-text-mid); }
.ml-c-opponents { font-weight: 600; color: var(--ml-text); }
.ml-c-venue { white-space: nowrap; }
.ml-c-score { white-space: nowrap; text-align: right; }

/* The score pill. Its colour is the result, so it is the one thing on the row
   that must read at a glance — hence the size bump over the body text and the
   tabular figures, which keep the pills the same width down the column. */
.ml-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 58px;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 1rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  background: #e8eaf0;
  color: var(--ml-text);
}
.ml-c-score.w .ml-pill { background: #dff0e3; color: var(--ml-win); }
.ml-c-score.d .ml-pill { background: #fbedca; color: var(--ml-draw); }
.ml-c-score.l .ml-pill { background: #f6dbdb; color: var(--ml-loss); }

/* Postponed, abandoned and the rest: a pill so the column keeps its rhythm,
   but quiet, and never coloured as though it were a result. */
.ml-pill-status {
  font-size: 0.72rem;
  font-weight: 600;
  font-style: italic;
  color: var(--ml-text-soft);
}
.ml-c-ht, .ml-c-attendance { text-align: right; white-space: nowrap; color: var(--ml-text-soft); }
.ml-c-result { width: 1%; white-space: nowrap; }

/* Long text truncates rather than forcing the table wider. Full value stays in
   the title attribute and in the modal. */
.ml-c-competition, .ml-c-opponents { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Missing data reads as a recorded absence, not a rendering failure. */
.ml-nil { color: #9aa1ae; }
.ml-approx { font-style: italic; color: var(--ml-text-soft); }

/* The mobile-only second line inside the fixture cell. Exactly one of this and
   the standalone Competition column is in the DOM flow at any width, so
   assistive tech never hears the competition twice. */
.ml-sub { display: none; font-size: 0.76rem; font-weight: 400; color: var(--ml-text-soft); }

.ml-status { display: inline-block; font-size: 0.7rem; font-style: italic; color: var(--ml-text-soft); }

/* Result badge — same colours as the home page .hp-badge. */
.ml-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border-radius: 3px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.ml-badge.w { background: #dff0e3; color: var(--ml-win); }
.ml-badge.d { background: #fbedca; color: var(--ml-draw); }
.ml-badge.l { background: #f6dbdb; color: var(--ml-loss); }
.ml-badge.x { background: #e8eaf0; color: var(--ml-text-soft); }

/* --- 3. foot: show more, and the empty state ------------------------------ */
.ml-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  border-top: 1px solid var(--ml-line);
  background: var(--ml-paper);
}
.ml-shown { font-size: 0.82rem; color: var(--ml-text-soft); font-variant-numeric: tabular-nums; }
.ml-more {
  min-height: 44px;
  padding: 0 20px;
  border: 1px solid var(--ml-blue);
  border-radius: 4px;
  background: var(--ml-surface);
  color: var(--ml-blue);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
.ml-more:hover { background: var(--ml-blue); color: #fff; }

.ml-empty { padding: 44px 24px; text-align: center; background: var(--ml-paper); }
.ml-empty-mark { font-size: 0.72rem; letter-spacing: 0.3em; color: var(--ml-gold-deep); margin-bottom: 12px; }
.ml-empty-head {
  font-family: 'Playfair Display', Georgia, serif;
  font-style: italic;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--ml-text);
  margin-bottom: 6px;
}
.ml-empty-body { font-size: 0.9rem; line-height: 1.55; color: var(--ml-text-mid); max-width: 42ch; margin: 0 auto; }

/* --- 4. breakpoints ------------------------------------------------------- */
/* The only structural change is at 767px, where six columns leave the table and
   their content folds into the fixture cell or defers to the match modal. */
@media (max-width: 1023px) {
  .ml-c-season, .ml-h-season, .ml-c-ht, .ml-h-ht { display: none; }
  .ml-c-competition, .ml-c-opponents { max-width: 18ch; }
}

@media (max-width: 767px) {
  .ml-c-competition, .ml-h-competition,
  .ml-c-venue, .ml-h-venue,
  .ml-c-team, .ml-h-team,
  .ml-c-attendance, .ml-h-attendance { display: none; }
  /* …unless Competition IS the fixture cell (/h2h, which has no Opponents
     column). It then stays and hosts the sub-line itself. */
  .ml-c-competition.ml-fixture { display: table-cell; max-width: none; white-space: normal; font-weight: 600; color: var(--ml-text); }
  .ml-h-competition.ml-h-fixture { display: table-cell; }
  .ml-sub { display: block; }
  .ml-c-opponents { max-width: none; white-space: normal; line-height: 1.25; }
  .ml-table tbody td { height: auto; padding: 9px 10px; }
  .ml-table tbody tr { min-height: 56px; }
  .ml-c-date, .ml-c-year { font-size: 0.82rem; }
  .ml-table thead th { font-size: 0.63rem; }
  .ml-th-static, .ml-th-btn { padding: 0 10px; }
  .ml-sortbar { display: flex; }
  .ml-head { padding: 14px 16px 10px; }
  .ml-title { font-size: 1.15rem; }
  /* Sorting lives in the select at this width, so header cells go inert. */
  .ml-table thead .ml-th-btn { pointer-events: none; }
  .ml-sort-ind { display: none; }
}

@media (max-width: 479px) {
  .ml-table { font-size: 0.84rem; }
  .ml-table tbody td { padding: 8px 8px; }
  .ml-th-static, .ml-th-btn { padding: 0 8px; }
  .ml-pill { min-width: 52px; padding: 3px 8px; font-size: 0.94rem; }
}

@media (max-width: 359px) {
  .ml-c-result, .ml-h-result { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ml-row, .ml-sort-ind { transition: none; }
}

/* ============================================================================
   STAT STRIP — the record summary above a match list
   ----------------------------------------------------------------------------
   Replaces the nine per-page card rows: .om-stat-grid/.om-stat-box (with its
   inline styles), .h2h-summary/.h2h-stat, .season-stat*, .otd-stat*, and the
   att-/gk-/sc-/goals-/wdl- equivalents as those pages are moved over.

   Shares the match-list tokens deliberately — the strip sits directly on top
   of an .ml-panel and the two should read as one object.
   ========================================================================== */
.ss-strip {
  display: flex;
  align-items: stretch;
  gap: 0;
  background: var(--ml-surface, #fff);
  border: 1px solid var(--ml-line);
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 1rem;
}

/* Hairline rules between groups instead of a border around each number. */
.ss-block {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.85rem 1.4rem;
  border-left: 1px solid var(--ml-line);
}
.ss-block:first-child { border-left: 0; }
.ss-block-record { flex: 1 1 auto; display: block; }
/* No record and no scoreline — see the note in stat-strip.js. The last block
   takes the slack the bar would have taken and its figures space out across
   it, so the strip ends flush with the panel it sits in. Set only on strips
   the component has marked, so /season, /onthisday, /opponent and /h2h keep
   their left-packed groups exactly as shipped. */
.ss-strip--fill > .ss-block:last-child { flex: 1 1 auto; }
.ss-strip--fill > .ss-block:last-child > .ss-row { flex: 1 1 auto; justify-content: space-evenly; }
.ss-block-goals { margin-left: auto; }
/* ...unless it is the whole strip. /goals-by-season has a scoreline and one
   item and no record, so the auto margin was shoving the only substantial
   block against the right edge with a hole where Played usually is. */
.ss-block-goals:first-child { margin-left: 0; }

/* Wraps because /match-cleanse puts six figures in one row and /goalkeeper
   four. Three never wrapped and still don't, so the shipped pages are
   unchanged; the row-gap only shows once a page needs a second line. */
.ss-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.9rem 1.5rem; }

.ss-group { text-align: center; min-width: 3.2rem; }

/* A fact that is words, not a quantity — "Sat 19 May" against BEST DAY.
   Deliberately smaller and lighter than .ss-value: it must not look like
   something you could subtract from the figure beside it. Serif, because
   by the numeral rule Playfair is what words get. */
.ss-note {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.15;
  color: var(--ml-text);
}
.ss-block-note .ss-group { min-width: 5rem; }

.ss-value {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  color: var(--ml-text);
}
/* One large figure, not seven — Played is the headline the others qualify. */
.ss-group-lead .ss-value { font-size: 2.1rem; }

.ss-value.w { color: var(--ml-win); }
.ss-value.d { color: var(--ml-draw); }
.ss-value.l { color: var(--ml-loss); }

.ss-label {
  margin-top: 0.25rem;
  font-size: 0.63rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ml-text-soft);
  white-space: nowrap;
}

/* The proportional W/D/L split. */
.ss-bar {
  display: flex;
  height: 6px;
  margin-top: 0.7rem;
  border-radius: 3px;
  overflow: hidden;
  background: var(--ml-line);
}
.ss-seg { display: block; height: 100%; }
.ss-seg.w { background: var(--ml-win); }
.ss-seg.d { background: var(--ml-draw); }
.ss-seg.l { background: var(--ml-loss); }

/* Goals read as a scoreline, because that is how a supporter reads them. */
.ss-score {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  color: var(--ml-text);
}
.ss-score-dash { color: var(--ml-text-soft); font-weight: 400; }

.ss-diff { text-align: center; min-width: 3rem; }
.ss-diff-v {
  display: block;
  font-size: 0.95rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ml-text-mid);
}
.ss-diff.w .ss-diff-v { color: var(--ml-win); }
.ss-diff.l .ss-diff-v { color: var(--ml-loss); }
.ss-diff-l {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.6rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ml-text-soft);
}

/* --- narrow: stack the three groups, keep the bar full width -------------- */
@media (max-width: 720px) {
  .ss-strip { flex-wrap: wrap; }
  .ss-block {
    border-left: 0;
    border-top: 1px solid var(--ml-line);
    padding: 0.7rem 1rem;
    width: 100%;
    justify-content: center;
  }
  .ss-block:first-child { border-top: 0; }
  .ss-block-played { padding-bottom: 0.4rem; }
  .ss-block-played,
  .ss-block-goals { justify-content: center; }
  .ss-block-goals { margin-left: 0; gap: 1.75rem; }
  .ss-row { justify-content: center; gap: 2rem; }
  .ss-group-lead .ss-value { font-size: 1.8rem; }
}

@media (max-width: 380px) {
  .ss-row { gap: 1.35rem; }
  .ss-value { font-size: 1.3rem; }
  .ss-score { font-size: 1.3rem; }
}

/* Team column — used only by lists that mix Southend sides (/season's "All
   matches" view, /onthisday, /attendances). Colour separates the sides at a
   glance; the unrecorded case is named rather than dashed. */
.ml-c-team, .ml-h-team { white-space: nowrap; }
.ml-team          { font-size: 0.8rem; font-weight: 600; color: var(--ml-text-mid); }
.ml-team-1stteam  { color: var(--ml-blue); }
.ml-team-reserves { color: var(--ml-text-mid); }
.ml-team-youth    { color: var(--ml-gold-deep); }
.ml-team-x        { color: var(--ml-text-soft); font-weight: 400; font-style: italic; }

/* Compact stat strip — one line for a competition-group header. Tokens are
   --ml-*, which .ss-strip already inherits; the delivered patch assumed a
   separate --ss-* set that this build does not have. */
.ss-strip.ss-compact { display: block; border: none; border-radius: 0; background: none; padding: 0; margin: 0; }
.ss-compact .ss-c-figs,
.ss-compact .ss-c-goals,
.ss-compact .ss-c-item  { display: inline-flex; align-items: baseline; gap: 12px; font-size: .82rem;
                          color: var(--ml-text-mid); font-variant-numeric: tabular-nums; margin-right: 16px; }
.ss-compact .ss-c-figs b,
.ss-compact .ss-c-goals,
.ss-compact .ss-c-item b { font-weight: 700; color: var(--ml-text); }
.ss-compact .ss-c-figs .w b { color: var(--ml-win); }
.ss-compact .ss-c-figs .d b { color: var(--ml-draw); }
.ss-compact .ss-c-figs .l b { color: var(--ml-loss); }
.ss-compact .ss-c-goals span { color: var(--ml-text-soft); font-weight: 600; }
.ss-compact .ss-bar-thin { height: 4px; margin-top: 8px; max-width: 420px; }

/* ============================================================================
   SEASON PAGE — Southend United History
   ----------------------------------------------------------------------------
   REPLACES the entire inline <style> block in season.html — .sort-group,
   .sort-group-header, .season-title and the two empty media queries. The
   .pm-* player-modal rules in that block belong to the player pop-up, not to
   this page: move them to style.css unchanged rather than deleting them.
   Also supersedes .filters-panel / .filters-grid / .filter-actions on this
   page only (other pages still use them).

   Namespaced .sn-*, on the tokens the header, modal, home page, match list
   (--ml-*) and stat strip (.ss-*) already established. Vanilla CSS, no new
   fonts, no new images.
   ============================================================================ */

.sn{--sn-blue:var(--royal-blue,#003087);--sn-blue-deep:#001f5c;--sn-blue-lift:#004abf;
--sn-gold:var(--gold-accent,#c8a84b);--sn-gold-deep:#8f7420;
--sn-bg:#f4f6fb;--sn-surface:var(--white,#fff);--sn-line:#e3e7f0;--sn-line-hard:#c8cfe0;
--sn-paper:#f7f5ef;--sn-rule:#ddd8ca;
--sn-text:#14181f;--sn-text-mid:#414a5a;--sn-text-soft:#6b7280;
background:var(--sn-bg);color:var(--sn-text);display:block}
.sn *,.sn *::before,.sn *::after{box-sizing:border-box}
.sn h1,.sn h2,.sn h3{font-family:'Playfair Display',Georgia,serif;margin:0;letter-spacing:-.015em}
.sn p{margin:0}
.sn ul,.sn ol{margin:0;padding:0;list-style:none}
.sn-sr{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.sn a:focus-visible,.sn button:focus-visible,.sn input:focus-visible{outline:3px solid var(--sn-gold);outline-offset:2px;border-radius:3px}
.sn-inner{max-width:1200px;margin:0 auto;padding:0 24px}

/* --------------------------------------------------------------------------
   1. MASTHEAD + SEASON CHOOSER
   The 113-option <select> becomes a typeahead combobox with previous/next and
   a decade index. Same interaction contract as the header's site search, so
   there is one combobox behaviour on the site rather than two.
   -------------------------------------------------------------------------- */
.sn-mast{padding:20px 0 0}
.sn-h1{font-size:clamp(1.85rem,3.4vw,2.6rem);font-weight:900;line-height:1.05;color:var(--sn-blue)}
.sn-h1 span{font-variant-numeric:tabular-nums}
.sn-meta{margin-top:9px;font-size:.88rem;color:var(--sn-text-soft);font-variant-numeric:tabular-nums}
.sn-meta b{color:var(--sn-text-mid);font-weight:600}

.sn-chooser{margin-top:16px;padding:14px 16px;background:var(--sn-surface);border:1px solid var(--sn-line);border-radius:6px}
.sn-choose-row{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}
.sn-combo{position:relative;flex:1 1 320px;min-width:0}
.sn-combo label{display:block;font-size:.66rem;font-weight:600;letter-spacing:.15em;text-transform:uppercase;color:var(--sn-text-soft);margin-bottom:6px}
.sn-combo input{width:100%;min-height:48px;padding:0 40px 0 14px;border:1px solid var(--sn-line-hard);border-radius:4px;background:var(--sn-surface)
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23003087' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 14px center;
font-family:inherit;font-size:1rem;color:var(--sn-text);-webkit-appearance:none;appearance:none}
.sn-combo input:focus{outline:none;border-color:var(--sn-blue);box-shadow:0 0 0 3px rgba(0,48,135,.14)}
.sn-results{position:absolute;z-index:40;top:calc(100% + 6px);left:0;right:0;max-height:320px;overflow-y:auto;background:var(--sn-surface);
border:1px solid var(--sn-line-hard);border-radius:4px;box-shadow:0 18px 44px -18px rgba(0,20,64,.5);display:none}
.sn-results.open{display:block}
.sn-results li{border-bottom:1px solid var(--sn-line)}
.sn-results li:last-child{border-bottom:none}
.sn-opt{display:flex;align-items:center;gap:12px;width:100%;min-height:44px;padding:8px 14px;background:none;border:0;font:inherit;font-size:.95rem;
color:var(--sn-text);text-align:left;cursor:pointer;font-variant-numeric:tabular-nums}
.sn-opt small{margin-left:auto;font-size:.78rem;color:var(--sn-text-soft)}
.sn-opt:hover,.sn-opt[aria-selected="true"]{background:#eef3fc}
.sn-opt[aria-selected="true"]{box-shadow:inset 3px 0 0 var(--sn-blue)}
.sn-results .sn-none{padding:14px;font-size:.9rem;color:var(--sn-text-soft)}

.sn-step{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:48px;padding:0 14px;border:1px solid var(--sn-line-hard);
border-radius:4px;background:var(--sn-surface);color:var(--sn-blue);font:inherit;font-size:.88rem;font-weight:600;cursor:pointer;white-space:nowrap}
.sn-step:hover:not([disabled]){border-color:var(--sn-blue);background:#f7f9fd}
.sn-step[disabled]{opacity:.42;cursor:default}
.sn-decades{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px;padding-top:12px;border-top:1px dotted var(--sn-line-hard)}
.sn-decades span{align-self:center;font-size:.66rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--sn-text-soft);margin-right:4px}
/* 44px, not the delivered 36px: the brief set 44 as the floor and this is a
   thirteen-button row, the densest tap target on the page. */
.sn-dec{min-height:44px;padding:0 11px;border:1px solid var(--sn-line);border-radius:3px;background:var(--sn-surface);
font:inherit;font-size:.82rem;font-weight:600;color:var(--sn-text-mid);cursor:pointer;font-variant-numeric:tabular-nums}
.sn-dec:hover{border-color:var(--sn-blue);color:var(--sn-blue)}
.sn-dec[aria-pressed="true"]{background:var(--sn-blue);border-color:var(--sn-blue);color:#fff}

/* --------------------------------------------------------------------------
   2. TEAM TABS — the page's central fix
   One tab per side that actually played that season, plus All. A side with no
   matches produces no tab at all; a season with one side produces a sentence
   instead of a tablist.
   -------------------------------------------------------------------------- */
.sn-tabs-wrap{margin-top:26px;border-bottom:2px solid var(--sn-blue)}
.sn-tabs{display:flex;gap:4px;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.sn-tabs::-webkit-scrollbar{display:none}
.sn-tab{display:flex;align-items:baseline;gap:9px;min-height:48px;padding:10px 18px;border:1px solid var(--sn-line);border-bottom:none;
border-radius:5px 5px 0 0;background:#eaeef7;color:var(--sn-text-mid);font-family:'Playfair Display',Georgia,serif;font-size:1.02rem;font-weight:700;
white-space:nowrap;cursor:pointer;transition:background .12s,color .12s}
.sn-tab:hover{background:#e2e8f5;color:var(--sn-blue)}
.sn-tab b{font-family:'Source Sans 3',sans-serif;font-size:.78rem;font-weight:600;color:var(--sn-text-soft);font-variant-numeric:tabular-nums}
.sn-tab[aria-selected="true"]{background:var(--sn-blue);border-color:var(--sn-blue);color:#fff}
.sn-tab[aria-selected="true"] b{color:var(--sn-gold)}
.sn-tab-x[aria-selected="true"]{background:var(--sn-text-mid);border-color:var(--sn-text-mid)}
.sn-one-side{margin-top:24px;padding:12px 16px;background:var(--sn-surface);border:1px solid var(--sn-line);border-left:3px solid var(--sn-gold);
border-radius:4px;font-size:.92rem;color:var(--sn-text-mid)}
.sn-one-side b{color:var(--sn-blue);font-weight:600}

.sn-panel{padding-top:20px}
.sn-note{margin-bottom:18px;padding:12px 16px;background:var(--sn-paper);border:1px solid var(--sn-rule);border-left:3px solid var(--sn-gold);
border-radius:4px;font-size:.88rem;line-height:1.55;color:var(--sn-text-mid);max-width:92ch}
.sn-note b{color:var(--sn-text);font-weight:600}

/* --------------------------------------------------------------------------
   3. COMPETITION GROUPS
   One full stat strip for the side, then a compact line per competition —
   ten full panels was fault 4.
   -------------------------------------------------------------------------- */
.sn-groups{margin-top:22px;display:flex;flex-direction:column;gap:22px}
.sn-group{background:var(--sn-surface);border:1px solid var(--sn-line);border-radius:6px;overflow:hidden}
.sn-group-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 20px;align-items:start;padding:14px 18px 12px;border-bottom:1px solid var(--sn-line)}
.sn-group-head h3{grid-column:1;font-size:1.14rem;font-weight:700;color:var(--sn-blue);line-height:1.2}
.sn-group-kind{grid-column:2;grid-row:1;align-self:center;font-size:.64rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
color:var(--sn-text-soft);white-space:nowrap}
.sn-group-sum{grid-column:1/-1;grid-row:2}
.sn-group .ml-panel{border:none;border-radius:0}
.sn-group .ml-head{display:none}
.sn-group .ml-table thead th{top:0}

/* --------------------------------------------------------------------------
   4. LOADING, ERROR, EMPTY
   -------------------------------------------------------------------------- */
.sn-skel{margin-top:26px;display:flex;flex-direction:column;gap:16px}
.sn-skel-block{background:var(--sn-surface);border:1px solid var(--sn-line);border-radius:6px}
.sn-skel-strip{height:96px}
.sn-skel-tabs{height:48px;background:#eaeef7;border-radius:5px 5px 0 0}
.sn-skel-row{height:46px;border-bottom:1px solid var(--sn-line);display:flex;align-items:center;gap:14px;padding:0 18px}
.sn-skel-row:last-child{border-bottom:none}
.sn-skel-row i{display:block;height:9px;border-radius:2px;background:#eef1f6}
.sn-skel-row i:nth-child(1){width:74px}
.sn-skel-row i:nth-child(2){flex:1;max-width:280px}
.sn-skel-row i:nth-child(3){width:46px;margin-left:auto}
.sn-skel-cap{font-size:.85rem;color:var(--sn-text-soft);padding:2px 2px 0}

.sn-msg{margin-top:26px;padding:26px 22px;background:var(--sn-surface);border:1px solid var(--sn-line);border-top:3px solid var(--sn-gold);border-radius:6px;text-align:center}
.sn-msg h2{font-size:1.15rem;font-weight:700;color:var(--sn-blue);margin-bottom:8px}
.sn-msg p{font-size:.92rem;line-height:1.55;color:var(--sn-text-mid);max-width:56ch;margin:0 auto}
.sn-retry{margin-top:16px;min-height:44px;padding:0 20px;border:1px solid var(--sn-blue);border-radius:4px;background:var(--sn-blue);color:#fff;
font:inherit;font-size:.9rem;font-weight:600;cursor:pointer}
.sn-retry:hover{background:var(--sn-blue-lift)}
.sn-foot-space{height:52px}

/* --------------------------------------------------------------------------
   5. BREAKPOINTS
      >=1024  chooser one row · tabs one row · group head 2-col
       1023   decade index scrolls horizontally
        767   prev/next drop their words to arrows only
        639   16px gutters · tabs scroll · group head stacks · chunk stays 25
        359   12px gutters
   -------------------------------------------------------------------------- */
@media (max-width:1023px){
  .sn-decades{overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none}
  .sn-decades::-webkit-scrollbar{display:none}
}
@media (max-width:767px){
  .sn-step span{display:none}
  .sn-step{padding:0 12px}
  .sn-combo{flex:1 1 200px}
}
@media (max-width:639px){
  .sn-inner{padding:0 16px}
  .sn-mast{padding:12px 0 0}
  .sn-chooser{padding:12px}
  .sn-tabs-wrap{margin-top:20px}
  .sn-tab{padding:9px 14px;font-size:.95rem}
  .sn-groups{gap:16px}
  .sn-group-head{grid-template-columns:minmax(0,1fr);padding:12px 14px 10px}
  .sn-group-kind{grid-column:1;grid-row:2;align-self:start}
  .sn-group-sum{grid-row:3}
  .sn-note{padding:11px 14px;font-size:.85rem}
  .sn-foot-space{height:34px}
}
@media (max-width:359px){
  .sn-inner{padding:0 12px}
  .sn-chooser{padding:10px}
}
@media (prefers-reduced-motion:reduce){
  .sn-tab{transition:none}
}


/* NOT rescued from season.html's inline <style>: its .vp-player-link rule.
   modal.js emits every player link inside <span class="vp-name">, and
   `.vp-name a` (0,1,1) outranks `.vp-player-link` (0,1,0), so that rule has
   never applied on any page — including the one it was written for. The .pm-*
   rules beside it were already in this file byte-for-byte, so nothing from
   that block needed moving. */

/* ============================================================================
   STATISTICS HUB — Southend United History
   ----------------------------------------------------------------------------
   Replaces the entire inline <style> block that used to live in
   statistics.html: every .landing-main / .landing-cards / .landing-card* rule,
   the dead .memorial-* block (~56 lines with no markup behind it) and the
   unused .photo-strip. Nothing above this point is touched.

   .landing-* is NOT deleted globally — landing.html still uses those names.
   This file only stops /statistics carrying its own private copy.
   ========================================================================== */

.sh{--sh-blue:var(--royal-blue,#003087);--sh-blue-deep:#001f5c;--sh-blue-lift:#004abf;
--sh-gold:var(--gold-accent,#c8a84b);--sh-gold-deep:#8f7420;
--sh-paper:#f7f5ef;--sh-paper-deep:#efebe0;--sh-paper-rule:#ddd8ca;
--sh-bg:#f4f6fb;--sh-surface:var(--white,#fff);--sh-line:#e3e7f0;--sh-line-hard:#c8cfe0;
--sh-text:#14181f;--sh-text-mid:#414a5a;--sh-text-soft:#6b7280;
--sh-win:#1a7a3c;--sh-draw:#b07a00;--sh-loss:#9b1c1c;
background:var(--sh-bg);color:var(--sh-text)}
.sh *,.sh *::before,.sh *::after{box-sizing:border-box}
.sh h1,.sh h2,.sh h3{font-family:'Playfair Display',Georgia,serif;margin:0;letter-spacing:-.015em}
.sh p{margin:0}
.sh ul,.sh ol{margin:0;padding:0;list-style:none}
.sh-sr{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.sh a:focus-visible,.sh button:focus-visible{outline:3px solid var(--sh-gold);outline-offset:2px;border-radius:3px}
.sh-inner{max-width:1200px;margin:0 auto;padding:0 24px}

/* --------------------------------------------------------------------------
   1. MASTHEAD — the page had no heading at all. One h1, one orienting line.
   -------------------------------------------------------------------------- */
.sh-mast{padding:22px 0 26px}
.sh-h1{font-size:clamp(1.9rem,3.6vw,2.7rem);font-weight:900;line-height:1.04;color:var(--sh-blue)}
.sh-span{margin-top:10px;font-size:.82rem;color:var(--sh-text-soft);font-variant-numeric:tabular-nums}

/* --------------------------------------------------------------------------
   2. FEATURED DESTINATION — /statistics/search, the one thing most people want
   -------------------------------------------------------------------------- */
.sh-feature{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:36px;align-items:center;
padding:30px 34px;border-radius:6px;border:1px solid var(--sh-blue-deep);
background:linear-gradient(135deg,var(--sh-blue-deep) 0%,var(--sh-blue) 62%,var(--sh-blue-lift) 100%);
color:#fff;text-decoration:none;transition:box-shadow .15s,transform .15s}
.sh-feature:hover{box-shadow:0 14px 40px -14px rgba(0,20,64,.65);transform:translateY(-2px)}
.sh-feature h2{font-size:clamp(1.5rem,2.6vw,2rem);font-weight:900;color:#fff;margin:12px 0 10px}
.sh-feature p{font-size:1rem;line-height:1.55;color:rgba(255,255,255,.84);max-width:52ch}
.sh-feature-cta{display:inline-flex;align-items:center;gap:9px;margin-top:20px;min-height:44px;padding:0 20px;
border-radius:4px;background:var(--sh-gold);color:#241c00;font-weight:700;font-size:.95rem}
.sh-feature:hover .sh-feature-cta{background:#dbbc63}
.sh-feature-figs{display:grid;gap:2px;border-left:1px solid rgba(255,255,255,.22);padding-left:32px}
.sh-feature-fig{display:flex;align-items:baseline;gap:12px;padding:9px 0;border-bottom:1px solid rgba(255,255,255,.14)}
.sh-feature-fig:last-child{border-bottom:none}
.sh-feature-fig b{font-size:1.5rem;font-weight:900;line-height:1;color:#fff;font-variant-numeric:tabular-nums;min-width:0}
.sh-feature-fig span{font-size:.72rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.66)}

/* --------------------------------------------------------------------------
   3. RECORD PANEL — the statistics a statistics page ought to show.
   Hairline rules and a proportional W/D/L bar, same idiom as the .ss-* strip.
   -------------------------------------------------------------------------- */
.sh-section{padding-top:38px}
.sh-sec-head{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;padding-bottom:10px;margin-bottom:18px;border-bottom:2px solid var(--sh-blue)}
.sh-sec-head h2{font-size:1.3rem;font-weight:700;color:var(--sh-blue)}

.sh-record{background:var(--sh-surface);border:1px solid var(--sh-line);border-radius:6px;overflow:hidden}
.sh-figs{display:grid;grid-template-columns:repeat(6,1fr)}
.sh-fig{padding:20px 16px 18px;border-right:1px solid var(--sh-line);text-align:center}
.sh-fig:last-child{border-right:none}
.sh-fig b{display:block;font-size:clamp(1.35rem,2.2vw,1.9rem);font-weight:900;line-height:1;color:var(--sh-blue);font-variant-numeric:tabular-nums}
.sh-fig span{display:block;margin-top:8px;font-size:.66rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--sh-text-soft)}

.sh-wdl{padding:20px 22px;border-top:1px solid var(--sh-line);background:var(--sh-paper)}
.sh-wdl-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:12px}
.sh-wdl-head h3{font-size:1.02rem;font-weight:700;color:var(--sh-blue)}
.sh-wdl-head p{font-size:.8rem;color:var(--sh-text-soft);margin-left:auto;font-variant-numeric:tabular-nums}
.sh-bar{display:flex;height:34px;border:1px solid var(--sh-paper-rule);border-radius:3px;overflow:hidden;background:#fff}
.sh-bar span{display:flex;align-items:center;justify-content:center;font-size:.78rem;font-weight:700;color:#fff;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden}
.sh-bar .w{background:var(--sh-win)}
.sh-bar .d{background:var(--sh-draw)}
.sh-bar .l{background:var(--sh-loss)}
.sh-key{display:flex;flex-wrap:wrap;gap:10px 26px;margin-top:11px;font-size:.84rem;color:var(--sh-text-mid);font-variant-numeric:tabular-nums}
.sh-key li{display:flex;align-items:center;gap:8px}
.sh-key i{width:11px;height:11px;border-radius:2px;flex:0 0 11px}
.sh-key .w i{background:var(--sh-win)}
.sh-key .d i{background:var(--sh-draw)}
.sh-key .l i{background:var(--sh-loss)}
.sh-note{margin-top:12px;padding-top:11px;border-top:1px dotted var(--sh-paper-rule);font-size:.82rem;line-height:1.55;color:var(--sh-text-soft);max-width:88ch}
.sh-note b{color:var(--sh-text-mid);font-weight:600}

.sh-land{display:grid;grid-template-columns:repeat(6,1fr);border-top:1px solid var(--sh-line)}
.sh-land li{padding:16px 18px;border-right:1px solid var(--sh-line)}
.sh-land li:last-child{border-right:none}
.sh-land-cap{display:block;font-size:.66rem;font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--sh-text-soft)}
.sh-land-val{display:block;margin-top:7px;font-size:1.12rem;font-weight:700;color:var(--sh-text);font-variant-numeric:tabular-nums}
.sh-land-sub{display:block;margin-top:4px;font-size:.78rem;color:var(--sh-text-soft)}

/* --------------------------------------------------------------------------
   4. DESTINATION CARDS — grouped, ranked, left-aligned.
   The old stagger was caused by a button pushed to the bottom of columns with
   different copy lengths. There is no button: titles are top-aligned against
   the icon box (not centred — centring is what re-introduces a few px of drift
   on two-line titles), and the cue is pinned to the bottom of a 1fr row, so
   both the title top and the cue baseline are identical across a row.
   -------------------------------------------------------------------------- */
.sh-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.sh-card{display:grid;grid-template-columns:40px minmax(0,1fr);grid-template-rows:auto 1fr;column-gap:14px;
padding:18px 18px 16px;background:var(--sh-surface);border:1px solid var(--sh-line);border-top:3px solid var(--sh-blue);
border-radius:4px;text-decoration:none;color:inherit;transition:border-color .15s,background .15s,transform .15s}
.sh-card:hover{background:#fcfdff;border-color:var(--sh-blue);border-top-color:var(--sh-gold);transform:translateY(-2px)}
.sh-card-icon{grid-row:1;grid-column:1;align-self:start;width:40px;height:40px;display:flex;align-items:center;justify-content:center;
border:1px solid var(--sh-line);border-radius:4px;background:#f7f9fd;color:var(--sh-blue)}
.sh-card:hover .sh-card-icon{border-color:var(--sh-gold)}
.sh-card-title{grid-row:1;grid-column:2;align-self:start;padding-top:9px;font-size:1.12rem;font-weight:700;color:var(--sh-blue);line-height:1.15}
.sh-card-body{grid-row:2;grid-column:1/-1;margin-top:13px;display:flex;flex-direction:column;min-height:74px}
.sh-card-desc{font-size:.86rem;line-height:1.5;color:var(--sh-text-mid);text-wrap:pretty}
.sh-card-cue{display:inline-flex;align-items:center;gap:7px;margin-top:auto;padding-top:12px;min-height:20px;
font-size:.8rem;font-weight:600;letter-spacing:.02em;color:var(--sh-blue);transition:gap .15s}
.sh-card:hover .sh-card-cue{gap:11px}
.sh-card-cue b{margin-left:auto;font-size:.86rem;color:var(--sh-text-soft);font-variant-numeric:tabular-nums}

/* --------------------------------------------------------------------------
   5. MAINTAINER STRIP — Data Cleansing, demoted out of the supporter grid
   -------------------------------------------------------------------------- */
.sh-maint{margin:40px 0 0;padding:16px 0 0;border-top:1px solid var(--sh-line-hard)}
.sh-maint h2{font-size:.68rem;font-family:'Source Sans 3',sans-serif;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--sh-text-soft)}
.sh-maint-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:8px;padding:10px 0}
.sh-maint-row a{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-size:.9rem;font-weight:600;color:var(--sh-text-mid);text-decoration:none}
.sh-maint-row a:hover{color:var(--sh-blue);text-decoration:underline;text-underline-offset:3px}
.sh-maint-row p{font-size:.84rem;color:var(--sh-text-soft)}
.sh-foot-space{height:46px}

/* --------------------------------------------------------------------------
   6. BREAKPOINTS
      >=1200  container caps; 6 figures across, 5 landmarks across, 4 cards
      1199    feature figures column narrows
      1023    feature stacks; figures 3x2; landmarks 3+2; cards 2-across
       767    landmarks 2-across
       639    figures 2x3; landmarks 1-col; cards become full-width rows with
              the icon inline, which is what keeps the mobile page short
       359    12px gutters
   -------------------------------------------------------------------------- */
@media (max-width:1199px){
  .sh-feature{gap:26px;padding:26px}
  .sh-feature-figs{padding-left:24px}
  .sh-grid{gap:14px}
}
@media (max-width:1023px){
  .sh-feature{grid-template-columns:minmax(0,1fr);gap:22px}
  .sh-feature-figs{border-left:none;border-top:1px solid rgba(255,255,255,.22);padding-left:0;padding-top:6px;
    grid-template-columns:repeat(3,1fr);gap:0}
  .sh-feature-fig{flex-direction:column;gap:5px;border-bottom:none;padding:12px 0 4px}
  .sh-figs{grid-template-columns:repeat(3,1fr)}
  .sh-fig:nth-child(3n){border-right:none}
  .sh-fig:nth-child(-n+3){border-bottom:1px solid var(--sh-line)}
  .sh-land{grid-template-columns:repeat(3,1fr)}
  .sh-land li:nth-child(3n){border-right:none}
  .sh-land li:nth-child(-n+3){border-bottom:1px solid var(--sh-line)}
  .sh-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:767px){
  .sh-land{grid-template-columns:repeat(2,1fr)}
  .sh-land li:nth-child(n){border-right:1px solid var(--sh-line);border-bottom:1px solid var(--sh-line)}
  .sh-land li:nth-child(2n){border-right:none}
  .sh-land li:last-child{border-bottom:none}
}
@media (max-width:639px){
  .sh-inner{padding:0 16px}
  .sh-mast{padding:12px 0 16px}
  .sh-section{padding-top:24px}
  .sh-sec-head{margin-bottom:14px}
  .sh-feature{padding:20px 16px;gap:16px}
  .sh-feature p{font-size:.93rem}
  .sh-feature-cta{margin-top:16px}
  .sh-feature-figs{grid-template-columns:repeat(3,1fr)}
  .sh-feature-fig b{font-size:1.2rem}
  .sh-figs{grid-template-columns:repeat(2,1fr)}
  .sh-fig{padding:12px 10px 11px;border-right:1px solid var(--sh-line);border-bottom:1px solid var(--sh-line)}
  .sh-fig b{font-size:1.2rem}
  .sh-fig span{margin-top:6px;font-size:.62rem}
  .sh-fig:nth-child(2n){border-right:none}
  .sh-fig:nth-child(n+5){border-bottom:none}
  .sh-wdl{padding:14px 16px}
  .sh-note{font-size:.79rem;line-height:1.5}
  /* Landmarks stay two-up: five stacked cells was 380px of the phone page. */
  .sh-land{grid-template-columns:repeat(2,1fr)}
  .sh-land li{padding:11px 14px}
  .sh-land-val{font-size:1.02rem;margin-top:5px}

  /* Genuine rows, not stacked tiles. Icon and title on one line, description
     clamped to two lines, cue dropped — its count is already in the record
     panel. This is what keeps fourteen destinations to ~1,400px on a phone
     instead of the ~2,000px fourteen stacked tiles produce. */
  .sh-grid{grid-template-columns:minmax(0,1fr);gap:8px}
  .sh-card{grid-template-columns:36px minmax(0,1fr);grid-template-rows:auto auto;column-gap:12px;padding:12px 14px;border-top-width:2px}
  .sh-card-icon{width:36px;height:36px}
  .sh-card-title{padding-top:7px;font-size:1.02rem}
  .sh-card-body{grid-column:2;margin-top:4px;min-height:0}
  .sh-card-desc{font-size:.82rem;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .sh-card-cue{display:none}
  .sh-maint{margin-top:24px}
  .sh-foot-space{height:32px}
}
@media (max-width:359px){
  .sh-inner{padding:0 12px}
  .sh-card{padding:12px;column-gap:10px}
  .sh-wdl{padding:14px 12px}
  .sh-key{gap:8px 16px}
  .sh-land{grid-template-columns:minmax(0,1fr)}
  .sh-land li{border-right:none}
}
@media (prefers-reduced-motion:reduce){
  .sh-card,.sh-feature,.sh-card-cue{transition:none}
  .sh-card:hover,.sh-feature:hover{transform:none}
}

/* ============================================================================
   DIRECTORY — /players and /opponents
   ----------------------------------------------------------------------------
   One search over the whole corpus, two configurations. Replaces the A–Z
   landing pages and the per-letter grids.
   ========================================================================== */
.dir-bar { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin: var(--panel-pad-tight) 0 12px; }

.dir-search { position: relative; flex: 1 1 260px; min-width: 0; }
.dir-search-icon { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text-light); pointer-events: none; }
.dir-search input {
  width: 100%; min-height: 44px; padding: 0 14px 0 36px;
  font: inherit; font-size: var(--fs-m);
  border: 1px solid var(--panel-line); border-radius: 4px; background: #fff; color: var(--text-dark);
}
.dir-search input:focus-visible { outline: 3px solid var(--gold-accent); outline-offset: 1px; }

.dir-controls { display: flex; gap: 8px; align-items: center; }
.dir-sort { min-height: 44px; padding: 0 10px; font: inherit; font-size: var(--fs-s);
  border: 1px solid var(--panel-line); border-radius: 4px; background: #fff; color: var(--text-mid); }

.dir-views { display: flex; border: 1px solid var(--panel-line); border-radius: 4px; overflow: hidden; }
.dir-view { min-height: 44px; padding: 0 14px; border: 0; background: #fff; cursor: pointer;
  font: inherit; font-size: var(--fs-s); font-weight: var(--fw-med); color: var(--text-mid); }
.dir-view + .dir-view { border-left: 1px solid var(--panel-line); }
.dir-view.is-on { background: var(--royal-blue); color: #fff; }

.dir-count { font-size: var(--fs-s); color: var(--text-light); font-variant-numeric: tabular-nums; margin-bottom: 10px; }
.dir-loading, .dir-empty { padding: 40px 8px; text-align: center; color: var(--text-light); }
.dir-empty-head { font-size: var(--fs-l); color: var(--text-mid); margin-bottom: 6px; }
.dir-empty-body { font-size: var(--fs-s); max-width: 46ch; margin: 0 auto; }

/* --- list: the default view ------------------------------------------------ */
.dir-list { border-top: 1px solid var(--panel-line); }
.dir-item {
  display: flex; align-items: center; gap: 14px;
  padding: 10px 8px; min-height: 60px;
  border-bottom: 1px solid var(--panel-line);
  text-decoration: none; color: inherit;
}
.dir-item:hover { background: #f7f9fd; }
.dir-item:hover .dir-name { text-decoration: underline; text-underline-offset: 2px; }

/* The figure is a fixed box whether or not an image exists, so a list of
   mostly-unphotographed players still lines up. */
.dir-figure {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 3px; overflow: hidden;
  background: var(--off-white); border: 1px solid var(--panel-line);
  display: flex; align-items: center; justify-content: center; position: relative;
}
.dir-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.dir-initials { display: none; font-size: var(--fs-s); font-weight: var(--fw-med); color: var(--text-light); letter-spacing: .04em; }
.dir-figure.is-blank .dir-initials { display: block; }

.dir-body { flex: 1 1 auto; min-width: 0; }
.dir-name { display: block; font-size: var(--fs-m); font-weight: var(--fw-med); color: var(--royal-blue); }
.dir-meta { display: block; font-size: var(--fs-xs); color: var(--text-light); font-variant-numeric: tabular-nums; }

.dir-stats { display: flex; gap: 18px; flex: 0 0 auto; }
.dir-stat { text-align: right; min-width: 2.6rem; }
.dir-stat b { display: block; font-size: var(--fs-m); font-weight: var(--fw-med);
  font-variant-numeric: tabular-nums lining-nums; color: var(--text-dark); }
.dir-stat-cap { display: block; font-size: var(--fs-micro); text-transform: uppercase;
  letter-spacing: var(--tracking-label); color: var(--text-light); }

/* --- compact: names only, for scanning many at once ------------------------ */
.dir-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.dir-chip {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px;
  border: 1px solid var(--panel-line); border-radius: 3px; background: #fff;
  font-size: var(--fs-s); color: var(--royal-blue); text-decoration: none;
}
.dir-chip:hover { border-color: var(--royal-blue); background: #f7f9fd; }

.dir-more {
  display: block; margin: 16px auto 0; min-height: 44px; padding: 0 20px;
  border: 1px solid var(--panel-line); border-radius: 4px; background: #fff;
  font: inherit; font-size: var(--fs-s); font-weight: var(--fw-med);
  color: var(--royal-blue); cursor: pointer;
}
.dir-more:hover { border-color: var(--royal-blue); background: #f7f9fd; }

@media (max-width: 560px) {
  .dir-controls { width: 100%; }
  .dir-sort { flex: 1 1 auto; min-width: 0; }
  /* Two stats, not four: P W D L at this width pushes the club name to one
     word per line. The full record is on the club's own page. */
  .dir-stats { gap: 12px; }
  /* Keep the first stat and anything marked key — for clubs that is P and the
     win percentage, which say more together than P and W do. The full P/W/D/L
     is on the club's own page. */
  .dir-stat:nth-child(n+2):not(.dir-stat-key) { display: none; }
  .dir-stat { min-width: 2.2rem; }
}

/* The first-team filter. A checkbox, not a third view toggle: it composes with
   the search box and the sort, which a segmented control would not. */
.dir-check {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 12px; white-space: nowrap;
  border: 1px solid var(--panel-line); border-radius: 4px; background: #fff;
  font-size: var(--fs-s); color: var(--text-mid); cursor: pointer;
}
.dir-check:hover { border-color: var(--royal-blue); }
.dir-check input { width: 16px; height: 16px; accent-color: var(--royal-blue); cursor: pointer; }
.dir-check:focus-within { outline: 3px solid var(--gold-accent); outline-offset: 1px; }
/* ============================================================================
   SUFC PLAYER PROFILE — the whole page.
   ----------------------------------------------------------------------------
   REPLACES: the entire inline <style> block in templates/player.html
             (.profile-wrap, .profile-photo*, .bio-*, .dates-*, .stats-*,
              .apps-*, .profile-loading, .death-age — all of it).
   KEEPS:    .bio-source (moved here unchanged), .ml-pill / .ml-c-score from
             the match list, the modal's card colours.
   BUILDS ON: foundations §1 tokens, .sufc-panel, .sufc-panel-title,
             .sufc-h1–h4, .sufc-fig, .sufc-label, .sufc-small, .sufc-num.
   No new font, no new image, no build step.
   ============================================================================ */

.pp{max-width:1100px;margin:0 auto}
.pp-loading{padding:64px 0;text-align:center;color:var(--text-light,#6b7280)}

/* ---------------------------------------------------------------------------
   1. MASTHEAD — name, photograph, the two figures, the vitals, the bookend
   dates. One panel doing the work that four cards used to start with.
   --------------------------------------------------------------------------- */
.pp-head{border-top:3px solid var(--gold-accent,#c8a84b);padding-bottom:0;overflow:hidden}
.pp-head-grid{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px 28px;align-items:start}
.pp-head--nophoto .pp-head-grid{grid-template-columns:minmax(0,1fr)}

.pp-photo{margin:0;width:224px;flex:0 0 auto}
.pp-photo img{display:block;width:100%;height:auto;border-radius:4px;border:1px solid var(--panel-line);box-shadow:var(--panel-shadow)}
.pp-photo figcaption{margin-top:8px;display:block}
.pp-photo.pp-photo--placeholder{width:112px}
.pp-photo--placeholder img{border-style:dashed;box-shadow:none;opacity:.7}

.pp-eyebrow{display:block;margin-bottom:6px}
.pp-name{margin:0}
.pp-vitals{margin-top:10px;max-width:70ch}
.pp-vitals b{font-weight:var(--fw-med);color:var(--text-mid,#374151)}
.pp-vitals .pp-sep{color:var(--panel-line-strong,#c8cfe0);padding:0 2px}

/* -- the figure rail: the two or three numbers that define a career -------- */
.pp-figs{display:flex;flex-wrap:wrap;gap:14px 44px;margin-top:18px;padding:16px 0;border-top:1px solid var(--panel-line);border-bottom:1px solid var(--panel-line)}
.pp-fig{display:flex;flex-direction:column;gap:1px;min-width:0}
.pp-fig-n{display:block}
.pp-fig-l{display:block;margin-top:2px}
.pp-fig-sub{display:block}
.pp-fig--span .sufc-fig{font-size:var(--fs-2xl)}
.pp-dagger{font-size:var(--fs-s);color:var(--gold-ink,#8a6d1f);text-decoration:none;vertical-align:super;font-weight:var(--fw-med);padding:0 .1em}
a.pp-dagger:hover{text-decoration:underline}

.pp-bio{margin-top:18px}
.pp-bio p{margin:0}
.bio-source{font-size:var(--fs-xs);color:var(--text-light,#6b7280);font-style:italic;vertical-align:super;margin-left:.35em;font-family:var(--font-sans);font-weight:var(--fw-body)}
.death-age,.pp-age{font-style:italic;color:var(--text-light,#6b7280)}

/* -- bookends: the dates a historian reaches for, as the masthead's foot --- */
.pp-bookends{list-style:none;margin:var(--panel-pad) calc(var(--panel-pad) * -1) 0;padding:0;background:var(--off-white,#f4f6fb);border-top:1px solid var(--panel-line);display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
.pp-bookend{padding:14px var(--panel-pad);border-left:1px solid var(--panel-line)}
.pp-bookend:first-child{border-left:none}
.pp-bookend-date{display:block;margin:3px 0 2px;font-size:var(--fs-l);font-weight:var(--fw-med);color:var(--royal-blue,#003087);font-variant-numeric:tabular-nums lining-nums}
.pp-bookend-detail{display:block}

/* ---------------------------------------------------------------------------
   2. PANEL HEADS — no dark blue bar. Hierarchy comes from order and size, so
   the masthead can lead and these two can read as sections under it.
   --------------------------------------------------------------------------- */
.pp-panel{margin-top:var(--panel-pad)}
.pp-panel > .sufc-panel-head{margin:0;padding:14px var(--panel-pad);align-items:baseline}
.pp-panel > .sufc-panel-head .sufc-panel-title{font-size:var(--fs-xl)}
.pp-panel > .sufc-panel-head .sufc-panel-head-note{white-space:nowrap}

/* ---------------------------------------------------------------------------
   3. CAREER RECORD
   --------------------------------------------------------------------------- */
.pp-record{width:100%;border-collapse:collapse}
.pp-record th{font-size:var(--fs-micro);font-weight:var(--fw-med);letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--text-light,#6b7280);text-align:left;padding:8px var(--panel-pad);background:var(--off-white,#f4f6fb);border-bottom:1px solid var(--panel-line)}
.pp-record td{padding:11px var(--panel-pad);border-bottom:1px solid var(--panel-line);font-size:var(--fs-s)}
.pp-record tbody tr:last-child td{border-bottom:none}
.pp-record th.n,.pp-record td.n{text-align:right;font-variant-numeric:tabular-nums lining-nums}
.pp-record td.n{font-weight:var(--fw-med);color:var(--royal-blue,#003087)}
.pp-record .pp-sub{color:var(--text-light,#6b7280);font-weight:var(--fw-body)}
.pp-record tr.pp-total td{background:var(--blue-pale,#e6efff);border-top:2px solid var(--royal-blue,#003087);font-weight:var(--fw-med);color:var(--royal-blue,#003087)}
.pp-record tr.pp-other td{color:var(--text-light,#6b7280);font-style:italic;background:#fafbfe}
.pp-record tr.pp-other td.n{color:var(--text-light,#6b7280)}
.pp-record tr.pp-other--first td{border-top:1px dashed var(--panel-line-strong,#c8cfe0)}

/* ---------------------------------------------------------------------------
   4. THE GAP BLOCK — goals the archive holds without a line-up to hang them
   on. Stated, sized and explained rather than left to look like an error.
   --------------------------------------------------------------------------- */
.pp-gapblock{display:flex;gap:16px;align-items:flex-start;padding:16px var(--panel-pad);background:#fdf9ee;border-top:2px solid var(--gold-accent,#c8a84b)}
.pp-gapblock .pp-gap-n{flex:0 0 auto;color:var(--gold-ink,#8a6d1f);line-height:1}
.pp-gapblock .pp-gap-t{margin:0;max-width:64ch}
.pp-gapblock .pp-gap-t b{font-weight:var(--fw-med);color:var(--text-dark,#111827)}
.pp-footnote{padding:12px var(--panel-pad);border-top:1px solid var(--panel-line);background:#fafbfe;max-width:none}

/* ---------------------------------------------------------------------------
   5. APPEARANCES — one disclosure per side.
   --------------------------------------------------------------------------- */
.pp-side{border-top:1px solid var(--panel-line)}
.pp-side-sum{display:flex;flex-wrap:wrap;align-items:center;gap:4px 16px;padding:12px var(--panel-pad);min-height:56px;cursor:pointer;list-style:none}
.pp-side-sum::-webkit-details-marker{display:none}
.pp-side-sum:hover{background:var(--blue-pale,#e6efff)}
.pp-side-chev{flex:0 0 auto;width:14px;height:14px;color:var(--royal-blue,#003087);transition:transform .15s ease}
.pp-side[open] > .pp-side-sum .pp-side-chev{transform:rotate(90deg)}
.pp-side-name{font-family:var(--font-serif);font-size:var(--fs-l);font-weight:var(--fw-head);color:var(--royal-blue,#003087);flex:0 0 auto}
.pp-side-chips{display:flex;flex-wrap:wrap;gap:2px 14px;flex:1 1 auto;min-width:0}
.pp-side-chips span{white-space:nowrap}
.pp-side-chips b{color:var(--royal-blue,#003087);font-weight:var(--fw-med);font-variant-numeric:tabular-nums lining-nums}
.pp-side-cta{flex:0 0 auto;margin-left:auto;color:var(--royal-blue,#003087);font-weight:var(--fw-med);white-space:nowrap}
.pp-side[open] > .pp-side-sum .pp-side-cta-show{display:none}
.pp-side:not([open]) > .pp-side-sum .pp-side-cta-hide{display:none}

.pp-matches{overflow-x:auto;border-top:1px solid var(--panel-line)}
.pp-mt{width:100%;border-collapse:collapse;font-size:var(--fs-xs)}
.pp-mt thead th{font-size:var(--fs-micro);font-weight:var(--fw-med);letter-spacing:.08em;text-transform:uppercase;color:var(--text-light,#6b7280);text-align:left;padding:7px 10px;background:var(--off-white,#f4f6fb);border-bottom:1px solid var(--panel-line);white-space:nowrap}
.pp-mt th.n,.pp-mt td.n{text-align:right}
.pp-mt td{padding:9px 10px;border-bottom:1px solid var(--panel-line);vertical-align:top;font-variant-numeric:tabular-nums lining-nums}
.pp-mt tbody tr:last-child td{border-bottom:none}
.pp-mt th:first-child,.pp-mt td:first-child{padding-left:var(--panel-pad)}
.pp-mt th:last-child,.pp-mt td:last-child{padding-right:var(--panel-pad)}
.pp-mt .pp-c-date,.pp-mt .pp-c-score{white-space:nowrap}
.pp-mt .pp-c-opp{font-weight:var(--fw-med)}
.pp-m-sub{display:none;color:var(--text-light,#6b7280);font-weight:var(--fw-body)}
.pp-row{cursor:pointer}
.pp-row:hover td{background:#f5f8ff}
.pp-row:focus-visible{outline:3px solid var(--gold-accent,#c8a84b);outline-offset:-3px}

/* season bands: 339 rows read as eleven seasons, not one list */
.pp-mt .pp-season th{padding:7px var(--panel-pad);background:var(--blue-pale,#e6efff);color:var(--royal-blue,#003087);font-family:var(--font-sans);font-size:var(--fs-s);font-weight:var(--fw-med);letter-spacing:0;text-transform:none;border-bottom:1px solid var(--panel-line);border-top:1px solid var(--panel-line)}
.pp-season-note{font-weight:var(--fw-body);color:var(--text-mid,#374151);margin-left:10px;font-variant-numeric:tabular-nums lining-nums}

.pp-cardmark{display:inline-block;width:10px;height:14px;border-radius:1px;vertical-align:-2px}
.pp-cardmark-yellow{background:var(--vp-booked,#b06f00)}
.pp-cardmark-red{background:var(--vp-sentoff,#b81c1c)}

/* ---------------------------------------------------------------------------
   6. THE THIN PAGE — 1,216 men played once. Say what the archive holds and
   stop, rather than leaving a column of white beside four empty cards.
   --------------------------------------------------------------------------- */
.pp-archive{margin-top:var(--panel-pad);background:var(--off-white,#f4f6fb);box-shadow:none;border-style:dashed}
.pp-archive p{margin:0;max-width:62ch}
.pp-archive p + p{margin-top:.7em}

/* ---------------------------------------------------------------------------
   7. BREAKPOINTS. Tested at 320, 375, 390, 768, 1024, 1280, 1440.
   --------------------------------------------------------------------------- */
@media (max-width:1023px){
  .pp-photo{width:190px}
  .pp-photo.pp-photo--placeholder{width:104px}
}
@media (max-width:767px){
  /* masthead stacks; the photo sits inline with the eyebrow so the name is
     never pushed below the fold on a phone */
  .pp-head-grid{grid-template-columns:auto minmax(0,1fr);gap:8px 18px}
  .pp-photo{width:104px}
  .pp-photo figcaption{display:none}
  .pp-photo.pp-photo--placeholder{width:76px}
  .pp-figs{gap:12px 28px}
  .pp-bookend{border-left:none;border-top:1px solid var(--panel-line)}
  .pp-bookend:first-child{border-top:none}
  /* competition and shirt fold into the opponent cell */
  .pp-mt .pp-c-comp,.pp-mt .pp-c-shirt,.pp-mt .pp-h-comp,.pp-mt .pp-h-shirt{display:none}
  .pp-m-sub{display:block;font-size:var(--fs-micro);line-height:1.35;margin-top:2px}
}
@media (max-width:479px){
  .pp-mt th:first-child,.pp-mt td:first-child{padding-left:14px}
  .pp-mt th:last-child,.pp-mt td:last-child{padding-right:14px}
  .pp-mt td,.pp-mt thead th{padding-left:5px;padding-right:5px}
  .pp-mt .pp-c-date{font-size:var(--fs-micro)}
  .pp-mt .ml-pill{min-width:42px;padding:3px 5px}
  .pp-side-name{font-size:var(--fs-m)}
  .pp-side-cta{margin-left:0}
  .pp-gapblock{flex-direction:column;gap:8px}
}
@media print{
  .pp-side > .pp-matches{display:block}
}

/* An unused substitute played no part in the match, so the row recedes: the
   date and opponent stay legible, the figures beside them do not compete with
   rows that describe an actual appearance. */
.pp-row--unused > td { color: var(--text-light, #6b7280); }
.pp-row--unused .ml-pill { opacity: .55; }

/* ============================================================================
   WIDE TABLES MUST BE REACHABLE
   ----------------------------------------------------------------------------
   .sufc-panel--flush sets overflow:hidden so a table's corners are clipped to
   the panel's radius. That is right until the table is wider than the panel,
   at which point the overflowing columns are not merely off-screen — they are
   unreachable, because nothing between them and the viewport can scroll.

   Measured at 375: /goals lost a 785px table, /goalkeeper 783px, /attendances
   551px and /match-cleanse 1,026px. /appearances was already fine, which is
   the pattern the rest follow — a scrolling wrapper around the table.

   Scoped to these four containers rather than to .sufc-panel--flush itself:
   setting overflow-x on the panel computes overflow-y to auto as well, which
   would break the sticky table headers in the match list.
   ========================================================================== */
/* A panel is often a grid or flex item, and those default to min-width:auto —
   they refuse to shrink below their content, so the panel grew to the table's
   width and the scroll container inside it never had anything to scroll. This
   one declaration is what makes the rules below work at all. */
.sufc-panel { min-width: 0; }
/* ...and whatever the grid's actual child is, which on /goals is an unnamed
   wrapper around the panel rather than the panel itself. */
.sufc-grid > *, .goals-grid > *, .gk-grid > * { min-width: 0; }

/* The direct child of the flush panel is what has to scroll. On /goalkeeper
   that child is an unnamed div, so the panel class selects it. */
.goals-card-body,
.gk-card > div,
.sc-card > .sc-table-wrap,
.sc-table-wrap { overflow-x: auto; }

/* This one is the panel itself — the table is a direct child, so the scroll
   has to live here. Vertical stays visible: there is no sticky header inside. */
.att-table-card { overflow-x: auto; overflow-y: visible; }

/* Same shape, same fix: a bare <table> as the direct child of a flush panel,
   which inherits .sufc-panel's overflow:hidden and so clipped the table dead
   with nothing to scroll it. Used by /name-cleanse, /name-report and
   /initials-report, and built in JS by namecleanse.js and players.js as well
   as declared in those two templates.

   /name-cleanse was the bad one: 1,817px of table in 1,150px of panel at
   1280, so 667px of it — six columns — could not be reached on a desktop, and
   1,482px of it at 375. These are the maintainer worklists, so it was the
   site's own tooling that was unusable rather than a reader-facing page,
   which is presumably why it went unnoticed.

   The overflow-y: visible does not survive: per spec, a visible paired with
   a scrolling overflow-x computes to auto, and it measures as auto here. It
   is written anyway to say which axis is wanted, and it is harmless because
   the panel has no height constraint — scrollHeight equals clientHeight, so
   no vertical scrollbar ever appears. What it must not do is create a
   scroll container around a sticky header, which is why this rule names one
   class instead of .sufc-panel--flush; the match list's sticky headers are
   the reason that shortcut is not taken anywhere in this block. */
.players-table-card { overflow-x: auto; overflow-y: visible; }

/* ============================================================================
   COOKIE CONSENT — the analytics banner and its footer re-entry point
   ----------------------------------------------------------------------------
   Only ever in the DOM when GA_MEASUREMENT_ID is set (see app.py); both
   elements are built by static/js/analytics.js, never by a template.

   Fixed to the bottom of the viewport on purpose: it must not cover the header
   or the search box, and being out of flow it shifts nothing when it appears
   or goes. Targets are 44px like the rest of the site. Focus rings come from
   the global :focus-visible rule in §1 and are not overridden here.
   ============================================================================ */

.sufc-consent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10050;
  background: var(--royal-blue, #003087);
  border-top: 3px solid var(--gold-accent, #c8a84b);
  box-shadow: 0 -6px 24px rgba(0, 32, 90, .28);
  color: #fff;
}
.sufc-consent-inner {
  max-width: 1200px; margin: 0 auto; padding: 14px 20px;
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
}
.sufc-consent-text {
  flex: 1 1 320px; margin: 0;
  font-family: var(--font-sans); font-size: var(--fs-s);
  line-height: var(--lh-body); color: #fff;
}
.sufc-consent-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.sufc-consent-btn {
  min-height: 44px; padding: 0 20px;
  border: 1px solid rgba(255, 255, 255, .55); border-radius: 4px;
  background: transparent; color: #fff;
  font: inherit; font-family: var(--font-sans);
  font-size: var(--fs-s); font-weight: var(--fw-med);
  cursor: pointer;
}
.sufc-consent-btn:hover { border-color: #fff; background: rgba(255, 255, 255, .12); }
.sufc-consent-btn--yes {
  background: var(--gold-accent, #c8a84b); border-color: var(--gold-accent, #c8a84b);
  /* Navy on gold, not white: white on #c8a84b is under 3:1. */
  color: #1a1a1a;
}
.sufc-consent-btn--yes:hover { background: #d8ba63; border-color: #d8ba63; }

/* Re-entry point. Matches the footer's own links — same 44px line box, same
   gold — because withdrawing consent has to be as easy as giving it. */
.sufc-consent-reopen {
  display: inline-block; min-height: 44px; line-height: 44px;
  margin: 0; padding: 0 12px;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-family: var(--font-sans); font-size: var(--fs-s);
  color: var(--gold-accent, #c8a84b);
}
.sufc-consent-reopen:hover { text-decoration: underline; }

@media (max-width: 560px) {
  .sufc-consent-inner { padding: 12px 16px; gap: 12px; }
  .sufc-consent-actions { width: 100%; }
  .sufc-consent-btn { flex: 1 1 0; padding: 0 12px; }
}
