/* ===== CSS Variables ===== */
:root {
    --bg-primary: #000000;
    --bg-secondary: #0a0a0a;
    --bg-tertiary: #1a1a1a;
    --bg-card: #141414;
    --border-color: #2a2a2a;
    --text-primary: #ffffff;
    --text-secondary: #a0a0b0;
    --text-muted: #6a6a7a;
    --accent-primary: #7CFF00;
    --accent-secondary: #a8ff4d;
    /* Dark ink preserves the lime brand surface while keeping button text
       readable. White on --accent-primary is only about 1.3:1 contrast. */
    --accent-ink: #081400;
    /* Channel values so translucent variants follow the brand. 25 rgba() glows
       and focus rings were still hardcoded to the pre-rebrand indigo, so
       selection states rendered in the old colour while the accent was green. */
    --accent-rgb: 124, 255, 0;
    --accent-secondary-rgb: 168, 255, 77;
    --accent-success: #22c55e;
    --accent-warning: #f59e0b;
    --accent-danger: #ef4444;
    /* Pitch presets, retuned as board surfaces rather than poster-paint grass.
       The old classic (#2d8f4e) was bright enough to compete with the brand
       accent for attention; the board should recede so the players read first.
       "Light" stays genuinely light for exports that need a printable pitch. */
    --pitch-classic: #1c4231;
    --pitch-dark: #143226;
    --pitch-light: #2e7a52;
    --pitch-night: #0f231b;
    /* Pitch markings are chalk on a board, not solid white paint. */
    --chalk-line: rgba(233, 242, 236, 0.42);
    --chalk-line-soft: rgba(233, 242, 236, 0.22);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5);
    --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.6);
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;
    --radius-xl: 24px;
    --transition-fast: 0.15s ease;
    --transition-normal: 0.25s ease;
    --transition-slow: 0.4s ease;

    /* Type. Inter for interface, IBM Plex Mono for anything countable - squad
       numbers, formation notation, counts. Numerals are the vernacular of a
       team sheet, so they get the instrument face rather than the UI face. */
    --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

    /* Type scale, 1.25 ratio. The stylesheet previously had no scale at all,
       so sizes were ad hoc across 8,000 lines. */
    --text-xs: 0.6875rem;   /* 11px - micro labels, position tags */
    --text-sm: 0.8125rem;   /* 13px - secondary UI */
    --text-base: 0.9375rem; /* 15px - body */
    --text-md: 1.125rem;    /* 18px */
    --text-lg: 1.4375rem;   /* 23px */
    --text-xl: 1.8125rem;   /* 29px */

    /* Spacing scale, 4px base. Also previously absent. */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-8: 3rem;

    /* Fixed chrome heights, so layout maths can account for both. */
    --header-h: 60px;
    --footer-h: 30px;

    /* Fixed-layer contract for mobile chrome and modal surfaces. */
    --z-pitch: 10;
    --z-header: 100;
    --z-context: 95;
    --z-scrim: 96;
    --z-sheet: 97;
    --z-mobile-nav: 101;
    --z-modal: 1100;
    --z-promo: 1200;
}

.error-page {
    min-height: 100vh;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 1rem;
    padding: 2rem;
    text-align: center;
}

.error-page p {
    color: var(--text-secondary);
}

/* ===== Reset & Base ===== */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 16px;
    scroll-behavior: smooth;
}

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--bg-primary);
    color: var(--text-primary);
    min-height: 100vh;
    overflow-x: hidden;
    line-height: 1.5;
}

/* Full width, height driven by its own content, contents right-aligned and
   spaced out. It used to be a centred strip; with the crawlable intro section
   above it removed, the footer is the only thing in this band and can own it. */
.site-footer {
    position: relative;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    width: 100%;
    height: auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem 1.75rem;
    padding: 0.6rem 1.25rem;
    background: rgba(10, 10, 15, 0.92);
    border-top: 1px solid var(--border-color);
    font-size: 0.72rem;
    color: var(--text-muted);
    text-align: right;
    letter-spacing: 0.02em;
    backdrop-filter: blur(4px);
}

/* Keep the site links on their own row; the bottom row separates copyright
   from the Donate button. */
.site-footer nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.75rem 1.5rem;
    margin-left: auto;
}

.site-footer p {
    margin: 0;
    margin-left: auto;
}

.site-footer a {
    color: var(--accent-primary);
    text-decoration: none;
}

.site-footer a:hover {
    text-decoration: underline;
}

/* ===== Header ===== */
.header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* Vertical padding tightened from 0.75rem when the logo grew 25% (56 -> 70px).
       The logo drives the header height, and the header eats the board: the pitch
       is aspect-locked and sized by AVAILABLE HEIGHT, so every pixel here is a
       pixel off the pitch. scripts/check_bundle.mjs caps this at 84px and caught
       the regression at 95px. */
    padding: 0.3rem 1.5rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border-color);
    position: sticky;
    top: 0;
    z-index: var(--z-header);
}

.header-brand {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.logo {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--text-primary);
    text-decoration: none;
}

.logo:hover {
    color: var(--text-primary);
}

/* 25% larger than the previous 56px. */
.app-logo {
    width: 70px;
    height: 70px;
    box-shadow: var(--shadow-sm);
    object-fit: contain;
    border-radius: 8px;
}

.wordmark {
    display: none;
    font-family: 'Orbitron', 'Inter', sans-serif;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

.wordmark span:last-child {
    color: var(--accent-primary);
}

.usmnt-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background: linear-gradient(135deg, #002868, #001845);
    border: 1px solid #bf0a30;
    border-radius: var(--radius-md);
    color: white;
    text-decoration: none;
    font-size: 0.8125rem;
    font-weight: 600;
    transition: all var(--transition-fast);
}

.usmnt-link-disabled {
    opacity: 0.65;
    cursor: not-allowed;
    pointer-events: none;
}

.usmnt-link:hover {
    background: linear-gradient(135deg, #bf0a30, #8b0721);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(191, 10, 48, 0.3);
}

.usmnt-flag {
    font-size: 1.125rem;
}

@media (max-width: 768px) {
    .usmnt-link span:not(.usmnt-flag) {
        display: none;
    }
    
    .usmnt-link {
        padding: 0.5rem 0.625rem;
    }

    .site-footer {
        bottom: auto;
        font-size: 0.66rem;
        gap: 0.4rem;
        padding: 0.3rem 0.5rem;
    }
}

.nav-tabs {
    display: flex;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    gap: 0.5rem;
    background: var(--bg-tertiary);
    padding: 0.25rem;
    border-radius: var(--radius-lg);
}

.nav-tab {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 1.25rem;
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.nav-tab:hover {
    color: var(--text-primary);
    background: var(--bg-card);
}

.nav-tab.active {
    background: var(--accent-primary);
    color: var(--accent-ink);
}

.header-actions {
    display: flex;
    gap: 0.75rem;
    position: relative;
    align-items: center;
}

.donate-mini {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    height: 36px;
    min-width: 74px;
    padding: 0 0.65rem;
    border-radius: var(--radius-md);
    /* Gold, with a sheen that travels across the face. The gradient supplies
       the metal (deep amber in the corners, near-white at the midpoint); the
       ::after pass is a narrow highlight that sweeps on hover. */
    position: relative;
    overflow: hidden;
    isolation: isolate;
    border: 1px solid #b8860b;
    background: linear-gradient(135deg, #b8860b 0%, #e8b923 28%, #fff3b0 50%, #e8b923 72%, #b8860b 100%);
    color: #2b1d02;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35);
    text-decoration: none;
    font-size: 0.72rem;
    font-weight: 700;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.5);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast),
                filter var(--transition-fast);
}

.pro-mini {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    height: 36px;
    min-width: 82px;
    padding: 0 0.65rem;
    border-radius: var(--radius-md);
    position: relative;
    overflow: hidden;
    isolation: isolate;
    border: 1px solid var(--accent-primary);
    background: linear-gradient(135deg, #1b3a1f 0%, #2f6b33 45%, #57b45c 100%);
    color: #eaffea;
    text-decoration: none;
    font-size: 0.72rem;
    font-weight: 700;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.18);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast),
                filter var(--transition-fast);
}

.pro-mini::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, 0.5) 50%, transparent 62%);
    transform: translateX(-120%);
    transition: transform 0.7s ease;
}

.pro-mini:hover::after,
.pro-mini:focus-visible::after {
    transform: translateX(120%);
}

.pro-mini:hover,
.pro-mini:focus-visible {
    transform: translateY(-1px);
    filter: brightness(1.08);
    box-shadow: 0 4px 10px rgba(87, 180, 92, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

.donate-mini::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.75) 50%, transparent 65%);
    transform: translateX(-120%);
    transition: transform 0.7s ease;
}

.donate-mini:hover::after,
.donate-mini:focus-visible::after {
    transform: translateX(120%);
}

/* Share picks up a restrained version of the same treatment: a sheen sweep,
   but keeping the neutral surface so it does not compete with Export PNG. */
#shareBtn {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}

#shareBtn::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.28) 50%, transparent 60%);
    transform: translateX(-120%);
    transition: transform 0.7s ease;
}

#shareBtn:hover::after,
#shareBtn:focus-visible::after {
    transform: translateX(120%);
}

@media (prefers-reduced-motion: reduce) {
    .donate-mini::after,
    #shareBtn::after {
        transition: none;
    }
}

.donate-mini i {
    font-size: 0.9rem;
}

.donate-mini:hover,
.donate-mini:focus-visible {
    transform: translateY(-1px);
    filter: brightness(1.06);
    box-shadow: 0 4px 10px rgba(184, 134, 11, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

@media (max-width: 768px) {
    .donate-mini {
        min-width: 40px;
        width: 40px;
        padding: 0;
        gap: 0;
    }

    .donate-mini span {
        display: none;
    }
}

.history-actions {
    display: flex;
    gap: 0.375rem;
}

/* Without this the wrapper is a plain block inside a flex row, so its two
   buttons stack vertically and force the whole header taller - and wider,
   because the row then has to fit a two-line item. Same shape as
   .history-actions. */
.draft-actions {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.autosave-status {
    color: var(--text-muted);
    font-size: var(--text-xs);
    grid-column: 1 / -1;
    justify-self: end;
    max-width: 100%;
    text-align: right;
    white-space: normal;
}

.autosave-status:not([data-mode="conflict"]):not([data-mode="error"]):not([data-mode="corrupt"]):not([data-mode="cleared"]) {
    display: none;
}

.history-btn {
    padding: 0.5rem 0.625rem;
    min-width: 38px;
    justify-content: center;
}

.history-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.recent-changes {
    position: relative;
    align-self: center;
    font-size: var(--text-xs);
}

.recent-changes summary {
    min-height: 38px;
    display: flex;
    align-items: center;
    padding: 0 0.5rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    background: var(--bg-card);
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
}

.recent-changes summary::-webkit-details-marker { display: none; }
.recent-changes[open] summary { color: var(--text-primary); border-color: var(--accent-primary); }

.recent-changes ol {
    position: absolute;
    z-index: 30;
    top: calc(100% + 0.375rem);
    left: 0;
    width: min(18rem, 82vw);
    max-height: 16rem;
    overflow: auto;
    margin: 0;
    padding: 0.35rem 0.5rem 0.35rem 2rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    box-shadow: var(--shadow-lg);
    color: var(--text-secondary);
}

.recent-changes li { padding: 0.35rem 0.15rem; }
.recent-changes li[aria-current="step"] { color: var(--text-primary); font-weight: 600; }


.winning-card.formation-card-focus {
    outline: 2px solid var(--accent-warning);
    outline-offset: 2px;
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.2);
}


/* ===== Buttons ===== */
/* The HTML `hidden` attribute must actually hide things. The UA stylesheet's
   [hidden]{display:none} is a single type-less selector, so ANY class rule that
   sets display beats it - .btn's `display: inline-flex` does, and so do the
   flex/grid rules on several panels. The result was that el.hidden = true set
   the property and changed nothing on screen: "Sign in to keep squads" stayed
   up after signing in, and "Save to account" was shown to users without Pro.
   Measured: hiddenProp true, computed display "flex".

   The codebase had been patching this one selector at a time
   (.editor-panel[hidden], #authDeleteConfirm[hidden], .ios-app-promo[hidden]);
   this closes the class so the next one does not have to be found by hand. */
[hidden] {
    display: none !important;
}

.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 1.25rem;
    border: none;
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.btn-primary {
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    color: var(--accent-ink);
    box-shadow: 0 4px 15px rgba(var(--accent-rgb), 0.3);
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(var(--accent-rgb), 0.4);
}

.btn-secondary {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
}

.btn-secondary:hover {
    background: var(--bg-card);
    border-color: var(--accent-primary);
}

/* Export Dropdown */
.export-dropdown {
    position: relative;
    display: flex;
}

.export-dropdown .btn-primary:first-child {
    border-radius: var(--radius-md) 0 0 var(--radius-md);
}

.export-dropdown-toggle {
    border-radius: 0 var(--radius-md) var(--radius-md) 0 !important;
    padding: 0.625rem 0.75rem !important;
    border-left: 1px solid rgba(255, 255, 255, 0.2) !important;
}

.export-dropdown-menu {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.5rem;
    min-width: 200px;
    box-shadow: var(--shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: all var(--transition-fast);
    z-index: 1000;
}

.export-dropdown-menu.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.export-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.625rem 0.875rem;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-fast);
    text-align: left;
}

.export-option:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.export-option i {
    width: 16px;
    color: var(--accent-primary);
}

/* ===== Main Content ===== */
.main-content {
    /* Subtract the fixed footer as well as the fixed header - it is 30px of
       real estate the column was previously laying out underneath. */
    height: calc(100vh - var(--header-h) - var(--footer-h));
    overflow: hidden;
}

.main-content.scroll-unlocked {
    height: auto;
    min-height: calc(100vh - var(--header-h) - var(--footer-h));
    overflow-y: auto;
    overflow-x: hidden;
    padding-bottom: 2.25rem;
}

.tab-content {
    display: none;
    height: 100%;
}

.tab-content.active {
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
}

.main-content.scroll-unlocked .tab-content,
.main-content.scroll-unlocked .tab-content.active {
    height: auto;
    min-height: 100%;
}

/* ===== Builder Layout =====
   The left rail owns pitch controls and style, the center owns the pitch, and
   the right rail owns the lineup system and players. */
.builder-container {
    display: grid;
    grid-template-columns: minmax(180px, 230px) minmax(0, 1fr) 320px;
    height: 100%;
    gap: 0;
}

/* When the lineup editor closes, its column goes away while Pitch & Style
   remains pinned on the left. */
body.editor-closed .builder-container {
    grid-template-columns: minmax(180px, 230px) minmax(0, 1fr);
}

/* Above the sheet breakpoint the builder tab is a column: the context bar
   takes its own height and the grid fills what is left, instead of the grid
   claiming 100% and pushing the bar's height into overflow. */
@media (min-width: 901px) {
    #builder-tab.tab-content.active {
        display: flex;
        flex-direction: column;
    }

    #builder-tab > .builder-container {
        flex: 1 1 auto;
        min-height: 0;
        height: auto;
        grid-template-rows: auto minmax(0, 1fr);
    }

    body.editor-closed .editor-sidebar {
        display: none;
    }

    /* Library/share/export controls and Edit/New sit over the right editor.
       The center pitch spans both rows; the left rail stays independent. */
    .lineup-action-stack {
        grid-column: 3;
        grid-row: 1;
        justify-self: stretch;
        width: 100%;
    }

    .lineup-workflow-actions > .btn { flex: 1 1 0; }

    .editor-sidebar {
        grid-column: 3;
        grid-row: 2;
        border-right: none;
        border-left: 1px solid var(--border-color);
    }

    .pitch-tools-sidebar {
        grid-column: 1;
        grid-row: 1 / span 2;
        min-width: 0;
    }

    .pitch-container {
        grid-column: 2;
        grid-row: 1 / span 2;
    }

    body.editor-closed #builder-tab > .builder-container {
        grid-template-columns: minmax(180px, 230px) minmax(0, 1fr);
        grid-template-rows: minmax(0, 1fr);
        position: relative;
    }

    body.editor-closed .lineup-action-stack {
        grid-column: 1;
        grid-row: 1;
        position: absolute;
        top: 0;
        right: var(--space-4);
        z-index: 2;
        justify-self: end;
        width: min(100%, 320px);
    }

    body.editor-closed .pitch-container {
        grid-column: 2;
        grid-row: 1;
    }

    body.editor-closed .pitch-tools-sidebar {
        grid-column: 1;
        grid-row: 1;
    }
}

.pitch-tools-sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-height: 0;
    padding: 0.75rem;
    border-right: 1px solid var(--border-color);
    background: var(--bg-primary);
    overflow-y: auto;
    scrollbar-width: thin;
}

.pitch-sidebar-section {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    flex: 0 0 auto;
}

.pitch-tools-sidebar .phase-toggle-container {
    flex: 0 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
    width: 100%;
    max-width: none;
}

.pitch-tools-sidebar .phase-toggle {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.pitch-tools-sidebar .phase-slider {
    top: 4px;
    left: 4px;
    width: calc(100% - 8px);
    height: calc(50% - 4px);
}

.pitch-tools-sidebar .phase-toggle.defensive .phase-slider { top: 50%; left: 4px; }
.pitch-tools-sidebar .phase-btn { justify-content: flex-start; min-height: 40px; padding-inline: 0.75rem; white-space: nowrap; }
.pitch-tools-sidebar .copy-phase-btn { justify-content: center; width: 100%; min-height: 40px; }

.pitch-tools-sidebar .line-tools {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
    width: 100%;
    max-width: none;
    padding: 0.75rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
}

.pitch-tools-sidebar .line-tools-buttons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }
.pitch-tools-sidebar .line-tools-buttons .btn { justify-content: center; min-width: 0; padding-inline: 0.5rem; }
.pitch-tools-sidebar .tactical-tool-status { margin: 0; line-height: 1.45; }

