/* One variable family, weight-differentiated. The opsz axis is left to
   the browser (font-optical-sizing is auto by default), which is why the
   wordmark at 1.5rem and a 0.74rem badge both stay evenly weighted.
   Subset to latin + the arrows/diamond/middot the UI actually draws, so
   this is 64KB rather than Inter's full 350KB. Italic is deliberately
   absent: nothing in this design uses it, and synthetic oblique covers
   any stray <em>. */
@font-face {
    font-family: 'Inter';
    src: url('fonts/Inter-Variable.woff2') format('woff2');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* ---------- theme tokens ----------

   Dark is the default and the design's primary. Light is a full
   re-tint of the same tokens, so every rule below this block is written
   once against the names and never against a literal color.

   Which theme applies is decided in three layers, weakest first:
     1. :root                    dark, the fallback when nothing else says
     2. prefers-color-scheme     the OS preference, for a first visit and
                                 for anyone running without JS
     3. [data-theme]             an explicit choice, stamped on <html> by
                                 theme.js and remembered in localStorage
   The light values appear twice on purpose: a media query and an
   attribute selector cannot be combined into one rule, and duplicating
   ~25 declarations is cheaper than the alternatives. Edit both. */

:root {
    /* Type and geometry are theme-independent: they live here only. */
    --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
            Roboto, Helvetica, Arial, sans-serif;
    --mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    --radius: 12px;
    --radius-sm: 8px;

    /* Surfaces, darkest to lightest. Flat colors on purpose: this design
       has no gradients and no texture, so depth comes from these steps
       plus a 1px --line, never from a shadow doing the work. */
    color-scheme: dark;
    --bg: #0b0d10;
    --surface: #14171c;      /* cards, tables, inputs */
    --surface-2: #1a1e25;    /* header, footer, table heads, raised */
    --surface-3: #222831;    /* hover */

    --line: #262c36;
    --line-strong: #333b47;

    --text: #e9ecf1;
    --muted: #98a2b0;

    /* --accent is the per-league brand hook: a league's theme.css
       overrides this one variable and its links, active pills, focus
       rings and chart strokes all follow. --on-accent is the text laid
       on top of it, which has to flip with the theme because the light
       accent is dark enough to need white. Everything else here is
       chrome and should stay put across leagues. */
    --accent: #00d6b4;
    --accent-dim: #00a98f;
    --accent-soft: rgba(0, 214, 180, 0.12);
    --on-accent: #04231d;

    /* State colors, each with a low-alpha tint for cell and row fills.
       The tints are alpha rather than solid so they compose correctly
       over --surface, --surface-2 and a hovered row alike. */
    --gold: #ffc44d;
    --gold-soft: rgba(255, 196, 77, 0.13);
    --red: #ff6b6b;
    --red-soft: rgba(255, 107, 107, 0.13);
    --green: #3ddc84;
    --green-soft: rgba(61, 220, 132, 0.13);

    /* The import job log stays a dark terminal in both themes: a white
       log block reads as a form field, not as output. */
    --code-bg: #05070a;
    --code-fg: #98a2b0;

    /* Shadows stay very dark and very soft: on a near-black page a
       light-theme shadow reads as grey haze instead of depth. */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45),
                 0 12px 32px rgba(0, 0, 0, 0.35);
}

/* Light, layer 2: the OS preference, but only until someone chooses.
   :not([data-theme]) is what lets an explicit dark choice beat a light
   system setting. */
@media (prefers-color-scheme: light) {
    :root:not([data-theme]) {
        color-scheme: light;
        --bg: #f5f6f8;
        --surface: #ffffff;
        --surface-2: #eef0f4;
        --surface-3: #e4e7ec;

        --line: #e1e5ea;
        --line-strong: #c9cfd8;

        --text: #11151b;
        --muted: #5b6673;

        --accent: #007a68;
        --accent-dim: #005e50;
        --accent-soft: rgba(0, 122, 104, 0.11);
        --on-accent: #ffffff;

        --gold: #8a5d00;
        --gold-soft: rgba(214, 152, 20, 0.16);
        --red: #c0392f;
        --red-soft: rgba(192, 57, 47, 0.11);
        --green: #12794a;
        --green-soft: rgba(18, 121, 74, 0.11);

        /* The log block stays a dark terminal in light mode too, so
           its foreground stays light. Only the value differs. */
        --code-fg: #a8b3c0;

        --shadow-sm: 0 1px 2px rgba(16, 22, 32, 0.07);
        --shadow-md: 0 4px 12px rgba(16, 22, 32, 0.09),
                     0 12px 32px rgba(16, 22, 32, 0.07);
    }
}

