/* Phase 6 — Shared CSS Foundation (D-07) */
/* Extracted from web/login.html, web/dashboard.html, web/group.html */

/* Phase 06.1 — FOUC prevention: i18n.js sets data-i18n-pending on <html> before
   the catalog fetch and removes it once the catalog is applied. This rule hides
   the body during that window so untranslated French text never flashes. */
html[data-i18n-pending] body { visibility: hidden; }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Reset & Base */
/* ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* T106 — Flag-emoji web font. Browsers that can't render Unicode regional-
   indicator flag emoji (notably Windows Chrome/Edge/Firefox) show bare two-letter
   codes ("AR", "FR", "GB"). We self-host the MIT-licensed TwemojiCountryFlags
   color font (COLR/CPAL) and put it FIRST in the font stacks below. The
   `unicode-range` restricts it to flag glyphs only (regional indicators + the
   black-flag tag-sequence range used by GB-ENG/GB-SCT), so it never touches
   non-flag text or the 🌍 earth emoji. The font is always defined — no runtime
   feature detection — and degrades gracefully: if the woff2 fails to load, or the
   browser already renders flags natively for a glyph the font lacks, the browser
   falls through per-glyph to the next family (native emoji). On Mac/iOS/Android
   this means flags render in Twemoji style instead of the native set, which is an
   accepted, consistent trade-off. */
@font-face {
    font-family: 'Twemoji Country Flags';
    src: url('/assets/fonts/TwemojiCountryFlags.woff2') format('woff2');
    font-display: swap;
    unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E0063, U+E0065,
                   U+E0067, U+E006C, U+E006E, U+E0073-E0074, U+E0077, U+E007F;
}

body {
    font-family: 'Twemoji Country Flags', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 20px;
}

/* T106 — Flag-emoji web font for form controls. Form controls don't inherit the
   body font in the UA stylesheet, so flags in text-only contexts (the account
   country search input .searchable-select-input and the penalty-winner
   <select>/<option> .penalty-select) would still render as bare codes without
   this. unicode-range (see @font-face above) keeps the font scoped to flag glyphs
   only, so Latin text in these controls is unaffected. */
input, select, option, textarea, button, .searchable-select-input {
    font-family: 'Twemoji Country Flags', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.container {
    width: 100%;
    max-width: 960px;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Card Layout */
/* ═══════════════════════════════════════════════════════════════════════════ */

.card {
    background: white;
    border-radius: 0 0 10px 10px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    width: 100%;
    overflow: hidden;
    display: flex;
    flex-direction: row;
}

.card-header {
    background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
    color: white;
    padding: 32px 36px 28px;
    text-align: center;
    max-width: 300px;
}

.card-header .trophy {
    font-size: 48px;
    display: block;
    margin-bottom: 10px;
}

.card-header h1 {
    font-size: 24px;
    font-weight: 600;
    margin-bottom: 4px;
}

.card-header p {
    font-size: 14px;
    font-weight: 400;
    opacity: 0.85;
}

.card-body {
    padding: 36px;
    width: 100%;
    /* As a flex child of .card (display:flex;flex-direction:row at >1000px), the
       default min-width:auto would let .card-body grow to its widest content's
       intrinsic size — e.g. a .grid-table with width:max-content — and burst out
       of the card, where .card overflow:hidden clips it off-page (no scroll).
       min-width:0 lets the flex child shrink below content width so inner
       overflow-x containers (.grid-scroll) become the width-constrained,
       scrollable element at ALL widths, not just ≤1000px where the card is block. */
    min-width: 0;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Form Elements */
/* ═══════════════════════════════════════════════════════════════════════════ */

.form-group {
    margin-bottom: 20px;
}

label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 6px;
}

input[type="text"],
input[type="password"],
input[type="email"],
select {
    width: 100%;
    padding: 11px 14px;
    border: 2px solid #e5e7eb;
    border-radius: 10px;
    font-size: 16px;
    color: #111827;
    transition: border-color 0.2s;
    background: #f9fafb;
}

input:focus,
select:focus {
    outline: none;
    border-color: #667eea;
    background: white;
}

/* T68 — Searchable select dropdown */
.searchable-select-wrapper {
    position: relative;
    width: 100%;
}

.searchable-select-input {
    width: 100%;
    padding: 11px 14px 11px 14px;
    padding-right: 40px;
    border: 2px solid #e5e7eb;
    border-radius: 10px;
    font-size: 16px;
    color: #111827;
    transition: border-color 0.2s, background 0.2s;
    background: #f9fafb;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%23111827' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 8px;
}

.searchable-select-input:focus {
    outline: none;
    border-color: #667eea;
    background-color: white;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%23111827' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 8px;
}

.searchable-select-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    list-style: none;
    margin: 6px 0 0 0;
    padding: 8px 0;
    border: 2px solid #e5e7eb;
    border-radius: 10px;
    background: white;
    max-height: 300px;
    overflow-y: auto;
    z-index: 10;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}

.searchable-select-dropdown.is-hidden {
    display: none;
}

.searchable-select-dropdown li {
    padding: 10px 14px;
    cursor: pointer;
    color: #111827;
    font-size: 16px;
    transition: background-color 0.15s;
}

.searchable-select-dropdown li:hover,
.searchable-select-dropdown li.highlighted {
    background-color: #f0f4ff;
}

.searchable-select-dropdown li.selected {
    background-color: #667eea;
    color: white;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Buttons */
/* ═══════════════════════════════════════════════════════════════════════════ */

.btn-primary {
    display: inline-block;
    padding: 13px 20px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.1s;
    text-decoration: none;
    white-space: nowrap;
    min-height: 44px;
    line-height: 1.2;
    vertical-align: middle;
}

button.btn-primary {
    width: 100%;
    display: block;
    margin-top: 8px;
}

.btn-primary:hover {
    opacity: 0.92;
    transform: translateY(-1px);
}

.btn-primary:active {
    transform: translateY(0);
}

.btn-primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Navigation */
/* ═══════════════════════════════════════════════════════════════════════════ */

.nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    padding: 12px 16px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border-radius: 10px 10px 0 0;
    margin-bottom: 5px;
}

.nav-brand {
    color: white;
    font-weight: 600;
    font-size: 16px;
    flex-shrink: 0;
}

.main-nav-brand {
    /* Reserve the logo height (30px) so the nav doesn't shift when nav.js
       populates the brand after /api/me resolves (T44/T51). */
    display: inline-flex;
    align-items: center;
    min-height: 30px;
}

.nav-links-group {
    display: flex;
    gap: 0;
    align-items: center;
    flex-wrap: wrap;
}

.nav a {
    color: white;
    text-decoration: none;
    font-size: 14px;
    display: inline-block;
    padding: 14px 11px;
    transition: background-color 0.15s;
}

.nav a:hover {
    background-color: rgba(255, 255, 255, 0.12);
}

.nav a:active {
    background-color: rgba(255, 255, 255, 0.22);
}

.nav a.active {
    font-weight: bold;
    text-decoration: underline;
}

.nav-username {
    color: white;
    font-size: 14px;
    font-weight: 600;
    opacity: 0.85;
}

/* T5: short vertical divider at the left edge of each sibling inside nav-links-group */
.nav-links-group > * + * {
    position: relative;
}

.nav-links-group > * + *::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
    height: 14px;
    background: rgba(255, 255, 255, 0.4);
}

