/*
 * Poker Night series admin shell — host sign-in panel for the series hub and
 * the series viewer.
 *
 * Same purple Series identity as hub.css / series.css (App05 PokerNight
 * AccentPurple.xaml): AccentColor #5B50D6, AccentDark #493EB5,
 * AccentForegroundDark #C4B5FD, gradient #766CF0 -> #5B50D6, washes
 * #211E49/#5F58A5 dark and #F0EFFF/#B8B2EF light. Dark-first with a
 * prefers-color-scheme: light override. External file only (CSP style-src 'self').
 *
 * SELF-CONTAINED ON PURPOSE. hub.css and series.css use the same palette under
 * different token names — --accent is the raw brand fill in hub.css but the
 * accent TEXT colour in series.css — so borrowing either vocabulary would make
 * this sheet render differently on the two pages. Every colour below comes from
 * its own --adm-* token instead.
 *
 * UR5 SCOPING RULE (enforced by tests/series-admin.test.cjs): apart from the
 * two :root blocks, which declare --adm-* custom properties and nothing else,
 * every selector in this file requires an ".adm" element. Those elements exist
 * only when series-admin-ui.js mounts the panel, so a visitor who never signs
 * in gets byte-for-byte the page they got before this file existed.
 */

:root {
    --adm-panel-bg: #211e49;
    --adm-panel-border: #5f58a5;
    --adm-fg: #f5f5f5;
    --adm-muted: #aeaeb2;
    --adm-accent-text: #c4b5fd;
    --adm-input-bg: rgba(16, 16, 18, 0.6);
    --adm-input-border: #5f58a5;
    /* Container borders (--adm-input-border) are decorative: the box they draw
     * is never the only thing identifying what is inside it. A TEXT FIELD's
     * border is different — it is the whole of the visual information marking
     * where the field is, so WCAG 1.4.11 asks for 3:1 against what it sits on
     * and --adm-input-border measures 2.30:1 dark / 1.91:1 light against the
     * field fill. This token exists so the fields can clear that without
     * darkening every note and section box on the panel. Measured against the
     * composited field fill: dark #c4b5fd on #171628 = 9.70:1, light #5b50d6
     * on #fcfcff = 5.89:1. Both colours are already in the palette. */
    --adm-field-border: #c4b5fd;
    /* Gradient fill behind white 800-weight label text on every primary button
     * and the host badge. The stops are contrast-bounded, not decorative: white
     * on the ORIGINAL light stop #766CF0 measures 4.06:1, which fails AA 4.5:1
     * for text this size (14.4px bold is below the 18.66px large-text
     * threshold). #6A5FE6 keeps the same gradient reading and measures 4.78:1;
     * the dark stop #5B50D6 measures 5.89:1. Both stops are declared once and
     * shared by the light and dark themes, so a future change cannot fix one
     * and leave the other failing. */
    --adm-grad-a: #6a5fe6;
    --adm-grad-b: #5b50d6;
    --adm-on-accent: #ffffff;
    --adm-focus: #766cf0;
    --adm-ok: #56c46e;
    --adm-danger: #ff9d96;
    --adm-wash: rgba(91, 80, 214, 0.12);
    --adm-shadow: 0 18px 50px rgba(0, 0, 0, 0.30);
    /* The gate sits on the PAGE background, not on the panel, so its colours
     * are measured against the page rather than --adm-panel-bg. The page fill
     * is #101012 dark / #ffffff light, overlaid by two radial washes; the
     * strongest stop is rgba(118, 108, 240, 0.16) dark and
     * rgba(118, 108, 240, 0.14) light, so the darkest/lightest composite the
     * gate can ever sit on is #201f36 dark and #ebeafd light. Every figure
     * below is measured against THAT composite, not the flat fill:
     *   dark  link #c4b5fd on #201f36 = 7.97:1 · note #aeaeb2 = 6.50:1
     *   light link #493eb5 on #ebeafd = 7.65:1 · note #555555 = 6.28:1 */
    --adm-gate-fg: #c4b5fd;
    --adm-gate-fg-strong: #ddd6fe;
    --adm-gate-note: #aeaeb2;
    /* Page plate underlay for the unlocked shell. The key-art field sits on
     * top of this colour; the light theme drops the plate entirely and shows
     * the flat wash instead, so this token is themed (declared twice). */
    --adm-field: #0a0f1e;
    /* Bar chrome (top bar, save bar, tab bar): flat underlay, gradient stops,
     * bottom border and the 1px blue glow line. The bars keep the dark
     * navy treatment in BOTH themes — same declared-once-shared rule as
     * --adm-grad-a/-b above, so one theme cannot drift from the other.
     * Contrast, measured against the lighter gradient stop #101a33 (the
     * worst case — #0a1122 is darker): white badge text 17.2:1,
     * --adm-accent-text #c4b5fd 10.1:1, --adm-muted #aeaeb2 7.8:1. All
     * clear AA 4.5:1 with room. */
    --adm-bar-bg: #15132b;
    --adm-bar-a: #101a33;
    --adm-bar-b: #0a1122;
    --adm-bar-border: #2b3c72;
    --adm-bar-glow: rgba(41, 121, 255, 0.35);
}