/* Light, layer 3: the explicit choice. Same values as above. */
:root[data-theme="light"] {
    color-scheme: light;
    --bg: #f5f6f8;
    --surface: #ffffff;
    --surface-2: #eef0f4;
    --surface-3: #e4e7ec;

    --line: #e1e5ea;
    --line-strong: #c9cfd8;

    --text: #11151b;
    --muted: #5b6673;

    --accent: #007a68;
    --accent-dim: #005e50;
    --accent-soft: rgba(0, 122, 104, 0.11);
    --on-accent: #ffffff;

    --gold: #8a5d00;
    --gold-soft: rgba(214, 152, 20, 0.16);
    --red: #c0392f;
    --red-soft: rgba(192, 57, 47, 0.11);
    --green: #12794a;
    --green-soft: rgba(18, 121, 74, 0.11);

    /* The log block stays a dark terminal in light mode too, so
       its foreground stays light. Only the value differs. */
    --code-fg: #a8b3c0;

    --shadow-sm: 0 1px 2px rgba(16, 22, 32, 0.07);
    --shadow-md: 0 4px 12px rgba(16, 22, 32, 0.09),
                 0 12px 32px rgba(16, 22, 32, 0.07);
}

* { box-sizing: border-box; }

::selection { background: var(--accent); color: var(--on-accent); }

html {
    scroll-behavior: smooth;
    /* Without this, mobile browsers "font boost" some blocks (notably
       the display:block tables from the mobile breakpoint) and not
       others, so table text renders at inconsistent sizes. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scrollbar-color: var(--line-strong) var(--bg);
    scrollbar-width: thin;
    /* color-scheme is set with the theme tokens above, not here: :root
       and html are the same element, so a second declaration would just
       be a specificity race with the light-theme rules. */
}

body {
    margin: 0;
    font-family: var(--sans);
    color: var(--text);
    background: var(--bg);
    line-height: 1.6;
    letter-spacing: -0.011em;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
}

/* ---------- header / footer ---------- */

header {
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    z-index: 50;
}