.pitch-appearance {
    flex: 0 0 auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--bg-secondary);
}

.pitch-appearance > summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0.65rem 0.75rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 700;
    cursor: pointer;
    list-style: none;
}

.pitch-appearance > summary::-webkit-details-marker { display: none; }
.pitch-appearance > summary i { color: var(--accent-primary); }
.pitch-appearance[open] > summary { border-bottom: 1px solid var(--border-color); }
.pitch-appearance-content { padding: 0.65rem; }
.pitch-appearance-content .panel { width: 100%; margin: 0 0 0.6rem; }
.pitch-appearance-content .panel:last-child { margin-bottom: 0; }

.sidebar {
    background: var(--bg-secondary);
    border-right: 1px solid var(--border-color);
    padding: 1rem;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--border-color) transparent;
}

.sidebar::-webkit-scrollbar {
    width: 6px;
}

.sidebar::-webkit-scrollbar-thumb {
    background: var(--border-color);
    border-radius: 3px;
}

#pitchToolsSidebar {
    padding: 0.75rem;
    border-right: 1px solid var(--border-color);
    background: var(--bg-primary);
}

/* ===== Lineup context bar =====
   The team identity and utility actions stay together above the workspace. */
.lineup-context-bar {
    display: grid;
    grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
    align-items: center;
    column-gap: 1rem;
    row-gap: 0.25rem;
    padding: 0.5rem 0.75rem;
    background: var(--bg-primary);
    border-bottom: 1px solid var(--border-color);
}

.lineup-context-identity {
    display: flex;
    align-items: center;
    min-width: 0;
}

.lineup-action-stack {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
}

.lineup-utility-actions {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.375rem;
    min-width: 0;
    justify-self: end;
}

.lineup-library-actions,
.lineup-sharing-actions,
.lineup-workflow-actions,
.lineup-history-group {
    display: flex;
    align-items: center;
    gap: 0.375rem;
}

.lineup-library-actions {
    justify-self: start;
}

.lineup-utility-actions .btn {
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
    white-space: nowrap;
}

.lineup-context-chip {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.lineup-context-format {
    color: var(--accent-primary);
}

.lineup-context-sep {
    color: var(--text-muted);
}

.lineup-context-btn {
    min-height: 44px;
}

.pitch-history-toolbar {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: min(100%, 1080px);
    min-height: 44px;
    margin-inline: auto;
}

.pitch-history-toolbar .history-btn { min-width: 44px; min-height: 44px; }

/* ===== Panels ===== */
.panel {
    background: var(--bg-card);
    border-radius: var(--radius-lg);
    margin-bottom: 0.75rem;
    border: 1px solid var(--border-color);
    overflow: hidden;
}

.panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.875rem 1rem;
    cursor: pointer;
    transition: background var(--transition-fast);
    -webkit-tap-highlight-color: transparent;
}

.panel-header:hover {
    background: var(--bg-tertiary);
}

.panel-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin: 0;
}

.panel-title i {
    color: var(--accent-primary);
    font-size: 0.875rem;
}

/* A real <button> rather than a bare <i>: the panel header is still
   click-to-collapse, but the chevron is what makes that reachable from the
   keyboard. Its click bubbles to the header handler, so it needs no listener
   of its own. */
.panel-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    min-height: 32px;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.625rem;
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}

.panel-toggle:hover {
    color: var(--text-primary);
}

.panel.collapsed .panel-toggle {
    transform: rotate(-90deg);
}

/* ===== Edit Lineup panel ===== */
.editor-sidebar {
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

.editor-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 1rem 0.5rem;
    background: var(--bg-primary);
    forced-color-adjust: none;
}

@media (min-width: 1025px) {
    /* Desktop has a separate Edit Lineup button, so the panel's duplicate
       heading and its otherwise empty header row are unnecessary. */
    .editor-header { display: none; }
}

.editor-sheet-handle {
    display: none;
    width: 44px;
    height: 24px;
    flex: 0 0 44px;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    cursor: grab;
}

.editor-sheet-handle span {
    display: block;
    width: 36px;
    height: 4px;
    border-radius: 99px;
    background: var(--text-muted);
}

.editor-sheet-handle:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.editor-close {
    display: none;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    background: none;
    border: none;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 1rem;
    cursor: pointer;
}

.editor-close:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.editor-tabs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.25rem;
    padding: 0 0.75rem;
    border-bottom: 1px solid var(--border-color);
}

/* The selected tab is marked three ways - weight, a solid underline and
   aria-selected - so it never depends on colour alone. */
.editor-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 44px;
    padding: 0.5rem 0.35rem;
    background: none;
    border: none;
    border-bottom: 3px solid transparent;
    color: var(--text-secondary);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.editor-tab i {
    font-size: 0.8125rem;
}

.editor-tab:hover {
    color: var(--text-primary);
}

.editor-tab[aria-selected="true"] {
    color: var(--text-primary);
    font-weight: 700;
    border-bottom-color: var(--accent-primary);
}

.editor-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 0.75rem 1rem 1rem;
    scrollbar-width: thin;
    scrollbar-color: var(--border-color) transparent;
}

.editor-body::-webkit-scrollbar {
    width: 6px;
}

.editor-body::-webkit-scrollbar-thumb {
    background: var(--border-color);
    border-radius: 3px;
}

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

/* --text-secondary, not --text-muted: this is the copy that explains what a
   control does (it is the aria-describedby target for the players-per-side
   selector and the formation picker), and #6a6a7a on the card background is
   about 3.5:1 - short of WCAG AA for body text. */
.helper-text {
    margin: 0.4rem 0 0;
    color: var(--text-secondary);
    font-size: 0.75rem;
    line-height: 1.4;
}

/* A helper line that is reporting a failure (sign-in). Colour alone is not the
   message - the text says what went wrong - so this only reinforces it. */
.helper-text.is-error {
    color: var(--accent-danger);
}

/* Squads kept on a Pro account, below the browser-local ones in the same
   panel. The rule is the seam between "in this browser" and "on your
   account"; both lists use the same .draft-row markup. */
.synced-squads {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
}

.synced-squads-title {
    margin: 0 0 0.4rem;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-secondary);
}

/* Export and delete, in the account modal. Scoped to this section rather than
   defining a global .btn-danger: that class is already used elsewhere with no
   rule behind it, and restyling those buttons is not this change's business. */
.auth-data-section {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
}

.auth-data-section h3 {
    margin: 0 0 0.25rem;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-secondary);
}

.auth-data-section .modal-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

/* Destructive, and it must not look like the button beside it. Outlined rather
   than filled so it does not read as the recommended action. */
.auth-data-section .btn-danger {
    background: transparent;
    color: var(--accent-danger);
    border: 1px solid var(--accent-danger);
}

.auth-data-section .btn-danger:hover {
    background: var(--accent-danger);
    color: #fff;
}

/* The irreversibility warning. The words carry the message; the colour and rule
   only reinforce them. */
.helper-text.is-warning {
    padding: 0.6rem 0.75rem;
    border-left: 3px solid var(--accent-danger);
    background: rgba(239, 68, 68, 0.08);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
}

#authDeleteConfirm[hidden] {
    display: none;
}

/* The `hidden` attribute alone does NOT hide this button.
 *
 * `hidden` is a user-agent `display: none`, and .btn sets `display: inline-flex`
 * - an author rule, so it wins. Without this, billing.js setting
 * `buy.hidden = true` changes the DOM and nothing on screen: somebody who
 * already owns Pro is still shown "Buy Pro". Caught by looking at a screenshot;
 * every scripted assertion read the `hidden` property and was perfectly happy.
 *
 * Same shape of fix as #authDeleteConfirm[hidden] and .ios-app-promo[hidden]
 * above/below. */
#authUpgradeBtn[hidden] {
    display: none;
}

/* ===== Players per side ===== */
.format-options {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(58px, 1fr));
    gap: 0.375rem;
}

.format-option {
    position: relative;
    min-height: 44px;
    padding: 0.5rem 0.35rem;
    background: var(--bg-tertiary);
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    color: var(--text-primary);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.format-option:hover {
    background: var(--bg-secondary);
    border-color: var(--accent-primary);
}

.format-option[aria-checked="true"] {
    background: rgba(var(--accent-rgb), 0.15);
    border-color: var(--accent-primary);
    color: var(--accent-primary);
    font-weight: 800;
}

/* Non-colour marker for the selected size. */
.format-option-check {
    display: none;
    position: absolute;
    top: 2px;
    right: 4px;
    font-size: 0.5625rem;
    color: var(--accent-primary);
}

.format-option[aria-checked="true"] .format-option-check {
    display: block;
}

.panel-content {
    padding: 0 1rem 1rem;
}

.panel.collapsed .panel-content {
    display: none;
}

/* Legacy support - panels without header */
.panel:not(:has(.panel-header)) {
    padding: 1rem;
}

.panel:not(:has(.panel-header)) .panel-title {
    margin-bottom: 0.875rem;
}

/* Touch improvements */
* {
    -webkit-tap-highlight-color: transparent;
}

input, button, select, textarea {
    touch-action: manipulation;
}

/* Prevent text selection on UI elements */
.panel-header,
.nav-tab,
.mobile-nav-btn,
.formation-btn,
.phase-btn,
.pitch-option,
.jersey-option {
    user-select: none;
    -webkit-user-select: none;
}

/* ===== Formation Grid ===== */
.formation-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.625rem;
}

.formation-search-wrap {
    margin-bottom: 0.625rem;
}

.formation-category-filters { display: flex; gap: .35rem; margin: .35rem 0 .65rem; overflow-x: auto; padding: .1rem .1rem .35rem; scrollbar-width: thin; }
.formation-category-filter { flex: 0 0 auto; min-height: 38px; padding: .45rem .7rem; color: var(--text-secondary); border: 1px solid var(--border-color); border-radius: 999px; background: var(--bg-tertiary); cursor: pointer; }
.formation-category-filter.active { color: var(--accent-primary); border-color: var(--accent-primary); background: rgba(var(--accent-rgb), .1); }
.formation-filter-status { min-height: 1.1rem; margin: 0 0 .45rem; font-size: .72rem; }
.formation-grid { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); }
.formation-option { display: grid; grid-template-columns: minmax(0, 1fr); align-items: stretch; gap: .25rem; min-width: 0; padding: .25rem; border: 1px solid transparent; border-radius: var(--radius-md); background: var(--bg-primary); }
.formation-option.selected { border-color: var(--accent-primary); box-shadow: inset 0 0 0 1px var(--accent-primary); }
.formation-option .formation-btn { width: 100%; }
.formation-option .formation-preview { max-width: none; }
.formation-actions { display: grid; grid-template-columns: minmax(0, 1fr) 38px; gap: .35rem; min-width: 0; }
.formation-actions .formation-use { justify-content: center; min-height: 44px; padding: .375rem .5rem; }
.formation-option[hidden] { display: none; }
.formation-favorite { width: 38px; min-width: 38px; min-height: 44px; color: #d4d4d4; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-tertiary); font-size: 1.15rem; cursor: pointer; }
.formation-favorite[aria-pressed="true"] { color: var(--accent-primary); }
.formation-category-filter:focus-visible, .formation-favorite:focus-visible { outline: 2px solid var(--accent-primary); outline-offset: 2px; }

/* ===== Formation Folders ===== */
.formation-folder {
    margin-bottom: 0.75rem;
}

.formation-folder:last-child {
    margin-bottom: 0;
}

.formation-folder-header {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.formation-folder-header:hover {
    background: var(--bg-primary);
    border-color: var(--accent-primary);
}

.folder-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
}

.folder-title i {
    color: var(--accent-primary);
    font-size: 0.75rem;
}

.folder-count {
    font-size: 0.6875rem;
    font-weight: 700;
    color: var(--text-muted);
    background: var(--bg-secondary);
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-sm);
}

.folder-arrow {
    font-size: 0.625rem;
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}

.formation-folder-header.collapsed .folder-arrow {
    transform: rotate(-90deg);
}

.formation-folder-content {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
    gap: 0.375rem;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease, padding 0.3s ease, margin 0.3s ease;
}

.formation-folder-content.open {
    /* Cards are taller than the old text-only buttons; 500px clipped the
       bottom rows of the largest folder. */
    max-height: 1600px;
    padding: 0.625rem;
    margin-top: 0.375rem;
    background: var(--bg-primary);
    border-radius: var(--radius-md);
    border: 1px solid var(--border-color);
}

/* Formation cards: shape name, team size and a pitch preview drawn from the
   same 0-100 coordinates the board uses (see formationPreviewSvg in app.js). */
.formation-btn {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    min-height: 44px;
    padding: 0.4rem 0.3rem 0.45rem;
    background: var(--bg-tertiary);
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    color: var(--text-primary);
    font-size: 0.72rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
    text-align: center;
}

.formation-preview {
    display: block;
    width: 100%;
    max-width: 54px;
    height: auto;
    border-radius: 3px;
    background: rgba(16, 84, 52, 0.55);
}

.formation-btn-name {
    line-height: 1.15;
}

.formation-btn-size {
    font-size: 0.625rem;
    font-weight: 600;
    color: var(--text-secondary);
}

/* Non-colour marker for the selected formation. */
.formation-btn-check {
    display: none;
    position: absolute;
    top: 2px;
    right: 4px;
    font-size: 0.5625rem;
    color: var(--accent-primary);
}

.formation-btn.active .formation-btn-check {
    display: block;
}

.formation-folder.hidden,
.formation-btn.hidden,
.formation-option.hidden {
    display: none;
}

.formation-btn:hover {
    background: var(--bg-secondary);
    border-color: var(--accent-primary);
}

.formation-btn.active {
    background: rgba(var(--accent-rgb), 0.15);
    border-color: var(--accent-primary);
    color: var(--accent-primary);
}

.formation-btn.active .formation-btn-size {
    color: var(--accent-primary);
}

/* ===== Form Elements ===== */
.form-group {
    margin-bottom: 0.875rem;
}

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

.form-row {
    display: flex;
    gap: 0.75rem;
}

.form-row .form-group {
    flex: 1;
    margin-bottom: 0.875rem;
}

.form-group label {
    display: block;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: 0.375rem;
}

.input {
    width: 100%;
    padding: 0.625rem 0.875rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    font-size: 0.875rem;
    transition: all var(--transition-fast);
}

.input:focus {
    outline: none;
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.15);
}

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

/* ===== Pitch Options ===== */
.pitch-options {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.5rem;
}