@media (prefers-color-scheme: light) {
    :root {
        --adm-panel-bg: #f0efff;
        --adm-panel-border: #b8b2ef;
        --adm-fg: #0f0f11;
        --adm-muted: #555555;
        --adm-accent-text: #493eb5;
        --adm-input-bg: rgba(255, 255, 255, 0.9);
        --adm-input-border: #b8b2ef;
        --adm-field-border: #5b50d6;
        --adm-focus: #5b50d6;
        --adm-ok: #2e7d32;
        --adm-danger: #a1120b;
        --adm-wash: rgba(91, 80, 214, 0.08);
        --adm-shadow: 0 14px 40px rgba(31, 26, 84, 0.10);
        --adm-gate-fg: #493eb5;
        --adm-gate-fg-strong: #3a3190;
        --adm-gate-note: #555555;
        --adm-field: #f0efff;
    }
}

/* ---- Panel shell ------------------------------------------------------- */

.adm {
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: clamp(14px, 2vh, 22px) clamp(14px, 2.4vw, 24px);
    background: var(--adm-panel-bg);
    border: 1px solid var(--adm-panel-border);
    border-radius: 14px;
    box-shadow: var(--adm-shadow);
    color: var(--adm-fg);
    font-size: clamp(0.9rem, 1.6vw, 1rem);
}

.adm * { box-sizing: border-box; }

/* The panel and its parts rely on the `hidden` attribute; make it win over the
 * explicit display values above (same rule and rationale as hub.css). */
.adm[hidden],
.adm [hidden] { display: none !important; }

.adm-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

/* The app icon beside the panel heading (decorative, empty alt): the brand
 * without re-typesetting the wordmark. */
.adm-head-icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    flex: 0 0 auto;
}

.adm-title {
    margin: 0;
    margin-right: auto;
    font-size: clamp(1rem, 2vw, 1.15rem);
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--adm-accent-text);
}

.adm-title:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: 3px;
    border-radius: 4px;
}

.adm-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    padding: 0.3em 0.85em;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--adm-on-accent);
    background: linear-gradient(90deg, var(--adm-grad-a), var(--adm-grad-b));
    border-radius: 999px;
}

.adm-badge::before {
    content: "●";
    font-size: 0.7em;
}

/* ---- Form + controls ---------------------------------------------------- */

.adm-form,
.adm-editor,
.adm-session,
.adm-conflict,
.adm-handoff {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
}

.adm-session {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 16px;
}

.adm-session-line {
    margin: 0;
    color: var(--adm-muted);
}

.adm-countdown { font-variant-numeric: tabular-nums; }

.adm-label {
    display: block;
    margin: 0;
    font-weight: 600;
}

.adm-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.adm-input,
.adm-select,
.adm-textarea {
    min-width: 0;
    width: 100%;
    min-height: 46px;
    padding: 0.6em 0.9em;
    font: inherit;
    color: var(--adm-fg);
    background: var(--adm-input-bg);
    border: 1px solid var(--adm-field-border);
    border-radius: 11px;
}

/* flex-basis is a MAIN-AXIS size. Most fields sit directly in the section
 * body, a COLUMN flex container, where a 200px basis becomes 200px of HEIGHT —
 * the giant vertically-centred boxes of the first release. The basis therefore
 * applies only inside .adm-row, the one place the main axis is horizontal. */
.adm-row .adm-input,
.adm-row .adm-select {
    width: auto;
    flex: 1 1 200px;
}

/* Selects drop the native chrome so the field treatment above actually shows,
 * and draw their own chevron — the native arrow over a custom fill is exactly
 * the "dropdowns are hard to see" report. The chevron is a data: URI (allowed
 * by img-src) in the palette's own accent, one per scheme. */