.nav-admin {
    background: linear-gradient(135deg, #4c5fc1 0%, #5e3a80 100%);
    margin-top: -12px;
    margin-bottom: 2px;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

/* T38/T39: Hamburger menu for mobile */
.nav-toggle {
    display: none;
    background: none;
    border: none;
    color: white;
    font-size: 24px;
    cursor: pointer;
    padding: 8px;
    line-height: 1;
}

/* T3: Champion overlay modal */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
}

.modal-overlay[hidden] { display: none; }

.modal-content {
    position: relative;
    width: min(640px, 100%);
    max-height: calc(100vh - 48px);
    background: white;
    border-radius: 14px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.modal-content iframe {
    width: 100%;
    /* JS-driven height via postMessage (see group.html / champion.html). */
    /* Fallback for the brief instant before the iframe reports its size. */
    height: 200px;
    border: 0;
    background: transparent;
    display: block;
}

.modal-close {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 36px;
    height: 36px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.08);
    color: #1e293b;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
}

.modal-close:hover { background: rgba(0, 0, 0, 0.15); }

.nav-links {
    margin-bottom: 16px;
    text-align: right;
    font-size: 14px;
}

.nav-links a {
    color: #667eea;
    text-decoration: none;
}

.nav-links a:hover {
    text-decoration: underline;
}

/* ───────────────────────────────────────────────────────────────────────────
   T55 — Language switcher dropdown (lives in the dark nav bar).
   White text + custom white caret on a translucent dark fill keeps it legible
   on the branded nav (WCAG AA: #fff on the dark nav is > 12:1). The native
   option list is forced to dark-on-white so it stays readable on every OS theme.
   Skin-specific accents (blue / gold focus ring) live in skin.css.
   ─────────────────────────────────────────────────────────────────────────── */
.nav-lang-select {
    width: auto;
    min-width: 74px;
    min-height: 44px;            /* 44px touch target — WCAG 2.5.5 */
    padding: 6px 32px 6px 11px;  /* extra right padding clears the caret */
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    color: #ffffff;
    background-color: rgba(255, 255, 255, 0.12);
    border: 1.5px solid rgba(255, 255, 255, 0.55);
    border-radius: 8px;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    /* White chevron caret so it stays visible against the dark nav. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%23ffffff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 12px 8px;
    transition: border-color 0.2s, background-color 0.2s;
}

.nav-lang-select:hover {
    background-color: rgba(255, 255, 255, 0.20);
    border-color: rgba(255, 255, 255, 0.85);
}

/* Override the generic `select:focus { background: white }` rule — a white fill
   would leave white text on white. Keep the dark fill and add a visible ring. */
.nav-lang-select:focus,
.nav-lang-select:focus-visible {
    background-color: rgba(255, 255, 255, 0.20);
    border-color: #ffffff;
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

/* The popup list renders with OS colors — pin it to dark-on-white for contrast. */
.nav-lang-select option {
    color: #111827;
    background-color: #ffffff;
}

/* ─────────────────────────────────────────────────────────────────────────── */
/* T56 — Standalone language switcher on nav-less auth pages                    */
/* (login / signup / forgot-password). Fixed top-right corner.                  */
/* The control reuses .nav-lang-select but forces a SOLID near-black fill        */
/* (instead of the nav's translucent one) so the white text keeps a >12:1        */
/* contrast ratio over the page's purple gradient, regardless of caret position. */
/* ─────────────────────────────────────────────────────────────────────────── */
.auth-lang-switch {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 50;
}

.auth-lang-switch .nav-lang-select {
    background-color: rgba(17, 24, 39, 0.92);
    border-color: rgba(255, 255, 255, 0.70);
}

.auth-lang-switch .nav-lang-select:hover,
.auth-lang-switch .nav-lang-select:focus,
.auth-lang-switch .nav-lang-select:focus-visible {
    background-color: rgba(17, 24, 39, 0.98);
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Tabs (D-07 — D-08) */
/* ═══════════════════════════════════════════════════════════════════════════ */

.tabs {
    display: flex;
    gap: 0;
    border-bottom: 2px solid #e5e7eb;
    margin-bottom: 20px;
}

.tab {
    padding: 10px 20px;
    cursor: pointer;
    border: none;
    background: transparent;
    color: #374151;
    font-size: 14px;
    font-weight: 500;
    transition: border-color 0.2s, color 0.2s;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
}

.tab:hover {
    color: #667eea;
}

.tab[aria-selected="true"] {
    border-bottom-color: #667eea;
    font-weight: bold;
    color: #667eea;
}

.tab-panel[hidden] {
    display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Tables & Leaderboards */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* T86: Card + ticker-box leaderboard (replaces the old table layout) */
.lb-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 16px;
}

.lb-row {
    background: #fff;
    border: 1px solid #ECECF0;
    border-radius: 18px;
    box-shadow: 0 1px 2px rgba(20, 20, 30, .04), 0 8px 24px rgba(20, 20, 30, .06);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 4px 16px;
}

.lb-rank {
    width: 48px;
    flex-shrink: 0;
    text-align: center;
    font-weight: 800;
    font-size: 18px;
    color: #1B1B22;
}

.lb-player {
    flex: 1;
    min-width: 0;
    font-weight: 700;
    color: #1B1B22;
    font-size: 15px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lb-pts-box {
    flex-shrink: 0;
    width: 60px;
    background: #fff;
    border: 1.5px solid #6C63E8;
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(63, 55, 201, .08);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3px 0;
}

.lb-pts-box .lb-pts-val {
    font-size: 30px;
    font-weight: 800;
    color: #1B1B22;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.5px;
    line-height: 1;
}

.lb-pts-box .lb-pts-label {
    font-size: 11px;
    font-weight: 600;
    color: #6B6B76;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-top: 2px;
}

.lb-stats {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    font-size: 13px;
    color: #6B6B76;
    text-align: right;
    min-width: 88px;
}

.lb-stats .lb-stat-val {
    font-weight: 700;
    color: #1B1B22;
}

/* T63-T65 / T85: Podium styling for top 3 — card border + soft tint, dark text (WCAG AA) */
.lb-row[data-rank="1"] {
    border-color: #DAA520;
    background: #FCF6E6;
}

.lb-row[data-rank="2"] {
    border-color: #C8C8C8;
    background: #F5F5F5;
}

.lb-row[data-rank="3"] {
    border-color: #CD7F32;
    background: #FBF0E6;
}

/* T104: "Average player" — non-ranked crowd-mean benchmark row. Neutral,
   visually distinct from gold/silver/bronze and from normal player rows
   (dashed border + subtle tint + italic label). Never has data-rank so it
   never picks up podium tinting. */
.lb-row-average {
    border-style: dashed;
    border-color: #B8B8C4;
    background: #FAFAFC;
    box-shadow: none;
}

.lb-row-average .lb-player {
    font-style: italic;
    color: #5A5A66;
}

.lb-row-average .lb-rank {
    color: #9A9AA6;
}

/* 260611-iha — robot/stat rows: same dashed/muted treatment as the average
   player but a faint blue tint so robots read as a distinct band. */
.lb-row-robot {
    border-style: dashed;
    border-color: #A9B4D6;
    background: #F4F6FC;
    box-shadow: none;
}

.lb-row-robot .lb-player {
    font-style: italic;
    color: #4A5A86;
}

.lb-row-robot .lb-rank {
    color: #8A95BC;
}

/* 260611-iha — admin robot-creation section in admin/users.html. */
.robot-admin {
    margin-top: 32px;
    padding-top: 24px;
    border-top: 1px solid #E2E2EA;
}

.robot-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin: 12px 0 8px;
}

.robot-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.85em;
}

.robot-field input[type="text"],
.robot-field input[type="file"] {
    min-width: 180px;
}

.robot-status {
    font-size: 0.85em;
}

.robot-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 8px;
}

.robot-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    border: 1px dashed #A9B4D6;
    border-radius: 8px;
    background: #F4F6FC;
}

.robot-row-name {
    font-style: italic;
    color: #4A5A86;
}

.lb-avg-hint {
    display: block;
    font-size: 0.72em;
    font-style: normal;
    color: #8A8A96;
    margin-top: 2px;
    line-height: 1.3;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Messages & Status */
/* ═══════════════════════════════════════════════════════════════════════════ */

.error {
    color: #991b1b;
    background: #fef2f2;
    border: 1px solid #fecaca;
    padding: 12px;
    border-radius: 10px;
    font-size: 14px;
    margin-bottom: 16px;
}

.error-text {
    color: #991b1b;
    font-size: 14px;
    font-weight: 400;
    margin-top: 4px;
}

.success {
    color: #15803d;
    background: #dcfce7;
    border: 1px solid #bbf7d0;
    padding: 12px;
    border-radius: 10px;
    font-size: 14px;
    margin-bottom: 16px;
}

.footnote {
    font-size: 12px;
    color: #6b7280;
    margin-top: 8px;
    font-style: italic;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Text & Links */
/* ═══════════════════════════════════════════════════════════════════════════ */

.signup-link {
    text-align: center;
    margin-top: 20px;
    font-size: 14px;
    color: #6b7280;
}

.signup-link a {
    color: #667eea;
    font-weight: 600;
    text-decoration: none;
}

.signup-link a:hover {
    text-decoration: underline;
}

.forgot-row {
    display: flex;
    justify-content: flex-end;
    margin-top: 6px;
}

.forgot-row a {
    font-size: 14px;
    font-weight: 400;
    color: #667eea;
    text-decoration: none;
}

.forgot-row a:hover {
    text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Empty State */
/* ═══════════════════════════════════════════════════════════════════════════ */

.empty-state {
    text-align: center;
    color: #6b7280;
    font-size: 14px;
    padding: 32px 0;
    line-height: 1.5;
}

.empty-state strong {
    display: block;
    font-size: 16px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 8px;
}

.empty-state a {
    color: #667eea;
    text-decoration: none;
    font-weight: 600;
}

.empty-state a:hover {
    text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Auth page layout (login, signup, forgot-password, join, champion)         */
/* Pages without nav: centered card, max 440px wide                          */
/* ═══════════════════════════════════════════════════════════════════════════ */

body.page-auth {
    align-items: safe center;
}

body.page-auth .card {
    max-width: 480px;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* select:disabled */
/* ═══════════════════════════════════════════════════════════════════════════ */

select:disabled {
    background: #f3f4f6;
    color: #6b7280;
    cursor: not-allowed;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Dashboard — Group list */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* T49 — the whole card is clickable. It is a flex row of one or two sibling
   anchors (main zone + optional admin zone); padding lives on the zones, not
   the card, so each zone's hover background fills its share edge-to-edge. */
.group-card {
    display: flex;
    align-items: stretch;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    margin-bottom: 12px;
    overflow: hidden;
}

.group-card:last-child {
    margin-bottom: 0;
}

/* Main zone — links to group.html. Takes the full width alone, or ~75% when
   the admin zone is present (flex 3 vs 1). */
.group-card-main {
    flex: 3;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 16px;
    min-height: 44px;
    text-decoration: none;
    color: inherit;
    transition: background-color 0.12s ease;
}

.group-card-main:hover {
    background: #f9fafb;
}

/* Admin zone — distinct ~25% right part linking to group-admin.html. */
.group-card-admin {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 16px 12px;
    min-height: 44px;
    border-left: 1px solid #e5e7eb;
    background: #f9fafb;
    color: #667eea;
    font-size: 14px;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 0.12s ease;
}

.group-card-admin:hover {
    background: #eef0fb;
}

.group-card-admin-icon {
    font-size: 15px;
    line-height: 1;
}

.group-name {
    font-size: 16px;
    font-weight: 600;
    color: #111827;
    flex: 1;
    min-width: 120px;
}

.member-count {
    font-size: 14px;
    color: #6b7280;
    white-space: nowrap;
}

.role-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 20px;
    font-size: 13px;
}

.role-badge.admin {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.role-badge.member {
    background: #f3f4f6;
    color: #374151;
}

.action-buttons {
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-bottom: 16px;
}

.action-buttons .btn-primary {
    flex: 1;
    text-align: center;
    max-width: 240px;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Toast notifications */
/* ═══════════════════════════════════════════════════════════════════════════ */

.toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    padding: 12px 24px;
    border-radius: 10px;
    font-size: 14px;
    z-index: 100;
    opacity: 0;
    transition: opacity 0.3s;
    pointer-events: none;
    white-space: nowrap;
}

.toast.show {
    opacity: 1;
}

.toast.success {
    background: #dcfce7;
    color: #15803d;
}

.toast.destructive {
    background: #fef2f2;
    color: #991b1b;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Multi-step forms (signup, forgot-password) */
/* ═══════════════════════════════════════════════════════════════════════════ */

.step {
    display: none;
}

.step.active {
    display: block;
}

.step-indicator {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-bottom: 28px;
}

.step-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #e5e7eb;
    transition: background 0.3s;
}

.step-dot.active {
    background: #667eea;
}

.step-dot.done {
    background: #10b981;
}

.step-title {
    font-size: 16px;
    font-weight: 600;
    color: #1e3c72;
    margin-bottom: 8px;
}

.step-desc {
    font-size: 14px;
    font-weight: 400;
    color: #6b7280;
    margin-bottom: 24px;
    line-height: 1.5;
}

.hint {
    font-size: 14px;
    font-weight: 400;
    color: #6b7280;
    opacity: 0.85;
    margin-top: 4px;
}

.password-rules {
    font-size: 14px;
    font-weight: 400;
    color: #6b7280;
    opacity: 0.85;
    margin-top: 6px;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.password-rules li::before {
    content: "· ";
}

.password-rules li.rule-ok {
    color: #10b981;
    opacity: 1;
}

.password-rules li.rule-ok::before {
    content: "✓ ";
}

.password-rules li.rule-fail {
    color: #ef4444;
    opacity: 1;
}

.password-rules li.rule-fail::before {
    content: "✗ ";
}

.success-icon {
    font-size: 48px;
    text-align: center;
    display: block;
    margin-bottom: 16px;
}

.success-title {
    font-size: 24px;
    font-weight: 600;
    color: #10b981;
    text-align: center;
    margin-bottom: 8px;
}

.success-desc {
    font-size: 14px;
    font-weight: 400;
    color: #6b7280;
    text-align: center;
    line-height: 1.5;
    margin-bottom: 28px;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Secondary / back links */
/* ═══════════════════════════════════════════════════════════════════════════ */

.back-link {
    text-align: center;
    margin-top: 20px;
    font-size: 14px;
    color: #6b7280;
}

.back-link a {
    color: #667eea;
    font-weight: 600;
    text-decoration: none;
}

.back-link a:hover {
    text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Champion page */
/* ═══════════════════════════════════════════════════════════════════════════ */

.champion-icon {
    font-size: 48px;
    display: block;
    margin-bottom: 10px;
}

.lock-notice {
    background: #f3f4f6;
    color: #6b7280;
    border-radius: 10px;
    padding: 12px 16px;
    font-size: 14px;
    margin-top: 16px;
    /* T59: shown via classList.remove('is-hidden'); base display is block */
}

.nav-link {
    margin-top: 16px;
    text-align: center;
    font-size: 14px;
}

.nav-link a {
    color: #667eea;
    text-decoration: none;
}

.nav-link a:hover {
    text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Phone Responsiveness (FE-04) */
/* ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 480px) {
    body {
        padding: 12px;
    }

    .container {
        width: 100%;
    }
    
    .modal-overlay {
        padding: 0px;
    }
    
    .card {
        width: 100%;
    }

    .card-header {
        padding: 20px 14px 14px;
    }

    .card-header h1 {
        font-size: 20px;
    }

    .card-body {
        padding: 14px;
    }

    .step-indicator {
        margin-right: 130px;
    }

    .nav {
        flex-direction: column;
        gap: 8px;
        align-items: flex-start;
    }

    .nav-brand {
        width: 100%;
    }

    .nav-links-group {
        width: 100%;
        gap: 12px;
    }

    .lb-stats {
        display: none;
    }

    .tabs {
        gap: 4px;
    }

    .tab {
        padding: 8px 12px;
        font-size: 13px;
    }

    button.btn-primary,
    .btn-primary[type="submit"] {
        padding: 11px 16px;
        font-size: 14px;
    }

    /* T49 — stack the zones vertically; each spans the full card width and the
       admin zone sits below with a top divider instead of a left one. */
    .group-card {
        flex-direction: column;
        align-items: stretch;
    }

    .group-card-main {
        align-items: flex-start;
        gap: 8px;
    }

    .group-card-admin {
        justify-content: flex-start;
        border-left: none;
        border-top: 1px solid #e5e7eb;
    }
}

@media (max-width: 525px) {
    .action-buttons {
        flex-direction: column;
    }

    .action-buttons .btn-primary {
        max-width: none;
    }
}

@media (max-width: 640px) {
    .card-body {
        padding: 24px 16px;
    }
}

@media (max-width: 700px) {
    body {
        padding: 0;
        height: 100vh;
    }

    .nav {
        border-radius: 0;
        flex-wrap: wrap;
    }

    .nav-toggle {
        display: flex;
    }

    .nav-links-group,
    .nav-admin {
        display: none;
    }

    .nav.menu-open .nav-links-group,
    .nav.menu-open + .nav-admin {
        display: flex;
        flex-basis: 100%;
        order: 2;
    }

    .nav-admin.menu-open {
        display: flex;
        flex-basis: 100%;
        order: 3;
        width: 100%;
    }

    .card {
        border-radius: 0;
    }
}

@media (max-width: 1000px) {
    .card {
        display: inherit;
        flex-direction: inherit;
    }
    .card-header {
        max-width: inherit;
    }
}

.responsive-table .row-main {
    cursor: pointer;
}

.responsive-table .col-collapsible {
    display: none;
}

.responsive-table .row-detail {
    display: table-row;
}

.responsive-table .row-detail > td {
    padding: 0 !important;
    background: #f9fafb;
    border-bottom: 1px solid #e5e7eb !important;
}

.responsive-table .detail-inner {
    max-height: 0;
    overflow-y: auto;
    padding: 0 12px;
    font-size: 13px;
    color: #374151;
    transition: max-height 180ms ease-out, padding 180ms ease-out;
}

.responsive-table .row-main.expanded + .row-detail .detail-inner {
    max-height: calc(100vh - 120px);
    padding: 10px 12px;
}

.responsive-table .detail-field {
    margin-bottom: 6px;
}

.responsive-table .detail-field:last-child {
    margin-bottom: 0;
}

.responsive-table .detail-label {
    font-weight: 600;
    color: #6b7280;
    margin-right: 6px;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* Scoring-rules display (shared by group.html summary + group-admin.html form) */
/* See /assets/scoring-rules.js                                                 */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* Collapsible read-only summary (group.html) */
.rules-summary {
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #f9fafb;
    margin-bottom: 16px;
    padding: 0 14px;
}

.rules-summary > summary {
    cursor: pointer;
    font-weight: 600;
    color: #1e3c72;
    padding: 10px 0;
    list-style: none;
    user-select: none;
}

.rules-summary > summary::-webkit-details-marker {
    display: none;
}

.rules-summary > summary::before {
    content: '▸';
    display: inline-block;
    margin-right: 8px;
    color: #6b7280;
    transition: transform 0.15s;
}

.rules-summary[open] > summary::before {
    transform: rotate(90deg);
}

.rules-summary #rules-content {
    padding: 4px 0 14px;
}

.rules-group {
    margin-bottom: 12px;
}

.rules-group:last-child {
    margin-bottom: 0;
}

.rules-group-title {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #6b7280;
    margin-bottom: 6px;
}

.rules-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 8px;
}

.rules-chip {
    position: relative;
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    font-size: 13px;
    color: #111827;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 999px;
    padding: 3px 10px;
    cursor: help;
}

.rules-chip b {
    color: #1e3c72;
}

/* Standalone info bubble carrier (group-admin.html form labels) */
.rules-info-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    cursor: help;
}

.rules-chip:focus,
.rules-info-wrap:focus {
    outline: 2px solid #00A0DB;
    outline-offset: 1px;
}

/* Label text + bubble prefix rendered into admin-form labels by decorateForm() */
.rules-label-text {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.rules-info {
    font-size: 11px;
    color: #9ca3af;
    align-self: center;
}

/* Info bubble — hidden until the carrier is hovered (desktop) or focused (tap). */
.rules-tooltip {
    position: absolute;
    bottom: calc(100% + 7px);
    left: 50%;
    transform: translateX(-50%);
    width: max-content;
    max-width: 220px;
    background: #18161B;
    color: #fff;
    font-size: 12px;
    font-weight: 400;
    line-height: 1.35;
    text-align: center;
    white-space: normal;
    padding: 6px 9px;
    border-radius: 6px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.12s ease;
    pointer-events: none;
    z-index: 20;
}

.rules-tooltip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: #18161B;
}

.rules-chip:hover .rules-tooltip,
.rules-chip:focus .rules-tooltip,
.rules-chip:focus-within .rules-tooltip,
.rules-info-wrap:hover .rules-tooltip,
.rules-info-wrap:focus .rules-tooltip,
.rules-info-wrap:focus-within .rules-tooltip {
    opacity: 1;
    visibility: visible;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — shared visibility utility                                              */
/* Replaces inline `style="display:none;"` on JS-toggled elements. The reveal   */
/* JS toggles this class via classList.add/remove('is-hidden') instead of       */
/* el.style.display so behavior is byte-identical to the old inline default.    */
/* ═══════════════════════════════════════════════════════════════════════════ */

.is-hidden {
    display: none !important;
}

/* T58 — full-width centered link styled as a primary button (signup /          */
/* forgot-password success "Aller à la connexion" link). Was an inline          */
/* style="text-align:center; text-decoration:none; display:block;" on a link.   */
.btn-primary--block {
    text-align: center;
    text-decoration: none;
    display: block;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — champion page (was inline <style> in champion.html)                    */
/* ═══════════════════════════════════════════════════════════════════════════ */

.empty-state--champion {
    padding: 16px 0 8px;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — group page (was inline <style> in group.html)                          */
/* ═══════════════════════════════════════════════════════════════════════════ */

.stage-heading {
    font-size: 20px;
    font-weight: 600;
    color: #1e3c72;
    margin-top: 32px;
    margin-bottom: 16px;
    padding-bottom: 8px;
    border-bottom: 2px solid #e5e7eb;
}

.stage-heading:first-child {
    margin-top: 0;
}

.prediction-table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 8px;
}

.prediction-table th {
    text-align: left;
    padding: 8px 12px;
    font-size: 13px;
    color: #6b7280;
    border-bottom: 2px solid #e5e7eb;
    font-weight: 600;
}

.prediction-table td {
    padding: 10px 12px;
    border-bottom: 1px solid #f3f4f6;
    font-size: 14px;
    color: #111827;
    vertical-align: middle;
}

/* T22 — venue label, pushed to the far right of the header row */
.venue-sub {
    font-size: 12px;
    color: #6b7280;
    margin-left: auto;
}

/* T40 — group letter badge */
.group-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    color: #667eea;
    background: #eef2ff;
    border-radius: 4px;
    padding: 1px 6px;
    margin-right: 6px;
    vertical-align: middle;
}

/* T24 — Champion link: discreet by default, screaming when unset (no pick) */
#champion-overlay-link {
    display: inline-block;
    padding: 4px 12px;
    border-radius: 999px;
    text-decoration: none;
    font-weight: 600;
    transition: transform 0.15s ease;
    position: relative;
}

/* T90 — urgency dot on champion link when < 24h until first match and no pick set */
#champion-overlay-link.champion-urgent::after {
    content: '';
    position: absolute;
    top: -3px;
    right: -3px;
    width: 9px;
    height: 9px;
    background: #ef4444;
    border-radius: 50%;
    border: 1.5px solid #fff;
    pointer-events: none;
}

#champion-overlay-link.champion-set {
    background: #dcfce7;
    color: #15803d;
    border: 1px solid #15803d33;
}

#champion-overlay-link.champion-unset {
    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
    color: #fff;
    box-shadow: 0 2px 10px rgba(245, 158, 11, 0.5);
    animation: champion-pulse 1.6s ease-in-out infinite;
    /* T96 — when unset, the button doesn't just glow, it's noticeably larger. */
    padding: 9px 20px;
    font-size: 1.1em;
}

/* T97 — lock countdown / "locked" status pill beside the champion button */
.champion-lock-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.8em;
    font-weight: 600;
    background: #eef2ff;
    color: #3730a3;
    vertical-align: middle;
}

.champion-lock-badge.is-urgent {
    background: #fee2e2;
    color: #b91c1c;
}

.champion-lock-badge.is-locked {
    background: #f3f4f6;
    color: #6b7280;
}

#champion-overlay-link.champion-locked-unset {
    background: #f3f4f6;
    color: #6b7280;
    text-decoration: line-through;
}

@keyframes champion-pulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
    #champion-overlay-link.champion-unset {
        animation: none;
    }
}

.score-inputs {
    display: flex;
    align-items: center;
    gap: 6px;
}

.score-input {
    width: 56px;
    height: 44px;
    text-align: center;
    font-size: 16px;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    background: #f9fafb;
    color: #111827;
    -moz-appearance: textfield;
    transition: border-color 0.2s, background 0.2s;
}

.score-input::-webkit-outer-spin-button,
.score-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.score-input:focus {
    border-color: #667eea;
    background: #fff;
    outline: none;
}

.score-input.locked {
    background: #f3f4f6;
    color: #6b7280;
    cursor: not-allowed;
}

.score-input.error {
    border-color: #991b1b;
}

.score-separator-slot {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.score-separator {
    font-size: 18px;
    color: #6b7280;
    transition: opacity 0.3s;
}

/* T93 — when a save lands, the ✓ fades in over the separator's slot. */
.score-separator-slot:has(.save-indicator.show) .score-separator {
    opacity: 0;
}

.penalty-select {
    height: 44px;
    border-radius: 10px;
    border: 1px solid #e5e7eb;
    padding: 0 8px;
    font-size: 14px;
    background: #f9fafb;
    color: #111827;
}

.penalty-select:focus {
    border-color: #667eea;
    outline: none;
}

.lock-badge {
    font-size: 13px;
    color: #6b7280;
}

.unlock-badge {
    font-size: 13px;
    color: #15803d;
}

/* T78 — live lock countdown: tabular figures keep the badge from jittering
   in width as the remaining time ticks down. */
.countdown-badge {
    font-variant-numeric: tabular-nums;
}

/* T91 — glow when < 24h until kickoff lock */
.countdown-badge.urgent {
    color: #dc2626;
    animation: urgency-glow 1.5s ease-in-out infinite;
}

@keyframes urgency-glow {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.55; }
}

@media (prefers-reduced-motion: reduce) {
    .countdown-badge.urgent {
        animation: none;
    }
}

.not-predictable-msg {
    font-size: 13px;
    color: #6b7280;
    font-style: italic;
}

/* T93 — absolutely positioned over the separator slot so it cycles in
   place of the — rather than living in the status area. */
.save-indicator {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    color: #15803d;
    opacity: 0;
    transition: opacity 0.3s;
}

.save-indicator.show {
    opacity: 1;
}

.member-row td {
    background: #f9fafb;
    font-size: 13px;
    color: #6b7280;
}

.member-username {
    font-weight: 600;
    color: #374151;
}

.visibility-hint {
    font-size: 13px;
    color: #6b7280;
    font-style: italic;
    margin-bottom: 8px;
    padding: 8px 12px;
    background: #f9fafb;
    border-radius: 8px;
}

/* Mobile: collapse to card blocks */
@media (max-width: 639px) {
    .prediction-table,
    .prediction-table tbody,
    .prediction-table td,
    .prediction-table tr {
        display: block;
    }

    .prediction-table thead {
        display: none;
    }

    .prediction-table tr {
        background: #fff;
        border: 1px solid #e5e7eb;
        border-radius: 10px;
        margin-bottom: 12px;
        padding: 12px;
    }

    .prediction-table td {
        border: none;
        padding: 4px 0;
    }

    .prediction-table td::before {
        content: attr(data-label);
        font-size: 12px;
        color: #6b7280;
        display: block;
        margin-bottom: 2px;
        font-weight: 600;
    }

    .member-row td {
        border-radius: 0;
        border: none;
    }
}

/* group.html-scoped empty-state override (padding 24px vs base 32px) */
.empty-state--group {
    text-align: center;
    color: #6b7280;
    font-size: 14px;
    padding: 24px 0;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T79-T83 — group page card layout (replaces the .prediction-table grid)        */
/* Each match is a self-contained card: header (group / kickoff / venue), a       */
/* main row of home flag-above-name LEFT, two central score stacks (▲/input/▼),   */
/* away flag-above-name RIGHT, the admin result split under each input, a penalty */
/* dropdown row, the status area, and an after-kickoff member-prediction list.    */
/* ═══════════════════════════════════════════════════════════════════════════ */

.match-card-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 8px;
}

.match-card {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 14px;
    padding: 14px 16px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    position: relative;
}

/* T90 — red corner triangle when < 24h before kickoff lock */
.match-card.urgent::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    border-style: solid;
    border-width: 0 33px 33px 0;
    border-color: transparent #ef4444 transparent transparent;
    border-radius: 0 14px 0 0;
    pointer-events: none;
}