.header-inner {
    max-width: 1020px;
    margin: 0 auto;
    padding: 0.7rem 1.5rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.brand {
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-decoration: none;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.brand-mark {
    width: 1.35em;
    height: 1.35em;
    flex-shrink: 0;
    color: var(--accent);
}

nav { display: flex; gap: 0.15rem; align-items: center; }

.nav-link {
    color: var(--muted);
    text-decoration: none;
    font-size: 0.875rem;
    font-weight: 550;
    padding: 0.4rem 0.75rem;
    border-radius: 999px;
    transition: background 0.15s, color 0.15s;
}

.nav-link:hover {
    color: var(--text);
    background: var(--surface-3);
    text-decoration: none;
}

/* ---------- light/dark switch ---------- */

/* Sits at the far right of the top bar at every width: it is one of the
   few controls that stays out of the hamburger, because it is a display
   preference rather than a place to go. */
.theme-toggle {
    margin-left: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    padding: 0;
    flex-shrink: 0;
    color: var(--muted);
    background: none;
    border: 1px solid var(--line);
    border-radius: 999px;
    cursor: pointer;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}

.theme-toggle:hover {
    color: var(--text);
    background: var(--surface-3);
    border-color: var(--line-strong);
    transform: none;
}

/* display:flex above would otherwise beat the UA stylesheet's
   [hidden] { display: none }, showing a dead button when JS is off. */
.theme-toggle[hidden] { display: none; }

.theme-toggle svg { width: 1.05rem; height: 1.05rem; }

/* Each icon shows the theme you would switch TO, so the button reads as
   a destination rather than a status. Dark is the default, so the sun
   shows first; the light rules mirror the three-layer setup above and
   both have to be edited together. */
.theme-toggle .moon { display: none; }
.theme-toggle .sun { display: block; }

@media (prefers-color-scheme: light) {
    :root:not([data-theme]) .theme-toggle .sun { display: none; }
    :root:not([data-theme]) .theme-toggle .moon { display: block; }
}

:root[data-theme="light"] .theme-toggle .sun { display: none; }
:root[data-theme="light"] .theme-toggle .moon { display: block; }

main {
    width: 100%;
    max-width: 1020px;
    margin: 0 auto;
    padding: 2rem 1.5rem 3.5rem;
    flex: 1;
}

footer {
    margin-top: 2rem;
    background: var(--surface-2);
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 0.85rem;
    text-align: center;
    padding: 1.5rem 1.5rem 1.7rem;
}

footer strong { color: var(--text); font-weight: 600; }

/* ---------- typography ---------- */

h1, h2, h3 {
    color: var(--text);
    line-height: 1.2;
    letter-spacing: -0.025em;
}

h1 {
    font-size: 2.1rem;
    font-weight: 750;
    margin: 0 0 0.35rem;
}

h2 {
    font-size: 1.15rem;
    font-weight: 650;
    margin: 2.4rem 0 0.8rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--line);
}

h3 {
    font-size: 1rem;
    font-weight: 650;
    margin: 1.5rem 0 0.4rem;
}

a { color: var(--accent); }

a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, .menu-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

.muted { color: var(--muted); }

.page-head {
    margin-bottom: 1.9rem;
    padding-bottom: 1.1rem;
    border-bottom: 1px solid var(--line);
}

.page-head.with-logo {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.league-logo {
    display: block;
    /* ~25% up from the old 210px, scaling down with the viewport so
       it stays proportional to the heading text beside it */
    width: clamp(185px, 27vw, 262px);
    border-radius: var(--radius);
    border: 1px solid var(--line);
    flex-shrink: 0;
}

.page-head-text .pills { margin-bottom: 0; }
.page-head .muted { margin: 0.1rem 0 0.85rem; }

.pills { display: flex; gap: 0.4rem; flex-wrap: wrap; }

.pill {
    display: inline-block;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 0.35rem 0.95rem;
    font-size: 0.875rem;
    font-weight: 550;
    text-decoration: none;
    color: var(--text);
    background: var(--surface);
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.pill:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--on-accent);
}

/* ---------- site menu (one hamburger, small screens only) ---------- */

/* Pure CSS (checkbox hack), no JS. Hidden entirely on wide screens,
   where the header nav and the pills row do the job. */
.menu-toggle-checkbox {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.menu-toggle { display: none; }
.menu-panel { display: none; }

.menu-toggle-checkbox:focus-visible + .header-inner .menu-toggle {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ---------- league cards (home) ---------- */

.welcome {
    margin: 0 0 0.2rem;
    color: var(--muted);
    font-size: 0.95rem;
}

.welcome + h1 { margin-top: 0; }

.league-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: 1rem;
    margin-top: 1.25rem;
}

/* Dashboard grouped by league type. Direct-child selectors only: the
   cards inside each group have their own h2, which must keep its own
   margins. The first heading sits closer to the page title than a
   mid-page section would. */
.league-group:first-of-type > h2 { margin-top: 1.5rem; }

/* One grid cell: the card, plus the update action underneath it when a
   settled season is missing. The card is a link, so the action cannot be
   nested inside it. */
.league-slot {
    display: flex;
    flex-direction: column;
}

.league-slot > .league-card { flex: 1; }

.badge.stale {
    border-color: transparent;
    color: var(--gold);
    background: var(--gold-soft);
    text-transform: none;
}

.stale-note { margin: 0.45rem 0 0; }

.league-update {
    display: block;
    margin-top: 0.5rem;
    padding: 0.5rem 0.7rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-align: center;
    text-decoration: none;
    color: var(--accent);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    transition: border-color 0.18s, color 0.18s, background 0.18s;
}

a.league-update:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.league-update.disabled {
    color: var(--muted);
    background: transparent;
    border-style: dashed;
    font-size: 0.72rem;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
}

.league-group > h2 .group-count {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin-left: 0.5rem;
    vertical-align: 0.12em;
}

.league-card {
    display: block;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.3rem 1.4rem 1.4rem;
    text-decoration: none;
    color: var(--text);
    position: relative;
    overflow: hidden;
    transition: border-color 0.18s, background 0.18s, transform 0.18s;
}

.league-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: var(--accent);
    opacity: 0;
    transition: opacity 0.18s;
}

.league-card:hover {
    border-color: var(--line-strong);
    background: var(--surface-2);
    transform: translateY(-2px);
}

.league-card:hover::before { opacity: 1; }

.league-card h2 {
    margin: 0 0 0.25rem;
    border: none;
    padding: 0;
    font-size: 1.2rem;
    font-weight: 700;
}

.league-card p { margin: 0.35rem 0 0; }

.league-card .league-format {
    margin-top: 0.15rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
}

.reigning { font-size: 0.92rem; }

/* ---------- import flow: fork cards, platform tiles, era chips ---------- */

.crumbs {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 0 0 0.4rem;
}

.crumbs + h1 { margin-top: 0; }

.choice-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1rem;
    margin: 1.4rem 0 2.2rem;
}