.pitch-option {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    min-height: 44px;
    padding: 0.5rem;
    background: transparent;
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.pitch-option:hover {
    border-color: var(--border-color);
}

.pitch-option.active {
    border-color: var(--accent-primary);
}

/* Non-colour marker for the selected surface - the border alone would be the
   only signal, and on a control whose whole subject is colour that is exactly
   the case where colour must not be load-bearing. */
.pitch-option-check {
    display: none;
    position: absolute;
    top: 2px;
    right: 4px;
    font-size: 0.5625rem;
    color: var(--accent-primary);
}

.pitch-option.active .pitch-option-check {
    display: block;
}

.pitch-option.active > span {
    color: var(--accent-primary);
    font-weight: 800;
}

.pitch-preview {
    width: 100%;
    aspect-ratio: 1;
    border-radius: var(--radius-sm);
}

.pitch-preview.classic { background: var(--pitch-classic); }
.pitch-preview.dark { background: var(--pitch-dark); }
.pitch-preview.light { background: var(--pitch-light); }
.pitch-preview.night { background: var(--pitch-night); }

.pitch-option span {
    font-size: 0.625rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* ===== Jersey Options ===== */
.jersey-options {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
}

.jersey-option {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem;
    background: transparent;
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.jersey-option:hover {
    border-color: var(--border-color);
}

.jersey-option.active {
    border-color: var(--accent-primary);
}

.jersey-preview {
    width: 32px;
    height: 32px;
    background: #e63946;
    border: 2px solid white;
}

.jersey-preview.circle {
    border-radius: 50%;
}

.jersey-preview.shirt {
    border-radius: 4px 4px 8px 8px;
    clip-path: polygon(15% 0%, 85% 0%, 100% 15%, 100% 100%, 0% 100%, 0% 15%);
}

.jersey-preview.modern {
    border-radius: 8px;
    background: linear-gradient(135deg, #e63946, #c1121f);
}

.jersey-option span {
    font-size: 0.625rem;
    color: var(--text-secondary);
    text-transform: uppercase;
}

/* ===== Color Pickers ===== */
.color-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.625rem;
}

.color-row label {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.color-picker {
    width: 40px;
    height: 28px;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    padding: 0;
    background: none;
}

.color-picker::-webkit-color-swatch-wrapper {
    padding: 0;
}

.color-picker::-webkit-color-swatch {
    border: 2px solid var(--border-color);
    border-radius: var(--radius-sm);
}

.color-presets {
    display: flex;
    gap: 0.375rem;
    margin-top: 0.75rem;
    flex-wrap: wrap;
}

.color-preset {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid var(--border-color);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.color-preset:hover {
    transform: scale(1.15);
    border-color: white;
}

.color-preset:nth-child(1) { background: linear-gradient(135deg, #e63946, #ffffff); }
.color-preset:nth-child(2) { background: linear-gradient(135deg, #1d3557, #f1faee); }
.color-preset:nth-child(3) { background: linear-gradient(135deg, #2a9d8f, #264653); }
.color-preset:nth-child(4) { background: linear-gradient(135deg, #f77f00, #003049); }
.color-preset:nth-child(5) { background: linear-gradient(135deg, #7209b7, #f72585); }
.color-preset:nth-child(6) { background: linear-gradient(135deg, #023e8a, #caf0f8); }

/* ===== Toggle Switch ===== */
.toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.625rem;
}

.toggle-row:last-child {
    margin-bottom: 0;
}

.toggle-row label:first-child {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.toggle {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
}

.toggle input {
    opacity: 0;
    width: 0;
    height: 0;
}

.toggle-slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background: var(--bg-tertiary);
    border-radius: 24px;
    transition: var(--transition-fast);
}

.toggle-slider::before {
    content: '';
    position: absolute;
    width: 18px;
    height: 18px;
    left: 3px;
    bottom: 3px;
    background: white;
    border-radius: 50%;
    transition: var(--transition-fast);
}

.toggle input:checked + .toggle-slider {
    background: var(--accent-primary);
}

.toggle input:checked + .toggle-slider::before {
    transform: translateX(20px);
}

/* ===== Player Badges ===== */
.player-badges {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.badge-btn {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-tertiary);
    border: 2px solid transparent;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.badge-btn:hover {
    border-color: var(--border-color);
    color: var(--text-primary);
}

.badge-btn.active {
    border-color: var(--accent-primary);
    background: rgba(var(--accent-rgb), 0.15);
    color: var(--accent-primary);
}

.badge-btn[data-badge="captain"] {
    color: #111111;
    background: #ffffff;
}

.badge-btn[data-badge="captain"].active {
    color: #111111;
    background: #ffffff;
    border-color: #ffffff;
}

.badge-btn[data-badge="assist"] {
    color: #ffffff;
}

.badge-btn[data-badge="injured"] {
    color: #ffffff;
}

.injured-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #ef4444;
    color: #ffffff;
    font-size: 1rem;
    font-weight: 800;
    line-height: 1;
}

.card-icon {
    width: 14px;
    height: 18px;
    border-radius: 2px;
}

.card-icon.yellow {
    background: #fbbf24;
}

.card-icon.red {
    background: #ef4444;
}

/* ===== Pitch Container =====

   This column used to be `align-items: center` + `overflow: hidden` around a
   wrapper taller than itself. Centering splits the overflow across both edges,
   so the phase toggle sat at y = -37 with no scrollbar able to reach it: the
   dual-phase feature was unclickable on any viewport under ~1122px tall.

   Now the column lays out from the top, the controls keep their natural height,
   and the pitch takes whatever vertical space is left over. Nothing overflows,
   so nothing can be clipped. */
.pitch-container {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding: var(--space-4);
    gap: var(--space-3);
    background: var(--bg-primary);
    min-height: 0;
    overflow: hidden;
}

.pitch-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    /* min-height:0 lets this shrink below its content's intrinsic height,
       which is what allows the pitch to be the part that gives. */
    min-height: 0;
    flex: 1 1 auto;
}

/* The pitch board owns only the canvas; setup, style, and roster controls live
   in their dedicated sidebars. */
.pitch-board {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
}

/* Above 900px the pitch is sized by leftover height. The roster is in the
   right editor, so it cannot reduce the pitch. */
@media (min-width: 901px) {
    .pitch-board {
        display: flex;
        flex-direction: row;
        align-items: stretch;
        gap: var(--space-4);
        flex: 1 1 auto;
        min-height: 0;
        width: 100%;
    }

    .pitch-board .pitch-stage {
        flex: 1 1 auto;
        min-width: 0;
    }

}

/* Chrome that is empty should not hold space away from the pitch. The match
   info strip renders nothing until a match is named, and the bench renders a
   prompt until a sub is added - together they were taking 154px off the hero. */
.match-info-display:empty {
    display: none;
}

.subs-bench {
    flex: 0 0 auto;
}

.subs-bench:not(.has-subs) .subs-container {
    padding: var(--space-2) 0 0;
}

.subs-bench:not(.has-subs) .subs-empty {
    padding: var(--space-2);
    font-size: var(--text-xs);
}

/* The pitch fills the leftover height; its width follows from the real 68x105
   proportions of a football pitch rather than a hardcoded 500x700 box. */
.pitch-stage {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Makes cqw/cqh below resolve against this box. */
    container-type: size;
}

/* ===== Phase Toggle ===== */
.phase-toggle-container {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    margin-bottom: 0.75rem;
    width: 100%;
    max-width: 500px;
}

.phase-toggle {
    display: flex;
    position: relative;
    background: var(--bg-tertiary);
    border-radius: var(--radius-lg);
    padding: 4px;
    border: 1px solid var(--border-color);
}

.phase-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 1.25rem;
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: color var(--transition-fast);
    position: relative;
    z-index: 2;
}

.phase-btn i {
    font-size: 0.875rem;
}

.phase-btn.active {
    color: var(--accent-ink);
}

.phase-btn[data-phase="possession"].active {
    color: var(--accent-ink);
}

.phase-btn[data-phase="defensive"].active {
    color: var(--accent-ink);
}

.phase-slider {
    position: absolute;
    top: 4px;
    left: 4px;
    width: calc(50% - 4px);
    height: calc(100% - 8px);
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    border-radius: var(--radius-md);
    transition: all var(--transition-normal);
    z-index: 1;
}

.phase-toggle.defensive .phase-slider {
    left: calc(50%);
    background: linear-gradient(135deg, #ef4444, #dc2626);
}

.copy-phase-btn {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 0.75rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
}

.copy-phase-btn:hover {
    background: var(--bg-card);
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

.copy-phase-btn i {
    font-size: 0.75rem;
}


.team-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 500px;
    padding: 0.75rem 1.25rem;
    background: var(--bg-card);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-color);
    border-bottom: none;
}

.lineup-context-identity > .team-header {
    align-items: flex-start;
    flex: 0 1 auto;
    width: auto;
    max-width: none;
    padding: 0.25rem 0.5rem;
    background: transparent;
    border: 0;
    border-radius: 0;
    white-space: nowrap;
}

.lineup-context-bar .team-identity-row {
    justify-content: flex-start;
    width: auto;
}

.lineup-context-bar .team-format {
    display: inline-flex;
}

.team-identity-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
}

.team-header .match-info-display {
    width: auto;
    max-width: 100%;
    min-height: 0;
    padding: 0.1rem 0.5rem 0;
    background: transparent;
    border-radius: 0;
    font-size: 0.72rem;
    line-height: 1.2;
}

.line-tools {
    width: 100%;
    max-width: 500px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem 0.75rem;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-top: none;
    margin-bottom: 0;
    gap: 0.75rem;
}

.line-tools-buttons {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.line-tools-style {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    color: var(--text-secondary);
    font-size: 0.75rem;
}

.annotation-style-select {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
    border-radius: var(--radius-sm);
    padding: 0.2rem 0.45rem;
    font-size: 0.75rem;
}

.line-tool-btn.active {
    border-color: var(--accent-primary);
    background: rgba(var(--accent-rgb), 0.15);
    color: var(--text-primary);
}

.line-tools-color {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    color: var(--text-secondary);
    font-size: 0.75rem;
}

.annotation-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 7;
    pointer-events: none;
}

body.annotation-mode-active .pitch {
    cursor: crosshair;
}

.annotation-line {
    /* Much thinner. At 0.8 on a 0-100 viewBox these read as bars across the
       pitch rather than as pressing runs, and they buried the players. */
    stroke-width: 0.3;
    fill: none;
    opacity: 0.92;
}

.annotation-ball {
    pointer-events: none;
}

.annotation-ball-outer {
    fill: #ffffff;
    stroke: #111111;
    stroke-width: 0.16;
    opacity: 0.97;
}

/* Seams run from the centre pentagon out to the rim. Stroked only - a fill
   here would close each seam into a wedge. */
.annotation-ball-seam {
    fill: none;
    stroke: #111111;
    stroke-width: 0.16;
    stroke-linecap: round;
}

.annotation-ball-panel {
    fill: #111111;
    stroke: #111111;
    stroke-width: 0.08;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 1;
}

.annotation-ball-highlight {
    fill: none;
    opacity: 0;
}

.team-name {
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--text-primary);
}

.team-name-edit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    margin-left: -0.35rem;
    padding: 0;
    color: var(--text-secondary);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.team-name-edit-btn:hover,
.team-name-edit-btn:focus-visible {
    color: var(--accent-primary);
    background: var(--bg-tertiary);
    border-color: var(--border-color);
}

.formation-display {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Players per side, beside the formation on the team identity row. */
.team-format {
    display: none;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    padding: 0.15rem 0.4rem;
    border-radius: var(--radius-sm);
}

.formation-name {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--accent-primary);
    background: rgba(var(--accent-rgb), 0.15);
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-md);
}

.phase-indicator {
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius-sm);
    background: rgba(var(--accent-rgb), 0.15);
    color: var(--accent-primary);
}

.phase-indicator.defensive {
    background: rgba(239, 68, 68, 0.15);
    color: #ef4444;
}

/* Pitch border color based on phase */
.pitch.defensive-phase {
    box-shadow: var(--shadow-xl), 0 0 0 2px rgba(239, 68, 68, 0.3);
}

.pitch.possession-phase {
    box-shadow: var(--shadow-xl), 0 0 0 2px rgba(var(--accent-rgb), 0.3);
}

/* Toast Notification */
.toast-notification {
    position: fixed;
    bottom: 2rem;
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    background: var(--bg-card);
    border: 1px solid var(--accent-primary);
    color: var(--text-primary);
    padding: 0.75rem 1.5rem;
    border-radius: var(--radius-lg);
    font-size: 0.875rem;
    font-weight: 500;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
    opacity: 0;
    transition: all var(--transition-normal);
    z-index: 9999;
}

.toast-notification.show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

/* Phase toggle responsive */
@media (max-width: 768px) {
    .phase-toggle-container {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        gap: 0.5rem;
        padding: 0.5rem;
    }
    
    .phase-toggle {
        flex: 1;
        min-width: 200px;
        max-width: 300px;
    }
    
    .copy-phase-btn {
        flex-shrink: 0;
    }
    
    /* Keep the phase labels. Hiding them left two unlabelled icons standing in
       for the app's central concept - a user cannot infer "In Possession" vs
       "Defensive" from a football and a shield. Drop the icons instead; the
       words are what carry the meaning. */
    .phase-btn i {
        display: none;
    }

    .phase-btn {
        padding: 0.625rem 0.75rem;
        font-size: var(--text-sm);
    }

    /* Icon-only on mobile: the label costs a whole row that the pitch needs. */
    .copy-phase-btn {
        font-size: 0;
        gap: 0;
        padding: 0.5rem 0.6rem;
        flex-shrink: 0;
    }

    .copy-phase-btn i {
        font-size: 0.85rem;
    }

    .line-tools {
        flex-direction: column;
        align-items: stretch;
    }

    .line-tools-buttons {
        justify-content: space-between;
    }
}

/* A real pitch is 68m x 105m. Sizing by that ratio instead of a fixed
   500x700 box means the board fits whatever space it is given, and the player
   coordinates (stored as percentages) stay accurate at every size.

   Height-driven on desktop: take the full stage height, derive width. The
   width-driven case for narrow screens is in the mobile section. */
.pitch {
    position: relative;
    /* Fit the board inside the stage on BOTH axes. Deriving width from
       `height: 100%` alone breaks whenever width is the binding constraint -
       aspect-ratio is ignored once both axes are definite, and the pitch
       stretches. Taking the smaller of the two limits keeps 68:105 exact at
       every window shape. */
    height: min(100cqh, 100cqw * 105 / 68);
    aspect-ratio: 68 / 105;
    background: var(--pitch-classic);
    border-radius: var(--radius-md);
    /* A token's label block hangs below its avatar, so the goalkeeper's (y=90)
       crosses the bottom edge on a short board - measured at 1100x800: pitch
       bottom 601, token bottom 610. `hidden` clips that out of painting AND of
       hit-testing, which is what made the keeper's in-token backup badge
       unreachable. Clipping a fixed margin outside the box instead keeps the
       board's own edge exact - nothing here is moved or resized - while the
       last few pixels of a token on the goal line stay visible and tappable.
       The overhang is 43px - 10% of the pitch height, so 32px covers every
       board taller than ~110px.
       `hidden` stays first as the fallback: where `clip` is unsupported this
       whole pair is ignored, and app.js's applyDeepTokenClass() feature-detects
       the same property and flips the label above the avatar there instead. */
    overflow: hidden;
    overflow: clip;
    overflow-clip-margin: 32px;
    box-shadow: var(--shadow-xl);
    transition: background var(--transition-normal);
    touch-action: none;
}

.pitch.dark { background: var(--pitch-dark); }
.pitch.light { background: var(--pitch-light); }
.pitch.night { background: var(--pitch-night); }

/* ===== Pitch Markings ===== */
.pitch-markings {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.center-circle {
    position: absolute;
    width: 120px;
    height: 120px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 2px solid rgba(255, 255, 255, 0.5);
    border-radius: 50%;
}

.center-line {
    position: absolute;
    width: 100%;
    height: 2px;
    top: 50%;
    left: 0;
    background: rgba(255, 255, 255, 0.5);
}

.center-dot {
    position: absolute;
    width: 8px;
    height: 8px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(255, 255, 255, 0.5);
    border-radius: 50%;
}

.penalty-area {
    position: absolute;
    width: 66%;
    height: 16%;
    left: 17%;
    border: 2px solid rgba(255, 255, 255, 0.5);
}

.penalty-area.top {
    top: 0;
    border-top: none;
}

.penalty-area.bottom {
    bottom: 0;
    border-bottom: none;
}

.goal-area {
    position: absolute;
    width: 32%;
    height: 6%;
    left: 34%;
    border: 2px solid rgba(255, 255, 255, 0.5);
}

.goal-area.top {
    top: 0;
    border-top: none;
}

.goal-area.bottom {
    bottom: 0;
    border-bottom: none;
}

.penalty-spot {
    position: absolute;
    width: 6px;
    height: 6px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(255, 255, 255, 0.5);
    border-radius: 50%;
}

.penalty-spot.top {
    top: 11%;
}

.penalty-spot.bottom {
    bottom: 11%;
}

.penalty-arc {
    position: absolute;
    width: 80px;
    height: 40px;
    left: 50%;
    transform: translateX(-50%);
    border: 2px solid rgba(255, 255, 255, 0.5);
    border-radius: 0 0 80px 80px;
}

.penalty-arc.top {
    top: 16%;
    border-top: none;
}

.penalty-arc.bottom {
    bottom: 16%;
    transform: translateX(-50%) rotate(180deg);
}

.corner-arc {
    position: absolute;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.5);
}

.corner-arc.top-left {
    top: 0;
    left: 0;
    border-radius: 0 0 100% 0;
    border-top: none;
    border-left: none;
}

.corner-arc.top-right {
    top: 0;
    right: 0;
    border-radius: 0 0 0 100%;
    border-top: none;
    border-right: none;
}

.corner-arc.bottom-left {
    bottom: 0;
    left: 0;
    border-radius: 0 100% 0 0;
    border-bottom: none;
    border-left: none;
}

.corner-arc.bottom-right {
    bottom: 0;
    right: 0;
    border-radius: 100% 0 0 0;
    border-bottom: none;
    border-right: none;
}

/* ===== Snap Guides ===== */
.snap-guides {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 5;
}

.snap-guide-h,
.snap-guide-v,
.snap-guide-center-h,
.snap-guide-center-v {
    position: absolute;
    background: rgba(var(--accent-rgb), 0.8);
    opacity: 0;
    transition: opacity 0.1s ease;
    z-index: 5;
}

.snap-guide-h {
    height: 1px;
    left: 0;
    right: 0;
    box-shadow: 0 0 4px rgba(var(--accent-rgb), 0.8);
}

.snap-guide-v {
    width: 1px;
    top: 0;
    bottom: 0;
    box-shadow: 0 0 4px rgba(var(--accent-rgb), 0.8);
}

.snap-guide-center-h {
    height: 2px;
    left: 0;
    right: 0;
    top: 50%;
    background: rgba(251, 191, 36, 0.8);
    box-shadow: 0 0 6px rgba(251, 191, 36, 0.8);
}

.snap-guide-center-v {
    width: 2px;
    top: 0;
    bottom: 0;
    left: 50%;
    background: rgba(251, 191, 36, 0.8);
    box-shadow: 0 0 6px rgba(251, 191, 36, 0.8);
}

.snap-guide-h.visible,
.snap-guide-v.visible,
.snap-guide-center-h.visible,
.snap-guide-center-v.visible {
    opacity: 1;
}

/* ===== Players ===== */
.players-container {
    position: absolute;
    inset: 0;
    z-index: var(--z-pitch);
}

.player {
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    cursor: grab;
    transform: translate(-50%, -50%);
    transition: transform 0.1s ease;
    z-index: 10;
    user-select: none;
    /* A short vertical gesture scrolls the page; app.js claims the pointer
       only after a deliberate drag threshold or brief hold. */
    touch-action: pan-y;
}

.player:active {
    cursor: grabbing;
    z-index: 20;
}

.player.selected {
    z-index: 30;
}

.player.selected .player-avatar {
    box-shadow: 0 0 0 3px var(--accent-primary), 0 0 20px rgba(var(--accent-rgb), 0.5);
}

.player-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: #e63946;
    border: 3px solid white;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Squad numbers in the mono face with tabular figures: a team sheet is a
       numbered document, and 1 / 7 / 11 should occupy the same width. */
    font-family: var(--font-mono);
    font-feature-settings: 'tnum' 1;
    font-size: var(--text-base);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: white;
    box-shadow: var(--shadow-md);
    transition: all var(--transition-fast);
}

.player-avatar.shirt {
    border-radius: 8px 8px 16px 16px;
}

.player-avatar.modern {
    border-radius: 12px;
    background: linear-gradient(135deg, #e63946, #c1121f);
}

.player:hover .player-avatar {
    transform: scale(1.1);
}

.player-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: 4px;
}

/* Fallback for browsers without overflow-clip-margin (see .pitch): there the
   label block of a token near the own goal line is still clipped out of
   painting and hit-testing at the bottom edge of #pitch, which made the
   in-token backup badge unreachable. Reversing the column moves the badge back
   inside the clip box. Applied only where the property is missing - see
   app.js's applyDeepTokenClass(), which feature-detects it - so on every
   current browser the keeper's label reads below its circle like everyone
   else's. */
.player.label-above {
    flex-direction: column-reverse;
}

.player.label-above .player-info {
    margin-top: 0;
    margin-bottom: 4px;
}

.player-name {
    font-size: 0.7rem;
    font-weight: 600;
    color: white;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
    max-width: 80px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.player-position {
    /* Position codes (GK, CDM, RWB) are notation, not prose. */
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.72);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
    transition: all 0.2s ease;
}

.player-position.position-changed {
    color: #fbbf24;
    transform: scale(1.2);
    text-shadow: 0 0 8px rgba(251, 191, 36, 0.8);
}

/* Linked Sub Display */
.player-linked-sub {
    color: rgba(var(--accent-secondary-rgb), 0.9);
    background: rgba(0, 0, 0, 0.6);
    padding: 0.125rem 0.375rem;
    border-radius: 3px;
    margin-top: 1px;
    text-shadow: none;
    white-space: nowrap;
    /* Same 80px as .player-name above it, so the pill never makes a token wider
       than its own name block. At 60px even a corrected 8px "P. Vandermeer"
       still lost its surname. */
    max-width: 80px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.player-linked-sub i {
    font-size: 0.4rem;
    margin-right: 2px;
}

.player-linked-sub,
.player-add-sub {
    border: 0;
    font: inherit;
    cursor: pointer;
}

/* Both pills restate their type AFTER the `font: inherit` above, because that
   shorthand resets font-size and font-weight to the inherited 16px/400. The
   linked pill used to be declared before it and never got its size back, so at
   16px in a 60px box the backup's name was clipped to about one character -
   "P. Vandermeer" rendered as "P. ...", which is the one thing the pill exists
   to say. */
.player-linked-sub {
    font-size: 0.5rem;
    font-weight: 500;
}

.player-linked-sub:hover,
.player-add-sub:hover {
    color: var(--accent-primary);
    background: rgba(var(--accent-rgb), 0.14);
}

.player-add-sub {
    font-size: 0.5rem;
    color: rgba(255, 255, 255, 0.68);
    background: rgba(0, 0, 0, 0.42);
    padding: 0.125rem 0.375rem;
    border-radius: 3px;
    margin-top: 1px;
}

/* Inline Editing */
.player-inline-edit {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 4px;
    z-index: 100;
}

.inline-name-input {
    width: 100px;
    padding: 0.375rem 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-align: center;
    background: var(--bg-card);
    border: 2px solid var(--accent-primary);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    outline: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.inline-name-input::placeholder {
    color: var(--text-muted);
    font-weight: 400;
}

.player.editing {
    z-index: 50;
}

.player.editing .player-avatar {
    box-shadow: 0 0 0 3px var(--accent-primary), 0 4px 12px rgba(var(--accent-rgb), 0.4);
}

/* Edit hint on hover */
.player::after {
    content: 'Double-tap to edit';
    position: absolute;
    bottom: -20px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.5rem;
    color: var(--accent-primary);
    background: rgba(0, 0, 0, 0.8);
    padding: 2px 6px;
    border-radius: 3px;
    white-space: nowrap;
    opacity: 0;
    transition: opacity 0.2s;
    pointer-events: none;
}

.player.selected::after {
    opacity: 1;
}

@media (max-width: 768px) {
    .player::after {
        content: 'Hold to edit';
    }
}

.player-badges-display {
    position: absolute;
    top: -8px;
    right: -8px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.player-badge {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.5rem;
    font-weight: 700;
    box-shadow: var(--shadow-sm);
}

.player-badge.goal {
    background: white;
    color: #1a1a25;
}

.player-badge.yellow {
    background: #fbbf24;
    border-radius: 2px;
}

.player-badge.red {
    background: #ef4444;
    border-radius: 2px;
}

.player-badge.captain {
    background: #ffffff;
    color: #111111;
}

.player-badge.assist {
    background: #1a1a25;
    color: #ffffff;
}

.player-badge.injured {
    background: #ef4444;
    color: #ffffff;
}

.injured-mark {
    font-size: .9rem;
    font-weight: 800;
    line-height: 1;
}

.player-badge.sub {
    background: var(--accent-primary);
    color: var(--accent-ink);
}

.match-info-display {
    width: 100%;
    max-width: 500px;
    padding: 0.5rem 1rem;
    background: var(--bg-tertiary);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    text-align: center;
    font-size: 0.8rem;
    color: var(--text-secondary);
    min-height: 32px;
}

/* ===== Modal ===== */
.modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    opacity: 0;
    visibility: hidden;
    /* `all` used to cover `visibility` too, so for the whole 0.25s after
       `.active` was added the dialog was still computed `hidden` - and a
       hidden element cannot take focus. trapModalFocus()'s opening focus()
       call silently did nothing, focus stayed on the button outside the
       dialog, and its Esc/Tab handler (bound to the dialog) never fired: no
       focus trap and no Escape, on every .modal in the app. Show instantly,
       and delay only the hide so the fade-out still reads. */
    transition: all var(--transition-normal), visibility 0s linear 0.25s;
}

.modal.active {
    opacity: 1;
    visibility: visible;
    transition: all var(--transition-normal), visibility 0s linear 0s;
}

.modal-content {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xl);
    width: 90%;
    max-width: 600px;
    max-height: 80vh;
    overflow-y: auto;
    position: relative;
    transform: scale(0.9);
    transition: transform var(--transition-normal);
}

.modal.active .modal-content {
    transform: scale(1);
}

.export-workflow-content {
    width: min(1120px, 95vw);
    max-width: 1120px;
    max-height: 92vh;
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
}

.export-workflow-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 3rem 1rem 0;
    border-bottom: 1px solid var(--border-color);
}

.export-workflow-heading h2 { margin: 0; font-size: 1.35rem; }
.export-workflow-heading .eyebrow { margin: 0 0 0.25rem; color: var(--text-muted); font-size: 0.65rem; letter-spacing: 0.12em; }

.export-workflow-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 1.25rem;
    min-height: 0;
    padding: 1.1rem 0;
    overflow-y: auto;
}

.export-preview-column { min-width: 0; }
.export-preview-frame {
    display: grid;
    place-items: center;
    min-height: 280px;
    max-height: 58vh;
    overflow: hidden;
    padding: 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: #14141d;
}

#exportPreviewCanvas { display: block; width: auto; height: auto; max-width: 100%; max-height: 54vh; object-fit: contain; border-radius: var(--radius-sm); }
.export-data-preview { display: grid; justify-items: center; gap: 0.6rem; color: var(--text-secondary); text-align: center; }
.export-data-preview i { color: var(--accent-primary); font-size: 2.5rem; }
.export-data-preview strong { color: var(--text-primary); }
.export-data-preview span { max-width: 24rem; font-size: 0.85rem; }
.export-preview-status { margin: 0.6rem 0 0; color: var(--text-secondary); font-size: 0.8rem; }
.recent-export-label { margin: 0 0 0.5rem; color: var(--accent-primary); font-size: 0.75rem; font-weight: 700; }

.export-options-column { min-width: 0; }
.export-category-tabs { display: flex; gap: 0.35rem; padding-bottom: 0.65rem; border-bottom: 1px solid var(--border-color); }
.export-category-tab { flex: 1; min-height: 42px; padding: 0.4rem; border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--text-secondary); font-weight: 600; cursor: pointer; }
.export-category-tab[aria-selected="true"] { border-bottom-color: var(--accent-primary); color: var(--text-primary); }
.export-choice-panel[hidden] { display: none; }
.export-choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.55rem; padding-top: 0.75rem; }
.export-choice {
    display: grid;
    grid-template-columns: 1.4rem minmax(0, 1fr);
    align-content: center;
    align-items: center;
    gap: 0.1rem 0.55rem;
    min-height: 76px;
    padding: 0.65rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-secondary);
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
}

.export-choice > i { grid-row: 1 / span 2; color: var(--accent-primary); }
.export-choice > span { font-size: 0.82rem; font-weight: 650; }
.export-choice > small { color: var(--text-muted); font-size: 0.68rem; line-height: 1.25; }
.export-choice:hover { border-color: var(--accent-primary); }
.export-choice[aria-pressed="true"] { border-color: var(--accent-primary); background: rgba(var(--accent-rgb), 0.12); box-shadow: 0 0 0 1px var(--accent-primary); }
.export-workflow-actions { display: flex; justify-content: flex-end; gap: 0.6rem; padding-top: 0.9rem; border-top: 1px solid var(--border-color); }

.community-card-actions { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-top: 0.9rem; }
.community-card-actions .btn { min-height: 40px; }

.mobile-edit-toolbar { display: none; }

@media (max-width: 768px) {
    body.mobile-builder-active .main-content { padding-bottom: calc(var(--mobile-nav-h, 62px) + 76px + 1rem); }
    body.mobile-builder-active .editor-sidebar { padding-bottom: calc(var(--mobile-nav-h, 62px) + 66px); }
    .mobile-edit-toolbar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: var(--mobile-nav-h, 62px);
        z-index: 102;
        display: grid;
        grid-template-columns: repeat(7, minmax(0, 1fr));
        gap: 0.15rem;
        min-height: 62px;
        padding: 0.3rem 0.35rem;
        border-top: 1px solid var(--border-color);
        background: var(--bg-secondary);
        box-shadow: 0 -5px 16px rgba(0, 0, 0, 0.18);
    }
    body:not(.mobile-builder-active) .mobile-edit-toolbar { display: none; }
    .mobile-edit-toolbar > button {
        display: flex;
        min-width: 0;
        min-height: 48px;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.2rem;
        padding: 0.2rem 0.1rem;
        border: 1px solid transparent;
        border-radius: var(--radius-md);
        background: transparent;
        color: var(--text-secondary);
        font-size: 0.62rem;
        font-weight: 650;
        cursor: pointer;
    }
    .mobile-edit-toolbar > button i { font-size: 0.95rem; }
    .mobile-edit-toolbar > button[aria-pressed="true"],
    .mobile-edit-toolbar > button[aria-expanded="true"] {
        border-color: var(--accent-primary);
        background: rgba(var(--accent-rgb), 0.14);
        color: var(--text-primary);
    }
    .mobile-edit-toolbar > button:disabled { opacity: 0.45; cursor: default; }
    .mobile-more-menu {
        position: absolute;
        right: 0.45rem;
        bottom: calc(100% + 0.35rem);
        display: grid;
        min-width: 12.5rem;
        padding: 0.35rem;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        background: var(--bg-card);
        box-shadow: var(--shadow-xl);
    }
    .mobile-more-menu[hidden] { display: none; }
    .mobile-more-menu button {
        display: flex;
        align-items: center;
        gap: 0.65rem;
        min-height: 44px;
        padding: 0.55rem 0.65rem;
        border: 0;
        border-radius: var(--radius-sm);
        background: transparent;
        color: var(--text-primary);
        text-align: left;
    }
    .mobile-more-menu button:hover,
    .mobile-more-menu button:focus-visible { background: var(--bg-tertiary); }
    .mobile-edit-toolbar [data-mobile-edit-action="undo"]:disabled { opacity: 0.45; }
    .lineup-history-group .recent-changes { min-height: 44px; }

    .export-workflow-modal { align-items: stretch; }
    .export-workflow-modal .modal-content,
    .export-workflow-modal.active .modal-content { transform: none; transition: none; }
    .export-workflow-content {
        width: 100%;
        max-width: none;
        height: 100dvh;
        max-height: 100dvh;
        padding: max(1rem, env(safe-area-inset-top)) 1rem max(1rem, env(safe-area-inset-bottom));
        border: 0;
        border-radius: 0;
    }
    .export-workflow-layout { display: flex; flex: 1; flex-direction: column; gap: 0.7rem; padding: 0.75rem 0; }
    .export-preview-frame { min-height: 0; max-height: 30vh; flex: 0 1 30vh; padding: 0.4rem; }
    #exportPreviewCanvas { max-height: 28vh; }
    .export-preview-status { margin-top: 0.35rem; }
    .export-category-tabs { position: sticky; top: 0; z-index: 1; background: var(--bg-card); }
    .export-choice-grid { gap: 0.4rem; padding-top: 0.5rem; }
    .export-choice { min-height: 66px; padding: 0.45rem; }
    .export-choice > span { font-size: 0.74rem; }
    .export-choice > small { font-size: 0.62rem; }
    .export-workflow-actions { padding-bottom: max(0px, env(safe-area-inset-bottom)); }
}

.modal-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-tertiary);
    border: none;
    border-radius: 50%;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all var(--transition-fast);
    z-index: 10;
}

.modal-close:hover {
    background: var(--accent-danger);
    color: white;
}

.modal-body {
    padding: 2rem;
}

.modal-body h2 {
    font-size: 1.75rem;
    font-weight: 800;
    margin-bottom: 0.5rem;
}

.modal-origin {
    font-size: 0.875rem;
    color: var(--accent-primary);
    margin-bottom: 1.5rem;
}

.modal-description {
    font-size: 1rem;
    color: var(--text-secondary);
    line-height: 1.7;
    margin-bottom: 1.5rem;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid var(--border-color);
}

.modal-section {
    margin-bottom: 1.5rem;
}

.modal-section h4 {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.75rem;
}

.modal-section ul {
    list-style: none;
}

.modal-section li {
    position: relative;
    padding-left: 1.25rem;
    margin-bottom: 0.5rem;
    font-size: 0.9375rem;
    color: var(--text-secondary);
}

.modal-section li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5em;
    width: 6px;
    height: 6px;
    background: var(--accent-primary);
    border-radius: 50%;
}

.modal-tags {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.modal-tag {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-primary);
    background: var(--bg-tertiary);
    padding: 0.375rem 0.75rem;
    border-radius: var(--radius-md);
}

/* ===== Mobile Navigation ===== */
.mobile-nav {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--bg-secondary);
    border-top: 1px solid var(--border-color);
    padding: 0.5rem 0.75rem;
    padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
    z-index: var(--z-mobile-nav);
    box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.3);
}