.adm-select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 2.6em;
    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 1.5 6 6.5 11 1.5' fill='none' stroke='%23c4b5fd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.9em center;
}

@media (prefers-color-scheme: light) {
    .adm-select {
        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 1.5 6 6.5 11 1.5' fill='none' stroke='%235b50d6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    }
}

.adm-pin {
    letter-spacing: 0.3em;
    font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace;
}

.adm-code {
    letter-spacing: 0.22em;
    text-transform: uppercase;
    font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace;
}

.adm-textarea {
    width: 100%;
    min-height: 96px;
    resize: vertical;
    line-height: 1.45;
}

.adm-input[aria-invalid="true"] { border-color: var(--adm-danger); }

.adm-input:focus-visible,
.adm-select:focus-visible,
.adm-textarea:focus-visible,
.adm-button:focus-visible,
.adm-link:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: 2px;
}

.adm-button {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.55em;
    min-height: 46px;
    padding: 0.6em 1.5em;
    font: inherit;
    font-weight: 800;
    letter-spacing: 0.03em;
    text-decoration: none;
    color: var(--adm-on-accent);
    background: linear-gradient(90deg, var(--adm-grad-a), var(--adm-grad-b));
    border: 0;
    border-radius: 11px;
    cursor: pointer;
    transition: filter 0.15s ease, box-shadow 0.15s ease;
}

.adm-button:hover {
    filter: brightness(1.08);
    color: var(--adm-on-accent);
    text-decoration: none;
}

.adm-button:disabled {
    opacity: 0.6;
    cursor: default;
    box-shadow: none;
}

.adm-button-ghost {
    color: var(--adm-accent-text);
    background: transparent;
    border: 1px solid var(--adm-input-border);
}

.adm-button-ghost:hover { color: var(--adm-accent-text); }

.adm-link {
    padding: 0.3em 0;
    font: inherit;
    font-weight: 600;
    color: var(--adm-accent-text);
    background: none;
    border: 0;
    border-radius: 4px;
    cursor: pointer;
    text-decoration: underline;
}

.adm-spinner {
    width: 1em;
    height: 1em;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #ffffff;
    border-radius: 50%;
    animation: adm-spin 0.7s linear infinite;
}

@keyframes adm-spin { to { transform: rotate(360deg); } }

/* ---- Supporting text ---------------------------------------------------- */

.adm-help {
    margin: 0;
    font-size: clamp(0.78rem, 1.4vw, 0.9rem);
    color: var(--adm-muted);
}

.adm-status {
    margin: 0;
    min-height: 1.3em;
    font-weight: 600;
}

.adm-status[data-kind="error"] { color: var(--adm-danger); }
.adm-status[data-kind="error"]::before { content: "\26A0 "; }
.adm-status[data-kind="warn"] { color: var(--adm-danger); }
.adm-status[data-kind="ok"] { color: var(--adm-ok); }
.adm-status[data-kind="ok"]::before { content: "\2713 "; }
.adm-status[data-kind="pending"] { color: var(--adm-muted); }

.adm-caps {
    margin: 0;
    padding: 0.7em 0.9em;
    font-size: clamp(0.78rem, 1.4vw, 0.9rem);
    color: var(--adm-fg);
    background: var(--adm-wash);
    border: 1px dashed var(--adm-input-border);
    border-radius: 10px;
}

.adm-conflict {
    padding: 0.8em 0.9em;
    background: var(--adm-wash);
    border: 1px solid var(--adm-danger);
    border-radius: 11px;
}

.adm-conflict-text {
    margin: 0;
    font-weight: 600;
}

/* ---- Edit surfaces (P6) -------------------------------------------------- */

/* Each editor is a native <details>: keyboard operation, roles and a focusable
 * summary for free, and a six-editor panel that does not bury the leaderboard. */

.adm-sections {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.adm-section {
    background: var(--adm-wash);
    border: 1px solid var(--adm-input-border);
    border-radius: 11px;
}

.adm-section-head {
    padding: 0.7em 0.9em;
    font-weight: 700;
    color: var(--adm-accent-text);
    cursor: pointer;
    list-style: revert;
}

.adm-section-head:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: -2px;
    border-radius: 11px;
}

.adm-section-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0 0.9em 0.9em;
    border-top: 1px solid var(--adm-input-border);
    padding-top: 0.8em;
}

