/* BCC2 base styles. Mobile-first. */

:root {
    --bg: #3a3d40;         /* dark body — a shade darker than the charcoal panels */
    --fg: #faf6db;         /* cream body text */
    --muted: #b0aa95;      /* dimmed cream — secondary text */
    --accent: #e58572;     /* soft coral — links, headings, readable on charcoal */
    --accent-2: #e05a4c;   /* brighter red — live pill, hot accents */
    --accent-dark: #881f05;/* burnt red — solid fills (buttons, champ) */
    --line: #4a4d50;       /* subtle dark rule */
    --panel: #55595c;      /* main charcoal — primary panel bg */
    --panel-2: #45484b;    /* darker panel shade — zebra rows, nested */
    --neutral: #a8a59b;    /* warm desaturated grey — alias/inactive/separator bg */
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--fg);
    font: 16px/1.45 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* All buttons read uppercase for consistency. Single-glyph buttons
   (× rm, etc.) are unaffected; this applies via text-transform so
   the source case stays normal-cased and readable. */
button { text-transform: uppercase; letter-spacing: 0.04em; }
button.rm { text-transform: none; letter-spacing: normal; }

header.site, footer.site {
    padding: 14px 20px;
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
}
header.site {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--bg);
}
footer.site {
    border-bottom: 0;
    border-top: 1px solid var(--line);
    color: var(--muted);
    justify-content: center;
}

.brand {
    display: inline-flex;
    align-items: center;
    background: var(--fg);            /* cream — pops the dark logo on charcoal */
    padding: 6px 12px;
    border-radius: 8px;
}
.brand img {
    height: 36px;
    width: auto;
    display: block;
}

.crumbs {
    color: var(--muted);
    font-size: 18px;
    font-weight: 500;
    line-height: 1.2;
}
.crumbs .sep { margin: 0 8px; opacity: 0.5; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--fg); }
.crumbs .current { color: var(--accent); font-weight: 600; }
.crumbs .current.champ { color: var(--accent-2); font-style: italic; font-weight: 700; }

/* Header search — pinned to the right end of the header. On wide screens
   the input is always visible. On narrow screens it collapses to a
   magnifying-glass button that expands the input on tap. */
.search {
    position: relative;
    margin-left: auto;    /* push to the right edge of the flex header */
    display: flex;
    align-items: center;
}
.search input[type=search] {
    width: 260px;
    box-sizing: border-box;
    padding: 8px 12px;
    background: var(--panel-2);
    color: var(--fg);
    border: 1px solid var(--line);
    border-radius: 8px;
    font: inherit;
    outline: none;
}
.search input[type=search]:focus { border-color: var(--accent); }
.search-toggle {
    display: none;        /* hidden on desktop; shown on narrow */
    background: var(--panel-2);
    color: var(--fg);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 6px 8px;
    cursor: pointer;
    line-height: 0;
}
.search-toggle:hover { border-color: var(--accent); }
.search .results {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    width: 260px;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    z-index: 60;
}
.search .results.hidden { display: none; }
.search .hit {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 8px 12px;
    color: var(--fg);
    border-bottom: 1px solid var(--line);
}
.search .hit:last-child { border-bottom: 0; }
.search .hit:hover { background: var(--panel-2); text-decoration: none; }
.search .hit .kind {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    min-width: 50px;
}
.search .hit.league .kind  { color: var(--accent); }
.search .hit.season .kind  { color: var(--accent); }
.search .hit.game .kind    { color: var(--accent-2); }
.search .hit.player .kind  { color: var(--muted); }
.search .hit .name { color: var(--fg); }

/* Header account widget — sits to the right of the search box. */
.account {
    display: flex;
    align-items: center;
    gap: 6px;
}
.account-link {
    color: var(--fg);
    font-weight: 500;
    padding: 4px 10px;
    border-radius: 6px;
    background: var(--panel-2);
    border: 1px solid var(--line);
}
.account-link:hover { border-color: var(--accent); text-decoration: none; }
.account-logout button {
    display: inline-flex;
    align-items: center;
    background: var(--panel-2);
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 5px 8px;
    font: inherit;
    cursor: pointer;
    line-height: 0;
}
.account-logout button:hover { color: var(--accent-2); border-color: var(--accent-2); }
.account-signin {
    display: inline-flex;
    align-items: center;
    color: var(--fg);
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 5px 8px;
    line-height: 0;
}
.account-signin:hover { border-color: var(--accent); text-decoration: none; }