/* HEADER — badge left, venue far-right (omitted when both absent) */
.match-card-header {
    display: flex;
    align-items: center;
    font-size: 12px;
    color: #6b7280;
    margin-bottom: 8px;
}

/* T88 — datetime at top of score-col, centered over the scores */
.match-card-datetime {
    font-size: 12px;
    color: #6b7280;
    text-align: center;
    font-variant-numeric: tabular-nums;
    margin-bottom: 4px;
}

/* MAIN — LEFT team / CENTER scores / RIGHT team */
.match-card-main {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.team-side {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    flex: 1 1 0;
    min-width: 84px;
    text-align: center;
}

.team-flag {
    font-size: 80px;
    line-height: 1;
}

.team-name {
    font-size: 14px;
    font-weight: 600;
    color: #111827;
}

/* CENTER — column: datetime on top, score stacks row below */
.score-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 0 0 auto;
}

/* T88 — stacks row inside score-col */
.score-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.score-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

/* T94 — unified vertical stepper: one rounded box wraps ▲ / number / ▼ so
   the score input reads as a single spinner control (see mock). The box look
   is scoped to the unlocked, editable state via :has(.score-ticker); locked
   stacks keep the standalone .score-input pill. */
.score-stack:has(.score-ticker) {
    gap: 0;
    width: 52px;
    border: 1.5px solid #d7dcf5;
    border-radius: 12px;
    background: #fff;
    overflow: hidden;
    box-shadow: 0 1px 2px rgba(63, 55, 201, .06);
    transition: border-color 0.2s, box-shadow 0.2s;
}