/* Narrow means narrow ACROSS, wherever the field sits: max-width in the column
 * flow (where a flex BASIS would set the height, not the width), a matching
 * basis when it lands in a row. */
.adm-narrow {
    max-width: 9rem;
    flex: 0 1 auto;
}

.adm-row .adm-narrow { flex: 0 1 9rem; }

.adm-label-inline {
    font-weight: 400;
    flex: 1 1 14rem;
}

.adm-confirm {
    align-items: flex-start;
    gap: 8px;
}

.adm-check {
    /* 24px is the WCAG 2.2 target-size minimum, and a checkbox has no padding
       to borrow from — the box IS the target. The blind-ladder rows and the
       confirmation checkboxes all measured 18px before this. */
    width: 24px;
    height: 24px;
    min-width: 24px;
    min-height: 24px;
    margin: 0.2rem 0 0;
    accent-color: var(--adm-grad-b);
}

.adm-check:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: 2px;
}

/* Wide editors scroll inside their own box; the panel itself never does. */
.adm-table-wrap {
    max-width: 100%;
    overflow-x: auto;
}

.adm-table {
    width: 100%;
    border-collapse: collapse;
    font-size: clamp(0.78rem, 1.4vw, 0.9rem);
}

.adm-table th {
    padding: 0.35em 0.5em;
    text-align: left;
    font-weight: 700;
    color: var(--adm-muted);
    white-space: nowrap;
}

.adm-table td {
    padding: 0.25em 0.5em;
    vertical-align: middle;
}

.adm-tr + .adm-tr td { border-top: 1px solid var(--adm-input-border); }

.adm-cell {
    width: auto;
    min-width: 5.5rem;
    min-height: 40px;
    padding: 0.35em 0.5em;
    flex: 0 0 auto;
}

/* Inputs in a table size to their column, not to the panel: a date is a date
 * wide, a multiplier is two characters and a chevron. Without these the table
 * columns stretch to fill an ultra-wide panel and the row reads as four
 * scattered islands. */
.adm-table .adm-input[type="date"] { max-width: 11rem; }
.adm-table select.adm-cell { max-width: 7.5rem; }

.adm-cell-seq,
.adm-cell-status {
    color: var(--adm-muted);
    white-space: nowrap;
}

/* Status as a quiet chip, so Upcoming / In progress / Finished scan as states
 * rather than as another run of table text. Same fg/bg pair as .adm-note, so
 * no new contrast figure is introduced. */
.adm-status-chip {
    display: inline-block;
    padding: 0.25em 0.8em;
    font-size: 0.85em;
    font-weight: 600;
    color: var(--adm-fg);
    background: var(--adm-wash);
    border: 1px solid var(--adm-input-border);
    border-radius: 999px;
    white-space: nowrap;
}

.adm-col-action { text-align: right; }

.adm-note {
    margin: 0;
    padding: 0.7em 0.9em;
    font-size: clamp(0.78rem, 1.4vw, 0.9rem);
    color: var(--adm-fg);
    background: var(--adm-panel-bg);
    border: 1px solid var(--adm-input-border);
    border-radius: 10px;
}

.adm-note-lock { border-style: dashed; }

.adm-note-warn { border-color: var(--adm-danger); }

.adm-derived {
    font-variant-numeric: tabular-nums;
    color: var(--adm-fg);
}

.adm-input:disabled,
.adm-select:disabled,
.adm-textarea:disabled,
.adm-check:disabled { opacity: 0.55; }

.adm-link:disabled {
    opacity: 0.55;
    cursor: default;
    text-decoration: none;
}

/* ---- P9: account actions (change PIN, unpublish) ------------------------- */

/* Two <details> disclosures sharing the editors' visual language, so the panel
   reads as one surface — but they are NOT snapshot editors: they act on the
   share itself. Kept below the editors because one of them destroys it. */