.mobile-nav-items {
    display: flex;
    justify-content: space-around;
    align-items: center;
    max-width: 500px;
    margin: 0 auto;
}

.mobile-nav-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 0.5rem 0.75rem;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 0.625rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
    border-radius: var(--radius-md);
    -webkit-tap-highlight-color: transparent;
}

.mobile-nav-btn i {
    font-size: 1.25rem;
}

.mobile-nav-btn:hover,
.mobile-nav-btn.active {
    color: var(--accent-primary);
    background: rgba(var(--accent-rgb), 0.1);
}

/* Scrim behind the Edit Lineup sheet on a phone. This is the old
   .sidebar-overlay, which had no live trigger anywhere in the markup; the
   sheet is that trigger now. Lighter than the drawer's 0.6 + blur so the
   board stays legible behind the sheet while it is open. */
.editor-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: var(--z-scrim);
}

/* ===== Responsive ===== */
@media (max-width: 1200px) {
    .builder-container {
        grid-template-columns: minmax(160px, 190px) minmax(0, 1fr) 292px;
    }

    /* Same single-track rule as the base state, and for the same reason: the
       closed panel is display:none above 901px, so declaring a leading zero
       track collapses the board into it. */
    body.editor-closed .builder-container {
        grid-template-columns: minmax(160px, 190px) minmax(0, 1fr);
    }
}

/* 1025-1024px down to the 900px sheet breakpoint the editor stays a docked
   column - it is a tablet, and there is room beside the board. Only the
   header chrome and the pitch sizing change here. */
@media (max-width: 1024px) {
    .mobile-nav {
        display: block;
    }

    /* Mobile nav simplified - 3 buttons */
    .mobile-nav-btn {
        flex: 1;
    }

    /* Hide desktop nav tabs */
    .header .nav-tabs {
        display: none;
    }

    .pitch-container {
        padding-bottom: 70px;
    }

    /* Width-driven rather than height-driven from here down. */
    .pitch {
        width: 100%;
        max-width: 460px;
        aspect-ratio: 68 / 105;
        height: auto;
    }

    .team-header,
    .match-info-display {
        max-width: 420px;
    }

    /* Hide collapsed panels' content completely */
    .sidebar .panel.collapsed .panel-content {
        display: none;
    }
}

/* Tablet header: iPad portrait is 1032px and the action row wants 1334px.
   Above 768px the desktop layout still applies - full text labels on every
   button, plus the Builder/Community tabs - and the row ran 302px past the
   viewport, pushing Export off-screen and making the whole document scroll
   sideways. The app ships TARGETED_DEVICE_FAMILY "1,2", so a reviewer will see
   this on the first launch on an iPad.

   Collapsing the action labels to icons is enough on its own: the row drops to
   roughly 450px and the nav tabs stay. The export caret deliberately stays
   visible here - above 768px the Export button performs the default export and
   the caret is what opens the chooser (see setupEventListeners in app.js). */
@media (max-width: 1200px) {
    .header-actions .btn span:not(.sr-only) {
        display: none;
    }

    .header-actions .btn i {
        margin-right: 0;
    }

    .header-actions .btn {
        padding: 0.5rem 0.7rem;
    }

    /* Routine save updates also appear in the Library. Keep conflict and
       failure states visible below the toolbar, where they have room to wrap. */
    .autosave-status {
        display: none;
    }

    .autosave-status[data-mode="conflict"],
    .autosave-status[data-mode="error"],
    .autosave-status[data-mode="corrupt"],
    .autosave-status[data-mode="cleared"] {
        display: block;
    }
}