.score-stack:has(.score-ticker):focus-within {
    border-color: #667eea;
    box-shadow: 0 0 0 3px rgba(102, 126, 234, .15);
}

/* ▲/▼ ticker buttons — bare chevrons inside the stepper box (no own chrome) */
.score-ticker {
    width: 100%;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    line-height: 1;
    color: #a5b0e8;
    background: transparent;
    border: 0;
    border-radius: 0;
    cursor: pointer;
    padding: 0;
    transition: background 0.15s, color 0.15s;
}

.score-ticker:hover {
    background: #eef1fd;
    color: #667eea;
}

.score-ticker:active {
    background: #e0e7ff;
}

.score-ticker:focus-visible {
    outline: 2px solid #667eea;
    outline-offset: -2px;
}

/* The number itself — flush, borderless, centered inside the stepper box. */
.score-stack:has(.score-ticker) .score-input {
    width: 100%;
    height: 34px;
    border: 0;
    border-radius: 0;
    background: transparent;
    font-size: 20px;
    font-weight: 700;
}

.score-stack:has(.score-ticker) .score-input:focus {
    background: transparent;
}

/* RESULT under inputs (T83) — sits inside each score-stack, directly below
   the prediction input, to save the vertical space of a separate row. */
.score-stack .match-result {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid #e5e7eb;
    width: 100%;
    font-size: 18px;
    font-weight: 700;
    color: #1e3c72;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.match-result-tab {
    font-size: 11px;
    font-weight: 600;
    color: #6b7280;
}