.adm-account {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* The confirmation half of the unpublish flow. Same treatment as .adm-conflict
   — a danger-bordered box on the panel wash — because it asks the same kind of
   question: an irreversible choice that needs reading before it is answered. */
.adm-confirm-box {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0.8em 0.9em;
    background: var(--adm-wash);
    border: 1px solid var(--adm-danger);
    border-radius: 11px;
}

/* The destructive action is deliberately the OUTLINED button and "Keep it
   published" is the filled one: a gradient fill reads as the recommended
   action, and deleting the page the whole group is reading is not that.
   Measured against the composited background it actually sits on
   (--adm-wash over --adm-wash over --adm-panel-bg, alpha included):
   dark  #ff9d96 on #2e296a = 6.40:1
   light #a1120b on #d9d6f9 = 5.75:1
   Both pass AA 4.5:1 for the 14.4px 800-weight label, and the 1px border
   clears the 3:1 non-text minimum by the same margin. */
.adm-button-danger {
    color: var(--adm-danger);
    background: transparent;
    border: 1px solid var(--adm-danger);
}

.adm-button-danger:hover {
    color: var(--adm-danger);
    filter: none;
    background: var(--adm-wash);
}

/* The spinner's fixed white borders are invisible on an outlined button, so
   both ghost variants take the panel's own border colour for the ring and the
   button's text colour for the moving head. Plain colours, no color-mix: this
   sheet ships to whatever browser the host's group happens to use. */
.adm-button-ghost .adm-spinner,
.adm-button-danger .adm-spinner {
    border-color: var(--adm-input-border);
    border-top-color: currentColor;
}

/* ---- Motion / narrow screens -------------------------------------------- */

@media (max-width: 520px) {
    .adm-button,
    .adm-select,
    .adm-input { flex: 1 1 auto; }
}

@media (prefers-reduced-motion: reduce) {
    .adm-spinner { animation: none; }
    .adm-button { transition: none; }
}

/* ---- P7: roster, prize split, table setup -------------------------------- */

/* An informational note, distinct from .adm-note-warn: it explains a boundary
   of the product rather than a hazard, so it borrows the accent rather than the
   danger colour. Both keep the panel's own foreground, so contrast is the
   panel's measured pair and not a new one. */
.adm-note-info { border-color: var(--adm-accent-text); }

/* Read-only term/value pairs (the finance surface). A <dl> rather than a table
   because these are definitions, not a grid, and a screen reader announces the
   pairing without any ARIA. */
.adm-readout {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: 0.35em 1em;
    margin: 0;
}

.adm-readout-key {
    margin: 0;
    font-size: clamp(0.78rem, 1.4vw, 0.9rem);
    color: var(--adm-muted);
}

.adm-readout-value {
    margin: 0;
    font-variant-numeric: tabular-nums;
    color: var(--adm-fg);
}

@media (max-width: 420px) {
    .adm-readout { grid-template-columns: minmax(0, 1fr); gap: 0 0; }
    .adm-readout-value { margin-bottom: 0.5em; }
}

.adm-roster-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15em;
}

.adm-roster-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75em;
    padding: 0.35em 0;
}

.adm-roster-row + .adm-roster-row { border-top: 1px solid var(--adm-input-border); }

/* A long name wraps rather than pushing Remove off the panel. */
.adm-roster-name-text {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* 44px of hit area without a visible box, so the row stays a list and the
   control still meets the touch-target guidance. */
.adm-roster-remove {
    flex: 0 0 auto;
    min-height: 44px;
    padding-inline: 0.25em;
}

.adm-place-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5em 0.75em;
}

.adm-place-cell {
    display: flex;
    flex-direction: column;
    gap: 0.2em;
}

.adm-label-small {
    font-size: clamp(0.72rem, 1.3vw, 0.82rem);
    color: var(--adm-muted);
}

/* The blind ladder is the widest thing in the panel; it scrolls inside its own
   .adm-table-wrap, and the panel itself never scrolls sideways. */
.adm-blind-table .adm-input { min-width: 5rem; }

/* A colour swatch is its own affordance; it keeps the field border for the
   3:1 boundary rule and a 44px target, but no text padding. */
.adm-chip-color {
    width: 56px;
    height: 44px;
    padding: 4px;
    background: var(--adm-input-bg);
    border: 1px solid var(--adm-field-border);
    border-radius: 11px;
    cursor: pointer;
}

.adm-chip-color:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: 2px;
}

/* ---- Rich text editor (grand prize, notes) ------------------------------- */

/* The editor shares the input treatment — same fill, same 3:1 field border —
   so it reads as a field that happens to have a toolbar, not a new widget. */
.adm-rte {
    width: 100%;
    background: var(--adm-input-bg);
    border: 1px solid var(--adm-field-border);
    border-radius: 11px;
    overflow: hidden;
}

.adm-rte:focus-within {
    outline: 2px solid var(--adm-focus);
    outline-offset: 2px;
}