@media (max-width: 768px) {
    .header {
        padding: 0.625rem 1rem;
        gap: 0.5rem;
    }
    
    .logo {
        font-size: 1rem;
    }

    .app-logo {
        width: 52px;
        height: 52px;
    }

    .logo i {
        font-size: 1.125rem;
    }

    /* The wordmark costs about 70px of a 375px header - more than any two
       controls - and the mark beside it already carries the branding. Every
       control in this row is icon-only at this width; the logo is no different.
       The accessible name stays on the .logo element's aria-label. */
    .wordmark {
        display: none;
    }
    
    .header-actions {
        gap: 0.375rem;
        /* Must not push the page wider than the viewport. Adding undo/redo
           tipped this row over at 375px, which made the whole document scroll
           sideways. */
        min-width: 0;
        flex-shrink: 1;
    }

    .header-actions .export-dropdown {
        min-width: 0;
    }

    /* Two 44px targets for one action do not fit a 375px header. The caret is
       dropped and the Export button opens the chooser itself instead (see
       setupEventListeners in app.js) - so every layout, and therefore the
       paywall, stays reachable on a phone. */
    .export-dropdown-toggle {
        display: none;
    }

    /* Full width so the chooser reads as a sheet rather than a clipped popover
       hanging off the right edge. */
    .export-dropdown-menu {
        right: 0;
        min-width: min(280px, calc(100vw - 2rem));
    }

    /* Status text, not a control. It is the first thing to go when the header
       runs out of room; the same information is on the draft panel. */
    .autosave-status {
        display: none;
    }

    /* Save Lineup used to be hidden here: the header was a hard ~393px budget
       on an iPhone and this was the one control redundant enough to shed,
       since the lineup autosaves anyway. That premise is gone - the lineup
       verbs now live in the context bar, which is its own row and wraps - so
       the button is visible at every width again. It goes icon-only below
       700px with the rest of the group. */

    /* Icon-only, like every other header control at this width. */
    .pro-chip span {
        display: none;
    }

    .pro-chip {
        padding: 0.28rem 0.45rem;
    }

    .header-actions .export-dropdown .btn:not(.export-dropdown-toggle) {
        border-radius: var(--radius-md);
    }
    
    .header-actions .btn {
        padding: 0.5rem 0.625rem;
        font-size: 0.75rem;
    }
    
    /* Hide button text on mobile, show only icons */
    .header-actions .btn span:not(.sr-only) {
        display: none;
    }
    
    .header-actions .btn i {
        margin-right: 0;
    }
    
    .sidebar {
        width: 85vw;
        max-width: 320px;
    }
    
    .pitch-wrapper {
        padding: 0.5rem;
    }
    
    .pitch {
        max-width: 100%;
        /* Was 0.65, a near-miss for 68:105 that squashed the board slightly. */
        aspect-ratio: 68 / 105;
    }
    
    .team-header,
    .match-info-display {
        max-width: 100%;
    }
    
    .team-header {
        padding: 0.5rem 0.75rem;
    }
    
    .team-name {
        font-size: 0.875rem;
    }
    
    .formation-name {
        font-size: 0.625rem;
        padding: 0.125rem 0.375rem;
    }
    
    .phase-indicator {
        font-size: 0.5rem;
        padding: 0.125rem 0.25rem;
    }
    
    .player {
        width: 48px;
        height: 48px;
    }
    
    .player-avatar {
        width: 36px;
        height: 36px;
        font-size: 0.8125rem;
        /* Larger touch target */
        min-width: 44px;
        min-height: 44px;
    }
    
    .player-name {
        font-size: 0.5625rem;
        max-width: 55px;
    }
    
    .player-position {
        font-size: 0.5rem;
    }
    
    .player::after {
        bottom: -16px;
        font-size: 0.5rem;
    }
    
    .inline-name-input {
        width: 120px;
        padding: 0.5rem 0.625rem;
        font-size: 0.875rem;
    }
    
    .phase-toggle-container {
        flex-direction: column;
        gap: 0.5rem;
        padding: 0 0.5rem;
    }
    
    .phase-toggle {
        width: 100%;
        max-width: 280px;
    }
    
    .phase-btn {
        padding: 0.5rem 0.75rem;
        font-size: 0.75rem;
    }
    
    .copy-phase-btn {
        padding: 0.375rem 0.75rem;
        font-size: 0.6875rem;
    }
    
    /* Subs bench mobile */
    .subs-bench {
        margin: 0.5rem;
        padding: 0.75rem;
        max-width: 100%;
    }
    
    .subs-header h3 {
        font-size: 0.75rem;
    }
    
    .sub-player {
        padding: 0.375rem 0.5rem;
    }
    
    .sub-avatar {
        width: 24px;
        height: 24px;
        font-size: 0.625rem;
    }
    
    .sub-name {
        font-size: 0.6875rem;
        max-width: 55px;
    }
    
    .sub-position {
        font-size: 0.5625rem;
    }
    
    /* Squad panel mobile */
    .squad-panel {
        margin: 0.5rem;
        max-width: 100%;
    }
    
    .tactics-header h1 {
        font-size: 1.75rem;
    }
    
    /* Better touch targets */
    .formation-btn {
        padding: 0.625rem 0.5rem;
        min-height: 44px;
    }
    
    .toggle {
        width: 48px;
        height: 26px;
    }
    
    .toggle-slider:before {
        width: 20px;
        height: 20px;
    }
    
    input:checked + .toggle-slider:before {
        transform: translateX(22px);
    }
}

@media (max-width: 480px) {
    .header {
        padding: 0.5rem 0.75rem;
    }
    
    .logo span {
        display: none;
    }

    /* At 375px the action row still ran ~20px past the viewport and clipped the
       Export button, so the document scrolled sideways - the one thing a native
       app must never do. Tightening the gaps rather than shrinking any touch
       target below Apple's 44pt minimum. */
    .header {
        padding: 0.625rem 0.5rem;
        gap: 0.25rem;
    }

    .header-actions,
    .history-actions,
    .draft-actions {
        gap: 0.25rem;
    }

    .header-brand {
        gap: 0.3rem;
    }

    /* The persistent Pro chip is the first thing to go at this width. The
       paywall is still reached from the export chooser, which is where the
       Pro layouts live and where intent to pay actually forms. */
    .pro-chip {
        display: none;
    }

    /* Ratio deliberately not restated - a pitch is 68:105 at every size. */
    
    .player {
        width: 44px;
        height: 44px;
    }
    
    .player-avatar {
        width: 32px;
        height: 32px;
        font-size: 0.75rem;
        min-width: 44px;
        min-height: 44px;
    }
    
    .player-name {
        font-size: 0.5rem;
        max-width: 45px;
    }
    
    .player-position {
        font-size: 0.4375rem;
    }
    
    .player::after {
        display: none;
    }
    
    .inline-name-input {
        width: 110px;
        font-size: 1rem;
    }
    
    /* Phase labels intentionally NOT hidden here: this block sits after the
       768px rules, so anything set here wins on a phone. Hiding the spans plus
       the icons hidden above left the toggle rendering as two blank blocks. */
    
    .mobile-nav-btn {
        padding: 0.375rem 0.5rem;
        font-size: 0.5625rem;
    }
    
    .mobile-nav-btn i {
        font-size: 1.125rem;
    }
    
    /* Better touch targets on mobile */
    .btn {
        min-height: 44px;
        min-width: 44px;
    }
    
    .toggle {
        width: 52px;
        height: 28px;
    }
    
    .sub-player {
        min-height: 44px;
    }
}

/* ===== Community Section ===== */
.lineups-container {
    max-width: 920px;
    margin: 0 auto;
    padding: 2rem;
}

.lineups-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.lineups-header h1 {
    margin: 0 0 .35rem;
}

.lineups-header p {
    margin: 0;
    color: var(--text-muted);
}

.my-lineups-list {
    max-height: none;
}

.ios-app-promo {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1200;
    display: flex;
    align-items: center;
    gap: 1rem;
    max-width: min(680px, calc(100vw - 2rem));
    padding: 1rem 3rem 1rem 1.15rem;
    border: 1px solid var(--accent-primary);
    border-radius: .9rem;
    background: #171b20;
    box-shadow: 0 18px 50px rgb(0 0 0 / .4);
}
.ios-app-promo[hidden] { display: none; }
.ios-app-promo strong, .ios-app-promo span { display: block; }
.ios-app-promo span { margin-top: .2rem; color: var(--text-muted); font-size: .9rem; }
.ios-app-promo-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
.ios-app-promo-close { position: absolute; top: .35rem; right: .6rem; border: 0; background: transparent; color: var(--text-muted); font-size: 1.4rem; cursor: pointer; }

@media (max-width: 640px) {
    .lineups-container { padding: 1rem; }
    .lineups-header { align-items: flex-start; flex-direction: column; }
    .ios-app-promo { left: .75rem; right: .75rem; bottom: .75rem; max-width: none; align-items: flex-start; flex-direction: column; }
}

/* ===== Community Section ===== */
.community-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem;
}

.community-header {
    text-align: center;
    margin-bottom: 2rem;
}

.community-header h1 {
    font-size: 2.5rem;
    font-weight: 800;
    margin-bottom: 0.5rem;
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.community-header p {
    font-size: 1.125rem;
    color: var(--text-secondary);
}

.community-controls {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 2rem;
}

.community-filters {
    display: grid;
    grid-template-columns: repeat(5, minmax(120px, 1fr));
    gap: 0.5rem;
    width: min(1100px, 100%);
}

.community-filter-panel {
    width: 100%;
}

.community-filters-toggle {
    display: none;
}

.community-filter-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.4rem;
    min-height: 0;
}

.community-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-height: 32px;
    padding: 0.25rem 0.55rem;
    border: 1px solid var(--accent-secondary);
    border-radius: 999px;
    background: rgba(var(--accent-rgb), 0.12);
    color: var(--text-primary);
    font-size: var(--text-xs);
    cursor: pointer;
}

.pagination-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 2rem;
}

.page-indicator {
    font-size: 0.875rem;
    color: var(--text-secondary);
    min-width: 110px;
    text-align: center;
}


.match-plan-presets {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
    margin-bottom: 0.75rem;
}

.match-plan-btn {
    border: 1px solid var(--border-color);
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    border-radius: var(--radius-sm);
    font-size: 0.74rem;
    padding: 0.4rem 0.45rem;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.match-plan-btn.active {
    border-color: var(--accent-primary);
    color: var(--text-primary);
    background: rgba(var(--accent-rgb), 0.15);
}

.match-plan-output {
    display: grid;
    gap: 0.45rem;
}

.match-plan-summary {
    font-size: 0.8rem;
    color: var(--text-primary);
    margin: 0;
}

.match-plan-phase {
    font-size: 0.78rem;
    color: var(--text-secondary);
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 0.42rem 0.5rem;
}

.match-plan-sub-title {
    margin-top: 0.2rem;
    font-size: 0.74rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.match-plan-subs {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.35rem;
}

.match-plan-subs li {
    font-size: 0.76rem;
    color: var(--text-secondary);
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 0.4rem 0.5rem;
}

.match-plan-subs .minute {
    color: var(--accent-primary);
    font-weight: 700;
}

.match-plan-subs .suggestion {
    color: var(--text-primary);
    font-weight: 600;
}

.sort-buttons {
    display: flex;
    gap: 0.5rem;
    background: var(--bg-tertiary);
    padding: 0.25rem;
    border-radius: var(--radius-lg);
}

.sort-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 1rem;
    background: transparent;
    border: none;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 0.8125rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.sort-btn:hover {
    color: var(--text-primary);
}

.sort-btn.active {
    background: var(--accent-primary);
    color: var(--accent-ink);
}

.community-type-filters {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
}

.type-filter-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.5rem 0.75rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.type-filter-btn:hover {
    color: var(--text-primary);
    border-color: var(--accent-secondary);
}

.type-filter-btn.active {
    background: rgba(var(--accent-secondary-rgb), 0.2);
    border-color: var(--accent-secondary);
    color: var(--text-primary);
}

.community-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1.5rem;
}

.lineup-card {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    cursor: pointer;
    transition: all var(--transition-normal);
}

.lineup-card:hover {
    transform: translateY(-4px);
    border-color: var(--accent-primary);
    box-shadow: 0 10px 30px rgba(var(--accent-rgb), 0.2);
}

.lineup-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 1rem;
}

.lineup-card-title {
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.lineup-card-formation {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--accent-primary);
    background: rgba(var(--accent-rgb), 0.15);
    padding: 0.25rem 0.625rem;
    border-radius: var(--radius-sm);
}

.lineup-card-meta-right {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.lineup-card-type {
    font-size: 0.625rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.18rem 0.45rem;
    border-radius: var(--radius-sm);
}

.lineup-card-type.lineup {
    background: rgba(var(--accent-rgb), 0.16);
    color: var(--accent-primary);
}

.lineup-card-type.camp {
    background: rgba(34, 197, 94, 0.14);
    color: var(--accent-success);
}

.lineup-card-author {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin-bottom: 0.75rem;
}

.lineup-card-description {
    font-size: 0.875rem;
    color: var(--text-secondary);
    line-height: 1.5;
    margin-bottom: 1rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ===== Share Modal ===== */
.share-modal-content {
    max-width: 450px;
}

.share-modal-body {
    padding: 2rem;
    text-align: center;
}

.share-icon {
    width: 64px;
    height: 64px;
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1.5rem;
}

.share-icon i {
    font-size: 1.5rem;
    color: white;
}

.share-modal-body h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}

.share-description {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
}

.share-form {
    text-align: left;
    margin-bottom: 1.5rem;
}

.share-form .form-group {
    margin-bottom: 1rem;
}

.textarea {
    min-height: 80px;
    resize: vertical;
}

.btn-large {
    width: 100%;
    padding: 0.875rem;
    font-size: 1rem;
}

.share-result {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border-color);
}

.share-success-icon {
    width: 48px;
    height: 48px;
    background: rgba(34, 197, 94, 0.15);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1rem;
}

.share-success-icon i {
    font-size: 1.5rem;
    color: var(--accent-success);
}

.share-result h3 {
    font-size: 1.125rem;
    font-weight: 600;
    margin-bottom: 1rem;
    color: var(--accent-success);
}

.share-link-container {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.share-link-input {
    flex: 1;
    font-size: 0.8125rem;
    background: var(--bg-tertiary);
}

.share-code-label {
    font-size: 0.875rem;
    color: var(--text-muted);
}

.share-code-label strong {
    color: var(--accent-primary);
    font-family: monospace;
    letter-spacing: 0.1em;
}

.share-result-actions {
    margin-top: 1rem;
}

.share-result-actions .btn {
    width: 100%;
}

/* Team size change confirmation (changeFormat). Reuses .modal/.modal-content/
   .modal-body; only the action row needs a rule, since .modal-actions is
   unstyled elsewhere too. */
.format-change-modal-content {
    max-width: 440px;
}

#formatChangeModal .modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

/* ===== New Lineup quick-start ===== */
.quick-start-content {
    max-width: 560px;
}

/* The shared .modal-close is 36px; this dialog is the one a phone user meets
   first, so its dismiss control gets a full touch target. */
.quick-start-modal .modal-close {
    width: 44px;
    height: 44px;
}

.quick-start-step {
    margin-top: 1.5rem;
}

.quick-start-step-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.625rem;
    font-size: 0.9375rem;
    font-weight: 700;
}

.quick-start-step-num {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(var(--accent-rgb), 0.15);
    color: var(--accent-primary);
    font-size: 0.75rem;
    font-weight: 800;
}

/* The picker's .formation-grid is a single column inside a 320px panel; here
   there is dialog width to spend, so the same cards lay out in a grid. */
/* No `max-height` / `overflow-y` here on purpose. Capping the card list put a
   second touch scroller inside the dialog's own scroller, which on a phone
   means a drag that scrolls the wrong thing depending on where it starts. The
   list now flows, and the actions below are pinned instead - so the primary
   action stays reachable at every list length (11v11 has 43 shapes) without a
   nested gesture surface. */
.quick-start-formations {
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
}

/* The dialog is the only scroller; its actions ride along at the bottom edge.
   `--bg-card` is .modal-content's own background, so the pinned bar reads as
   part of the dialog rather than as a floating panel. */
.quick-start-content .modal-body {
    padding-bottom: 0;
}

.quick-start-actions {
    position: sticky;
    bottom: 0;
    z-index: 1;
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.75rem;
    padding: 0.75rem 0 1.25rem;
    background: var(--bg-card);
    box-shadow: 0 -10px 12px -10px rgba(0, 0, 0, 0.55);
}

.quick-start-actions .btn {
    min-height: 44px;
}

.quick-start-freeform-help {
    margin-top: 1.25rem;
    text-align: right;
}

@media (max-width: 600px) {
    /* Stack in DOM order, which puts the primary action at the bottom -
       nearest the thumb - without the visual order and the tab order
       disagreeing. */
    .quick-start-actions {
        flex-direction: column;
    }

    .quick-start-actions .btn {
        width: 100%;
        justify-content: center;
    }

    .quick-start-freeform-help {
        text-align: left;
    }
}