/* PENALTY ROW — centered, below the score row */
.match-card-penalty {
    display: flex;
    justify-content: center;
    margin-top: 10px;
}

/* STATUS AREA — points pill + lock/countdown badges + updated-at meta */
.match-card-status {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    margin-top: 10px;
    font-size: 13px;
    text-align: center;
}

.points-earned {
    display: inline-block;
    font-size: 12px;
    font-weight: 700;
    color: #15803d;
    background: #dcfce7;
    border-radius: 999px;
    padding: 2px 10px;
}

.match-status-meta {
    font-size: 12px;
    color: #6b7280;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: center;
}

.updated-at {
    color: #9ca3af;
}

/* MEMBER LIST — compact, after kickoff, below the card */
.member-pred-list {
    list-style: none;
    margin: -4px 0 4px;
    padding: 8px 16px;
    background: #f9fafb;
    border: 1px solid #f3f4f6;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.member-pred-item {
    /* 3-column grid keeps the score in a fixed, centered column so it never
       shifts relative to the (left-anchored) username — regardless of its own
       width or whether the points pill is present (T110). */
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
    font-size: 13px;
    color: #6b7280;
}

.member-pred-score {
    font-variant-numeric: tabular-nums;
    color: #374151;
    text-align: center;
}

/* Points pill (when scored) sits at the row's right edge, third grid column. */
.member-pred-item .points-earned {
    justify-self: end;
}

/* Narrow screens: shrink flags + let the main row breathe */
@media (max-width: 639px) {
    .match-card-main {
        gap: 8px;
    }
    .team-flag {
        font-size: 40px;
    }
    .team-name {
        font-size: 13px;
    }
    .team-side {
        min-width: 64px;
    }
    .score-row {
        gap: 6px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — group-admin page (was inline <style> + inline attrs in group-admin.html)*/
/* Page-local overrides are scoped under body.page-group-admin so the relocated  */
/* .btn-primary / .card / .modal-overlay redefinitions stay page-local exactly   */
/* as the original <style> block did (it only affected this page).               */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* One-time invite code reveal banner */
/* Full-screen dimmed backdrop that centers the card, mirroring .modal-overlay.
   The dark tint lives on this element (not a ::before on the card) so it
   covers the whole viewport and never paints over the card's own background. */
.invite-reveal-banner {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(0, 0, 0, 0.4);
    z-index: 1000;
    /* T59: shown via classList.remove('is-hidden'); visible state is flex */
}

/* The white card itself — matches .modal-card. */
.invite-reveal-card {
    width: 100%;
    max-width: 540px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    background: white;
    color: #374151;
    border-radius: 20px;
    padding: 32px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}

.invite-reveal-banner strong {
    display: block;
    font-size: 20px;
    font-weight: 600;
    color: #1e3c72;
    margin-bottom: 8px;
}

.invite-reveal-banner p {
    font-size: 14px;
    line-height: 1.5;
    margin-bottom: 12px;
}

.reveal-field-label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #6b7280;
    margin: 14px 0 4px;
}

/* A selectable text zone paired with its aligned small "Copier" button. */
.copy-row {
    display: flex;
    align-items: stretch;
    gap: 8px;
}

.copy-zone {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    background: #f9fafb;
    border: 2px solid #e5e7eb;
    border-radius: 10px;
    padding: 10px 12px;
    color: #111827;
    font-size: 14px;
    line-height: 1.4;
    word-break: break-all;
    user-select: all;
}

.code-display {
    font-family: 'Courier New', Consolas, monospace;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: 0.05em;
}

.reveal-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 20px;
}

.invitation-display {
    font-size: 14px;
}

/* Small copy button sized to sit flush beside its text zone. */
.copy-mini {
    flex: 0 0 auto;
    align-self: stretch;
    display: inline-flex;
    align-items: center;
    background: #fff;
    border: 2px solid #e5e7eb;
    color: #2a5298;
    border-radius: 10px;
    padding: 0 14px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    line-height: 1.2;
    white-space: nowrap;
    transition: border-color 0.2s;
}

.copy-mini:hover {
    border-color: #667eea;
}

/* Primary CTA — matches .btn-primary (purple gradient) used across the app. */
.btn-dismiss {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border: none;
    color: white;
    border-radius: 10px;
    padding: 0 20px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    height: 44px;
    white-space: nowrap;
    transition: opacity 0.2s, transform 0.1s;
}

.btn-dismiss:hover {
    opacity: 0.92;
    transform: translateY(-1px);
}

body.page-group-admin .card {
    margin-bottom: 24px;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
}

.section-title {
    font-size: 18px;
    font-weight: 600;
    color: #1e3c72;
}

/* T58 — replaces inline style="margin-bottom:16px;" on a few section titles */
.section-title--spaced {
    margin-bottom: 16px;
}

.section-divider {
    margin: 32px 0;
    border: none;
    border-top: 1px solid #e5e7eb;
}

body.page-group-admin .btn-primary {
    display: inline-block;
    padding: 0 20px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.1s;
    height: 44px;
    white-space: nowrap;
}

body.page-group-admin .btn-primary:hover {
    opacity: 0.92;
    transform: translateY(-1px);
}

body.page-group-admin .btn-primary:active {
    transform: translateY(0);
}

body.page-group-admin .btn-primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

.btn-secondary {
    padding: 0 20px;
    background: white;
    color: #374151;
    border: 2px solid #e5e7eb;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s;
    height: 44px;
    white-space: nowrap;
}

.btn-secondary:hover {
    border-color: #667eea;
}

.btn-destructive {
    background: #991b1b;
    color: white;
    border: none;
    border-radius: 10px;
    padding: 0 16px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    height: 36px;
    white-space: nowrap;
    transition: background 0.2s;
}

.btn-destructive:hover {
    background: #7f1d1d;
}

/* Badges */
.badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 20px;
    font-size: 13px;
    font-weight: 400;
}