.adm-rte[aria-disabled="true"] { opacity: 0.55; }

.adm-rte-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    padding: 4px 6px;
    border-bottom: 1px solid var(--adm-input-border);
}

.adm-rte-tool {
    /* 32x32 clears the WCAG 2.2 24x24 target minimum with optical margin. */
    min-width: 32px;
    min-height: 32px;
    padding: 0 6px;
    font: inherit;
    font-size: 0.9em;
    font-weight: 700;
    color: var(--adm-accent-text);
    background: none;
    border: 0;
    border-radius: 7px;
    cursor: pointer;
}

.adm-rte-tool:hover { background: var(--adm-wash); }

.adm-rte-tool:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: -1px;
}

.adm-rte-tool:disabled { opacity: 0.55; cursor: default; }

.adm-rte-tool-italic { font-style: italic; }
.adm-rte-tool-underline { text-decoration: underline; }

.adm-rte-area {
    min-height: 96px;
    max-height: 40vh;
    padding: 0.6em 0.9em;
    overflow-y: auto;
    line-height: 1.45;
    color: var(--adm-fg);
    outline: none;
}

/* Block spacing INSIDE the editor mirrors the viewer's .rich-text rules, so
   what the host sees while typing is what the leaderboard shows. */
.adm-rte-area h1,
.adm-rte-area h2,
.adm-rte-area h3 {
    margin: 0.5em 0 0.25em;
    font-weight: 800;
    line-height: 1.25;
}

.adm-rte-area h1 { font-size: 1.3em; }
.adm-rte-area h2 { font-size: 1.15em; }
.adm-rte-area h3 { font-size: 1em; }

.adm-rte-area p { margin: 0 0 0.4em; }
.adm-rte-area p:last-child { margin-bottom: 0; }

.adm-rte-area ul,
.adm-rte-area ol {
    margin: 0.25em 0;
    padding-left: 1.4em;
}

/* ---- The header door: Manage season -------------------------------------- */

/* The prominent counterpart to the quiet footer gate: a filled button in the
   viewer's own header bar. Same gradient and white-on-accent pair as
   .adm-button, so its contrast is already measured; only the scale differs —
   header chrome, not a form action. */
.adm-manage {
    min-height: 40px;
    padding: 0.45em 1.1em;
    font-size: clamp(0.8rem, 1.4vw, 0.95rem);
}

/* ---- Live tournament (P8.2) ---------------------------------------------
 *
 * Same --adm-* vocabulary as the rest of the panel; no new colour is introduced,
 * so every contrast figure already measured for this sheet still holds. The
 * only new constraints are target sizes: a live board is operated fast, often
 * one-handed, and a mis-tap knocks out the wrong player.
 */

.adm-subhead {
    margin: 1.1em 0 0.4em;
    font-size: clamp(0.9rem, 1.6vw, 1rem);
    font-weight: 800;
    letter-spacing: 0.02em;
    color: var(--adm-fg);
}

.adm-tourney-headline {
    margin: 0.2em 0 0.6em;
    font-weight: 700;
    color: var(--adm-fg);
}

/* Server-computed figures. Laid out as a definition-style list so a screen
   reader reads "label, value" pairs rather than a run of loose numbers. */
.adm-tourney-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.4rem;
    margin: 0 0 0.8em;
    padding: 0;
    list-style: none;
}

.adm-tourney-stat {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 6.5rem;
}

.adm-tourney-stat-label {
    font-size: clamp(0.7rem, 1.2vw, 0.78rem);
    color: var(--adm-muted);
}

.adm-tourney-stat-value {
    font-size: clamp(0.95rem, 1.8vw, 1.15rem);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--adm-fg);
}

.adm-tourney-list,
.adm-tourney-order,
.adm-tourney-picker {
    margin: 0 0 0.6em;
    padding: 0;
    list-style: none;
}

.adm-tourney-order { counter-reset: none; }

.adm-tourney-row,
.adm-tourney-order-row,
.adm-tourney-pick-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    /* 44px keeps every row comfortably past the WCAG 2.2 24x24 minimum even
       where the row itself is the hit area. */
    min-height: 44px;
    padding: 0.3em 0;
}

.adm-tourney-row + .adm-tourney-row,
.adm-tourney-order-row + .adm-tourney-order-row,
.adm-tourney-pick-row + .adm-tourney-pick-row {
    border-top: 1px solid var(--adm-input-border);
}