.choice-card {
    display: block;
    text-align: center;
    padding: 2rem 1.5rem 1.9rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--text);
    transition: border-color 0.18s, background 0.18s, transform 0.18s;
}

.choice-card:hover {
    border-color: var(--accent);
    background: var(--surface-2);
    transform: translateY(-2px);
}

.choice-card .choice-mark {
    width: 64px;
    height: 64px;
    color: var(--accent);
    transition: transform 0.18s;
}

.choice-card:hover .choice-mark { transform: scale(1.08); }

.choice-card h2 {
    margin: 0.5rem 0 0.35rem;
    border: none;
    padding: 0;
    font-size: 1.4rem;
    font-weight: 700;
}

.choice-card p {
    margin: 0;
    color: var(--muted);
    font-size: 0.95rem;
}

.platform-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0.85rem;
    margin: 0.9rem 0 2rem;
}

.platform-tile {
    display: block;
    text-align: center;
    padding: 1.4rem 1rem 1.3rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    border-top: 3px solid var(--tint, var(--accent));
    text-decoration: none;
    color: var(--text);
    transition: border-color 0.18s, background 0.18s, transform 0.18s;
}

a.platform-tile:hover {
    border-color: var(--tint, var(--accent));
    background: var(--surface-2);
    transform: translateY(-2px);
}

.platform-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    margin: 0 auto 0.55rem;
    object-fit: contain;
    /* Shared with the monogram so a half-filled set (some platforms with
       a logo, some without) still reads as one row of tiles. */
    border-radius: 16px;
    transition: transform 0.18s;
}

a.platform-tile:hover .platform-mark { transform: scale(1.08); }

/* A dropped-in logo always sits on a white chip, in BOTH themes. Brand
   marks are fixed colors and most are drawn for light backgrounds: the
   NFL shield's navy would all but vanish on the dark tile, and a chip is
   the only thing that makes an arbitrary third-party file safe here
   without editing it. Consequence, documented in
   static/platforms/README.md: supply a logo that reads on white. */
img.platform-mark {
    background: #fff;
    padding: 7px;
    border: 1px solid var(--line);
}

.platform-monogram {
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--on-accent);
    background: var(--tint, var(--accent));
}

.platform-tile h2 {
    margin: 0 0 0.2rem;
    border: none;
    padding: 0;
    font-size: 1.05rem;
    font-weight: 650;
}

.platform-tile p { margin: 0; font-size: 0.875rem; color: var(--muted); }

.platform-tile .why {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--line);
    font-size: 0.85rem;
    text-align: left;
    color: var(--muted);
}

.choice-card.disabled, .platform-tile.disabled {
    opacity: 0.6;
    background: transparent;
    border-style: dashed;
}

.choice-card.disabled .choice-mark { color: var(--muted); }

.platform-tile.disabled .platform-monogram {
    background: var(--muted);
    opacity: 0.65;
}

.era-line { margin: 0.4rem 0 0; }

.era-chip {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    background: var(--surface-3);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 0.14rem 0.6rem;
    margin: 0.15rem 0.25rem 0.15rem 0;
    white-space: nowrap;
}

/* ---------- tables ---------- */

table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin: 0.6rem 0 1.75rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    overflow: hidden;
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
}

th, td {
    text-align: left;
    padding: 0.6rem 0.8rem;
    border-bottom: 1px solid var(--line);
}

/* Numbers carry the weight in this design, so they get the tighter
   tracking and the heavier face; prose columns stay normal. */
td { font-feature-settings: "tnum" 1; }

thead th {
    font-size: 0.72rem;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
}

/* No zebra striping: on dark, alternating fills fight the row dividers
   and make dense tables read as noise. A thin --line per row plus a
   hover fill is enough to track across. */
tbody tr { transition: background 0.12s; }
tbody tr:hover { background: var(--surface-3); }
tbody tr:last-child td { border-bottom: none; }

/* click-to-sort headers (tablesort.js) */
thead th.sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    transition: color 0.12s;
}

thead th.sortable::after {
    content: "\2195"; /* up-down arrow */
    margin-left: 0.3em;
    opacity: 0.4;
}

thead th.sortable:hover { color: var(--text); }

thead th.sort-asc::after {
    content: "\2191";
    opacity: 1;
    color: var(--accent);
}

thead th.sort-desc::after {
    content: "\2193";
    opacity: 1;
    color: var(--accent);
}