.badge-admin {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.badge-member {
    background: #f3f4f6;
    color: #374151;
}

.badge-active {
    background: #dcfce7;
    color: #15803d;
}

.badge-expired, .badge-revoked {
    background: #f3f4f6;
    color: #6b7280;
}

.badge-used {
    background: #fef3c7;
    color: #92400e;
}

/* Tables */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table thead th {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 2px solid #e5e7eb;
    font-size: 13px;
    font-weight: 600;
    color: #6b7280;
}

.data-table tbody td {
    padding: 12px;
    font-size: 14px;
    color: #374151;
    border-bottom: 1px solid #f3f4f6;
}

.data-table tbody tr:last-child td {
    border-bottom: none;
}

.code-id-cell {
    font-family: 'Courier New', Consolas, monospace;
    font-size: 13px;
    color: #6b7280;
}

/* T84 — collapsible invite-code sections (active / used / expired) */
.codes-section { margin-bottom: 12px; border: 1px solid #e5e7eb; border-radius: 10px; overflow: hidden; }
.codes-section-header {
    width: 100%; display: flex; align-items: center; gap: 8px;
    padding: 12px 14px; background: #f9fafb; border: none; cursor: pointer;
    font-size: 15px; font-weight: 600; color: #1e3c72; text-align: left;
}
.codes-section-header:hover { background: #f3f4f6; }
.codes-section-count { color: #6b7280; font-weight: 400; }
.codes-section-chevron { margin-left: auto; transition: transform 0.15s; color: #6b7280; }
.codes-section.is-open .codes-section-chevron { transform: rotate(90deg); }
.codes-section-body { display: none; padding: 0 14px 8px; }
.codes-section.is-open .codes-section-body { display: block; }

/* Confirm modal (group-admin) */
body.page-group-admin .modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 200;
}

body.page-group-admin .modal-overlay.open {
    display: flex;
}

body.page-group-admin .modal-card {
    background: white;
    border-radius: 20px;
    padding: 32px;
    max-width: 440px;
    width: 90%;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}

body.page-group-admin .modal-title {
    font-size: 20px;
    font-weight: 600;
    color: #991b1b;
    margin-bottom: 12px;
}

body.page-group-admin .modal-body {
    font-size: 14px;
    color: #374151;
    margin-bottom: 24px;
    line-height: 1.5;
}

body.page-group-admin .modal-actions {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
}

/* T58 — scoring-rules form: replaces the per-element inline style="..." attrs */
.reveal-invite-code {
    font-weight: 600;
    color: #2a5298;
    word-break: break-all;
}

.rules-lock-banner {
    /* T59: shown via classList.remove('is-hidden'); base display is block */
    background: #f8d7da;
    color: #721c24;
    padding: 0.75em 1em;
    border-radius: 6px;
    margin-bottom: 1em;
}

.rules-fieldset {
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 16px 20px;
    margin-bottom: 16px;
}

.rules-legend {
    font-weight: 600;
    color: #1e3c72;
    padding: 0 8px;
}

.rules-grid {
    display: grid;
    gap: 10px;
    margin-top: 8px;
}

.rules-label {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 14px;
}

.rules-input {
    width: 70px;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 14px;
}

.rules-input--narrow {
    width: 60px;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 14px;
}

.rules-actions {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.rules-save-status {
    font-size: 14px;
}

@media (max-width: 640px) {
    body.page-group-admin .section-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }

    body.page-group-admin .data-table {
        font-size: 13px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — admin/groups page (was inline <style> + inline attrs)                  */
/* ═══════════════════════════════════════════════════════════════════════════ */

body.page-admin-groups .card {
    margin-bottom: 24px;
}

body.page-admin-groups .section-title {
    font-size: 18px;
    font-weight: 600;
    color: #1e3c72;
    margin-bottom: 16px;
}

body.page-admin-groups .form-group {
    margin-bottom: 16px;
}

body.page-admin-groups input[type="text"] {
    height: 44px;
}

.create-row {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: flex-end;
}

.create-row .form-group {
    flex: 1;
    min-width: 200px;
    margin-bottom: 0;
}

body.page-admin-groups .btn-primary {
    display: inline-block;
    padding: 0 24px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.1s;
    height: 44px;
    white-space: nowrap;
    vertical-align: bottom;
}

body.page-admin-groups .btn-primary:hover {
    opacity: 0.92;
    transform: translateY(-1px);
}

body.page-admin-groups .btn-primary:active {
    transform: translateY(0);
}

body.page-admin-groups .btn-primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

.groups-table {
    width: 100%;
    border-collapse: collapse;
}

.groups-table thead tr {
    background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
}

.groups-table thead th {
    color: white;
    font-size: 14px;
    font-weight: 600;
    padding: 12px 16px;
    text-align: left;
}

.groups-table tbody td {
    padding: 14px 16px;
    font-size: 14px;
    color: #374151;
    border-bottom: 1px solid #e5e7eb;
}

.groups-table tbody tr:last-child td {
    border-bottom: none;
}

.groups-table tbody tr:nth-child(even) {
    background: #f9fafb;
}

.slug-cell {
    font-family: 'Courier New', Consolas, monospace;
    font-size: 13px;
    color: #6b7280;
}

.manage-link {
    color: #667eea;
    text-decoration: none;
    font-weight: 600;
    font-size: 14px;
}

.manage-link:hover {
    text-decoration: underline;
}

@media (max-width: 640px) {
    body.page-admin-groups .create-row {
        flex-direction: column;
    }

    body.page-admin-groups .create-row .btn-primary {
        width: 100%;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — admin/scores page (was inline <style>; no inline attrs)                */
/* ═══════════════════════════════════════════════════════════════════════════ */

body.page-admin-scores .card {
    max-width: 960px;
}

body.page-admin-scores .hint {
    font-size: 14px;
    color: #6b7280;
    margin-bottom: 24px;
    line-height: 1.5;
}

.stage-section {
    margin-bottom: 32px;
}

.stage-section h2 {
    font-size: 18px;
    font-weight: 600;
    color: #1e3c72;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 2px solid #e5e7eb;
}

.match-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.match-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 12px 16px;
    background: #f9fafb;
    border-radius: 10px;
    border: 1px solid #e5e7eb;
}

.match-row.locked {
    opacity: 0.55;
}

.teams {
    font-size: 14px;
    font-weight: 600;
    color: #111827;
    min-width: 160px;
    flex: 1;
}

.kickoff {
    font-size: 13px;
    color: #6b7280;
    min-width: 140px;
}

body.page-admin-scores .score-input {
    width: 52px;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 14px;
    text-align: center;
}

.score-sep {
    font-size: 16px;
    font-weight: 600;
    color: #6b7280;
}

.pk-select {
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    padding: 4px 8px;
    font-size: 13px;
    color: #374151;
}

.btn-save {
    padding: 6px 16px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.btn-save:hover {
    opacity: 0.9;
}

.row-status {
    font-size: 13px;
    min-width: 60px;
}

body.page-admin-scores .nav-links {
    margin-bottom: 16px;
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

body.page-admin-scores .nav-links a {
    font-size: 14px;
    color: #667eea;
    text-decoration: none;
    font-weight: 600;
}

body.page-admin-scores .nav-links a:hover {
    text-decoration: underline;
}

@media (max-width: 640px) {
    body.page-admin-scores .match-row { flex-direction: column; align-items: flex-start; }
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T58 — admin/users page (was inline <style> + inline attrs)                   */
/* ═══════════════════════════════════════════════════════════════════════════ */

.users-table {
    width: 100%;
    border-collapse: collapse;
}

.users-table thead tr {
    background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
}

.users-table thead th {
    color: white;
    font-size: 14px;
    font-weight: 600;
    padding: 16px;
    text-align: left;
}

.users-table tbody tr:nth-child(even) {
    background: #f9fafb;
}

.users-table tbody td {
    padding: 16px;
    font-size: 14px;
    font-weight: 400;
    color: #374151;
    border-bottom: 1px solid #e5e7eb;
}

body.page-admin-users .btn-primary {
    padding: 10px 16px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border: none;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.1s;
    white-space: nowrap;
}

body.page-admin-users .btn-primary:hover {
    opacity: 0.92;
    transform: translateY(-1px);
}

body.page-admin-users .btn-primary:active {
    transform: translateY(0);
}

body.page-admin-users .btn-secondary {
    padding: 10px 16px;
    background: white;
    color: #374151;
    border: 2px solid #e5e7eb;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.2s;
}

body.page-admin-users .btn-secondary:hover {
    border-color: #667eea;
}

.btn-link {
    background: none;
    border: none;
    color: #667eea;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    padding: 10px 16px;
}

.btn-link:hover {
    text-decoration: underline;
}

.modal-backdrop {
    /* T59: hidden by default via .is-hidden in markup; visible state is flex */
    display: flex;
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    align-items: center;
    justify-content: center;
}

body.page-admin-users .modal-card {
    background: white;
    border-radius: 20px;
    max-width: 440px;
    width: 90%;
    padding: 36px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}

body.page-admin-users .modal-title {
    font-size: 24px;
    font-weight: 600;
    margin-bottom: 16px;
    color: #111827;
}

.warning-notice {
    background: #fef2f2;
    border-left: 4px solid #ef4444;
    padding: 12px 14px;
    color: #991b1b;
    font-size: 14px;
    font-weight: 400;
    margin-bottom: 24px;
    border-radius: 0 8px 8px 0;
}

body.page-admin-users .modal-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 24px;
}

/* T58 — replaces inline style on #modal-target */
.modal-target {
    font-size: 16px;
    font-weight: 400;
    color: #374151;
    margin-bottom: 8px;
}

.token-reveal {
    border: 2px dashed #667eea;
    border-radius: 10px;
    padding: 24px;
    margin-bottom: 24px;
}

.token-reveal h3 {
    font-size: 24px;
    font-weight: 600;
    color: #1e3c72;
    margin-bottom: 16px;
}

.token-reveal p {
    font-size: 16px;
    font-weight: 400;
    color: #374151;
    margin-bottom: 16px;
    line-height: 1.5;
}

.token-reveal code {
    font-family: 'Courier New', 'Consolas', monospace;
    font-size: 16px;
    font-weight: 400;
    color: #667eea;
    background: #f9fafb;
    padding: 12px 16px;
    border-radius: 8px;
    display: block;
    user-select: all;
    margin: 16px 0;
    word-break: break-all;
}

.token-actions {
    display: flex;
    gap: 8px;
    margin-top: 16px;
    flex-wrap: wrap;
}

body.page-admin-users .empty-state {
    text-align: center;
    padding: 48px 0;
}

body.page-admin-users .empty-state h3 {
    font-size: 24px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 8px;
}

body.page-admin-users .empty-state p {
    font-size: 16px;
    font-weight: 400;
    color: #6b7280;
    line-height: 1.5;
}

/* T25 — role toggles in the Roles column */
.role-toggles {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: center;
}

.role-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 500;
    color: #374151;
    cursor: pointer;
    user-select: none;
}

.role-toggle input[type="checkbox"] {
    cursor: pointer;
    width: 16px;
    height: 16px;
    accent-color: #667eea;
}

.role-toggle input[type="checkbox"]:disabled {
    cursor: not-allowed;
}

.role-status {
    font-size: 12px;
    min-width: 18px;
}

.role-status.ok { color: #15803d; }
.role-status.err { color: #991b1b; }

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T76 — Join overlay (iframe-embedded form)                                      */
/* Reuses: form-group, label, input[type="text"], error-text, btn-primary        */
/* ═══════════════════════════════════════════════════════════════════════════ */

.join-overlay-body {
    margin: 0;
    padding: 24px;
    background: white;
}

.join-form-wrapper {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.join-overlay-body .form-group {
    margin-bottom: 0;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T59 — classes for styles formerly set imperatively in JS (.style.* / cssText) */
/* Pure refactor: every rule below reproduces a value that used to live in        */
/* inline JS. Genuinely dynamic values (e.g. champion-overlay iframe height in     */
/* group.html) intentionally remain in JS and are NOT represented here.            */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* --- Status text colors (hex variants: admin/users, admin/groups) --- */
.status-ok { color: #15803d; }
.status-error { color: #991b1b; }

/* --- Status text colors (CSS keyword variants: admin/scores, group-admin) --- */
/* Kept distinct from the hex variants above so rendering stays byte-identical:    */
/* the legacy code used the 'green'/'red' keywords here, not #15803d/#991b1b.      */
.status-ok-kw { color: green; }
.status-error-kw { color: red; }

/* --- Neutral / muted helper text (loading + empty spans, helper notes) --- */
.muted-note { color: #6b7280; }

/* admin/scores.html — helper paragraph under the title (was p2 inline styles) */
.scores-help-note {
    margin-top: 8px;
    font-size: 13px;
    color: #6b7280;
}

/* admin/users.html — access-denied paragraph (was accessP.style.cssText, an  */
/* inline style). Scoped under the page body so it beats the lower            */
/* `body.page-admin-users .empty-state p { color:#6b7280 }` descendant rule   */
/* and renders red, exactly as the old inline style did.                       */
body.page-admin-users .empty-state p.access-denied-note {
    color: #991b1b;
    font-size: 16px;
    font-weight: 400;
}

/* --- Monospace identifier values (admin/groups slug, group-admin invite id) --- */
/* Base = font-family only (group-admin invite id had no color override).        */
/* The --muted modifier adds grey, matching admin/groups slug which did.          */
.mono-value {
    font-family: 'Courier New', Consolas, monospace;
}
.mono-value--muted {
    color: #6b7280;
}

/* --- admin/users.html detail builders (buildSkinField / memberships) --- */
.user-detail-field {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
}
.user-detail-field--gap8 {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
}
.user-detail-select {
    width: 100%;
}
.user-detail-label {
    font-weight: 600;
    font-size: 13px;
}
.user-detail-save-btn {
    margin-top: 4px;
}
.user-detail-status {
    font-size: 13px;
    margin-left: 8px;
}
.user-detail-save-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.membership-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.membership-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 0;
    border-bottom: 1px solid #f3f4f6;
}
.membership-row-label {
    font-size: 14px;
    color: #374151;
}
.membership-toggle-btn {
    padding: 6px 12px;
    font-size: 13px;
}

/* admin/users.html — secondary action buttons spaced after the primary one */
.btn-spaced-left {
    margin-left: 8px;
}

/* --- admin/groups.html appearance form (skin + language selects) --- */
.appear-field {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
}
.appear-label {
    font-weight: 600;
    font-size: 13px;
}
.appear-select {
    width: 100%;
}
.appear-save-btn {
    margin-top: 6px;
}
.appear-status {
    font-size: 13px;
    margin-left: 8px;
}
.appear-save-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* --- group.html — locked-match member-row indent (was paddingLeft inline) --- */
.member-indent {
    padding-left: 32px;
}

/* --- champion.html — disabled submit button cursor --- */
.cursor-not-allowed {
    cursor: not-allowed;
}

/* --- forgot-password.html — retry link color --- */
.retry-link {
    color: #667eea;
}

/* --- group.html — body scroll-lock while the champion overlay is open --- */
body.modal-open {
    overflow: hidden;
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* T61 — account.html read-only profile                                        */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* The username in the navbar is a link (T61). It keeps the .nav-username look
   and inherits the .nav a rules; only the hover affordance is added here so it
   reads as clickable. */
a.nav-username {
    text-decoration: none;
}
a.nav-username:hover {
    opacity: 1;
    text-decoration: underline;
}

/* Profile field list: label / value pairs laid out as a two-column grid that
   collapses to stacked rows on narrow screens. */
.profile-list {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 8px 20px;
    margin: 8px 0 24px;
}
.profile-list dt {
    font-weight: 600;
    color: #374151;
}
.profile-list dd {
    margin: 0;
    color: #111827;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

@media (max-width: 480px) {
    .profile-list {
        grid-template-columns: 1fr;
        gap: 2px 0;
    }
    .profile-list dd {
        margin-bottom: 12px;
    }
}

/* Group memberships: badge + name rows, no list bullets. */
.account-group-list {
    list-style: none;
    padding: 0;
    margin: 8px 0 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.account-group-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
}

/* ── Phase 7 — "Grille" comparison matrix (COMP-01) ──────────────────────────
   Wide-grid mobile strategy (D-09): sticky left match column + horizontal
   scroll for member columns; nothing hidden. Bucket cell colors are applied
   inline (skin-neutral fixed hex, D-20) — not here. */
.grid-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Never exceed the card's content box at ANY width. With .card-body now
       min-width:0, this is the width-constrained scroll container: the
       max-content .grid-table scrolls horizontally WITHIN the card (sticky match
       column preserved) instead of pushing the table/badges off-page (>1000px). */
    max-width: 100%;
}
.grid-table {
    border-collapse: collapse;
    width: max-content;
    min-width: 100%;
    font-size: 14px;
}
.grid-table th,
.grid-table td {
    padding: 6px 8px;
    border: 1px solid #e5e7eb;
    text-align: center;
    vertical-align: middle;
}
.grid-col-head {
    min-width: 72px;
    font-size: 13px;
    font-weight: 600;
    background: #f9fafb;
    white-space: nowrap;
}
.grid-col-average,
.grid-col-robot {
    font-style: italic;
    color: #5A5A66;
}
.grid-name-link {
    color: var(--l2c-blue-500, #00A0DB);
    text-decoration: none;
}
.grid-name-link:hover {
    text-decoration: underline;
}
/* Sticky left column (row header) + sticky corner so member cells slide under. */
.grid-table th:first-child,
.grid-table td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: #fff;
    box-shadow: 2px 0 0 -1px #e5e7eb, 6px 0 6px -4px rgba(0, 0, 0, 0.12);
}
.grid-corner {
    background: #f9fafb !important;
    min-width: 90px;
    z-index: 2;
}
/* Match column: full label at rest (🇦🇷 Argentina 2–1 Mexico 🇲🇽) on one line.
   The team NAME spans collapse away once the matrix is side-scrolled
   (.grid-scroll.is-scrolled, toggled in group.html loadGrid), leaving just
   flags + score (🇦🇷 2–1 🇲🇽) so the sticky column shrinks and frees horizontal
   room. min-width is only the collapsed floor — content grows the cell at rest. */
.grid-row-head {
    min-width: 90px;
    text-align: left;
    font-weight: 600;
    color: #1e3c72;
    white-space: nowrap;
}
.grid-rh-name {
    margin: 0 0.35em;
}
.grid-rh-mid {
    margin: 0 0.3em;
    font-variant-numeric: tabular-nums;
}
/* The collapse: drop team names once the matrix has been scrolled horizontally. */
.grid-scroll.is-scrolled .grid-row-head .grid-rh-name {
    display: none;
}
.grid-cell {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.grid-cell-score {
    font-weight: 600;
}
.grid-cell .points-earned {
    margin-left: 4px;
}

/* Narrow-viewport prono-cell collapse (≤700px): drop verbose chrome so more
   players fit and cells aren't cramped. Each cell collapses to a tight
   score-over-badge stack; row/column headers and cell padding tighten so the
   member columns shrink visibly and more fit before the horizontal scroll
   kicks in. Skin-neutral (no var(--l2c-*)) and i18n-safe — this is pure CSS
   layout, no JS-built label is changed, so no __i18nOnLangChange re-render is
   needed (the score/badge text is the same in both languages). */
@media (max-width: 700px) {
    .grid-table {
        font-size: 12px;
    }
    .grid-table th,
    .grid-table td {
        padding: 3px 4px;
    }
    /* Member-name column heads: shrink hard. The link wraps onto ≤2 lines so a
       long display name no longer forces a wide column. */
    .grid-col-head {
        min-width: 44px;
        max-width: 64px;
        font-size: 11px;
        white-space: normal;
        word-break: break-word;
        line-height: 1.15;
    }
    .grid-corner,
    .grid-row-head {
        min-width: 78px;
        font-size: 11px;
    }
    .grid-row-head {
        /* Keep the full label on ONE line at rest (no wrap → no vertical sprawl,
           the original ≤700px complaint); side-scrolling collapses it to flags +
           score via .is-scrolled, so the wide name column is transient on mobile. */
        white-space: nowrap;
        line-height: 1.15;
    }
    .grid-cell {
        /* Score-only stack: predicted score on top, compact points pill beneath
           (instead of beside), so the cell column stays ~44px narrow. */
        white-space: normal;
        line-height: 1.1;
    }
    .grid-cell-score {
        display: block;
    }
    .grid-cell .points-earned {
        display: inline-block;
        margin-left: 0;
        margin-top: 2px;
        padding: 0 4px;
        font-size: 9px;
        line-height: 1.4;
    }
}

/* Phone-width (≤360px): squeeze a touch more — minimal cell padding so the
   spreadsheet stays usable with the sticky match column. */
@media (max-width: 360px) {
    .grid-table th,
    .grid-table td {
        padding: 2px 3px;
    }
    .grid-col-head {
        min-width: 40px;
        max-width: 52px;
    }
    .grid-corner,
    .grid-row-head {
        min-width: 72px;
    }
}

/* ── Phase 7 — Profile page is a full-width analytics page ────────────────────
   Unlike the login-style row card (300px gradient sidebar + body), the profile
   card stays VERTICAL/full-width at every width: a full-width header banner on
   top + a full-width body. Without this, at >1000px the base `.card` flips to
   `flex-direction:row` and squeezes the body to ~600px beside the 300px header —
   which clipped the Chart.js canvases (~1/3 cut off). Forcing column keeps the
   body ~888px so the charts + bracket get the full width. */
body.page-profile .card {
    flex-direction: column;
}
body.page-profile .card-header {
    max-width: none;
}

/* ── Phase 7 — Profile bracket (COMP-02 / D-14) ──────────────────────────────
   The KO rounds render as BOTH a wide CSS bracket-TREE (.bracket-tree, shown
   ≥1000px and scrollable horizontally inside the card) and a narrow stage-LIST
   fallback (.bracket-list, <1000px). Scored-pick tints are skin-neutral fixed
   hex (D-20); bracket.js applies the bucket bg/ink inline and these shared
   classes carry the SAME fixed hex so the tints are also expressed in CSS. */
.profile-bracket {
    margin-bottom: 24px;
}
.bracket-group-stage {
    margin-bottom: 24px;
}

/* The bucket tints — DARKER than the original UI-SPEC pastels for legibility
   (checkpoint feedback: #dcfce7/#dbeafe read "almost invisible"). Skin-neutral
   fixed hex (mirrors the grid GRID_BUCKET_STYLE); each carries a saturated
   left-border accent so the bucket stays readable even where the fill washes
   out — identical on l2c + argentina (D-20, no var(--l2c-*)). */
.bracket-node.bucket-exact_score {
    background: #a7f3d0;
    color: #065f46;
    border-left: 4px solid #059669;
}
.bracket-node.bucket-correct_winner,
.bracket-node.bucket-correct_draw_outcome {
    background: #bfdbfe;
    color: #1e3a8a;
    border-left: 4px solid #2563eb;
}
.bracket-node.bucket-miss {
    background: #e5e7eb;
    color: #4b5563;
    border-left: 4px solid #9ca3af;
}
.bracket-node.bucket-pending {
    background: #f9fafb;
    color: #9ca3af;
}

/* Per-tie node, building on .match-card. */
.bracket-node {
    padding: 10px 12px;
    font-size: 14px;
}
.bracket-node-teams {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-weight: 600;
}
.bracket-team {
    white-space: nowrap;
}
.bracket-node-pred {
    margin-top: 6px;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}
.bracket-node-result {
    margin-top: 2px;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    opacity: 0.85;
}
.bracket-node-points {
    margin-top: 6px;
}

/* Bracket display strategy (D-14 — "never a sideways-squeezed tree"; COMP-02).
   The profile card is full-width vertical (body ~888px), but a full 6-round KO
   tree (r32→r16→qf→sf→3rdplace→final) needs 6×170 + 5×16 = 1100px — more than
   the card ever offers. Rather than break out of the card (which fought
   `.card { overflow:hidden }` and clipped the final round with no scroll), the
   tree scrolls HORIZONTALLY inside the card at ≥1000px — the app's .grid-scroll
   idiom (.card-body has min-width:0, so the overflow-x:auto tree is the
   width-constrained scroll container and never bursts/clips). Below 1000px the
   stacked stage-list is shown — the spec endorses it as satisfying COMP-02 and
   it's the clean phone/tablet view. DEVIATION from D-14's locked ≤639px list
   breakpoint (raised to <1000px) is documented in deferred-items.md.
   DEFAULT (mobile-first): list shown, tree hidden; the ≥1000px query swaps. */
.bracket-tree {
    display: none;
}
.bracket-list {
    display: block;
}
.bracket-round {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    gap: 16px;
    min-width: 170px;
    flex: 0 0 auto;
}
.bracket-round-title {
    font-size: 13px;
    font-weight: 600;
    color: #6b7280;
    text-align: center;
    margin: 0 0 4px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
/* CSS-only connector line between a node and the next round (decorative). */
.bracket-round:not(.bracket-round-final) .bracket-node {
    position: relative;
}
.bracket-round:not(.bracket-round-final) .bracket-node::after {
    content: '';
    position: absolute;
    top: 50%;
    right: -16px;
    width: 16px;
    border-top: 2px solid #e5e7eb;
    pointer-events: none;
}

/* ≥1000px (desktop): show the wide KO tree, scrollable horizontally INSIDE the
   card. No container breakout — overflow-x:auto makes the tree the scroll
   container, constrained to the card-body width via its min-width:0, so the
   final round is always reachable by scrolling and nothing is clipped. The
   stacked stage-list hides. Below 1000px the mobile-first defaults keep it. */
@media (min-width: 1000px) {
    .bracket-tree {
        display: flex;
        gap: 16px;
        align-items: stretch;
        padding-bottom: 8px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .bracket-list {
        display: none;
    }
}

/* ── Phase 7 — Profile charts (COMP-03/04/05) ────────────────────────────────
   Each chart sits in a .card-bordered block with a .stage-heading title + a
   fixed-height canvas wrap (Chart.js needs a sized parent with
   maintainAspectRatio:false). Skin-neutral — no var(--l2c-*). */
.profile-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}
.profile-group-switcher {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: #6b7280;
}
.profile-group-switcher select {
    min-height: 44px;
}
.chart-block {
    margin-top: 24px;
}
.chart-title {
    margin-top: 0;
}
.chart-canvas-wrap {
    position: relative;
    height: 300px;
}
.chart-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-bottom: 12px;
}
.chart-control {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: #6b7280;
}
.chart-control select {
    min-height: 44px;
}
.chart-control-toggle {
    font-weight: 400;
}

/* ═══════════════════════════════════════════════════════════════════════════
   GROUP PAGE NAVIGATION (T111 / T112 / T113 / T117) — quick-260623-iis
   All rules scoped to .group-page so the sticky nav/tabs never leak to the
   other pages that reuse .nav / .tabs.
   ═══════════════════════════════════════════════════════════════════════════ */

/* T113 — sticky, "headroom"-style header + tabs.
   The site nav pins to the top; the tabs pin directly below it using a measured
   nav height (--group-sticky-h, set by JS on load + resize). Scrolling DOWN
   slides both out of view (body.chrome-hidden); scrolling UP a little brings
   them back. */
/* The base .card uses `overflow: hidden` to contain the wide Grille table.
   But an ancestor with a scrolling mechanism (hidden/auto/scroll) captures
   sticky descendants — it would stop .tabs from pinning. `overflow: clip`
   clips identically (Grille stays contained) yet is NOT a scroll container,
   so .tabs sticks to the viewport. Browsers without `clip` drop this rule and
   fall back to the base `hidden` (tabs simply don't pin — graceful). */
.group-page .card {
    overflow: clip;
}

.group-page .nav {
    position: sticky;
    top: 0;
    z-index: 40;
    transition: transform 0.25s ease;
}

.group-page .tabs {
    position: sticky;
    top: var(--group-sticky-h, 56px);
    z-index: 30;
    background: #fff;
    /* Cover the rounded card edge + give the pinned bar a subtle lift. */
    padding-top: 4px;
    margin-top: -4px;
    box-shadow: 0 4px 6px -6px rgba(0, 0, 0, 0.25);
    transition: transform 0.25s ease;
}

/* Headroom: hide both bars when scrolling down past the chrome. The tabs
   travel further (its own height + the nav's) so it never peeks under the nav. */
.group-page.chrome-hidden .nav {
    transform: translateY(-120%);
}
.group-page.chrome-hidden .tabs {
    transform: translateY(calc(-100% - var(--group-sticky-h, 56px) - 12px));
}

@media (prefers-reduced-motion: reduce) {
    .group-page .nav,
    .group-page .tabs {
        transition: none;
    }
}

/* Programmatic scroll-to-card (T111/T112/T117) must clear the sticky chrome:
   land the card below nav + tabs, not behind them. */
.group-page .match-card {
    scroll-margin-top: calc(var(--group-sticky-h, 56px) + 64px);
}

/* T117 — per-card 🔗 deep-link copy button. Sits at the LEFT of the card header
   so it never collides with the T90 urgent red corner triangle (top-right). */
.match-link-copy {
    background: transparent;
    border: none;
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    padding: 4px 6px;
    margin-right: 6px;
    border-radius: 6px;
    color: #9ca3af;
    transition: background-color 0.15s, color 0.15s;
}
.match-link-copy:hover {
    color: #667eea;
    background: rgba(102, 126, 234, 0.1);
}
.match-link-copy:focus-visible {
    outline: 2px solid #667eea;
    outline-offset: 1px;
}

/* T117 — brief highlight when a deep-link lands on a card. */
.match-card--targeted {
    animation: match-target-flash 2.2s ease-out;
}
@keyframes match-target-flash {
    0%, 30%   { box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.55); }
    100%      { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); }
}
@media (prefers-reduced-motion: reduce) {
    .match-card--targeted { animation: none; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.55); }
}

/* T112 — floating "jump to next upcoming match" button (bottom-right). */
.fab-jump-next {
    position: fixed;
    right: 18px;
    bottom: 18px;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: none;
    cursor: pointer;
    font-size: 24px;
    line-height: 1;
    color: #fff;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.18s ease, opacity 0.18s ease;
}
.fab-jump-next:hover {
    transform: translateY(-2px) scale(1.05);
}
.fab-jump-next:focus-visible {
    outline: 3px solid #fff;
    outline-offset: -3px;
}
.fab-jump-next[hidden] {
    display: none;
}
@media (prefers-reduced-motion: reduce) {
    .fab-jump-next { transition: none; }
    .fab-jump-next:hover { transform: none; }
}