@media (max-width: 700px) {
    /* Tighter header: smaller gaps + padding so brand, search, and
       account fit together on one row without awkward wrapping. */
    header.site {
        gap: 10px;
        padding: 10px 14px;
    }
    .brand { padding: 4px 10px; }
    .brand img { height: 28px; }

    /* Crumbs always go to their own row below — they can be long
       enough to push the right-side widgets onto a third line. */
    .crumbs {
        order: 99;
        flex: 1 1 100%;
        font-size: 16px;
    }
    .crumbs .sep { margin: 0 5px; }

    .account-link { padding: 4px 8px; font-size: 14px; }
    .account-logout button { padding: 4px 9px; }

    /* Search: input collapses to a magnifying-glass button; tap to
       expand the input. While open, it takes the whole header so the
       brand/crumbs/account widgets get out of the way. */
    .search-toggle { display: inline-flex; align-items: center; }
    .search input[type=search] { display: none; }
    .search.open { flex: 1 1 100%; }
    .search.open .search-toggle { display: none; }
    .search.open input[type=search] { display: block; width: 100%; }
    .search.open .results { left: 0; right: 0; width: auto; }
    header.site:has(.search.open) > :not(.search) { display: none; }
}

main {
    max-width: 1000px;
    margin: 0 auto;
    padding: 20px 12px 40px;
}

h1 { margin: 0 0 16px; font-size: 28px; color: var(--accent); }

/* Championship games get the red + italic treatment wherever a game
   name appears (h1, list links, table links). */
.champ, .champ .game-name {
    color: var(--accent-2);
    font-style: italic;
    font-weight: 700;
}
a.champ:hover, a.champ:hover .game-name { color: var(--accent-2); }
h2 { margin: 0 0 12px; font-size: 18px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }

.panel {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 18px 20px;
    margin-bottom: 18px;
}

/* Per-game leaderboard panels on the season page — collapsed by default,
   the summary row styled to match the .panel h2 look. */
details.game-collapse > summary {
    cursor: pointer;
    font-size: 18px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    list-style: none;
}
details.game-collapse > summary::-webkit-details-marker { display: none; }
details.game-collapse > summary::before {
    content: '▸';
    display: inline-block;
    width: 1em;
    color: var(--muted);
    transition: transform 0.15s;
}
details.game-collapse[open] > summary::before { transform: rotate(90deg); }
details.game-collapse[open] > summary { margin-bottom: 12px; }

.meta {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
    color: var(--muted);
    font-size: 14px;
}
/* Spacing below .meta only matters when something follows it (e.g. on
   the game page). Inside a .panel where it's the only child, the panel's
   own padding handles spacing — adding margin-bottom here would make the
   bottom gap larger than the top. */
.meta:not(:last-child) { margin-bottom: 14px; }
.meta strong { color: var(--fg); font-weight: 600; }

.empty {
    color: var(--muted);
    padding: 12px 0;
}

code {
    background: var(--panel-2);
    padding: 2px 5px;
    border-radius: 3px;
    font-size: 14px;
    color: var(--fg);
}

.badge {
    display: inline-block;
    background: var(--accent-dark);
    color: white;
    font-size: 11px;
    font-weight: 700;
    padding: 3px 7px;
    border-radius: 4px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    vertical-align: middle;
    margin-left: 6px;
}
.badge.small { font-size: 10px; padding: 2px 5px; }
.badge.alias { background: var(--neutral); }