/* ---------- badges ---------- */

.badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 650;
    letter-spacing: 0.03em;
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 0.14rem 0.6rem;
    color: var(--muted);
    background: var(--surface-3);
    white-space: nowrap;
    text-transform: uppercase;
    vertical-align: middle;
}

.badge.champion, .badge.championship {
    border-color: transparent;
    color: var(--gold);
    background: var(--gold-soft);
}

.badge.sacko {
    border-color: transparent;
    color: var(--red);
    background: var(--red-soft);
}

/* Made the bracket. Existing tokens on purpose: --accent already has to
   pass AA as link text in both themes, and --accent-soft is a 12% wash
   over the surface under it, so this adds no color to re-check. */
.badge.playoffs {
    border-color: transparent;
    color: var(--accent);
    background: var(--accent-soft);
}

td.win { font-weight: 700; color: var(--text); }

/* A year inside a league's run with nothing imported. Present so the
   run reads continuously, recessed so it never reads as a season. */
.season-missing td {
    color: var(--muted);
    background: repeating-linear-gradient(
        135deg, transparent 0 6px, var(--surface-3) 6px 7px);
}

.season-missing td:first-child { font-variant-numeric: tabular-nums; }

/* ---------- head-to-head grid ---------- */

.h2h { font-size: 0.84rem; }
.h2h th { font-size: 0.72rem; }
.h2h td, .h2h th { padding: 0.35rem 0.4rem; text-align: center; }
.h2h thead th { writing-mode: initial; }
.h2h tbody th {
    text-align: left;
    font-size: 0.84rem;
    font-weight: 550;
    color: var(--text);
    text-transform: none;
    letter-spacing: 0;
}
.h2h td.self { color: var(--line-strong); background: var(--bg); }
.h2h td.lead { background: var(--green-soft); color: var(--green); font-weight: 600; }
.h2h td.trail { background: var(--red-soft); color: var(--red); font-weight: 600; }
.h2h a { text-decoration: none; font-weight: 600; }

/* ---------- trophy hall ---------- */

.trophy-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.85rem;
    margin: 0.9rem 0 2rem;
}

.trophy-card {
    display: block;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    border-top-width: 3px;
    padding: 1.1rem 0.6rem 1rem;
    text-align: center;
    text-decoration: none;
    color: var(--text);
    transition: border-color 0.18s, background 0.18s, transform 0.18s;
}

.trophy-card:hover {
    background: var(--surface-2);
    transform: translateY(-2px);
}

.trophy-card .icon {
    width: 44px;
    height: 44px;
    transition: transform 0.18s;
}

.trophy-card:hover .icon { transform: scale(1.12); }

.trophy-card.champion { border-top: 3px solid var(--gold); }
.trophy-card.champion .icon { color: var(--gold); }
.trophy-card.champion:hover { border-color: var(--gold); }

.trophy-card.sacko { border-top: 3px solid var(--red); }
.trophy-card.sacko .icon { color: var(--red); }
.trophy-card.sacko:hover { border-color: var(--red); }

.trophy-year {
    font-size: 1.3rem;
    font-weight: 750;
    letter-spacing: -0.03em;
    margin-top: 0.3rem;
}

.trophy-owner { font-weight: 600; }

.trophy-team {
    font-size: 0.8rem;
    margin-top: 0.1rem;
    color: var(--muted);
    overflow-wrap: break-word;
}

.trophy-card.scoring { border-top: 3px solid var(--accent); }
.trophy-card.scoring .icon { color: var(--accent); }
.trophy-card.scoring:hover { border-color: var(--accent); }

/* ---------- sparklines / analytics ---------- */

.spark-block { margin: 0.5rem 0 1rem; }
.spark-label { font-size: 0.85rem; margin-bottom: 0.1rem; }
.spark { display: block; height: 84px; }
.spark-line { fill: none; stroke: var(--accent); stroke-width: 2; }
.spark-dot { fill: var(--accent); }
.spark-dot.gold { fill: var(--gold); }
.spark-dot.red { fill: var(--red); }
.spark-text { font-size: 11px; fill: var(--muted); }

tr.robbed { background: var(--gold-soft); }

.name-list { line-height: 2.1; }
.name-entry {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 0.2rem 0.75rem;
    margin-right: 0.35rem;
    font-size: 0.9rem;
    white-space: nowrap;
    display: inline-block;
}

/* ---------- forms / admin ---------- */