/* ===== Community Responsive ===== */
@media (max-width: 768px) {
    .community-header h1 {
        font-size: 1.75rem;
    }
    
    .community-grid {
        grid-template-columns: 1fr;
    }

    .community-filters-toggle {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }

    .community-filter-panel {
        display: none;
        position: fixed;
        left: 0.75rem;
        right: 0.75rem;
        bottom: calc(var(--mobile-nav-h, 62px) + 0.75rem);
        z-index: var(--z-sheet);
        max-height: min(76dvh, 560px);
        padding: 1rem;
        overflow-y: auto;
        border: 1px solid var(--border-color);
        border-radius: var(--radius-lg);
        background: var(--bg-secondary);
        box-shadow: var(--shadow-xl);
    }

    .community-filter-panel.is-open {
        display: block;
    }

    .community-filters {
        grid-template-columns: 1fr;
        width: 100%;
    }

    .community-filters .input,
    .community-filters .btn {
        min-height: 44px;
        width: 100%;
    }

    .community-filter-chips {
        justify-content: flex-start;
    }
    
    .sort-buttons {
        flex-wrap: wrap;
        justify-content: center;
    }

    .community-filters {
        grid-template-columns: 1fr 1fr;
    }

    .community-filters .btn {
        grid-column: 1 / -1;
    }

    .lineup-card-preview {
        margin: 0.65rem 0 0.75rem;
    }

    .mini-pitch {
        padding: 0.4rem 0.45rem;
        gap: 0.24rem;
    }

    .mini-player-dot {
        width: 6px;
        height: 6px;
    }
}

/* ===== Substitutes Bench ===== */
.subs-bench {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1rem;
    margin-top: 1rem;
    width: 100%;
    max-width: 500px;
}

.subs-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.subs-header h3 {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.subs-header h3 i {
    color: var(--accent-primary);
}

.subs-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.subs-count {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--bg-tertiary);
    padding: 0.25rem 0.5rem;
    border-radius: var(--radius-sm);
}

.subs-hint {
    margin-top: 0.75rem;
    padding: 0.5rem 0.75rem;
    background: rgba(var(--accent-rgb), 0.1);
    border-radius: var(--radius-md);
    font-size: 0.6875rem;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.subs-hint i {
    color: var(--accent-primary);
}

.subs-hint.hidden {
    display: none;
}

/* Link Sub Section */
.link-sub-section {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color);
}

.link-sub-section label {
    display: block;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: 0.375rem;
}

.link-sub-section select {
    width: 100%;
    margin-bottom: 0.375rem;
}

.link-sub-hint {
    font-size: 0.6875rem;
    color: var(--text-muted);
    margin: 0;
}

.btn-sm {
    padding: 0.375rem 0.625rem;
    font-size: 0.75rem;
}

.subs-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    min-height: 50px;
}

.sub-player {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.sub-player:hover {
    border-color: var(--accent-primary);
    background: var(--bg-primary);
}

.sub-player.selected {
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.2);
}

/* Border and glow are both colour, so on their own they are the only signal
   that a bench row is the one being edited. The tick is the non-colour half,
   the same device .pitch-option-check uses for the selected pitch surface.

   Two classes deep on purpose: Font Awesome's own `.fas { display: ... }` is
   loaded after this stylesheet, so a single-class rule here loses to it and the
   tick showed on every row. */
.sub-player .sub-player-check {
    display: none;
    font-size: 0.625rem;
    color: var(--accent-primary);
}

.sub-player.selected .sub-player-check {
    display: inline-block;
}

.sub-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6875rem;
    font-weight: 700;
    color: white;
}

/* A real <button>, so the bench is reachable by keyboard. It has to shed the
   UA button chrome to keep looking like the text block it replaced. */
.sub-info {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    text-align: left;
    color: inherit;
    cursor: pointer;
}

.sub-assignment {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 130px;
}

.sub-assignment-label {
    font-size: 0.6rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.sub-assign-select {
    font-size: 0.66rem;
    padding: 0.2rem 0.3rem;
    background: var(--bg-primary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    max-width: 170px;
}

.sub-link-summary {
    font-size: 0.62rem;
    color: var(--text-muted);
    max-width: 170px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sub-name {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-primary);
    max-width: 80px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sub-position {
    font-size: 0.625rem;
    color: var(--text-muted);
}

.sub-remove {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.25rem;
    font-size: 0.625rem;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

/* focus-within as well as hover: the button is invisible until revealed, and
   revealing it only on hover left it unusable by keyboard - you could tab to a
   control you could not see. */
.sub-player:hover .sub-remove,
.sub-player:focus-within .sub-remove,
.sub-remove:focus-visible {
    opacity: 1;
}

.sub-remove:hover {
    color: var(--accent-danger);
}

/* A coarse pointer has no hover to reveal anything with, so the remove button
   was permanently invisible on touch while still being tappable. Show it, and
   give it a target big enough to hit on purpose rather than by accident. */
@media (pointer: coarse) {
    .sub-remove {
        opacity: 1;
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

.sub-inline-edit {
    flex: 1;
    padding: 0.375rem 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    background: var(--bg-tertiary);
    border: 2px solid var(--accent-primary);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    outline: none;
    max-width: 100px;
}

.sub-info {
    display: flex;
    flex-direction: column;
}

.subs-empty {
    width: 100%;
    text-align: center;
    padding: 1rem;
    color: var(--text-muted);
    font-size: 0.75rem;
}

.subs-empty-lead {
    display: block;
    margin-top: 0.35rem;
    font-weight: 600;
    color: var(--text-secondary);
}

/* Hidden by default on compact layouts, where the bench follows the pitch. */
.subs-empty-detail {
    display: none;
}

@media (min-width: 901px) {
    .subs-empty-detail {
        display: block;
        margin-top: 0.5rem;
        line-height: 1.45;
        text-wrap: pretty;
    }

    /* The slim empty treatment further up exists to stop an empty bench eating
       board height while it is stacked under the pitch. In the rail there is no
       height to save and 11px is too small for copy whose job is to explain the
       feature, so the normal sizing is restored. */
    .subs-bench:not(.has-subs) .subs-empty {
        padding: 1rem 0.75rem;
        font-size: 0.75rem;
    }
}

/* ===== Camp/Squad Mode ===== */
.panel-description {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-bottom: 0.75rem;
    line-height: 1.4;
}

.squad-size-control {
    margin-top: 0.75rem;
}

.squad-size-control label {
    display: block;
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin-bottom: 0.5rem;
}

.squad-presets {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.squad-preset-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.125rem;
    padding: 0.625rem 0.5rem;
    background: var(--bg-tertiary);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.squad-preset-btn:hover {
    border-color: var(--accent-primary);
    background: var(--bg-primary);
}

.squad-preset-btn.active {
    background: rgba(var(--accent-rgb), 0.15);
    border-color: var(--accent-primary);
}

.preset-number {
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--text-primary);
}

.squad-preset-btn.active .preset-number {
    color: var(--accent-primary);
}

.preset-label {
    font-size: 0.625rem;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.squad-size-options {
    display: flex;
    gap: 0.375rem;
    margin-bottom: 0.5rem;
}

.squad-size-btn {
    flex: 1;
    padding: 0.5rem 0.25rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.squad-size-btn:hover {
    border-color: var(--accent-primary);
}

.squad-size-btn.active {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: var(--accent-ink);
}

.custom-size-row {
    display: flex;
    gap: 0.375rem;
}

.custom-size-row .input-sm {
    flex: 1;
    padding: 0.375rem 0.5rem;
    font-size: 0.75rem;
}

/* Squad Panel */
.squad-panel {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    margin-top: 1rem;
    width: 100%;
    max-width: 500px;
}

.tactical-tool-status {
    margin: 0.45rem 0 0;
    color: var(--text-muted);
    font-size: var(--text-xs);
}

body.annotation-mode-active .pitch {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    cursor: crosshair;
}

body.annotation-mode-active .line-tool-btn.active {
    border-color: var(--accent-primary);
    background: var(--accent-primary);
    color: #fff;
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.2);
}

.player-actions { margin-top: 0.75rem; }
.player-actions-group { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.player-actions-group[hidden] { display: none; }
.player-action-status { margin: 0.5rem 0 0; color: var(--accent-primary); font-size: var(--text-sm); }
body.player-target-select-active .pitch .player { cursor: crosshair; outline: 2px solid transparent; }
body.player-target-select-active .pitch .player:hover,
body.player-target-select-active .pitch .player:focus { outline-color: var(--accent-primary); }

@media (min-width: 901px) {
    /* The roster stays in Players and scrolls with the right editor. */
    .editor-panel #squadPanel {
        width: 100%;
        max-width: none;
        margin: 0.75rem 0 0;
        padding: 0.75rem;
    }
}

/* What squad mode gives you, in the dialog a free user sees when they press
   Squad (#squadProModal). */
.squad-pro-list {
    margin: 0.6rem 0 0;
    padding-left: 1.1rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.5;
}

.squad-pro-list li {
    margin-bottom: 0.25rem;
}

.squad-header {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border-color);
}

.squad-header h2 {
    font-size: 1rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.squad-header h2 i {
    color: var(--accent-primary);
}

/* Was a single-line "0 / 23" pill. Variable team sizes made the content
   three labelled metrics, which overflowed a narrow panel; it wraps between
   metrics now instead of mid-label. */
.squad-counter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.15rem 0.75rem;
    max-width: 100%;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.4;
    padding: 0.375rem 0.75rem;
    background: var(--bg-tertiary);
    border-radius: var(--radius-md);
}

.squad-counter-item {
    white-space: nowrap;
}

.squad-counter.at-limit {
    background: rgba(239, 68, 68, 0.15);
    color: var(--accent-danger);
}

.squad-counter.near-limit {
    background: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
}

.squad-list {
    max-height: 400px;
    overflow-y: auto;
}

.squad-category {
    margin-bottom: 1rem;
}

.squad-category:last-child {
    margin-bottom: 0;
}

.squad-category-header {
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
    padding-left: 0.25rem;
}

.squad-player-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem;
    background: var(--bg-tertiary);
    border-radius: var(--radius-md);
    margin-bottom: 0.375rem;
    cursor: pointer;
    transition: all var(--transition-fast);
}

.squad-player-row:hover {
    background: var(--bg-primary);
}

.squad-player-row.starting {
    border-left: 3px solid var(--accent-primary);
}

.squad-player-row.substitute {
    border-left: 3px solid var(--accent-secondary);
}

.squad-player-number {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6875rem;
    font-weight: 700;
    color: white;
    flex-shrink: 0;
}

.squad-player-details {
    flex: 1;
    min-width: 0;
}

.squad-player-name {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.squad-player-position {
    font-size: 0.6875rem;
    color: var(--text-muted);
}

.squad-player-link {
    display: block;
    font-size: 0.62rem;
    color: var(--accent-secondary);
    margin-top: 0.1rem;
}

.squad-player-badge {
    font-size: 0.625rem;
    padding: 0.125rem 0.375rem;
    border-radius: var(--radius-sm);
    font-weight: 600;
}

.squad-player-badge.starting {
    background: rgba(var(--accent-rgb), 0.15);
    color: var(--accent-primary);
}

.squad-player-badge.sub {
    background: rgba(var(--accent-secondary-rgb), 0.15);
    color: var(--accent-secondary);
}

.squad-player-remove {
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.25rem;
    opacity: 0;
    transition: opacity var(--transition-fast);
}

.squad-player-row:hover .squad-player-remove {
    opacity: 1;
}

.squad-player-remove:hover {
    color: var(--accent-danger);
}

.squad-actions {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-color);
}

.squad-actions .btn {
    width: 100%;
}

/* Add Player Modal */
.add-player-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.add-player-form .form-row {
    display: flex;
    gap: 0.75rem;
}

.add-player-form .form-row .form-group {
    flex: 1;
}

/* ===== Builder Mobile First Overrides ===== */
@media (max-width: 900px) {
    body.editor-open {
        overflow: hidden;
    }

    /* Hand scrolling back to the page.
     *
     * The desktop layout is a fixed-height <main> with each tab scrolling
     * internally, so the base rules set `.main-content { overflow: hidden }`
     * and `.tab-content.active { overflow-y: auto; overflow-x: hidden }`.
     * The mobile block relaxed the heights but never the overflow, which left
     * scroll containers that no longer scroll - and two consequences:
     *
     *   1. Sticky children resolve against the nearest scrollport, which was
     *      #builder-tab, not the page. The bars' offsets (56px, 98px) are
     *      sized to clear the 60px page header, so measured from a scrollport
     *      that already begins below the header they parked the jump bar 56px
     *      past its own flow position - a permanent 54px band of dead black
     *      under the header, and the phase toggle overlapping the team name
     *      by 24px below it.
     *   2. Those containers are `height: auto` here, so they grow to fit and
     *      never scroll. A sticky child of a scrollport that never scrolls
     *      never sticks: both bars paid the layout cost of stickiness while
     *      scrolling away with the content anyway.
     *
     * `overflow: visible` on both axes is required rather than merely omitting
     * the property - the base rules still apply otherwise. Note the axes
     * cannot disagree: `overflow-x: hidden` alone would force overflow-y to
     * compute as `auto` and recreate the scrollport. Sideways overflow is
     * guarded instead by scripts/check_bundle.mjs, which fails the build if
     * the document scrolls horizontally at 375/393/440px.
     */
    .main-content {
        height: auto;
        min-height: calc(100vh - 60px);
        padding-bottom: 5.25rem;
        overflow: visible;
    }

    .tab-content,
    .tab-content.active {
        height: auto;
        min-height: 100%;
        /* See .main-content above: this is the element that was actually
           capturing sticky positioning for the whole builder. */
        overflow: visible;
    }

    #builder-tab {
        padding: 0.5rem;
        scroll-padding-top: 6.5rem;
    }

    .lineup-context-bar {
        position: sticky;
        /* Parks directly under the sticky header. --header-h is measured at
           runtime by syncLayoutMetrics() in native.js, because in the app the
           header grows by env(safe-area-inset-top) and no literal is right on
           both a notched iPhone and a home-button one. The 60px fallback only
           applies before that first measurement lands. */
        top: var(--header-h, 60px);
        z-index: 95;
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.375rem;
        background: var(--bg-primary);
        padding: 0.25rem 0.15rem;
        border-bottom: none;
    }

    .lineup-context-identity {
        flex: 0 1 auto;
        max-width: 100%;
    }

    .lineup-utility-actions { margin-left: auto; }

    /* Keep the announcement region accessible while the visible identity row
       occupies its place in the context bar. */
    .lineup-context-chip {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }

    /* Keep the library/share/export row and Edit/New controls together above
       the pitch; the editor itself remains a bottom sheet. */
    .lineup-action-stack {
        order: -2;
        display: flex;
        flex: 1 1 auto;
        width: 100%;
        min-width: 0;
    }

    .lineup-workflow-actions { width: 100%; }

    .lineup-history-group { gap: 0.375rem; }

    .lineup-context-bar > .autosave-status {
        display: block;
        flex: 1 0 100%;
        text-align: left;
    }

    .lineup-library-actions { gap: 0.375rem; }

    .lineup-library-actions .btn,
    .lineup-sharing-actions .btn,
    .lineup-workflow-actions .btn {
        padding: 0.5rem 0.6rem;
        min-width: 44px;
        min-height: 44px;
        justify-content: center;
    }

    #editLineupBtn {
        flex: 1 1 155px;
        justify-content: center;
    }

    .pitch-history-toolbar { width: 100%; }

    .builder-container {
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
        min-height: 0;
    }

    /* The Edit Lineup panel becomes a bottom sheet. It sits above the scrim
       and below the mobile nav, scrolls on its own (.editor-body owns the
       overflow), and leaves the top of the board visible so an edit can be
       seen landing. Closing is presentational only - every control writes
       straight to state, so nothing is discarded. */
    .editor-sidebar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        z-index: var(--z-sheet);
        width: 100%;
        max-width: none;
        /* 76dvh left literally none of the board visible above the sheet at
           375x812 (the board starts 288px down and the sheet started at
           195px). 56dvh plus revealBoardAboveSheet() in app.js puts a usable
           strip of pitch on screen while the sheet is open: 111px of
           unoccluded board at 375x812 - the penalty area and the top halves
           of two tokens. The sheet's own content scrolls, so the height given
           up costs scrolling inside the panel, not access - but it does have
           to stay clear of the bottom nav, see padding-bottom below. */
        max-height: 50dvh;
        display: flex;
        padding: 0;
        border: none;
        border-top: 1px solid var(--border-color);
        border-radius: var(--radius-lg) var(--radius-lg) 0 0;
        background: var(--bg-secondary);
        box-shadow: 0 -12px 32px rgba(0, 0, 0, 0.45);
        transform: translateY(100%);
        transition: transform 0.22s ease;
        visibility: hidden;
        /* .mobile-nav is fixed at z-index 101, above this sheet, so without
           this the bottom of the panel - including the Edit Player name field
           the tap-a-player flow exists to reach - sat behind it and could not
           be tapped. --mobile-nav-h is measured in native.js and already
           includes the nav's own safe-area padding. */
        padding-bottom: var(--mobile-nav-h, 62px);
    }

    .editor-sidebar[data-sheet-state="expanded"] {
        max-height: 88dvh;
    }

    .editor-sheet-handle {
        display: inline-flex;
        margin: 0 auto;
        order: 0;
    }

    .editor-header {
        display: flex;
        position: relative;
        flex-wrap: wrap;
        justify-content: center;
        padding-top: 0.35rem;
    }

    .editor-close {
        position: absolute;
        top: 0.25rem;
        right: 0.5rem;
        order: 2;
    }

    body.editor-open .editor-sidebar {
        transform: translateY(0);
        visibility: visible;
    }

    body.editor-open .editor-overlay {
        display: block;
    }

    .editor-close {
        display: inline-flex;
    }

    .editor-tab {
        flex-direction: column;
        gap: 0.15rem;
        font-size: 0.75rem;
    }

    .sidebar .panel {
        width: 100%;
        min-width: 0;
        margin-bottom: 0.6rem;
    }

    .panel-header {
        min-height: 48px;
    }

    .panel-toggle {
        min-width: 44px;
        min-height: 44px;
    }

    /* Pitch first. The builder used to open on a stack of control panels with
       the pitch 854px down the page, so a phone user could not see their XI
       without scrolling for it. The thing you came to look at goes at the top. */
    .pitch-container {
        order: -1;
        padding: 0;
        align-items: stretch;
        overflow: visible;

        /* `flex: 1` from the 768px block resolves to `flex: 1 1 0%`, which
           sizes this column by flex distribution rather than by its content.
           Once .pitch-stage stops applying size containment (see below) the
           board's real height has to be allowed to propagate up, or the
           container clips it again. */
        flex: 0 0 auto;
        height: auto;
        min-height: 0;
    }

    .pitch-wrapper {
        width: 100%;
        max-width: 100%;
        align-items: stretch;
    }

    /* Width-driven on narrow screens: the pitch takes the full column width and
       its height follows from the 68:105 ratio. (Desktop is the reverse.)

       `container-type: size` from the base rule has to go with it. Size
       containment means children cannot contribute to this box's height, so
       `height: auto` collapsed to whatever flex handed down - 447px on an
       iPhone - while the pitch inside was 630px. `align-items: center` then
       split the 183px overflow above and below, pushing the attacking third
       under the sticky header where no amount of scrolling could reach it.

       Inline-size containment keeps cqw working for anything that needs it
       while letting the block axis follow content. Nothing here needs cqh:
       the mobile `.pitch` rule below is width-driven. */
    .pitch-stage {
        height: auto;
        flex: 0 0 auto;
        container-type: inline-size;
        align-items: stretch;
    }

    .pitch {
        width: 100%;
        height: auto;
    }

    .pitch-board {
        display: block;
    }

    /* Stacked, this wrapper's children are the sticky phase bar, the board and
       the annotation tools. A 12px rhythm between full-width bands is board
       height spent on air, and the top inset only ever showed as a gap between
       two sticky bars that park flush against each other the moment you
       scroll. */
    .pitch-wrapper {
        gap: 0.375rem;
        padding: 0 0.5rem 0.5rem;
    }

    /* Dissolve the Pitch wrapper into the phone flow: phase stays above the
       pitch, drawing tools and the collapsed Appearance section follow it. */
    .pitch-tools-sidebar,
    .pitch-sidebar-section {
        display: contents;
    }

    #pitchToolsSidebar {
        padding: 0;
        border: 0;
        overflow: visible;
    }

    .pitch-tools-sidebar .phase-toggle-container { order: -3; }
    .pitch-board { order: -1; }
    .pitch-tools-sidebar .line-tools {
        order: 1;
        width: 100%;
        justify-content: flex-start;
    }

    .pitch-appearance {
        order: 2;
        width: 100%;
        margin: 0 0 0.5rem;
    }

    #builderPitchSection {
        scroll-margin-top: 7rem;
    }

    .phase-toggle-container,
    .team-header,
    .line-tools,
    .pitch,
    .subs-bench,
    .squad-panel,
    .match-info-display {
        max-width: 100%;
    }

    /* One row, not two. The toggle and the copy button stacked here, which
       made a two-state switch 90px tall and left the copy button floating
       centred under it, attached to nothing. Side by side it is 44px and the
       copy button sits against the toggle whose phases it copies between. */
    .phase-toggle-container {
        position: sticky;
        /* Below the header AND the jump bar. Both are measured, so this stays
           correct when either changes height. */
        top: calc(var(--header-h, 60px) + var(--jump-h, 43px));
        z-index: 92;
        background: var(--bg-primary);
        flex-direction: row;
        align-items: center;
        gap: 0.375rem;
        /* .pitch-wrapper owns the rhythm here; a margin on top of its gap is
           the same space charged twice. */
        margin-bottom: 0;
        padding: 0.25rem 0;
    }

    .phase-toggle {
        flex: 1 1 auto;
        width: auto;
        max-width: none;
    }

    .phase-btn {
        flex: 1;
        justify-content: center;
        min-height: 44px;
    }

    /* Icon-only, and square, so it reads as an adjunct to the toggle rather
       than a third phase. The label stays in the accessibility tree - only its
       rendered size is zeroed. */
    .copy-phase-btn {
        flex: 0 0 auto;
        width: 44px;
        min-width: 44px;
        justify-content: center;
        min-height: 44px;
        font-size: 0;
        gap: 0;
        padding: 0;
    }

    .copy-phase-btn i {
        font-size: 0.85rem;
    }

    .lineup-context-bar .team-header .formation-display {
        gap: 0.375rem;
    }

    .line-tools {
        gap: 0.5rem;
        border-radius: 0;
        padding: 0.6rem;
    }

    .line-tools-buttons {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 0.4rem;
    }

    .line-tools-style {
        justify-content: space-between;
        width: 100%;
    }

    .annotation-style-select {
        flex: 1;
        min-height: 36px;
    }

    .line-tools-buttons .btn {
        justify-content: center;
        min-height: 42px;
        padding: 0.4rem;
        font-size: 0.72rem;
    }

    .line-tools-color {
        justify-content: space-between;
        width: 100%;
    }

    .pitch {
        width: 100%;
        height: auto;
        border-radius: 0;
    }

    .subs-bench,
    .squad-panel {
        margin: 0;
        border-radius: var(--radius-md);
    }

    .subs-container {
        display: grid;
        grid-template-columns: 1fr;
        gap: 0.45rem;
    }

    .sub-player {
        width: 100%;
        min-height: 46px;
        justify-content: flex-start;
    }

    .sub-assignment {
        min-width: 0;
    }

    .sub-assign-select,
    .sub-link-summary {
        max-width: none;
        width: 100%;
    }
}