.status {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.status-scheduled { background: var(--panel-2); color: var(--muted); }
.status-live      { background: var(--accent-2); color: white; }
.status-complete  { background: #4a7c3a; color: white; }

.pc.up { color: #4a7c3a; font-weight: 600; margin-left: 4px; }
.pc.dn { color: var(--accent-2); font-weight: 600; margin-left: 4px; }

/* Season pot summary panel — sits above the championship/leaderboard. */
.pot-summary .pot-headline {
    font-size: 22px;
    font-weight: 600;
    color: var(--fg);
    margin: 4px 0 10px;
}
.pot-summary .pot-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 10px;
}
.pot-summary .pot-tile {
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 8px 12px;
}
.pot-summary .pot-tile .asset {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
.pot-summary .pot-tile .qty   { font-size: 15px; }
.pot-summary .pot-tile .value { font-size: 15px; font-weight: 600; margin-top: 2px; }

.pot-adjustments { margin-top: 14px; }
.pot-adjustments h3 {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    margin: 0 0 6px;
}
.pot-adjustments .mini-table { width: auto; font-size: 14px; }
.pot-adjustments .mini-table td { padding: 3px 10px 3px 0; }
.pot-adjustments .mini-table td.num { font-weight: 600; }
.pot-adjustments .mini-table td.num.up { color: #4a7c3a; }
.pot-adjustments .mini-table td.num.dn { color: var(--accent-2); }
.pot-adjustments .mini-table td.rm-cell form { display: inline; }
.pot-adjustments .add-adjustment {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 8px;
}
.pot-adjustments .add-adjustment input[type=text]   { flex: 1 1 220px; }
.pot-adjustments .add-adjustment input[type=number] { width: 120px; }
.pot-adjustments .add-adjustment input {
    font: inherit;
    padding: 6px 8px;
    border: 1px solid var(--line);
    border-radius: 5px;
    background: var(--bg);
    color: var(--fg);
}
.pot-adjustments .add-adjustment button {
    font: inherit;
    padding: 7px 14px;
    background: var(--accent-dark);
    color: white;
    border: 0;
    border-radius: 5px;
    cursor: pointer;
}

/* Game-attached pot adjustment: tucked under the "Invested:" line. */
.invest-adj {
    font-size: 13px;
    color: var(--muted);
    margin-left: 14px;
}
.invest-adj .amt         { font-weight: 600; margin-left: 4px; }
.invest-adj .amt.up      { color: #4a7c3a; }
.invest-adj .amt.dn      { color: var(--accent-2); }

/* Admin knockouts panel: mini-table + add form inline like pot adjustments. */
.ko-list tr.self-keep td em { font-style: italic; color: var(--muted); }
.add-knockout {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 8px;
    flex-wrap: wrap;
}
.add-knockout select,
.add-knockout input {
    font: inherit;
    padding: 6px 8px;
    border: 1px solid var(--line);
    border-radius: 5px;
    background: var(--bg);
    color: var(--fg);
}
.add-knockout input[type=number] { width: 160px; }
.add-knockout button {
    font: inherit;
    padding: 7px 14px;
    background: var(--accent-dark);
    color: white;
    border: 0;
    border-radius: 5px;
    cursor: pointer;
}

/* Free entries — asterisk + footnote on the results table, admin-only
   checkbox column for toggling. */
.free-mark       { color: var(--accent); margin-left: 1px; }
.improvement-badge {
    margin-left: 8px;
    padding: 1px 6px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: white;
    border-radius: 4px;
    white-space: nowrap;
}
.improvement-badge.most-improved  { background: #4a7c3a; }   /* green */
.improvement-badge.least-improved { background: var(--accent-2); }
.improvement-badge.bubble-boy     { background: #7a4a0f; }   /* muted amber — bubbled */
.improvement-badge.consolation    { background: #6a6f73; }   /* neutral gray */
.free-footnote   { color: var(--muted); font-size: 12px; margin: 6px 0 0; }
.free-col        { text-align: center; }
.free-col input  { margin: 0; cursor: pointer; }
.free-save       { margin-top: 8px; }

/* A pot-split row set to "remainder" — the value box is unused so grey it out. */
.pot-split-row.remainder input[type=number] { opacity: 0.45; }

/* Admin inline edit panels */
details.admin-edit {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 8px;
    margin: 0 0 16px;
    padding: 8px 14px;
}
details.admin-edit > summary {
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    padding: 4px 0;
}
details.admin-edit[open] > summary { margin-bottom: 10px; }
details.admin-edit form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px 14px;
    padding-bottom: 10px;
}
details.admin-edit label {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
/* Checkbox labels read "[ ] Text", not stacked. */
details.admin-edit label:has(> input[type=checkbox]) {
    flex-direction: row;
    align-items: center;
    gap: 6px;
}
details.admin-edit label.wide { grid-column: 1 / -1; }
/* Any direct child of an admin-edit form marked .wide spans every column.
   Without this, fieldsets / nested details that live next to single-column
   inputs end up overlapping awkwardly inside auto-fit grid cells. */
details.admin-edit > form > .wide { grid-column: 1 / -1; }
details.admin-edit input, details.admin-edit textarea, details.admin-edit select {
    font: inherit;
    padding: 6px 8px;
    border: 1px solid var(--line);
    border-radius: 5px;
    background: var(--bg);
    color: var(--fg);
    text-transform: none;
    letter-spacing: normal;
}
details.admin-edit .actions {
    grid-column: 1 / -1;
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    padding-top: 4px;
}
details.admin-edit button {
    font: inherit;
    padding: 7px 16px;
    background: var(--accent-dark);
    color: white;
    border: 0;
    border-radius: 5px;
    cursor: pointer;
}
details.admin-edit button:hover { filter: brightness(1.1); }

details.admin-edit .hint {
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--muted);
    margin-top: 2px;
}
details.admin-edit .hint code {
    font-size: 11px;
    padding: 1px 4px;
}
details.admin-edit .hint.wide { grid-column: 1 / -1; padding-top: 2px; }

/* Season-level "Default game settings" block — mirrors the structure of the
   game-level override, but nested under the season form. */
details.admin-edit fieldset.defaults-block {
    grid-column: 1 / -1;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 6px 12px 10px;
    margin: 4px 0 0;
    background: var(--bg);
}
details.admin-edit fieldset.defaults-block legend {
    padding: 0 6px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
details.admin-edit fieldset.defaults-block .defaults-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 8px 14px;
}
/* An inherited value (null on the game, falling back to season) reads
   dimmer than an explicit override — so the admin can see at a glance
   which fields this game has chosen to override. */
details.admin-edit fieldset.defaults-block label.field.inherited {
    opacity: 0.55;
}
details.admin-edit fieldset.defaults-block label.field.inherited select,
details.admin-edit fieldset.defaults-block label.field.inherited input {
    font-style: italic;
}

details.admin-edit fieldset.payout-schedule {
    grid-column: 1 / -1;
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 8px 12px 10px;
    margin: 4px 0 0;
    background: var(--bg);
}
details.admin-edit fieldset.payout-schedule legend {
    padding: 0 6px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
details.admin-edit fieldset.payout-schedule label.inline {
    flex-direction: row;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    margin: 4px 0 6px;
}
details.admin-edit fieldset.payout-schedule label.inline input { width: 80px; }
details.admin-edit table.mini-table {
    width: 100%;
    border-collapse: collapse;
    margin: 4px 0;
}
details.admin-edit table.mini-table th,
details.admin-edit table.mini-table td {
    padding: 3px 4px;
    text-align: left;
    border: 0;
}
details.admin-edit table.mini-table th {
    font-size: 11px;
    text-transform: uppercase;
    color: var(--muted);
}
details.admin-edit table.mini-table input,
details.admin-edit table.mini-table select {
    width: 100%;
    box-sizing: border-box;
}
details.admin-edit table.mini-table td:last-child  { width: 28px; text-align: center; }
details.admin-edit table.mini-table th.auto,
details.admin-edit table.mini-table td.auto { background: var(--panel-2); text-align: center; }
details.admin-edit table.mini-table td.first-cell { font-weight: 600; color: var(--accent-dark); }
details.admin-edit table.mini-table th.auto small { font-weight: 400; color: var(--muted); font-size: 10px; }

/* Payout grid: let each % input breathe, and scroll the table when the
   fieldset's own width is too narrow to fit every column. */
details.admin-edit fieldset.payout-schedule { overflow-x: auto; }
details.admin-edit table.payout-grid input[type=number] {
    text-align: right;
    min-width: 58px;
}
/* Hide the number-input spinners inside the payout schedule — admin always
   types the numbers in, so the up/down arrows just waste horizontal space. */
details.admin-edit fieldset.payout-schedule input[type=number] {
    -moz-appearance: textfield;
    appearance: textfield;
}
details.admin-edit fieldset.payout-schedule input[type=number]::-webkit-inner-spin-button,
details.admin-edit fieldset.payout-schedule input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
details.admin-edit button.rm, details.admin-edit button.add-row {
    font: inherit;
    padding: 3px 8px;
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: 4px;
    cursor: pointer;
}
details.admin-edit button.rm { padding: 1px 7px; font-size: 14px; line-height: 1; }
details.admin-edit button.add-row:hover { color: var(--accent-dark); border-color: var(--accent-dark); }

details.admin-edit .attend-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 4px 14px;
    padding: 6px 0;
}
details.admin-edit label.attend {
    flex-direction: row;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    text-transform: none;
    letter-spacing: normal;
    color: var(--fg);
}
details.admin-edit label.attend small { color: var(--muted); margin-left: auto; font-size: 11px; }

.hidden { display: none !important; }

/* Lists */
ul.seasons, ul.games {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 8px;
}
ul.seasons li a, ul.games li a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    color: var(--fg);
}
ul.seasons li a:hover, ul.games li a:hover {
    border-color: var(--accent);
    text-decoration: none;
}
.season-name, .game-name { font-weight: 600; }
.season-range, .game-when { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

/* Tables */
table.leaderboard, table.results {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}
table.leaderboard th, table.results th,
table.leaderboard td, table.results td {
    padding: 8px 10px;
    text-align: left;
    border-bottom: 1px solid var(--line);
}
table.leaderboard th, table.results th {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 600;
    border-bottom: 1px solid var(--line);
}
table .num { text-align: right; }
table tbody tr:hover { background: rgba(255,255,255,0.05); }
table tr.alias td { color: var(--muted); font-style: italic; }

/* All-time leaderboard: cut at top 10 publicly; admins see the long tail
   below a heavier divider, dimmed so it reads as secondary. */
tr.leaderboard-divider td {
    padding: 0;
    border-bottom: 3px double var(--accent-dark);
}
tr.below-cut td { color: var(--muted); }

/* Homepage "next game" banner — countdown to cards-up + link to the
   current season. */
.home-next { padding: 14px 18px; }
.home-next-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}
.home-next-label {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    font-weight: 700;
}
.home-next-season {
    font-size: 13px;
    color: var(--accent);
    font-weight: 600;
}
.home-next-season:hover { text-decoration: none; color: var(--accent-2); }
.home-next-link {
    display: block;
    color: var(--fg);
}
.home-next-link:hover { text-decoration: none; }
.home-next-when {
    font-size: 18px;
    color: var(--muted);
    margin-bottom: 4px;
}
.home-next-countdown {
    font-size: 30px;
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.home-next-empty .home-next-label { color: var(--muted); }

/* Payouts preview block — label on top, pair row below. The pair row
   never wraps; instead, the rank/cash text and inter-pair gap scale
   with viewport width via clamp() so a long row of payouts squishes
   to fit instead of breaking onto a second line. */
.payouts-preview {
    margin: 0 0 16px;
    padding: 10px 14px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    overflow: hidden;
}
.payouts-preview .label {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
}
.payouts-preview .pairs {
    display: flex;
    flex-wrap: nowrap;
    align-items: baseline;
    gap: clamp(6px, 2.5vw, 18px);
    min-width: 0;
}
.payouts-preview .pair {
    display: inline-flex;
    align-items: baseline;
    gap: clamp(3px, 1vw, 6px);
    flex: 0 0 auto;
    white-space: nowrap;
}
.payouts-preview .rank {
    font-size: clamp(9px, 2.2vw, 11px);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
}
.payouts-preview .cash {
    font-size: clamp(14px, 4.5vw, 20px);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
}

/* RSVP status icons in the season-leaderboard cells of upcoming games.
   The clock is an inline SVG (using currentColor) instead of an emoji
   so the color rule actually takes effect; the rest are plain text
   glyphs that respect color out of the box. */
.rsvp-icon         { font-weight: 700; line-height: 1; }
.rsvp-icon svg     { vertical-align: -2px; }
.rsvp-icon-in      { color: #2e7d32; }
.rsvp-icon-late    { color: #8fd17a; }
.rsvp-icon-out     { color: var(--accent-2); }
.rsvp-icon-unknown { color: var(--muted); }

/* Player avatars — circular images with a textured grey placeholder
   when the player hasn't uploaded one yet. */
.avatar {
    display: inline-block;
    vertical-align: middle;
    border-radius: 50%;
    overflow: hidden;
    flex: 0 0 auto;
    object-fit: cover;
    background: var(--panel-2);
}
.avatar-sm { width: 22px; height: 22px; }
.avatar-md { width: 36px; height: 36px; }
.avatar-lg { width: 80px; height: 80px; }
.avatar-placeholder {
    background-color: #4a4d50;
    background-image:
        radial-gradient(circle at 20% 25%, rgba(255,255,255,0.05) 0 1px, transparent 1px),
        radial-gradient(circle at 70% 60%, rgba(255,255,255,0.04) 0 1px, transparent 1px),
        radial-gradient(circle at 40% 80%, rgba(0,0,0,0.10) 0 1px, transparent 1px),
        linear-gradient(135deg, rgba(255,255,255,0.03), transparent 60%);
    background-size: 6px 6px, 8px 8px, 5px 5px, 100% 100%;
}

/* Inline player rows: avatar + name on a baseline. Used everywhere
   players are listed (RSVP buckets, leaderboards, etc.). */
.player-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.player-link .avatar { vertical-align: middle; }

/* Player edit form: avatar preview alongside the file input. Spans
   the full form width because the file input chrome doesn't fit
   neatly inside a half-width grid cell. */
.avatar-field {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    grid-column: 1 / -1;
    max-width: 100%;
    min-width: 0;
}
.avatar-field-input {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 0;
    min-width: 0;
}
.avatar-field input[type=file] {
    font-size: 13px;
    max-width: 100%;
}

.player-header { display: flex; align-items: center; gap: 18px; }
.player-header h2 { margin: 0 0 4px; font-size: 22px; color: var(--fg); text-transform: none; letter-spacing: 0; }
.player-header-meta { flex: 1; }

/* Inline avatar prompt shown right after a player RSVPs, when they
   haven't uploaded one yet. */
.rsvp-avatar-prompt {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    margin: 14px 0;
}
.rsvp-avatar-prompt-text { display: flex; flex-direction: column; min-width: 0; }
.rsvp-avatar-prompt input[type=file] { font-size: 13px; max-width: 100%; min-width: 0; flex: 1 1 0; }

/* When the game-body partial is embedded on the season page, paint a
   full-bleed band behind it so it stands out from the season info
   without eating horizontal space with a card border. The negative-
   margin / matching-padding trick extends the background to the
   viewport edges while the content stays in main's normal column. */
.embedded-game {
    background: var(--neutral);
    margin-left:  calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 12px calc(50vw - 50%);
    margin-bottom: 16px;
}

/* RSVP panel — four status buckets across the top, the player's own
   action row below, an admin manage section after that. */
.rsvp-buckets {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}
.rsvp-bucket {
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 10px 12px;
}
.rsvp-bucket h3 {
    margin: 0 0 6px;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 600;
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.rsvp-bucket h3 .count {
    background: var(--panel);
    color: var(--fg);
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 11px;
}
.rsvp-bucket ul { list-style: none; padding: 0; margin: 0; }
.rsvp-bucket li { padding: 2px 0; }
.rsvp-bucket .empty { color: var(--muted); margin: 0; font-size: 13px; }
.rsvp-bucket.rsvp-in    h3 { color: #8fd17a; }
.rsvp-bucket.rsvp-late  h3 { color: var(--accent); }
.rsvp-bucket.rsvp-out   h3 { color: var(--accent-2); }

.rsvp-mine {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 12px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: 8px;
    /* Single source of truth for the vertical gap between buckets,
       the player's own action row, and the admin manage panel. */
    margin: 14px 0;
}

/* Attention-grabbing pulse when the logged-in user hasn't RSVPed yet
   for the game they're looking at. The keyframe spends most of its
   cycle dim, then briefly flares a soft accent ring so it nudges the
   eye without strobing. */
@keyframes rsvp-attention {
    0%, 70%, 100% {
        box-shadow: 0 0 0 0 rgba(229, 133, 114, 0);
        border-color: var(--line);
    }
    35% {
        box-shadow: 0 0 0 5px rgba(229, 133, 114, 0.35);
        border-color: var(--accent);
    }
}
.rsvp-mine--needs-rsvp {
    animation: rsvp-attention 3.5s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .rsvp-mine--needs-rsvp { animation: none; border-color: var(--accent); }
}
.rsvp-btn {
    background: var(--panel);
    color: var(--fg);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 6px 12px;
    font: inherit;
    cursor: pointer;
}
.rsvp-btn:hover { border-color: var(--accent); }
.rsvp-btn.current {
    background: var(--accent-dark);
    border-color: var(--accent-dark);
    color: white;
}
.rsvp-btn.rm:hover { border-color: var(--accent-2); color: var(--accent-2); }

.rsvp-list td { padding: 4px 10px 4px 0; }
.rsvp-list .rm-cell { width: 1%; }
.rsvp-add { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.invite-toggle-all-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    user-select: none;
}

@media (max-width: 600px) {
    .rsvp-buckets { grid-template-columns: 1fr; }
}

/* Location block in the game edit form. The "+ Add a new location"
   inputs stay hidden until the dropdown switches to "new". */
.location-block #new-location-fields { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 8px; }
.location-block #new-location-fields.hidden { display: none; }
.meta .addr { color: var(--muted); }

/* Outbound messaging — flash banner after a redirect, plus the inline
   send-invite form on the player edit panel. */
.flash {
    background: var(--panel);
    border: 1px solid var(--accent);
    color: var(--fg);
    padding: 8px 14px;
    border-radius: 8px;
    margin-bottom: 14px;
}
.send-invite,
.link-telegram { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.send-invite input[type=text] { flex: 1 1 240px; }

/* Game-page mass-invite button: lives between the player's RSVP row and
   the admin manage panel. */
.mass-invite {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    /* Same vertical rhythm as .rsvp-mine — 14px above and below. */
    margin: 14px 0;
}
.mass-invite button {
    background: var(--accent-dark);
    color: white;
    border: 0;
    border-radius: 6px;
    padding: 8px 14px;
    font: inherit;
    cursor: pointer;
}
.mass-invite button:hover { filter: brightness(1.1); }

/* Login page — SMS form + Telegram bot link. Phone input mirrors the
   header search input so the page reads consistently. */
.login-sms { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.login-sms input[type=tel] {
    box-sizing: border-box;
    padding: 8px 12px;
    background: var(--panel-2);
    color: var(--fg);
    border: 1px solid var(--line);
    border-radius: 8px;
    font: inherit;
    outline: none;
}
.login-sms input[type=tel]:focus { border-color: var(--accent); }
.btn-link {
    display: inline-block;
    background: var(--accent-dark);
    color: white;
    padding: 8px 14px;
    border: 0;
    border-radius: 6px;
    font: inherit;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    cursor: pointer;
}
.btn-link:hover { filter: brightness(1.1); text-decoration: none; }

/* Tables — horizontal scroll on narrow screens */
.panel:has(table) { overflow-x: auto; }

/* Matrix leaderboard: wide tables with a narrow per-game column.
   The containing panel drops its horizontal padding so the matrix table
   extends to the panel edges regardless of viewport width or how many
   games the season has. */
.panel:has(table.matrix) { padding: 0; overflow: hidden; }
.panel:has(table.matrix) > .scroller { overflow-x: auto; }
/* The matrix panel zeroes its own padding so the wide table can run
   edge-to-edge in its scroller. Inset siblings (the payout-preview
   strips) need their own margins on every side; vertical margins
   collapse so stacked strips don't double-space. */
.panel:has(table.matrix) > .payouts-preview { margin: 14px; }

table.matrix th, table.matrix td { padding: 3px 5px; vertical-align: middle; font-size: 13px; }
table.matrix thead tr:first-child th { font-size: 11px; }
table.matrix th a { color: var(--fg); }
table.matrix th a:hover { color: var(--accent-dark); }
/* Dropped-score cells: grayed out so the "best N of M" rule is visible. */
table.matrix td.dropped { color: var(--muted); }
/* Zebra shading on every other game column to aid scanning up/down. */
table.matrix th.alt, table.matrix td.alt { background: rgba(255,255,255,0.05); }

/* Admin-only champ-player override column. Tri-state segmented control. */
table.matrix .col-override { text-align: center; min-width: 96px; }
.tri {
    display: inline-flex;
    border: 1px solid var(--line);
    border-radius: 999px;
    overflow: hidden;
    background: var(--bg);
}
.tri input { position: absolute; opacity: 0; pointer-events: none; }
.tri label {
    cursor: pointer;
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    user-select: none;
}
.tri label:has(input:checked) { color: white; }
.tri label:nth-child(1):has(input:checked) { background: var(--accent-2); }
.tri label:nth-child(2):has(input:checked) { background: var(--neutral); }
.tri label:nth-child(3):has(input:checked) { background: #4a7c3a; }
.override-actions {
    padding: 10px 12px;
    display: flex;
    justify-content: flex-end;
}
.override-actions button {
    font: inherit;
    padding: 7px 16px;
    background: var(--accent-dark);
    color: white;
    border: 0;
    border-radius: 5px;
    cursor: pointer;
}

/* Edge columns are sticky-pinned on each side; the middle game-score
   columns scroll horizontally underneath them. None of these have
   min-widths — the JS at the bottom of the season view measures their
   actual content widths on load and writes them into the CSS vars
   below, so the sticky offsets always track the real layout. */
table.matrix .col-rank,
table.matrix .col-player,
table.matrix .col-points,
table.matrix .col-stack,
table.matrix .col-override {
    position: sticky;
    z-index: 2;
    background: var(--panel-2);
}
table.matrix .col-rank   { left: 0; }
table.matrix .col-player { left: var(--col-rank-w, 0); box-shadow: 2px 0 6px rgba(0,0,0,0.4); }
table.matrix .col-points { right: 0; box-shadow: -2px 0 6px rgba(0,0,0,0.4); }
table.matrix .col-stack    { right: 0; }
table.matrix .col-override { right: 0; box-shadow: -2px 0 6px rgba(0,0,0,0.4); }
/* When optional right-edge columns are present, scoot the inner ones
   leftward by the dynamic width of the columns to their right. The
   rightmost keeps the box-shadow; inner ones drop it. */
table.matrix.has-stack    .col-points    { right: var(--col-stack-w, 0); box-shadow: none; }
table.matrix.has-stack    .col-stack     { box-shadow: -2px 0 6px rgba(0,0,0,0.4); }
table.matrix.has-override .col-points    { right: var(--col-stack-plus-override-w, 0); box-shadow: none; }
table.matrix.has-override .col-stack     { right: var(--col-override-w, 0); box-shadow: none; }
/* Hover background carries to sticky cells too. */
table.matrix tbody tr:hover .col-rank,
table.matrix tbody tr:hover .col-player,
table.matrix tbody tr:hover .col-points,
table.matrix tbody tr:hover .col-stack,
table.matrix tbody tr:hover .col-override {
    background: var(--panel-2);
}
/* Prize stacks under the rank number so the column can stay narrow. */
.col-rank .rank-prize {
    display: block;
    font-size: 11px;
    font-weight: 600;
    color: var(--accent);
    line-height: 1.1;
}
/* Sub-header row: month labels beneath each game column. */
table.matrix thead tr.sub th {
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.04em;
    padding: 4px 8px;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    text-transform: none;
}

/* Tournament clock — big-and-loud panel above the game body. State line
   ("CARDS UP IN" / "LEVEL N" / "PAUSED") on top, fat time digits in the
   middle, blinds + level notes underneath, and a thin progress bar
   showing how far into the current level we are. */
.game-clock {
    background: linear-gradient(180deg, #131821 0%, #0e1218 100%);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 22px 18px 16px;
    margin: 0 0 18px;
    text-align: center;
    color: var(--fg);
    position: relative;
    overflow: hidden;
}
.game-clock-state {
    font-size: clamp(20px, 4vw, 36px);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 8px;
    line-height: 1.1;
}
.game-clock-time {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    /* JS rewrites font-size on every tick + on resize to fill the panel
       width. The max() here is the fallback if JS fails to load — no
       upper cap, so the digits grow with the viewport. */
    font-size: max(56px, 14vw);
    line-height: 1;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--accent);
    white-space: nowrap;
    overflow: hidden;
}
.game-clock-blinds {
    margin-top: 6px;
    /* JS rewrites font-size on every tick + on resize to fill the panel
       width, just like the time digits. The max() is the no-JS fallback —
       no upper cap. */
    font-size: max(28px, 8vw);
    line-height: 1;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--fg);
    white-space: nowrap;
    overflow: hidden;
    text-align: center;
}
.game-clock-blinds .sb,
.game-clock-blinds .bb { font-weight: 700; }
.game-clock-blinds .sep {
    color: var(--muted);
    margin: 0 0.15em;
    font-weight: 400;
}
/* Level/break notes — a small subordinate line under the headline. */
.game-clock-notes {
    margin-top: 6px;
    font-size: 12px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    min-height: 1em;
}
.game-clock-notes:empty { display: none; }
.game-clock-progress {
    margin: 18px auto 6px;
    height: 8px;
    width: 100%;
    max-width: 480px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 4px;
    position: relative;
    /* No overflow:hidden — the playhead marker on the bar deliberately
       extends taller than the track. */
}
.game-clock-progress-bar {
    display: block;
    height: 100%;
    width: 0;
    background: var(--accent);
    border-radius: 4px 0 0 4px;
    position: relative;
    transition: width 0.5s linear;
}
/* Vertical playhead at the boundary between completed and remaining
   time. Sticks above and below the track for emphasis. */
.game-clock-progress-bar::after {
    content: '';
    position: absolute;
    right: -2px;
    top: -7px;
    bottom: -7px;
    width: 4px;
    background: var(--accent);
    border-radius: 2px;
}
/* Small "Next: X / Y" or "Next: 20m Break" line under the progress bar. */
.game-clock-next {
    margin-top: 10px;
    font-size: clamp(16px, 2.4vw, 24px);
    color: var(--muted);
    letter-spacing: 0.04em;
    min-height: 1em;
}
.game-clock-next:empty { display: none; }
/* Pre-game state: nothing to track yet, so suppress the progress bar
   and the "Next:" tease until cards are up. */
.game-clock--pre-game .game-clock-progress,
.game-clock--pre-game .game-clock-next { display: none; }
.game-clock-pause {
    margin-top: 14px;
}
.game-clock-pause button {
    font-size: 12px;
    letter-spacing: 0.08em;
    padding: 6px 16px;
}
.game-clock--final .game-clock-time { color: var(--muted); }
.game-clock--preview {
    border-color: var(--accent-2);
    box-shadow: 0 0 0 1px rgba(224, 90, 76, 0.25) inset;
}
.game-clock-preview-flag {
    position: absolute;
    top: 6px;
    right: 8px;
    font-size: 10px;
    letter-spacing: 0.12em;
    color: var(--accent-2);
    text-transform: uppercase;
    font-weight: 700;
}

/* Page-wide mute toggle pinned to bottom-left. Starts in the muted state
   (X icon, dimmed). One click anywhere on the site swaps to the speaker
   icon and unmutes; thereafter clicking the button toggles. */
.bcc-mute {
    position: fixed;
    left: 12px;
    bottom: 12px;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: rgba(20, 24, 30, 0.85);
    color: var(--fg);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 50;
    padding: 0;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.bcc-mute:hover { color: var(--accent); }
.bcc-mute .bcc-mute-on,
.bcc-mute .bcc-mute-off { display: none; }
.bcc-mute[data-muted="0"] .bcc-mute-on  { display: block; }
.bcc-mute[data-muted="1"] .bcc-mute-off { display: block; color: var(--muted); }

/* Blind structure editor inside Edit Game. Nested <details> so it
   stays collapsed by default; the preset bar / grid / save-as-preset
   block only render when the admin opens it. */
details.blind-editor { margin-top: 4px; }
details.blind-editor > summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    padding: 6px 0;
    user-select: none;
}
details.blind-editor[open] > summary { color: var(--fg); margin-bottom: 8px; }
.blind-preset-bar {
    display: flex;
    gap: 10px;
    align-items: end;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.blind-preset-bar label { display: flex; flex-direction: column; gap: 4px; }
.blind-preset-bar select { min-width: 180px; }
.blind-preset-delete:disabled { opacity: 0.4; cursor: not-allowed; }
.blind-grid { width: 100%; }
.blind-grid th { text-align: left; font-size: 11px; letter-spacing: 0.06em; color: var(--muted); }
.blind-grid td.lv { width: 32px; color: var(--muted); font-variant-numeric: tabular-nums; }
.blind-grid td input[type="number"][name$="[mins]"] { min-width: 5ch;  padding-left: 4px; padding-right: 2px; }
.blind-grid td input[type="number"][name$="[big]"]  { min-width: 10ch; padding-left: 4px; padding-right: 2px; }
.blind-grid tr.is-break td input[type="number"][name$="[big]"] { display: none; }
.blind-grid td input[type="text"]   { width: 100%; min-width: 140px; }
.blind-grid td.rm-cell { width: 24px; }
/* Beats the generic last-child width on admin-edit mini-tables. The
   column shrinks to fit the buttons; the inner flex div holds spacing
   constant regardless of whitespace between the button tags. */
details.admin-edit table.mini-table td.row-controls {
    width: 1%;
    white-space: nowrap;
    padding-left: 6px;
}
.blind-grid .row-ctrl {
    display: flex;
    justify-content: flex-end;
    gap: 2px;
}
.blind-grid .row-ctrl .row-mv,
.blind-grid .row-ctrl .rm {
    flex: 0 0 auto;
    background: transparent;
    border: 1px solid var(--line);
    color: var(--muted);
    width: 24px;
    height: 24px;
    padding: 0;
    border-radius: 4px;
    cursor: pointer;
    line-height: 1;
    font-size: 14px;
}
.blind-grid .row-ctrl .row-mv:hover,
.blind-grid .row-ctrl .rm:hover { color: var(--fg); border-color: var(--accent); }
.blind-grid-actions { margin: 8px 0 14px; }
.blind-preset-save {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    border-top: 1px dashed var(--line);
    padding-top: 10px;
}
.blind-preset-save .blind-preset-name { flex: 0 1 220px; }
.blind-preset-save .hint { flex-basis: 100%; }