input[type="text"], input[type="email"], input[type="password"], select {
    font: inherit;
    /* size="24" and friends set a character width that can exceed a phone
       screen; never let a field push the page sideways. */
    max-width: 100%;
    padding: 0.5rem 0.7rem;
    color: var(--text);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    transition: border-color 0.15s, box-shadow 0.15s;
}

input::placeholder { color: var(--muted); }

input[type="text"]:focus, input[type="email"]:focus,
input[type="password"]:focus, select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

button {
    font: inherit;
    font-weight: 650;
    letter-spacing: -0.01em;
    padding: 0.5rem 1.2rem;
    cursor: pointer;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--accent);
    color: var(--on-accent);
    transition: background 0.15s, transform 0.15s, filter 0.15s;
}

button:hover {
    background: var(--accent-dim);
    transform: translateY(-1px);
}

button.danger-link {
    background: none;
    border: none;
    color: var(--red);
    padding: 0;
    text-decoration: underline;
    font-size: 0.875rem;
    font-weight: 400;
    letter-spacing: 0;
}

button.danger-link:hover { transform: none; background: none; }

.danger-zone {
    margin-top: 2.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--line);
}

button.danger {
    color: var(--red);
    border: 1px solid var(--red);
    background: none;
}

button.danger:hover { background: var(--red-soft); }

.hints {
    font-size: 0.9rem;
    color: var(--muted);
    background: var(--surface);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    padding: 0.75rem 0.9rem 0.75rem 2rem;
    margin: 0.75rem 0 1.25rem;
}

.hints li { margin: 0.2rem 0; }

.notice {
    background: var(--gold-soft);
    border: 1px solid transparent;
    border-left: 3px solid var(--gold);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    padding: 0.75rem 1rem;
}

/* ---------- import console ---------- */

input[type="number"] {
    font: inherit;
    padding: 0.5rem 0.7rem;
    color: var(--text);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    width: 6rem;
}

.import-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.9rem;
    margin: 0.75rem 0 1.5rem;
}

.import-form label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.875rem;
    color: var(--muted);
}

.import-form button { padding: 0.5rem 1.5rem; }

.job-log {
    background: var(--code-bg);
    /* --code-fg, not --muted: this block stays dark in both themes, so
       its text cannot follow a token that flips to dark grey. */
    color: var(--code-fg);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 0.85rem 1.1rem;
    overflow-x: auto;
    font-family: var(--mono);
    font-size: 0.8rem;
    line-height: 1.6;
}

/* ---------- motion preferences ---------- */

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { transition: none !important; }
}

/* ---------- login ---------- */

.login-form {
    max-width: 22rem;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin-top: 1rem;
}

.login-form label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.875rem;
    color: var(--muted);
}

.login-form button { align-self: flex-start; padding: 0.5rem 1.4rem; }

.login-error {
    color: var(--red);
    background: var(--red-soft);
    border-radius: var(--radius-sm);
    padding: 0.6rem 0.9rem;
    max-width: 22rem;
}

.logout-form { display: inline; }

/* carries .nav-link too; just strip button chrome so it matches. Only
   font-family is inherited: the `font` shorthand would also reset size
   and weight, and because this rule comes after .nav-link it would win,
   rendering "Log out" a size larger than every link beside it. */
.logout-button {
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    line-height: inherit;
    color: var(--muted);
    letter-spacing: inherit;
}

.logout-button:hover {
    background: var(--surface-3);
    color: var(--text);
    transform: none;
}