@media (max-width: 480px) {
    .lineup-context-bar {
        /* Same measured value at this breakpoint - see the rule above. */
        top: var(--header-h, 56px);
    }

    .phase-toggle-container {
        top: calc(var(--header-h, 56px) + var(--jump-h, 42px));
    }

    .line-tools-buttons .btn {
        font-size: 0.66rem;
    }


    .mobile-nav-btn {
        min-height: 44px;
    }
}

/* =====================================================================
   Native (iOS) presentation
   ---------------------------------------------------------------------
   Everything in this block is scoped to .is-native, which static/js/native.js
   puts on <html> only when Capacitor reports a native platform. The web app is
   byte-for-byte unaffected; these rules exist to erase the handful of tells
   that make a WebView feel like a web page rather than an app.
   ===================================================================== */

.is-native {
    /* iOS reports 100vh as the height *without* browser chrome, which in a
       WebView overshoots and pushes content under the home indicator. dvh is
       the dynamic viewport and is what the layout actually has. */
    --footer-h: 0px;
    -webkit-tap-highlight-color: transparent;
}

.is-native body {
    min-height: 100dvh;
    /* Rubber-band scrolling past the top of a native app screen reads as a
       broken page. The pitch is a fixed board, so there is nothing to reveal. */
    overscroll-behavior: none;
}

/* A tactical board is a drag surface. Long-pressing a player token must pick
   it up, not raise the iOS text-selection loupe and copy/paste callout. */
.is-native .pitch,
.is-native .player,
.is-native .substitute-item,
.is-native .nav-tab,
.is-native .mobile-nav-btn,
.is-native .phase-btn,
.is-native .btn {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

/* Text the user may legitimately want to copy stays selectable. */
.is-native .share-link-input,
.is-native input,
.is-native textarea {
    -webkit-user-select: text;
    user-select: text;
}

/* The status bar overlays the WebView, so the sticky header has to pay for it
   itself or the notch eats the wordmark. */
.is-native .header {
    /* Treat tiny synthetic insets as zero while preserving the full inset on
       notched devices. This keeps the desktop bundle smoke-test header on one
       row without changing real iPhone safe-area spacing. */
    padding-top: max(0.75rem, env(safe-area-inset-top));
}

.is-native .main-content,
.is-native .builder-container {
    min-height: auto;
}

/* Web-only chrome that has no place in an app: the copyright bar and the
   donate link are replaced by the App Store listing and StoreKit. */
.is-native .site-footer {
    display: none;
}

/* iOS zooms the viewport when a focused input renders below 16px. The design
   system's 15px body size is exactly on the wrong side of that line. */
.is-native input,
.is-native textarea,
.is-native select {
    font-size: 16px;
}

/* Bottom nav has to clear the home indicator, and the scroll container has to
   clear the bottom nav. */
.is-native .mobile-nav {
    padding-bottom: max(0.75rem, env(safe-area-inset-bottom));
}

.is-native .main-content {
    padding-bottom: calc(64px + env(safe-area-inset-bottom));
}

/* ===== Pro chip (paywall entry point) ===== */
.pro-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.28rem 0.6rem;
    border-radius: 999px;
    border: 1px solid rgba(var(--accent-rgb), 0.45);
    background: rgba(var(--accent-rgb), 0.12);
    color: var(--accent-primary);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    min-height: 32px;
}

.pro-chip[hidden] {
    display: none;
}

.pro-chip:active {
    transform: scale(0.96);
}

/* ===== Paywall ===== */
.paywall-content {
    max-width: 420px;
    width: min(92vw, 420px);
    padding: 2rem 1.5rem calc(1.5rem + env(safe-area-inset-bottom));
    text-align: center;
}

.paywall-mark {
    width: 56px;
    height: 56px;
    margin: 0 auto 1rem;
    display: grid;
    place-items: center;
    border-radius: var(--radius-lg, 14px);
    background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
    color: #04120a;
    font-size: 1.5rem;
}

.paywall-content h2 {
    font-size: var(--text-lg);
    margin-bottom: 0.35rem;
}

.paywall-sub {
    color: var(--text-secondary);
    font-size: var(--text-sm);
    margin-bottom: 1.5rem;
}

.paywall-features {
    list-style: none;
    display: grid;
    gap: 1rem;
    margin: 0 0 1.75rem;
    text-align: left;
}