.adm-tourney-row-name {
    flex: 1 1 8rem;
    font-weight: 600;
    color: var(--adm-fg);
    overflow-wrap: anywhere;
}

.adm-tourney-row-meta {
    flex: 0 0 auto;
    font-size: clamp(0.72rem, 1.3vw, 0.82rem);
    font-variant-numeric: tabular-nums;
    color: var(--adm-muted);
}

/* The place is never the ONLY thing distinguishing a row — the player's name
   sits beside it — so the muted tone here carries emphasis, not meaning. */
.adm-tourney-place {
    flex: 0 0 3rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--adm-accent-text);
}

.adm-tourney-row-actions {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.adm-tourney-act {
    min-height: 44px;
    padding: 0.45em 0.9em;
    font-size: clamp(0.75rem, 1.3vw, 0.85rem);
}

.adm-tourney-row-out .adm-tourney-row-name { font-weight: 500; }

.adm-tourney-anon,
.adm-tourney-size {
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
}

/* The confirmation step for anything irreversible. Given the panel's warning
   treatment so it cannot be mistaken for an ordinary row, and never auto-
   focused on its own Confirm button. */
.adm-tourney-confirm {
    flex-direction: column;
    gap: 0.6rem;
    margin: 0.6em 0;
    padding: 0.8em 0.9em;
    background: var(--adm-wash);
    border: 1px solid var(--adm-field-border);
    border-radius: 12px;
}

.adm-confirm-text {
    margin: 0;
    font-weight: 600;
    color: var(--adm-fg);
}

.adm-tourney-total {
    margin: 0.4em 0 0.8em;
    font-variant-numeric: tabular-nums;
}

.adm-tourney-clock-state {
    margin: 0.5em 0;
    font-weight: 600;
    color: var(--adm-fg);
}

.adm-tourney-payouts td { padding-top: 0.3em; padding-bottom: 0.3em; }

.adm-check-row {
    align-items: center;
    gap: 0.6rem;
}

/* ---- The blind clock, run from here ------------------------------------ */

/* CONTRAST. Every pair below is measured against the COMPOSITED console fill,
 * not against --adm-panel-bg: the console sits on --adm-wash, which is
 * translucent (rgba(91,80,214,.12) dark / .08 light), so the real backdrop is
 * #28245a dark and #e4e2fc light. Measured on those:
 *   --adm-accent-text  7.63:1 dark · 6.28:1 light   (the countdown)
 *   --adm-fg          12.93:1 dark · 15.12:1 light  (blinds, pills)
 *   --adm-muted        6.37:1 dark ·  5.89:1 light  (ante, next level)
 * All clear AA 4.5:1 for body text, and the countdown clears the 3:1 large-text
 * bar many times over.
 *
 * --adm-ok is deliberately NOT used for the running state: it measures 4.05:1
 * on the light console fill and would fail. Nothing here signals state by
 * colour alone anyway — the pill says "Running", "Paused" or "Finished" in
 * words, which is what a screen reader and a colour-blind host both need. */
.adm-tourney-clock-console {
    margin: 0.7em 0;
    padding: 0.9em 1em;
    background: var(--adm-wash);
    border: 1px solid var(--adm-input-border);
    border-radius: 14px;
}

.adm-tourney-clock-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.adm-tourney-clock-pill {
    padding: 0.25em 0.7em;
    color: var(--adm-fg);
    font-size: clamp(0.75rem, 1.4vw, 0.9rem);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border: 1px solid var(--adm-input-border);
    border-radius: 999px;
}

/* State is carried by the word inside the pill; the border is a second,
   redundant cue rather than the only one. */
.adm-tourney-clock-run.adm-is-paused { border-style: dashed; }
.adm-tourney-clock-run.adm-is-ended { border-color: var(--adm-field-border); }

/* The countdown. This panel is the host's console, not the room's display —
   the full-screen clock page is one tap away and is what the table reads from
   across the room. Even so this is sized to be legible at arm's length and
   from a seat or two away: it floors at 2.5rem (40px) on the narrowest phone
   and reaches 5rem (80px) on a laptop. Tabular figures stop the line jittering
   as the digits change, which is what makes a countdown tiring to watch. */
.adm-tourney-clock-timer {
    margin: 0.1em 0 0.05em;
    color: var(--adm-accent-text);
    font-size: clamp(2.5rem, 9vw, 5rem);
    font-weight: 800;
    line-height: 0.95;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.adm-tourney-clock-blinds {
    margin: 0;
    color: var(--adm-fg);
    font-size: clamp(1.15rem, 3.4vw, 1.8rem);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.adm-tourney-clock-ante,
.adm-tourney-clock-next {
    margin: 0.15em 0 0;
    color: var(--adm-muted);
    font-size: clamp(0.85rem, 1.7vw, 1rem);
}

/* Heard, never seen: the level and blinds are announced once per level, so a
   screen reader is not read a new number every quarter second. */
.adm-tourney-clock-spoken {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.adm-tourney-clock-controls {
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.7em;
}

/* WCAG 2.2 target size: 44px, comfortably over the 24px floor, because these
   are pressed mid-hand with a room waiting. */
.adm-tourney-clock-act {
    min-height: 44px;
    padding: 0.45em 0.9em;
    font-size: clamp(0.75rem, 1.3vw, 0.85rem);
}

.adm-tourney-clock-summary {
    margin: 0.3em 0 0.5em;
    color: var(--adm-muted);
    font-size: 13px;
}

.adm-tourney-clock-levels { margin: 0.4em 0; }

.adm-tourney-clock-levels-head {
    cursor: pointer;
    color: var(--adm-accent-text);
    font-weight: 600;
    /* The disclosure triangle is small; give the whole summary a real target. */
    min-height: 44px;
    display: flex;
    align-items: center;
}

.adm-tourney-clock-level-list {
    margin: 0.4em 0;
    padding: 0;
    list-style: none;
}

.adm-tourney-clock-level-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem;
    padding: 0.45em 0;
    border-top: 1px solid var(--adm-input-border);
}

.adm-tourney-clock-level-name {
    flex: 1 1 5rem;
    color: var(--adm-fg);
    font-weight: 600;
    font-size: 13px;
}

.adm-tourney-clock-level-cell {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    /* A basis rather than a width so four cells wrap onto a phone instead of
       overflowing the row. */
    flex: 0 1 5.5rem;
}

.adm-tourney-clock-level-label {
    color: var(--adm-muted);
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.adm-tourney-clock-level-input {
    min-height: 44px;
    font-variant-numeric: tabular-nums;
}

/* ---- The gate: host sign-in, made findable ----------------------------- */

/* The ONE thing this stylesheet renders for a visitor who never signs in.
 * It is appended after the page footer as the last child of <main>, in footer
 * type and footer colours, so it reads as site chrome rather than as part of
 * the leaderboard. It carries no box of its own: a bordered control here would
 * need a 3:1 boundary (WCAG 1.4.11) against a page background that varies with
 * the hero wash, and would shout at players who have no reason to press it. An
 * underlined text button carries its own contrast and needs no boundary. */
.adm-gate {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 2px 10px;
    margin: 0;
    text-align: center;
    font-size: clamp(0.72rem, 1.3vw, 1rem);
    line-height: 1.5;
}

.adm-gate-button {
    flex: 0 0 auto;
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    /* WCAG 2.2 SC 2.5.8: the target must clear 24x24. The padding takes the
     * rendered box past 34px tall at every clamp step, and min-width holds the
     * short axis if the label is ever translated shorter. */
    padding: 8px 6px;
    min-height: 24px;
    min-width: 24px;
    background: none;
    border: 0;
    border-radius: 8px;
    font: inherit;
    font-weight: 600;
    color: var(--adm-gate-fg);
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.adm-gate-button:hover { color: var(--adm-gate-fg-strong); }

.adm-gate-button:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: 2px;
}

.adm-gate-note {
    flex: 0 1 auto;
    margin: 0;
    color: var(--adm-gate-note);
}

/* ---- Panel dismiss ------------------------------------------------------ */

.adm-close {
    flex: 0 0 auto;
    appearance: none;
    -webkit-appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 32x32 clears SC 2.5.8's 24x24 with room for the glyph's optical centre. */
    width: 32px;
    height: 32px;
    margin: -4px -6px -4px 0;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 8px;
    font-size: 1.25rem;
    line-height: 1;
    /* #aeaeb2 on #211e49 = 6.97:1 dark; #555555 on #f0efff = 6.57:1 light. */
    color: var(--adm-muted);
    cursor: pointer;
}

.adm-close:hover { color: var(--adm-fg); }

.adm-close:focus-visible {
    outline: 2px solid var(--adm-focus);
    outline-offset: 2px;
}