/* ---------- scrollbar (webkit) ---------- */

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb {
    background: var(--line-strong);
    border-radius: 8px;
    border: 2px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* ---------- accounts: invites, your account, members ---------- */

/* The hint under a field in the login-shaped forms. Sits inside the
   label, so it has to stop inheriting the label's flex column gap. */
.field-hint {
    font-size: 0.8rem;
    color: var(--muted);
}

/* A freshly minted invite link: shown once, so it is hard to miss and
   easy to select. Breaks anywhere, since a token has no spaces. */
.token-shown {
    background: var(--accent-soft);
    border: 1px solid transparent;
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    padding: 0.9rem 1.1rem 1rem;
    margin: 1rem 0 1.5rem;
}

.token-shown h2 { margin-top: 0; }

.token-box {
    font-family: var(--mono);
    font-size: 0.85rem;
    line-height: 1.5;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 0.6rem 0.8rem;
    overflow-wrap: anywhere;
    user-select: all;
}

/* The address a league name will produce. Read-only text, not a field:
   nobody is asked to write one, it is shown so the URL is not a
   surprise. */
.slug-preview {
    font-size: 0.85rem;
    color: var(--muted);
    overflow-wrap: anywhere;
}

.slug-preview [data-slug-for] { color: var(--text); }

/* The override on a row an import guard stopped. Coloured like the
   warning it answers, so it does not read as an ordinary option. */
.confirm-check {
    color: var(--gold);
    font-weight: 600;
    white-space: nowrap;
}

.confirm-check input { accent-color: var(--gold); }

/* What the platform calls a league, under the editable name field. The
   name can be typed over, so this stays as the record of which league
   the id actually resolved to. */
.platform-name {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.78rem;
    color: var(--muted);
}

.account-facts { max-width: 34rem; }
.account-facts th { width: 9rem; text-align: left; }

.league-list { padding-left: 1.1rem; }
.league-list li { margin: 0.25rem 0; }

/* ---------- person profile ---------- */

/* An owner's name linking to their profile. A standings column of
   accent-colored links reads as a wall of teal, so these keep the text
   color and carry a quiet underline instead. The underline is always
   there, not just on hover: color alone is not an accessible way to
   mark a link, and hover does not exist on a phone. */
.person-link {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--line-strong);
    text-underline-offset: 0.15em;
    transition: color 0.15s, text-decoration-color 0.15s;
}

.person-link:hover {
    color: var(--accent);
    text-decoration-color: currentColor;
}

/* One card per league, never a combined view: each card is a closed box
   so the numbers inside it visibly belong to that league alone. */
.person-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.2rem 1.3rem 1.3rem;
    margin-bottom: 1.1rem;
}

.person-card-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.person-card-logo {
    width: 42px;
    height: 42px;
    object-fit: contain;
    border-radius: var(--radius-sm);
    flex: none;
}

.person-card-head h2 {
    margin: 0;
    padding: 0;
    border: none;
    font-size: 1.2rem;
    font-weight: 700;
}

.person-card-head h2 a { text-decoration: none; }
.person-card-head h2 a:hover { text-decoration: underline; }
.person-card-head p { margin: 0.15rem 0 0; font-size: 0.85rem; }

.person-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.9rem;
    margin: 1.1rem 0 0;
}

.person-stats div { min-width: 3.5rem; }

.person-stats dt {
    font-size: 0.7rem;
    font-weight: 650;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
}

.person-stats dd {
    margin: 0.15rem 0 0;
    font-size: 1.05rem;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
}

.person-note { margin: 0.7rem 0 0; font-size: 0.8rem; }

.person-card table { margin: 1.1rem 0 0; }
.person-card table tbody tr:last-child td { border-bottom: none; }

.person-links { margin: 1rem 0 0; font-size: 0.85rem; }
.person-links a { text-decoration: none; }
.person-links a:hover { text-decoration: underline; }

/* League access checkboxes: a bare list, no fieldset chrome, so a row
   of them reads as one cell rather than a nested box. */
.league-checks {
    border: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.league-checks legend {
    padding: 0;
    font-size: 0.875rem;
    color: var(--muted);
}

label.check {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.875rem;
    white-space: nowrap;
}

label.check input { margin: 0; accent-color: var(--accent); }

/* Start of a new platform account in the season-by-season owner editor.
   A heavier rule than the ordinary row divider, so one franchise's run
   of years reads as a block and a mid-run owner change is visible. */
.group-start td { border-top: 2px solid var(--line-strong); }

.members td { vertical-align: top; }
.members .via { color: var(--muted); font-size: 0.85rem; }

.member-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
}

/* ---------- small screens ---------- */