.paywall-features li {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.paywall-features i {
    color: var(--accent-primary);
    margin-top: 0.15rem;
    width: 1.1rem;
    text-align: center;
}

.paywall-features strong {
    display: block;
    font-size: var(--text-base);
    margin-bottom: 0.1rem;
}

.paywall-features span {
    display: block;
    color: var(--text-secondary);
    font-size: var(--text-sm);
    line-height: 1.4;
}

.paywall-buy {
    width: 100%;
    min-height: 50px;
}

.paywall-buy[disabled] {
    opacity: 0.6;
}

/* Restore Purchases is required by Guideline 3.1.1 and must be findable.
   Quiet, but never hidden behind a menu. */
.paywall-restore {
    display: block;
    width: 100%;
    margin-top: 0.85rem;
    padding: 0.6rem;
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: var(--text-sm);
    text-decoration: underline;
    cursor: pointer;
    min-height: 44px;
}

.paywall-legal {
    margin-top: 1.25rem;
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.paywall-legal a {
    color: var(--text-secondary);
}

/* ===== Community offline and empty states =====
   .community-empty had no rules at all: its icon, heading, copy and (since
   the format filters) its clear-filters button rendered as a bare left-aligned
   stack. Shares .community-offline's layout because they are the same thing -
   a full-width message in place of the grid. */
.community-offline,
.community-empty {
    grid-column: 1 / -1;
    display: grid;
    justify-items: center;
    gap: 0.6rem;
    padding: 2rem 1.5rem 3rem;
    text-align: center;
    color: var(--text-secondary);
}

.community-offline {
    padding: 3rem 1.5rem;
}

.community-offline i,
.community-empty i {
    font-size: 2rem;
    color: var(--text-muted);
}

.community-offline h3,
.community-empty h3 {
    color: var(--text-primary);
    font-size: var(--text-md);
}

.community-offline p,
.community-empty p {
    max-width: 34ch;
    font-size: var(--text-sm);
    line-height: 1.5;
}

.community-offline .btn,
.community-empty .btn {
    margin-top: 0.5rem;
    min-height: 44px;
}

/* ===== Legal / support pages (/privacy, /support) =====
   Plain prose pages that App Store Connect links to. Deliberately independent
   of the builder layout so they render correctly with the app shell absent. */
.legal-page {
    max-width: 46rem;
    margin: 0 auto;
    padding: 2.5rem 1.25rem 4rem;
    line-height: 1.65;
    color: var(--text-secondary);
}

.legal-home {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 2rem;
    color: var(--text-primary);
    text-decoration: none;
    font-weight: 700;
}

.legal-home .app-logo {
    width: 28px;
    height: 28px;
}

.legal-page h1 {
    color: var(--text-primary);
    font-size: var(--text-xl);
    line-height: 1.2;
    margin-bottom: 0.35rem;
}

.legal-updated {
    color: var(--text-muted);
    font-size: var(--text-sm);
    margin-bottom: 2rem;
}

.legal-lead {
    font-size: var(--text-md);
    color: var(--text-primary);
    margin-bottom: 2rem;
}

.legal-page h2 {
    color: var(--text-primary);
    font-size: var(--text-md);
    margin: 2.25rem 0 0.6rem;
}

.legal-page h3 {
    color: var(--text-primary);
    font-size: var(--text-base);
    margin: 1.5rem 0 0.4rem;
}

.legal-page p,
.legal-page ul {
    margin-bottom: 1rem;
}

.legal-page ul {
    padding-left: 1.15rem;
}

.legal-page li {
    margin-bottom: 0.4rem;
}

.legal-page a {
    color: var(--accent-primary);
}

.legal-page strong {
    color: var(--text-primary);
}

.legal-footer {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 3rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--border-color);
    font-size: var(--text-sm);
}
/* Product-wide interaction safety: keyboard users always retain a visible focus target. */
:focus-visible { outline: 3px solid #ffd166; outline-offset: 3px; }
.player:focus-visible { z-index: 20; box-shadow: 0 0 0 4px #111827, 0 0 0 7px #ffd166; }
.autosave-status { color: var(--text-muted, #71808a); font-size: .75rem; white-space: nowrap; }
.autosave-status.saved { color: #86efac; }
.autosave-status.cleared { color: #ffd166; }
.draft-manager { border: 0; border-radius: 0; background: transparent; color: var(--text, #fff); max-width: min(92vw, 760px); width: min(92vw, 760px); padding: 0; overflow: visible; }
.draft-manager[open] { display: block; opacity: 1; visibility: visible; }
.draft-manager::backdrop { background: rgb(0 0 0 / .65); }
.draft-manager .modal-content { width: 100%; max-width: none; box-sizing: border-box; padding: 1.25rem; }
.draft-list { display: grid; gap: .65rem; margin: 1rem 0; max-height: 50vh; overflow: auto; }
.draft-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; border: 1px solid rgb(255 255 255 / .12); border-radius: 10px; padding: .75rem; }
.draft-row span { display: block; color: var(--text-muted, #9aa7b1); font-size: .8rem; margin-top: .25rem; }
.draft-row-actions { display: flex; gap: .35rem; flex-wrap: wrap; }
@media (max-width: 700px) { .draft-actions .btn span { display: none; } .autosave-status { display: none; } .draft-row { align-items: flex-start; flex-direction: column; } }

/* Unified Library: restrained cards keep the item, origin and next action
   readable without turning the collection into a dashboard. */
.library-container { width: min(1100px, calc(100% - 2rem)); margin: 0 auto; padding: 2rem 0 4rem; }
.library-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem; margin-bottom: 1.5rem; }
.library-header h1 { margin: 0; }
.library-header p, .library-panel-heading p { color: var(--text-muted, #a0a0a0); margin: .45rem 0 0; }
.library-section-tabs { display: flex; gap: .35rem; overflow-x: auto; border-bottom: 1px solid #303030; margin: 1.5rem 0; scrollbar-width: thin; }
.library-pro-badge { display: inline-flex; align-items: center; margin-left: .3rem; padding: .08rem .35rem; border-radius: 999px; background: rgba(124, 255, 0, .12); color: #7cff00; font-size: .65rem; font-weight: 800; letter-spacing: .04em; }
.library-section-tab { flex: 0 0 auto; min-height: 44px; padding: .65rem 1rem; color: #aaa; background: transparent; border: 0; border-bottom: 2px solid transparent; cursor: pointer; }
.library-section-tab:hover, .library-section-tab:focus-visible { color: #fff; }
.library-section-tab.active { color: #7cff00; border-bottom-color: #7cff00; }
.library-section-panel[hidden] { display: none; }
.library-panel-heading { margin: 1.25rem 0; }
.library-panel-heading h2 { margin: 0; font-size: 1.25rem; }
.library-item-list { display: grid; gap: .7rem; }
.library-item-card { display: flex; justify-content: space-between; align-items: center; gap: 1rem; min-width: 0; padding: 1rem; border: 1px solid #303030; border-radius: 10px; background: #141414; }
.match-plans-access, .match-plans-empty { margin: 1rem 0; padding: 1rem; border: 1px solid #303030; border-radius: 10px; background: #141414; color: #b8bec8; }
.match-plans-status { min-height: 1.4em; color: #8992a0; }
.match-plan-create-form { display: grid; gap: .65rem; max-width: 44rem; margin: 1rem 0; padding: 1rem; border: 1px solid #343b2f; border-radius: 12px; background: #11150f; }
.match-plan-create-form[hidden] { display: none; }
.match-plan-create-form h3 { margin: 0; }
.match-plan-name-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .75rem; }
.match-plan-name-fields > div { display: grid; gap: .4rem; }
.match-plan-form-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.match-plan-card .library-item-main { flex: 1; }
.match-plan-workspace { display: grid; gap: 1rem; margin: 0 0 1rem; padding: 1rem; border: 1px solid var(--border-color); border-top: 2px solid var(--accent-primary); border-radius: 12px; background: var(--bg-card); }
.match-plan-workspace[hidden], .match-plan-matchup-view[hidden] { display: none; }
.match-plan-workspace-header { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.match-plan-workspace-header h2 { margin: 0; font-size: 1.25rem; }
.match-plan-workspace-kicker { margin: 0 0 .2rem; color: var(--text-muted); font-size: .75rem; }
.match-plan-workspace-actions { display: flex; align-items: center; justify-content: flex-end; gap: .6rem; color: var(--text-secondary); font-size: .85rem; }
.match-plan-view-tabs { display: inline-flex; gap: .3rem; width: max-content; max-width: 100%; padding: .25rem; border: 1px solid var(--border-color); border-radius: 10px; background: var(--bg-secondary); }
.match-plan-view-tab { padding: .55rem .85rem; border: 0; border-radius: 7px; background: transparent; color: var(--text-secondary); font: inherit; font-weight: 650; cursor: pointer; }
.match-plan-view-tab.active { background: var(--accent-primary); color: var(--accent-ink); }
.match-plan-workspace:has(.match-plan-view-tab[aria-selected="true"][data-match-plan-view="opponent"]) { border-top-color: #4f8fff; }
.match-plan-view-tab:focus-visible, .match-plan-workspace button:focus-visible, .match-plan-workspace select:focus-visible { outline: 2px solid var(--accent-primary); outline-offset: 2px; }
.match-plan-editor-hint { margin: 0; color: var(--text-secondary); }
.matchup-phase-controls { display: flex; justify-content: center; align-items: end; gap: .8rem; }
.matchup-phase-controls label { display: grid; gap: .35rem; min-width: 10rem; color: var(--text-secondary); font-size: .82rem; font-weight: 650; }
.matchup-vs { padding-bottom: .55rem; color: var(--text-muted); font-size: .85rem; }
.matchup-team-labels { display: flex; justify-content: space-between; width: min(100%, 36rem); margin: 0 auto; color: var(--text-primary); font-weight: 700; }
.matchup-pitch { position: relative; width: min(100%, 36rem); aspect-ratio: 3 / 4; margin: 0 auto; overflow: hidden; border: 2px solid rgba(233, 242, 236, .48); border-radius: 8px; background: var(--pitch-classic); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .25); }
.matchup-pitch-markings { z-index: 0; pointer-events: none; }
.matchup-pitch::before { position: absolute; inset: 0; border: 1px solid var(--chalk-line); content: ''; pointer-events: none; }
.matchup-pitch::after { position: absolute; top: 50%; left: 0; width: 100%; border-top: 1px solid var(--chalk-line); content: ''; pointer-events: none; }
.matchup-pitch-markings { position: absolute; top: 50%; left: 50%; width: 26%; aspect-ratio: 1; transform: translate(-50%, -50%); border: 1px solid var(--chalk-line); border-radius: 50%; pointer-events: none; }
.matchup-annotation-layer { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.matchup-player { position: absolute; z-index: 2; display: flex; flex-direction: column; align-items: center; width: 4.8rem; transform: translate(-50%, -50%); color: #fff; text-align: center; font-size: .65rem; line-height: 1.05; pointer-events: none; }
.matchup-player-marker { display: grid; place-items: center; width: 1.85rem; height: 1.85rem; margin-bottom: .12rem; border: 2px solid rgba(255, 255, 255, .95); border-radius: 50%; background: var(--accent-primary); color: var(--accent-ink); font-size: .72rem; font-weight: 800; box-shadow: 0 1px 4px rgba(0, 0, 0, .5); }
.matchup-player.opponent .matchup-player-marker { background: #4f8fff; color: #07152d; }
.matchup-player-name { max-width: 100%; padding: .08rem .2rem; border-radius: 3px; background: rgba(0, 0, 0, .58); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.matchup-ball { position: absolute; z-index: 3; width: .65rem; height: .65rem; transform: translate(-50%, -50%); border: 1px solid #111; border-radius: 50%; background: #fff; }
.matchup-rotate-note { width: min(100%, 36rem); margin: 0 auto; color: var(--text-muted); font-size: .8rem; }
#builder-tab.match-plan-show-matchup > :not(#matchPlanWorkspace) { display: none !important; }
.library-item-main { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-width: 0; flex: 1; }
.library-item-main > div { min-width: 0; }
.library-item-main strong { display: block; overflow-wrap: anywhere; }
.library-item-main > div > span { display: block; margin-top: .3rem; color: var(--text-muted, #a0a0a0); font-size: .85rem; }
.library-origin-badge { flex: 0 0 auto; padding: .25rem .55rem; border: 1px solid #3a4931; border-radius: 999px; color: #b5ff7e; background: #1c2815; font-size: .75rem; }
.library-item-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.library-overflow { position: relative; }
.library-overflow > button { min-width: 44px; min-height: 40px; font-size: 1.2rem; }
.library-overflow-menu { position: absolute; z-index: 20; top: calc(100% + .3rem); right: 0; display: grid; min-width: 150px; padding: .3rem; border: 1px solid #393939; border-radius: 8px; background: #1c1c1c; box-shadow: 0 8px 28px #0009; }
.library-overflow-menu[hidden] { display: none; }
.library-overflow-menu button { min-height: 40px; padding: .55rem .7rem; color: #eee; text-align: left; border: 0; border-radius: 5px; background: transparent; cursor: pointer; }
.library-overflow-menu button:hover, .library-overflow-menu button:focus-visible { background: #303030; }
.library-overflow-menu button.danger { color: #ff8f8f; }
.library-empty { padding: 1.4rem; border: 1px dashed #414141; border-radius: 10px; color: #c5c5c5; }
.library-empty p { margin: 0 0 .75rem; }
.library-container :focus-visible { outline: 2px solid #7cff00; outline-offset: 2px; }
.formation-library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: .7rem; }
.library-formation-card { display: grid; grid-template-columns: 76px minmax(0, 1fr); align-items: center; gap: .65rem .8rem; padding: .7rem; border: 1px solid #303030; border-radius: 10px; background: #141414; }
.library-formation-card.selected { border-color: #7cff00; box-shadow: inset 0 0 0 1px #7cff00; }
.library-formation-preview { display: grid; place-items: center; width: 76px; height: 76px; border-radius: 7px; color: #7cff00; background: #1c4231; }
.library-formation-preview .formation-preview { width: 68px; height: 68px; }
.library-formation-copy { min-width: 0; }
.library-formation-copy strong, .library-formation-copy span { display: block; }
.library-formation-copy span { margin-top: .25rem; color: #aaa; font-size: .75rem; }
.library-formation-actions { grid-column: 1 / -1; display: flex; gap: .45rem; }
.library-custom-formations { margin-top: 2rem; }
.library-custom-formations > h3 { margin-bottom: .5rem; }
.library-review-action { display: flex; justify-content: center; margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid #303030; }
@media (max-width: 700px) {
    .library-container { width: min(100% - 1.25rem, 1100px); padding-top: 1.25rem; }
    .library-header { align-items: flex-start; flex-direction: column; }
    .library-item-card { align-items: stretch; flex-direction: column; }
    .match-plan-name-fields { grid-template-columns: 1fr; }
    .match-plan-workspace-header { align-items: flex-start; flex-direction: column; }
    .match-plan-workspace-actions { width: 100%; justify-content: flex-start; flex-wrap: wrap; }
    .matchup-phase-controls { gap: .45rem; }
    .matchup-phase-controls label { min-width: 0; flex: 1; }
    .matchup-team-labels { font-size: .85rem; }
    .matchup-player { width: 3.5rem; font-size: .55rem; }
    .matchup-player-marker { width: 1.55rem; height: 1.55rem; font-size: .65rem; }
    .library-item-actions .btn { min-height: 44px; }
    .formation-library-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .library-formation-card { grid-template-columns: 52px minmax(0, 1fr); }
    .library-formation-preview { width: 52px; height: 64px; }
    .library-formation-preview .formation-preview { width: 48px; height: 58px; }
}

/* Desktop keeps pitch and style controls in a dedicated left work area. */
@media (min-width: 901px) {
    .pitch-tools-sidebar { position: relative; }
}

/* Below 700px the New Lineup action keeps its icon and hides its long label so
   the controls remain comfortable beside each other above the pitch. */
@media (max-width: 700px) {
    .lineup-workflow-actions #mainNewLineupBtn span {
        display: none;
    }
}

/* Touch targets. These buttons inherit the desktop .btn height of 38px, which
   is under the 44px minimum, and the existing bump only applied at phone
   widths - so a tablet (768px, coarse pointer) got 38px targets. Keyed on the
   pointer type rather than a width, since that is the thing that actually
   decides whether a finger is involved. */
@media (pointer: coarse) {
    .lineup-library-actions .btn,
    .lineup-sharing-actions .btn,
    .lineup-workflow-actions .btn,
    .lineup-history-group .btn {
        min-height: 44px;
    }

    /* The paywall entry point, and the smallest control in the header at
       31x32. It is also the one control here that has to be hit deliberately
       rather than found by habit. */
    .pro-chip {
        min-width: 44px;
        min-height: 44px;
        justify-content: center;
    }

    /* Share and Export. Phone widths already bump these; a tablet did not, so
       the two most-used controls in the product were 30px there. The header's
       own content is 45px tall below 1024px and 49px above it, so nothing here
       makes the header taller - scripts/check_bundle.mjs caps it at 84px. */
    .header-actions .btn {
        min-width: 44px;
        min-height: 44px;
    }

    /* Every export layout is chosen from this menu - including the Pro ones,
       so the paywall is behind it - and its rows were 35px. */
    .export-option {
        min-height: 44px;
    }

    /* Two short each. */
    .line-tools-buttons .btn,
    .copy-phase-btn {
        min-height: 44px;
    }

    /* The bench verbs are .btn-sm, which is 26-28px tall. */
    .subs-header-actions .btn {
        min-height: 44px;
    }

    /*
     * Deliberately NOT bumped: .player-add-sub, the "Add backup" pill under
     * each token. It is 44x28 and it stays that way. Eleven 44px targets on a
     * 375px-wide board would cover the pitch, and the rows are ~70px apart
     * with a 48px token, so a 44px-tall target - painted or invisible - lands
     * on the player below and takes its taps. Linking a substitute is
     * available at full size in the bench, on every substitute row.
     */
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .01ms !important; } }

/* ===== Growth surface (web only): site footer ===== */

/* Full width. This rule used to cap it at 860px and centre it, which is what
   kept the footer a narrow strip; the base rule above owns the layout now. */
.site-footer { max-width: none; width: 100%; margin: 0; padding: 0.75rem 1.5rem; border-top: 1px solid rgb(255 255 255 / .1); color: var(--text-muted, #9aa7b1); font-size: .85rem; }
.site-footer nav { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 1rem 1.5rem; margin-bottom: .6rem; }
.site-footer a { color: var(--text-muted, #9aa7b1); text-decoration: none; }
.site-footer a:hover { color: var(--accent-primary); }
.site-footer-bottom { display: flex; flex: 1 0 100%; align-items: center; justify-content: space-between; gap: 0.75rem; }
.site-footer-bottom p { min-width: 0; margin: 0; text-align: left; }
.site-footer-actions { display: flex; flex: 0 0 auto; align-items: center; gap: 0.5rem; margin-left: auto; }
.site-footer .footer-pro-button, .site-footer .footer-pro-button:hover, .site-footer .footer-pro-button:focus-visible { color: #eaffea; }
.site-footer .footer-donate-button { flex: 0 0 auto; width: auto; min-width: 82px; height: 36px; padding: 0 0.85rem; color: #2b1d02; }
.site-footer .footer-donate-button:hover, .site-footer .footer-donate-button:focus-visible { color: #2b1d02; }
.site-footer .footer-donate-button span { display: inline; }

@media (max-width: 768px) {
    .site-footer .footer-donate-button { min-width: 74px; padding: 0 0.65rem; }
}

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

/* Formation guide pages (rendered inside .legal-page) */
.formation-diagram { margin: 1.5rem 0; }
.formation-diagram svg { width: 100%; max-width: 420px; display: block; margin: 0 auto; border-radius: 12px; }
.formation-diagram figcaption { text-align: center; color: var(--text-muted, #9aa7b1); font-size: .8rem; margin-top: .5rem; }
.formation-cta { margin: 1.25rem 0; }
.legal-page .formation-cta .btn-primary { color: var(--accent-ink); text-decoration: none; }
.formation-guide-list { list-style: none; padding: 0; }
.formation-guide-list li { padding: .7rem 0; border-bottom: 1px solid rgb(255 255 255 / .08); }
.formation-guide-list li a { color: var(--accent-primary); text-decoration: none; font-size: 1.05rem; }
.formation-guide-list li a:hover { text-decoration: underline; }
.formation-guide-list li span { display: block; color: var(--text-muted, #9aa7b1); font-size: .85rem; margin-top: .2rem; }

/* Read-only lineup page additions */
.lineup-player-list { list-style: none; padding: 0; columns: 2; column-gap: 2rem; }
.lineup-player-list li { padding: .3rem 0; break-inside: avoid; }
.lineup-player-list .player-pos { color: var(--text-muted, #9aa7b1); font-size: .85rem; }
.lineup-cta-row { display: flex; gap: .6rem; flex-wrap: wrap; margin: 1.25rem 0 .75rem; }

@media (max-width: 700px) {
  .lineup-player-list { columns: 1; }
}

/* ===== Free/Pro separation surfaces (separation plan Waves 1-4) ===== */

.btn-block { display: flex; width: 100%; justify-content: center; margin-bottom: .6rem; }
#squadsPanel .draft-list, #templateList { margin-bottom: .75rem; }
#squadsPanel .draft-row, #brandPanel .draft-row { padding: .55rem; }

.brand-badge-preview { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; display: block; margin: 0 auto .6rem; border: 2px solid rgb(255 255 255 / .2); }

/* Centre the card's own text and the badge's alt text. The status line and the
   alt text sat left while the badge image was already centred by the margin
   above, so a card with no preset read as lopsided. */
#brandPanel .panel-content { text-align: center; }
#brandPresetStatus { margin: 0 0 .6rem; text-align: center; }
.brand-badge-preview { text-align: center; font-size: .7rem; line-height: 1.2; }
.brand-upload-label { cursor: pointer; }
.brand-actions { display: flex; gap: .4rem; flex-wrap: wrap; justify-content: center; }

/* Version history entry point on owned share pages */
.version-history-fab { position: fixed; right: 1rem; bottom: 4.5rem; z-index: 1100; box-shadow: 0 8px 24px rgb(0 0 0 / .4); }
#versionHistoryDialog { background: #1e1e2a; color: var(--text, #eef2f7); border: 1px solid rgb(255 255 255 / .14); border-radius: 14px; padding: 1.25rem; max-width: 520px; width: calc(100vw - 2rem); }
#versionHistoryDialog::backdrop { background: rgb(0 0 0 / .55); }
#versionHistoryDialog h3 { margin-bottom: .75rem; }
#versionHistoryDialog .draft-list { max-height: 50vh; overflow-y: auto; margin-bottom: .75rem; }

/* W4.2: quiet Pro marker on gated export options (iOS free tier only) */
.export-option .pro-flash { margin-left: auto; color: var(--accent-primary); opacity: .8; font-size: .75em; }

/* The same accent mark on a gated CONTROL rather than a gated menu row: squad
   mode is Pro, and its button keeps its place and stays pressable - the lock is
   the offer, not a disabled button, because pressing it is what brings the
   explanation up (see renderSquadModeToggle in app.js). */
.btn.is-pro-locked .pro-lock { color: var(--accent-primary); opacity: .85; font-size: .75em; }

/* /pro comparison table. The note above it carries the one qualifier the whole
   table depends on - which platform each lock is on - so it is quiet but not
   fine print. */
.pro-compare-note { margin: .25rem 0 0; color: var(--text-muted, #9aa7b1); font-size: .88rem; }
.pro-compare { width: 100%; border-collapse: collapse; margin: 1rem 0 1.5rem; font-size: .92rem; }
.pro-compare th, .pro-compare td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid rgb(255 255 255 / .08); }
.pro-compare th:nth-child(n+2), .pro-compare td:nth-child(n+2) { text-align: center; white-space: nowrap; }
.pro-compare thead th { color: var(--accent-primary); }
/* The nowrap above keeps the value columns on one line, which on a phone pushed
   the page to ~590px of horizontal scroll and squeezed the feature names into a
   ribbon - the table was already unreadable there before the free/Pro cells got
   any longer. Below 700px the values wrap instead. */
@media (max-width: 700px) {
    .pro-compare { font-size: .82rem; }
    .pro-compare th, .pro-compare td { padding: .45rem .35rem; }
    .pro-compare td:nth-child(n+2) { white-space: normal; }
}
.pro-page-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1rem 0; }

/* Sign in / account control. Sits beside Pro but is deliberately quieter than
   both Pro and Donate: it is a utility, not an offer. When signed in it shows
   the address, which can be long, so it truncates rather than pushing the
   header controls off the right edge. */
.auth-mini {
    max-width: 200px;
    overflow: hidden;
}

.auth-mini #authHeaderLabel {
    display: inline-block;
    max-width: 150px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.auth-mini.is-signed-in {
    border-color: var(--accent-primary);
    color: var(--accent-primary);
}

@media (max-width: 768px) {
    .auth-mini #authHeaderLabel {
        display: none;
    }
    .auth-mini {
        min-width: 40px;
    }
}

/* Inline SVG badge glyphs. Font Awesome Free has no football boot - the nearest
   is fa-shoe-prints, two small footprints that turn to mush at badge size - so
   the assist icon is drawn here instead. currentColor makes it inherit the
   button's active/inactive treatment like a font glyph would. */
.badge-icon-svg {
    width: 1em;
    height: 1em;
    fill: currentColor;
    display: block;
}