@media (max-width: 720px) {
    main { padding: 1.25rem 1rem 2.5rem; }
    h1 { font-size: 1.65rem; }

    /* Header: it is sticky, so every row it grows costs vertical space on
       every screen. Shrink the wordmark and tighten the padding so the
       bar stays as short as it can while keeping the full title. */
    .header-inner { padding: 0.5rem 1rem; gap: 0.3rem 0.6rem; }
    .brand { font-size: 1rem; gap: 0.4rem; }
    nav { flex-wrap: wrap; gap: 0.15rem; }
    .nav-link { padding: 0.5rem 0.7rem; font-size: 0.875rem; }

    /* Tables: the old rule forced nowrap on every cell, which made even
       narrow tables scroll. Only headers refuse to wrap now; numbers and
       records have no spaces to break at anyway, so in practice just the
       prose columns (team, owner, league) wrap, which is what should give
       on a phone. When a table still overflows, the first column pins so
       you never lose track of whose row you are reading. */
    table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
        font-size: 0.875rem;
    }

    th, td { padding: 0.55rem 0.6rem; }
    th { white-space: nowrap; }

    thead th:first-child, tbody td:first-child {
        position: sticky;
        left: 0;
        z-index: 1;
    }

    /* Sticky cells need their own opaque fill or the scrolling content
       shows through. With striping gone these are just the surface
       colors, but they must stay solid (not the alpha state tints). */
    thead th:first-child { background: var(--surface-2); }
    tbody td:first-child { background: var(--surface); }
    tbody tr:hover td:first-child { background: var(--surface-3); }

    /* Thumb-sized controls. The scoped button rules are listed too: they
       out-specify a bare `button` selector, so they need naming here. */
    button { padding: 0.65rem 1.3rem; }
    .theme-toggle { width: 2.75rem; height: 2.75rem; padding: 0; }
    .theme-toggle svg { width: 1.15rem; height: 1.15rem; }
    .import-form button, .login-form button { padding: 0.65rem 1.4rem; }
    .pill { padding: 0.55rem 1rem; }
    .league-update { padding: 0.7rem; font-size: 0.85rem; }

    /* The smallest labels are legible sizes on a phone. */
    .league-group > h2 .group-count { font-size: 0.75rem; }
    .era-chip { font-size: 0.75rem; }
    .league-update.disabled { font-size: 0.8rem; }
    .badge { font-size: 0.72rem; }

    /* Import screens: tiles two across instead of one tall column, and
       form fields full width so nothing can push the page sideways. */
    .platform-tiles {
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
        gap: 0.7rem;
    }

    .platform-mark { width: 50px; height: 50px; }
    .platform-tile h2 { font-size: 1rem; }
    .platform-tile { padding: 1.1rem 0.7rem 1rem; }
    .choice-card { padding: 1.5rem 1.1rem; }
    .import-form { gap: 0.7rem; }
    .import-form label { width: 100%; }
    .import-form input { width: 100%; }

    /* The invite form's league checkboxes are a fieldset, not a label,
       so they need naming to go full width with everything else. A
       checkbox must not stretch with them. */
    .import-form .league-checks { width: 100%; }
    .import-form .league-checks input { width: auto; }
    .token-box { font-size: 0.78rem; }

    /* One hamburger, upper left, ahead of the wordmark. The right-hand
       nav and the league pills row both fold into its panel, so there is
       never more than one menu on screen. */
    .header-inner { justify-content: flex-start; gap: 0.15rem 0.7rem; }
    nav { display: none; }
    .pills-nav { display: none; }

    .menu-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 2.6rem;
        height: 2.6rem;
        margin-left: -0.4rem;
        border-radius: var(--radius-sm);
        cursor: pointer;
        user-select: none;
        -webkit-tap-highlight-color: transparent;
    }

    /* One bar, plus two box-shadow copies above and below. */
    .menu-toggle span {
        display: block;
        width: 1.25rem;
        height: 2px;
        border-radius: 1px;
        background: var(--text);
        box-shadow: 0 6px 0 var(--text), 0 -6px 0 var(--text);
        transition: background 0.15s, box-shadow 0.15s;
    }

    .menu-toggle-checkbox:checked + .header-inner .menu-toggle {
        background: var(--surface-3);
    }

    .menu-toggle-checkbox:checked ~ .menu-panel {
        display: flex;
        flex-direction: column;
        padding: 0.4rem 0.75rem 0.9rem;
        border-top: 1px solid var(--line);
    }

    .menu-link {
        display: block;
        width: 100%;
        text-align: left;
        padding: 0.75rem 0.5rem;
        font-size: 0.95rem;
        font-weight: 550;
        color: var(--text);
        text-decoration: none;
        border-bottom: 1px solid var(--line);
    }

    /* the last row has no rule under it, whether it is a link or the
       form wrapping the logout button */
    .menu-panel > :last-child,
    .menu-panel > :last-child .menu-link { border-bottom: none; }

    /* the logout button, stripped back to look like the links */
    .menu-logout {
        background: none;
        border: none;
        border-bottom: 1px solid var(--line);
        border-radius: 0;
        letter-spacing: normal;
        color: var(--text);
        cursor: pointer;
    }

    .menu-logout:hover {
        background: var(--surface-3);
        transform: none;
    }

    .menu-divider {
        margin: 0.8rem 0 0.1rem;
        padding: 0 0.5rem;
        font-size: 0.72rem;
        font-weight: 650;
        text-transform: uppercase;
        letter-spacing: 0.07em;
        color: var(--muted);
    }
}
