/* Player Explorer: grouped column picker (<details>/<summary>) */
.pe-colpicker-summary {
    list-style: none;
}

.pe-colpicker-summary::-webkit-details-marker {
    display: none;
}

/* Player Explorer controls dropdown styling */
.pe-controls-body {
    display: none !important;
}

.pe-controls.is-open .pe-controls-body {
    display: flex !important;
}

@media (min-width: 768px) {
    .pe-controls-body {
        display: inline-flex !important;
        width: auto !important;
    }
}

@media (max-width: 767px) {
    .pe-controls-body {
        display: none !important;
    }

    .pe-controls.is-open .pe-controls-body {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.5rem;
    }

    .pe-controls-body > * {
        width: 100%;
    }

    .pe-controls-item-filters {
        grid-column: 1;
        grid-row: 1;
    }

    .pe-controls-item-export {
        grid-column: 2;
        grid-row: 1;
    }

    .pe-controls-item-percentiles {
        grid-column: 1;
        grid-row: 2;
    }

    .pe-controls-item-adp {
        grid-column: 2;
        grid-row: 2;
    }

    .pe-controls-item-aps {
        grid-column: 1 / -1;
        grid-row: 3;
    }
}

.pe-colpicker-chevron {
    transition: transform 150ms ease;
}

.pe-colpicker-details[open] .pe-colpicker-chevron {
    transform: rotate(90deg);
}

@media (min-width: 768px) {
    .pe-controls-body {
        display: inline-flex !important;
        width: auto !important;
    }
}

/* Player Explorer controls: transparent button backgrounds */
.pe-controls-btn {
    /* Quiet button (uiux-audit P2-11): the old fully-transparent strip made
       Filters/Export/Save-view read as inert text. */
    background: rgba(255, 255, 255, 0.05) !important;
    border: 1px solid rgba(255, 255, 255, 0.10) !important;
    border-radius: 8px;
    box-shadow: none !important;
}

.pe-controls-btn:hover,
.pe-controls-btn:focus,
.pe-controls-btn:active {
    background: rgba(255, 255, 255, 0.09) !important;
    border-color: rgba(255, 255, 255, 0.22) !important;
    box-shadow: none !important;
}

.pe-controls-chip {
    background: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
}

/* Mobile dropdown feel for Player Explorer controls */
@media (max-width: 767px) {
    .pe-controls-toggle {
        background: rgba(17, 17, 20, 0.6) !important;
        border: 1px solid rgba(255, 255, 255, 0.16) !important;
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
        box-shadow: none !important;
    }

    .pe-controls-toggle.neo-shadow,
    .pe-controls-toggle.neo-shadow:active {
        box-shadow: none !important;
    }

    .pe-controls-toggle.pe-controls-btn {
        border-color: rgba(255, 255, 255, 0.16) !important;
        background: rgba(17, 17, 20, 0.6) !important;
    }

    .pe-controls.is-open .pe-controls-toggle {
        border-color: rgba(255, 255, 255, 0.3) !important;
    }

    .pe-controls-chevron {
        transition: transform 200ms ease;
    }

    .pe-controls.is-open .pe-controls-chevron {
        transform: rotate(180deg);
    }

    .pe-controls.is-open .pe-controls-body {
        border: 1px solid rgba(255, 255, 255, 0.16);
        background: rgba(17, 17, 20, 0.55);
        backdrop-filter: blur(12px);
        -webkit-backdrop-filter: blur(12px);
        border-radius: 12px;
        padding: 0.6rem;
        box-shadow: none;
        animation: pe-controls-drop 180ms ease;
        transform-origin: top center;
    }
}

@keyframes pe-controls-drop {
    from {
        opacity: 0;
        transform: translateY(-4px) scaleY(0.98);
    }
    to {
        opacity: 1;
        transform: translateY(0) scaleY(1);
    }
}

/* Baseball Stats Guru Custom Styles */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
    /* Dark, desaturated blue-gray UI palette (flat, no glassmorphism) */
    --primary-color: #0b0d11;
    --secondary-color: #1c2027;
    /* Single restrained UI accent (periwinkle); not performance semantics */
    --accent-color: #6b8aff;
    --accent-rgb: 107, 138, 255;
    --accent2-color: #22d3ee;
    --accent2-rgb: 34, 211, 238;
    /* Reserved strictly for AI/generate actions */
    --accent3-color: #a06bff;
    --accent3-rgb: 160, 107, 255;
    --accent-gradient: linear-gradient(90deg, rgba(var(--accent-rgb), 1) 0%, rgba(var(--accent3-rgb), 1) 100%);
    /* Global semantics: red = better, blue = worse */
    --success-color: #e15759;
    --danger-color: #4c9cdf;
    /* Percentile ramp endpoints — mirrored in src/core/color_utils.py
       (PCT_GOOD/PCT_MID/PCT_POOR); change them TOGETHER. (uiux-audit P1-7) */
    --pct-good: #e15759;
    --pct-mid: #b0bec5;
    --pct-poor: #4c9cdf;
    --warning-color: #ffc107;
    --dark-bg: #0b0d11;
    --dark-bg-2: #0e1117;
    --card-bg: #16191f;
    --card-bg-rgb: 22, 25, 31;
    --hover-bg: #1c2027;
    --text-primary: #e8eaed;
    --text-secondary: #9ba1ad;
    --text-secondary-rgb: 155, 161, 173;
    --border-color: #232830;
    --radius: 12px;
    --space-12: 12px;
    --space-16: 16px;
    --space-24: 24px;
}

/* Belt-and-braces for the Tailwind custom palette (uiux-audit P0-1): these
   utility classes are used in callback-rendered content, and when the Play
   CDN misconfigures (as it silently did until 2026-07) they produce NO css
   at all — dead CTAs, colorless win/loss text. Defined here against the same
   CSS variables so they can never vanish again. The CDN's generated <style>
   loads after this sheet, so when Tailwind IS healthy its identical rules
   win the cascade and nothing changes. */
.text-success { color: var(--success-color); }
.text-danger { color: var(--danger-color); }
.bg-success { background-color: var(--success-color); }
.bg-danger { background-color: var(--danger-color); }
.bg-accent { background-color: rgba(var(--accent-rgb), 1); }
.bg-accent\/90 { background-color: rgba(var(--accent-rgb), 0.9); }
.bg-accent\/20 { background-color: rgba(var(--accent-rgb), 0.2); }
.bg-accent\/10 { background-color: rgba(var(--accent-rgb), 0.1); }
.bg-accent\/5 { background-color: rgba(var(--accent-rgb), 0.05); }
.bg-accent3 { background-color: rgba(var(--accent3-rgb), 1); }
.text-accent { color: var(--accent-color); }
.text-accent2 { color: var(--accent2-color); }
.text-accent3 { color: var(--accent3-color); }
.border-accent { border-color: var(--accent-color); }
.text-textPrimary { color: var(--text-primary); }
.text-textSecondary { color: var(--text-secondary); }
.bg-cardBg { background-color: var(--card-bg); }
.bg-darkBg { background-color: var(--dark-bg); }

/* --- Shared UI atoms (core/ui_components.py, uiux-audit P1) --------------- */

/* Ramp micro-legend (P1-7) */
.ramp-legend {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.72rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.ramp-legend-chip {
    width: 10px;
    height: 10px;
    border-radius: 4px;
    display: inline-block;
}

.ramp-legend-chip--good { background: var(--pct-good); }
.ramp-legend-chip--poor { background: var(--pct-poor); }
.ramp-legend-sep { opacity: 0.6; }

/* Skeleton loading placeholders (P1-2) — real content dimensions, shimmer */
.skeleton {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    /* F3-01: 4.5%/6% alphas were invisible on desktop card surfaces. */
    background: rgba(255, 255, 255, 0.07);
}

.skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent,
        rgba(255, 255, 255, 0.12), transparent);
    animation: skeleton-shimmer 1.4s infinite;
}

@keyframes skeleton-shimmer {
    100% { transform: translateX(100%); }
}

.skeleton-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
}

.loading-status {
    margin-top: 10px;
    font-size: 0.8rem;
    color: var(--text-secondary);
    text-align: center;
}

@media (prefers-reduced-motion: reduce) {
    .skeleton::after { animation: none; }
}

/* Standard empty state (P1-10) */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    text-align: center;
    padding: 24px;
}

.empty-state-icon {
    font-size: 1.8rem;
    color: var(--text-secondary);
    opacity: 0.8;
}

.empty-state-message {
    color: var(--text-secondary);
    font-size: 0.95rem;
    max-width: 36ch;
    margin: 0;
}

/* Expanded Splits tables (uiux-audit P0-7): horizontal scroll with a sticky
   Split column so every metric column is reachable on narrow viewports. */
.es-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.es-table th:first-child,
.es-table td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--card-bg);
}

.es-table th,
.es-table td {
    white-space: nowrap;
}

/* Overlay priority arbitration (date picker vs nav search dropdown)
   JS in assets/overlayPriority.js toggles body[data-overlay-top]. */
body {
    --overlay-date-z: 10050;
    --overlay-search-z: 10060;
}

/* Secondary accent for interactive hover/focus states. */
.app-widget button:hover,
.app-widget a:hover {
    color: var(--text-primary);
}

.app-widget button:focus-visible,
.app-widget a:focus-visible,
.app-widget input:focus-visible,
.app-widget textarea:focus-visible,
.app-widget select:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.55);
}

.app-widget .Select-control:hover,
.app-widget .Select-control:focus,
.app-widget .Select-control:focus-within {
    border-color: rgba(var(--accent-rgb), 0.6) !important;
    box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.25);
}

.app-widget input:focus,
.app-widget textarea:focus {
    border-color: rgba(var(--accent-rgb), 0.6) !important;
    box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.25);
}

/* Input depth: subtle border for dark backgrounds. */
.app-widget input,
.app-widget textarea,
.app-widget .Select-control,
.app-widget .Select__control {
    box-shadow: none;
    border: 1px solid var(--border-color);
    background-color: var(--dark-bg-2) !important;
}

/* Unified button styling inside widgets. */
.app-widget button {
    border-radius: 10px;
    transition: transform 120ms ease, box-shadow 160ms ease, filter 160ms ease;
    box-shadow: none;
}

.app-widget button:active {
    transform: translateY(1px);
    filter: brightness(0.98);
}

/* Primary buttons. */
.app-widget button.bg-success,
.app-widget button.bg-primary,
.app-widget button.bg-accent {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* Secondary buttons. */
.app-widget button.bg-secondary {
    border: none;
    box-shadow: none;
}

/* Ghost/neutral buttons. */
.post-content .player-percentile-image {
    width: 100%;
    height: auto;
    display: block;
    margin: 0 auto;
}

@media (min-width: 768px) {
    .post-content .player-percentile-image {
        width: 50%;
    }
}

.app-widget button.bg-cardBg\/40,
.app-widget button.bg-cardBg\/60,
.app-widget button.bg-cardBg\/50 {
    box-shadow: none;
    border: 1px solid var(--border-color);
}

/* Chip styling for filters/toggles. */
.app-chip {
    border-radius: 9999px;
    border: none;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-secondary);
    box-shadow: none;
    transition: box-shadow 160ms ease, border-color 160ms ease, color 160ms ease;
}

.app-chip:hover {
    border-color: transparent;
    color: var(--text-primary);
}

.app-chip.is-active,
.app-chip:has(input:checked) {
    border-color: transparent;
    color: var(--text-primary);
    background: rgba(var(--accent-rgb), 0.18);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), 0.45);
}

/* Player Explorer: keep Percentiles label white (chip defaults are gray). */
.pe-controls-item-percentiles,
.pe-controls-item-percentiles span {
    color: var(--text-primary) !important;
}

/* Player Explorer: keep Avg Percentile Score label white. */
.pe-controls-item-aps,
.pe-controls-item-aps span {
    color: var(--text-primary) !important;
}

/* Player Trends: remove shadow box around Percentiles toggle chip. */
#pt-show-percentiles-wrap,
#pt-show-percentiles-wrap:hover,
#pt-show-percentiles-wrap:focus,
#pt-show-percentiles-wrap:focus-visible,
#pt-show-percentiles-wrap:has(input:checked),
#pt-show-percentiles-wrap:has(input:checked):hover {
    box-shadow: none !important;
    background: transparent !important;
    border: none !important;
}

#pt-show-percentiles-wrap .form-check,
#pt-show-percentiles-wrap .form-check-input,
#pt-show-percentiles-wrap .form-check-input:focus {
    box-shadow: none !important;
}

#pt-show-percentiles-wrap .text-textSecondary {
    color: var(--text-primary) !important;
}

@media (max-width: 767px) {
    .pt-toolbar {
        display: grid !important;
        grid-template-columns: 1fr 1fr 1fr;
        gap: 0.75rem !important;
        align-items: center;
    }

    #pt-open-controls {
        justify-self: start;
    }

    #pt-show-percentiles-wrap {
        justify-self: center;
    }

    #pt-download-chart {
        justify-self: end;
    }

    .pt-trends-widget {
        padding-left: 0.75rem !important;
        padding-right: 0.75rem !important;
    }

    #pt-chart-title {
        display: block;
        white-space: normal !important;
        overflow-wrap: anywhere;
        word-break: break-word;
        font-size: 0.9rem;
        line-height: 1.2;
    }
}

body[data-overlay-top="date"] {
    --overlay-date-z: 10060;
    --overlay-search-z: 10050;
}

body[data-overlay-top="search"] {
    --overlay-date-z: 10050;
    --overlay-search-z: 10060;
}

/* Player Trends: ensure the active control card (player vs date)
   is the top stacking context. Without this, the dropdown/calendar
   can render underneath adjacent cards due to backdrop-filter stacking contexts. */
.pt-overlay-card {
    position: relative;
    overflow: visible !important;
}

.pt-player-card {
    z-index: var(--overlay-search-z);
}

.pt-date-card {
    z-index: var(--overlay-date-z);
}

/* Global Styles */
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background:
        radial-gradient(900px circle at 78% 6%, rgba(var(--accent-rgb), 0.06), transparent 60%),
        linear-gradient(160deg, var(--dark-bg) 0%, var(--dark-bg-2) 100%);
    color: var(--text-primary);
    line-height: 1.6;
}

@media (min-width: 768px) {
    body {
        background-attachment: fixed;
    }
}

/* Tooltip styling (Bootstrap removed) */
.tooltip {
    position: absolute;
    z-index: 1070;
    display: block;
    margin: 0;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 0.875rem;
    font-style: normal;
    font-weight: 500;
    line-height: 1.2;
    text-align: left;
    text-decoration: none;
    letter-spacing: 0;
    white-space: normal;
    opacity: 1;
}

.tooltip-inner {
    max-width: 320px;
    padding: 0.6rem 0.75rem;
    color: var(--text-secondary);
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
}

.tooltip .tooltip-arrow {
    position: absolute;
    width: 0.8rem;
    height: 0.4rem;
}

.tooltip .tooltip-arrow::before {
    position: absolute;
    content: "";
    border-color: transparent;
    border-style: solid;
}

.bs-tooltip-top .tooltip-arrow {
    bottom: 0;
}

.bs-tooltip-top .tooltip-arrow::before {
    top: -1px;
    border-width: 0.4rem 0.4rem 0;
    border-top-color: var(--border-color);
}

.bs-tooltip-bottom .tooltip-arrow {
    top: 0;
}

.bs-tooltip-bottom .tooltip-arrow::before {
    bottom: -1px;
    border-width: 0 0.4rem 0.4rem;
    border-bottom-color: var(--border-color);
}

/* Enhanced Cards */
.custom-card {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 1.5rem;
    margin-bottom: 1.5rem;
    box-shadow: none;
    transition: transform 0.2s ease, border-color 0.2s ease;
}

.custom-card:hover {
    transform: translateY(-2px);
    border-color: rgba(var(--accent-rgb), 0.45);
}

/* Neomorphism (soft UI) utilities: use sparingly on small controls */
.neo-shadow {
    box-shadow:
        6px 6px 14px rgba(0, 0, 0, 0.45),
        -6px -6px 14px rgba(255, 255, 255, 0.06);
}

.neo-shadow:active {
    box-shadow:
        inset 4px 4px 10px rgba(0, 0, 0, 0.55),
        inset -4px -4px 10px rgba(255, 255, 255, 0.06);
}

.card-header {
    font-size: 1.25rem;
    font-weight: 600;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 2px solid var(--accent-color);
    color: var(--text-primary);
}

/* Enhanced Form Controls */
.control-group {
    margin-bottom: 1.25rem;
}

.control-label {
    display: block;
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: 0.5rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Dropdown Enhancements */
.Select-control {
    background-color: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 8px !important;
    transition: border-color 0.2s ease;
    min-height: 36px !important;
    height: 36px !important;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* react-select v5 (Dash 3+). Keep styling aligned with legacy .Select-control. */
.Select__control {
    background-color: rgba(var(--card-bg-rgb), 0.55) !important;
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    border-radius: 8px !important;
    transition: border-color 0.2s ease;
    min-height: 36px !important;
    height: 36px !important;
    box-shadow: none !important;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.Select__control--is-focused {
    border-color: rgba(255, 255, 255, 0.45) !important;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2) !important;
}

.Select__value-container,
.Select__input-container,
.Select__single-value,
.Select__placeholder {
    min-height: 34px !important;
    line-height: 34px !important;
    color: var(--text-primary) !important;
    font-size: 0.875rem;
}

.Select__input-container input {
    color: var(--text-primary) !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    outline: none !important;
}

.Select__indicator,
.Select__dropdown-indicator,
.Select__clear-indicator {
    color: var(--text-secondary) !important;
}

.Select__indicator-separator {
    background-color: rgba(255, 255, 255, 0.12) !important;
}

.Select__menu,
.Select__menu-portal {
    background-color: rgba(var(--card-bg-rgb), 0.85) !important;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    border-radius: 8px !important;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    color: var(--text-primary) !important;
}

/* Posts: align filter row control heights (input, dropdowns, and featured tile) */
.posts-filters-row {
    position: relative;
    z-index: 2147483645;
    overflow: visible !important;
}

.posts-filters-row .pt-player-dropdown {
    position: relative;
    z-index: 2147483646 !important;
    overflow: visible !important;
}

.posts-filters-row .pt-player-dropdown:focus-within {
    z-index: 2147483647 !important;
}

.posts-filters-row .Select-menu-outer,
.posts-filters-row .Select__menu,
.posts-filters-row .Select__menu-portal {
    z-index: 2147483647 !important;
    position: absolute !important;
}

.posts-filters-row .Select-control {
    min-height: 42px !important;
    height: 42px !important;
}

.posts-filters-row .Select-placeholder,
.posts-filters-row .Select-value-label,
.posts-filters-row .Select-control .Select-value,
.posts-filters-row .Select-input input {
    line-height: 40px !important;
}

/* Posts: embedded page widgets (iframes) */
.post-embed-iframe {
    width: 100%;
    border: 0;
    display: block;
    background: rgba(var(--card-bg-rgb), 0.6);
}

/* Posts: Markdown readability + tables */
.post-content {
    color: rgba(255, 255, 255, 0.92);
    font-size: 1.02rem;
    line-height: 1.85;
}

.post-content .dash-markdown {
    color: inherit;
}

.post-content p,
.post-content li {
    color: rgba(255, 255, 255, 0.92);
}

/* Ensure Markdown lists actually show bullets/numbers (some global CSS resets can remove markers). */
.post-content ul {
    list-style: disc;
    padding-left: 1.35rem;
    margin: 0.75rem 0 1rem;
}

.post-content ol {
    list-style: decimal;
    padding-left: 1.5rem;
    margin: 0.75rem 0 1rem;
}

.post-content li {
    margin: 0.25rem 0;
}

/* Markdown lists: restore bullets/numbering (some global resets remove them) */
.post-content ul,
.post-content ol {
    padding-left: 1.25rem;
    margin: 0.75rem 0 1rem;
    list-style-position: outside;
}

.post-content ul {
    list-style-type: disc;
}

.post-content ol {
    list-style-type: decimal;
}

.post-content li {
    display: list-item;
    margin: 0.25rem 0;
}

.post-content a {
    color: var(--accent2-color);
    text-decoration: none;
}

.post-content a:hover {
    text-decoration: underline;
}

.post-content h1,
.post-content h2,
.post-content h3,
.post-content h4 {
    color: var(--text-primary);
    font-weight: 800;
    letter-spacing: -0.01em;
}

.post-content h2 {
    margin-top: 2.2rem;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.post-content h3 {
    margin-top: 1.75rem;
}

.post-content hr {
    border: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    margin: 2rem 0;
}

/* Markdown tables: real grid with dividers + header styling */
.post-content table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin: 1rem 0 1.5rem;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 12px;
    overflow: hidden;
    background: rgba(var(--card-bg-rgb), 0.35);
}

.post-content thead th {
    background: rgba(var(--card-bg-rgb), 0.85);
    color: var(--text-primary);
    font-weight: 800;
    font-size: 0.9rem;
    letter-spacing: 0.01em;
    text-transform: none;
}

.post-content th,
.post-content td {
    padding: 10px 12px;
    border-right: 1px solid rgba(255, 255, 255, 0.10);
    border-bottom: 1px solid rgba(255, 255, 255, 0.10);
    vertical-align: top;
}

.post-content tr:last-child td {
    border-bottom: 0;
}

.post-content th:last-child,
.post-content td:last-child {
    border-right: 0;
}

.post-content tbody tr:nth-child(even) {
    background: rgba(255, 255, 255, 0.03);
}

@media (max-width: 640px) {
    .post-content table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Posts: Roto+ swimlane flowchart */
.post-content .roto-swimlane-graph {
    margin: 1.25rem 0 1.75rem;
    padding: 10px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    background: rgba(var(--card-bg-rgb), 0.30);
}

.post-content .roto-swimlane-graph__graph {
    width: 100%;
}

.post-content .roto-swimlane {
    display: grid;
    grid-template-columns: 1fr 2px 1fr;
    gap: 18px;
    margin: 1.25rem 0 1.75rem;
    padding: 16px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    background: rgba(var(--card-bg-rgb), 0.30);
}

.post-content .roto-swimlane__divider {
    background: rgba(255, 255, 255, 0.12);
    border-radius: 999px;
}

.post-content .roto-swimlane__lane {
    min-width: 0;
    padding: 12px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(var(--card-bg-rgb), 0.20);
}

.post-content .roto-swimlane__lane-title {
    font-weight: 900;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    font-size: 0.82rem;
    color: rgba(255, 255, 255, 0.86);
    margin: 4px 0 10px;
}

.post-content .roto-swimlane__group {
    position: relative;
    padding: 10px 8px 12px;
    margin: 10px 0 16px;
}

.post-content .roto-swimlane__group-title {
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.68);
    margin: 0 0 10px;
}

.post-content .roto-swimlane__inputs {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin-bottom: 8px;
}

.post-content .roto-swimlane__lane--hitters .roto-swimlane__inputs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.post-content .roto-swimlane__lane--pitchers .roto-swimlane__inputs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.post-content .roto-swimlane__input {
    position: relative;
    padding-bottom: 18px;
}

.post-content .roto-swimlane__wire {
    position: absolute;
    left: 50%;
    top: calc(100% - 18px);
    height: 18px;
    width: 2px;
    transform: translateX(-50%);
    background: rgba(255, 255, 255, 0.22);
}

.post-content .roto-swimlane__wire::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -2px;
    width: 0;
    height: 0;
    transform: translateX(-50%);
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid rgba(255, 255, 255, 0.32);
}

.post-content .roto-swimlane__bus {
    height: 2px;
    width: 100%;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.18);
    margin: 0 0 10px;
}

.post-content .roto-swimlane__box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 42px;
    padding: 10px 12px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(var(--card-bg-rgb), 0.55);
    color: rgba(255, 255, 255, 0.92);
    font-size: 0.88rem;
    line-height: 1.2;
    text-align: center;
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.25);
}

.post-content .roto-swimlane__box--model {
    border-color: rgba(var(--accent2-rgb), 0.55);
    background: linear-gradient(
        90deg,
        rgba(var(--accent2-rgb), 0.18) 0%,
        rgba(var(--accent-rgb), 0.14) 100%
    );
    color: var(--text-primary);
    font-weight: 900;
    letter-spacing: 0.01em;
    width: min(360px, 92%);
}

.post-content .roto-swimlane__box--xref {
    border-color: rgba(255, 255, 255, 0.22);
    background: rgba(255, 255, 255, 0.07);
    font-weight: 700;
}

.post-content .roto-swimlane__arrow {
    text-align: center;
    margin: 6px 0 10px;
    color: rgba(255, 255, 255, 0.60);
    font-weight: 800;
}

.post-content .roto-swimlane__aggregate {
    grid-column: 1 / -1;
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.post-content .roto-swimlane__box--aggregate {
    width: 100%;
    justify-content: center;
    border-radius: 12px;
    padding: 10px 12px;
    white-space: normal;
    text-align: center;
    border-color: rgba(var(--accent-rgb), 0.40);
    background: rgba(var(--accent-rgb), 0.10);
    font-weight: 900;
    font-size: 1rem;
}

@media (max-width: 900px) {
    .post-content .roto-swimlane {
        grid-template-columns: 1fr;
    }

    .post-content .roto-swimlane__divider {
        display: none;
    }
}

/* react-select v2/v3 (Dash versions vary) */
.posts-filters-row .Select__control {
    min-height: 42px !important;
    height: 42px !important;
}

.posts-filters-row .Select__value-container,
.posts-filters-row .Select__input,
.posts-filters-row .Select__single-value,
.posts-filters-row .Select__placeholder {
    min-height: 40px !important;
}

/* Selected value + placeholder text */
.Select-placeholder,
.Select-value-label,
.Select-control .Select-value,
.Select-input input {
    color: var(--text-primary) !important;
    font-size: 0.875rem;
    line-height: 34px !important;
}

.Select-input input {
    /* NO width override here (R0-06): react-select v1 sizes this input via
       JS; forcing width:auto made it ~186px and ballooned every fixed-width
       dropdown over its neighbors (home h-scroll, ES pill occlusion,
       Arsenal arrow hijack). */
    border: none !important;
    box-shadow: none !important;
    outline: none !important;
    background: transparent !important;
}

.Select,
.Select-control {
    max-width: 100%;
}

.Select-control {
    table-layout: fixed;
}

.Select--multi .Select-value {
    line-height: 1.2 !important;
}

.Select-control .Select-value-label {
    color: var(--text-primary) !important;
}

.Select-control:hover {
    border-color: rgba(255, 255, 255, 0.45) !important;
}

.Select-menu-outer {
    background-color: rgba(var(--card-bg-rgb), 0.85) !important;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    border-radius: 8px !important;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

/* Player Trends: keep dropdown menu above other cards */
.pt-player-dropdown {
    position: relative;
    z-index: 10050;
    overflow: visible !important;
}

.pt-player-dropdown .Select-input,
.pt-player-dropdown .Select-input input {
    background: transparent !important;
    min-width: 0 !important;
}

.pt-player-dropdown .Select-input input {
    /* No width:auto here (R0-06): input default size is ~166px and defeats
       react-select's inline autosize; min-width floor is enough. */
    min-width: 24px !important;
}

@media (min-width: 768px) {
    #pc-open-controls,
    #ps-open-controls {
        background: transparent !important;
        border: none !important;
        box-shadow: none !important;
    }
}

#pc-open-controls:hover,
#ps-open-controls:hover {
    background: transparent !important;
}

/* Player Trends: when maxed at 3 players, make selected chips dark so text stays readable. */
.pt-player-dropdown.pt-player-dropdown-maxed .Select--multi .Select-value {
    background: rgba(var(--card-bg-rgb), 0.78) !important;
    border: 1px solid rgba(255, 255, 255, 0.10) !important;
}

.pt-player-dropdown.pt-player-dropdown-maxed .Select--multi .Select-value-icon {
    border-right: 1px solid rgba(255, 255, 255, 0.08) !important;
    color: var(--text-secondary) !important;
}

.pt-player-dropdown.pt-player-dropdown-maxed .Select--multi .Select-value-icon:hover {
    background: rgba(255, 255, 255, 0.06) !important;
    color: var(--text-primary) !important;
}

/* When a dropdown is focused/open, raise its stacking context above sibling dropdowns.
   This prevents the menu from rendering behind other player selectors in the same panel. */
.pt-player-dropdown:focus-within {
    z-index: 2147483646 !important;
}

/* Player Profiles: DatePicker popover should overlay cards/graphs.
   Some containers (e.g., backdrop-filter / Plotly) create stacking contexts; force the DatePicker wrapper above. */
.pp-date-picker {
    position: relative;
    z-index: var(--overlay-date-z);
    overflow: visible !important;
}

.pp-date-picker .DateRangePicker,
.pp-date-picker .DateRangePickerInput,
.pp-date-picker .DateInput {
    overflow: visible !important;
}

/* Player Profiles header: keep the DatePicker from overflowing into the Season dropdown.
   Allow it to wrap within its grid cell instead of forcing a single line. */
.pp-date-picker .DateRangePicker {
    width: 100% !important;
    min-width: 0 !important;
    flex-wrap: wrap !important;
    white-space: normal !important;
}

/* Player Profiles: the header card uses backdrop-blur which creates a stacking context.
   When the calendar opens, it can overlap the lower grid; keep this card above the rest. */
.pp-profile-header-card {
    position: relative;
    z-index: 10;
    overflow: visible !important;
}

/* Navbar: player profile search dropdown should be able to overlay page content.
   Z-index is dynamically swapped with the date picker based on last interaction. */
.nav-player-dropdown {
    position: relative;
    z-index: var(--overlay-search-z);
    overflow: visible !important;
}

/* Player Profiles: season dropdown should overlay the date picker/cards.
   Uses the same overlay priority variables as navbar + date picker. */
.pp-player-dropdown {
    position: relative;
    z-index: var(--overlay-search-z);
    overflow: visible !important;
}

/* Player Profiles: when a dropdown is focused/open, keep it above sibling controls. */
.pp-player-dropdown:focus-within {
    z-index: 2147483646 !important;
}

.pp-player-dropdown:focus-within .Select-menu-outer,
.pp-player-dropdown:focus-within .Select__menu,
.pp-player-dropdown:focus-within .Select__menu-portal {
    z-index: 2147483647 !important;
}

.pp-player-dropdown .Select-menu-outer {
    z-index: calc(var(--overlay-search-z) + 1) !important;
    position: absolute !important;
}

.pp-player-dropdown .Select__menu,
.pp-player-dropdown .Select__menu-portal {
    z-index: calc(var(--overlay-search-z) + 1) !important;
}

/* Player Profiles header: allow the react-select control to shrink inside a tight modal.
   Without this, the internal input can enforce a min-content width and visually overlap the date picker. */
.pp-player-dropdown .Select,
.pp-player-dropdown .Select-control,
.pp-player-dropdown .Select-input,
.pp-player-dropdown .Select-input input {
    min-width: 0 !important;
    width: 100% !important;
}

.pp-date-picker .DateRangePickerInput {
    max-width: 100% !important;
}

.nav-player-dropdown .Select-menu-outer {
    z-index: calc(var(--overlay-search-z) + 1) !important;
    position: absolute !important;
}

.nav-player-dropdown .Select__menu,
.nav-player-dropdown .Select__menu-portal {
    z-index: calc(var(--overlay-search-z) + 1) !important;
}

/* Player Trends / Player Comparison: season dropdown should overlay the date picker when active.
   Uses the same overlay priority variables as navbar + date picker. */
.pt-season-dropdown,
.pc-season-dropdown,
.pt-matchup-dropdown,
.pc-matchup-dropdown {
    position: relative;
    z-index: var(--overlay-search-z);
    overflow: visible !important;
}

/* Player Comparison/Trends: when dropdowns are focused/open, keep them above sibling controls. */
.pt-season-dropdown:focus-within,
.pc-season-dropdown:focus-within,
.pt-matchup-dropdown:focus-within,
.pc-matchup-dropdown:focus-within {
    z-index: 2147483646 !important;
}

.pt-season-dropdown:focus-within .Select-menu-outer,
.pc-season-dropdown:focus-within .Select-menu-outer,
.pt-matchup-dropdown:focus-within .Select-menu-outer,
.pc-matchup-dropdown:focus-within .Select-menu-outer,
.pt-season-dropdown:focus-within .Select__menu,
.pc-season-dropdown:focus-within .Select__menu,
.pt-matchup-dropdown:focus-within .Select__menu,
.pc-matchup-dropdown:focus-within .Select__menu,
.pt-season-dropdown:focus-within .Select__menu-portal,
.pc-season-dropdown:focus-within .Select__menu-portal,
.pt-matchup-dropdown:focus-within .Select__menu-portal,
.pc-matchup-dropdown:focus-within .Select__menu-portal {
    z-index: 2147483647 !important;
}

.pt-season-dropdown .Select-menu-outer,
.pc-season-dropdown .Select-menu-outer,
.pt-matchup-dropdown .Select-menu-outer,
.pc-matchup-dropdown .Select-menu-outer {
    z-index: calc(var(--overlay-search-z) + 1) !important;
    position: absolute !important;
}

.pt-season-dropdown .Select__menu,
.pt-season-dropdown .Select__menu-portal,
.pc-season-dropdown .Select__menu,
.pc-season-dropdown .Select__menu-portal,
.pt-matchup-dropdown .Select__menu,
.pt-matchup-dropdown .Select__menu-portal,
.pc-matchup-dropdown .Select__menu,
.pc-matchup-dropdown .Select__menu-portal {
    z-index: calc(var(--overlay-search-z) + 1) !important;
}

.pt-player-dropdown .Select-menu-outer {
    z-index: 2147483647 !important;
    position: absolute !important;
}

.pt-player-dropdown .Select,
.pt-player-dropdown .Select-control {
    overflow: visible !important;
}

/* react-select v2/v3 classnames (Dash versions vary) */
.pt-player-dropdown .Select__menu,
.pt-player-dropdown .Select__menu-portal {
    z-index: 2147483647 !important;
}

/* DatePicker can create a competing stacking context; keep it below menus */
.DateRangePicker_picker,
.DateRangePicker_picker__directionLeft,
.DateRangePicker_picker__directionRight {
    /* Must sit above AG Grid, modals, and Plotly modebars */
    z-index: calc(var(--overlay-date-z) + 1) !important;
}

/* Dash sometimes renders SingleDatePicker for certain components */
.SingleDatePicker_picker,
.SingleDatePicker_picker__directionLeft,
.SingleDatePicker_picker__directionRight {
    z-index: calc(var(--overlay-date-z) + 1) !important;
}

/* React-Dates portal modes (used when with_portal / with_full_screen_portal is enabled).
   These must out-rank Plotly graphs which can create their own stacking contexts. */
.DateRangePicker__portal,
.SingleDatePicker__portal,
.DateRangePicker_picker__portal,
.SingleDatePicker_picker__portal,
.DayPicker_portal__horizontal,
.DayPicker_portal__vertical {
    z-index: 2147483647 !important;
}

/* React-Dates calendar popover: dark theme */
.DateRangePicker_picker,
.SingleDatePicker_picker {
    background: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 12px !important;
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55) !important;
}

.DayPicker,
.DayPicker__withBorder,
.CalendarMonth,
.CalendarMonthGrid,
.CalendarMonthGrid_month__horizontal,
.DayPicker_transitionContainer,
.DayPicker_focusRegion {
    background: var(--card-bg) !important;
}

.CalendarMonth_caption {
    color: var(--text-primary) !important;
    font-weight: 700 !important;
}

.DayPicker_weekHeader {
    color: var(--text-secondary) !important;
}

.DayPickerNavigation_button {
    background: transparent !important;
    border: 1px solid rgba(255, 255, 255, 0.12) !important;
    border-radius: 10px !important;
}

.DayPickerNavigation_button:hover {
    border-color: rgba(var(--accent-rgb), 0.65) !important;
    background: rgba(var(--accent-rgb), 0.10) !important;
}

.DayPickerNavigation_svg {
    fill: var(--text-secondary) !important;
}

.CalendarDay__default {
    background: transparent !important;
    color: var(--text-primary) !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

.CalendarDay__default:hover {
    background: rgba(var(--accent-rgb), 0.10) !important;
    border-color: rgba(var(--accent-rgb), 0.65) !important;
    color: var(--text-primary) !important;
}

.CalendarDay__outside {
    color: rgba(var(--text-secondary-rgb), 0.55) !important;
    border-color: rgba(255, 255, 255, 0.05) !important;
}

.CalendarDay__blocked_out_of_range,
.CalendarDay__blocked_calendar {
    color: rgba(var(--text-secondary-rgb), 0.35) !important;
    background: rgba(255, 255, 255, 0.02) !important;
    border-color: rgba(255, 255, 255, 0.04) !important;
}

.CalendarDay__selected,
.CalendarDay__selected:active,
.CalendarDay__selected:hover {
    background: rgba(var(--accent-rgb), 0.35) !important;
    border: 1px solid rgba(var(--accent-rgb), 0.95) !important;
    color: var(--text-primary) !important;
}

.CalendarDay__hovered_span,
.CalendarDay__hovered_span:hover {
    background: rgba(var(--accent-rgb), 0.14) !important;
    border-color: rgba(var(--accent-rgb), 0.35) !important;
    color: var(--text-primary) !important;
}

.CalendarDay__selected_span,
.CalendarDay__selected_span:hover {
    background: rgba(var(--accent-rgb), 0.22) !important;
    border-color: rgba(var(--accent-rgb), 0.45) !important;
    color: var(--text-primary) !important;
}

/* React-Dates: hide the keyboard shortcuts help button (the small '?' triangle) */
.DayPickerKeyboardShortcuts_show,
.DayPickerKeyboardShortcuts_show__bottomRight,
.DayPickerKeyboardShortcuts_show__bottomRight::before,
.DayPickerKeyboardShortcuts_show__bottomRight::after {
    display: none !important;
}

.Select-option {
    background-color: transparent !important;
    color: var(--text-primary) !important;
    padding: 10px 12px !important;
}

.Select-option:hover {
    background-color: var(--hover-bg) !important;
}

/* Button Enhancements */
.btn-custom {
    border-radius: 8px;
    padding: 0.75rem 1.5rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    transition: all 0.3s ease;
    border: none;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.btn-custom:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

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

/* Slider Enhancements */
.rc-slider-track {
    background-color: var(--accent-color) !important;
}

.rc-slider-handle {
    border-color: var(--accent-color) !important;
    background-color: var(--accent-color) !important;
}

.rc-slider-handle:hover {
    box-shadow: 0 0 0 8px rgba(var(--accent-rgb), 0.2);
}

.rc-slider-mark-text {
    color: var(--text-secondary) !important;
    font-size: 0.75rem;
}

/* Checklist Enhancements */
.custom-checklist label {
    display: flex;
    align-items: center;
    padding: 0.5rem 0;
    cursor: pointer;
    transition: color 0.2s ease;
}

.custom-checklist label:hover {
    color: var(--accent-color);
}

.custom-checklist input[type="checkbox"] {
    margin-right: 0.75rem;
    width: 18px;
    height: 18px;
    cursor: pointer;
}

/* Apple-style switch (used for the Percentiles toggle in Player Explorer header) */
.pe-apple-switch .form-check {
    display: flex;
    align-items: center;
    margin: 0;
    min-height: 0;
    padding-left: 0;
}

.pe-apple-switch .form-check-input {
    width: 46px !important;
    height: 26px !important;
    margin: 0 !important;
    cursor: pointer;
    border-radius: 9999px !important;
    border: none !important;
    background-image: none !important;
    background-color: rgba(var(--text-secondary-rgb), 0.28) !important;
    box-shadow: none !important;
    transition: background-color 150ms ease, box-shadow 150ms ease;
    appearance: none;
    -webkit-appearance: none;
    position: relative;
}

.pe-apple-switch .form-check-input::before {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 22px;
    height: 22px;
    border-radius: 9999px;
    background: #ffffff;
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35);
    transition: transform 150ms ease;
}

.pe-apple-switch .form-check-input:focus {
    outline: none;
    box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.22) !important;
}

.pe-apple-switch .form-check-input:checked {
    background-color: var(--accent-color) !important;
    box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.18) !important;
}

.pe-apple-switch .form-check-input:checked::before {
    transform: translateX(20px);
}

.pe-apple-switch .form-check-label {
    margin: 0;
    padding: 0;
}

/* Table Enhancements */
.dash-table-container {
    background-color: var(--card-bg) !important;
    border-radius: 12px;
    overflow: hidden;
    /* R11-26: black-on-near-black shadows read as mud — in-flow surfaces
       elevate with the hairline token; shadows are reserved for overlays. */
    border: var(--hairline);
    box-shadow: none;
}

.dash-spreadsheet-container {
    max-height: 70vh !important;
}

.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner table {
    border-spacing: 0;
}

.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th {
    background-color: var(--primary-color) !important;
    color: var(--text-primary) !important;
    font-weight: 600 !important;
    padding: 1rem 0.75rem !important;
    text-transform: uppercase;
    font-size: 0.75rem;
    letter-spacing: 0.5px;
    border-bottom: 2px solid var(--accent-color) !important;
}

.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner td {
    padding: 0.75rem !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
}

.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner tr:hover td {
    background-color: var(--hover-bg) !important;
    cursor: pointer;
}

/* AG Grid Enhancements */
.ag-theme-alpine-dark {
    --ag-background-color: var(--card-bg);
    --ag-header-background-color: var(--primary-color);
    --ag-odd-row-background-color: transparent; /* R11-25: no zebra */
    --ag-row-hover-color: var(--hover-bg);
    --ag-border-color: var(--border-color);
    --ag-header-foreground-color: var(--text-primary);
    --ag-foreground-color: var(--text-primary);
    font-family: 'Inter', sans-serif;
}

/* Player Explorer tabs (match app theme) */
.pe-view-tabs .nav-tabs {
    border-bottom: 1px solid var(--border-color);
}

.pe-view-tabs .nav-link {
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 600;
    font-size: 0.75rem;
    border: 1px solid transparent;
    border-top-left-radius: 8px;
    border-top-right-radius: 8px;
}

.pe-view-tabs .nav-link:hover {
    color: var(--text-primary);
    border-color: var(--border-color);
}

.pe-view-tabs .nav-link.active {
    color: var(--text-primary);
    background-color: var(--card-bg);
    border-color: var(--border-color) var(--border-color) var(--card-bg);
}

/* Player Explorer dcc.Tabs (Tailwind migration) */
.pe-view-tabs {
    border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}

.pe-view-tabs {
    /* Tab row scrolls rather than wrapping labels to 2-3 lines (P2-11). */
    overflow-x: auto;
    scrollbar-width: thin;
    /* R0-07: dcc.Tabs gives each tab width:calc(100%/N); with nowrap labels the
       text painted into the neighbor and clicks selected the wrong tab.
       Flex row + content-sized tabs makes the overflow scroll real. */
    flex-wrap: nowrap;
}

@media (min-width: 768px) {
    /* !important: beats the Tailwind md:block on pp-stats-tabs. */
    .pe-view-tabs {
        display: flex !important;
    }
}

.pe-view-tabs .tab {
    width: auto !important;
    flex: 0 0 auto !important;
}

.pe-view-tabs .tab {
    background: transparent !important;
    color: var(--text-secondary) !important;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 700;
    font-size: 0.75rem;
    white-space: nowrap;
    padding: 6px 10px 10px !important;
    border: none !important;
    border-bottom: 2px solid transparent !important;
    line-height: 1.2 !important;
    min-height: 32px !important;
    height: auto !important;
    position: relative;
}

.pe-view-tabs .tab:hover {
    color: var(--text-primary) !important;
    background-color: rgba(var(--accent-rgb), 0.10) !important;
}

.pe-view-tabs .tab--selected {
    color: var(--text-primary) !important;
    border-bottom-color: transparent !important;
}

.pe-view-tabs .tab--selected::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--accent-color);
    border-radius: 4px;
}

.ag-theme-alpine-dark .ag-header-cell {
    font-weight: 600;
    text-transform: uppercase;
    font-size: 0.75rem;
    letter-spacing: 0.5px;
}

.ag-theme-alpine-dark .ag-cell {
    padding: 12px 8px;
}

/* In-cell sparklines (Player Explorer) */
.sparkline-cell {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 100%;
    line-height: 1;
}

.sparkline-wrap {
    width: 60px;
    height: 18px;
    flex: 0 0 auto;
    opacity: 0.95;
    display: flex;
    align-items: center;
}

.sparkline-svg {
    width: 60px;
    height: 18px;
    display: block;
    vertical-align: middle;
}

.sparkline-svg path {
    stroke: var(--text-secondary);
}

.sparkline-svg.sparkline-up path {
    stroke: var(--success-color);
}

.sparkline-svg.sparkline-down path {
    stroke: var(--danger-color);
}

.sparkline-svg.sparkline-flat path {
    stroke: var(--text-secondary);
    opacity: 0.8;
}

.sparkline-value {
    white-space: nowrap;
}

/* Trend-direction glyph beside sparklines (uiux-audit P0-10): direction is
   encoded by the arrow, hue only reinforces it (red = hot/up, blue = cold/
   down). */
.sparkline-dir,
.home-snapshot-dir {
    font-size: 0.7em;
    line-height: 1;
    flex: 0 0 auto;
}

/* Home leader rows link to profiles. */
.home-snapshot-name-link {
    text-decoration: none;
    color: inherit;
    min-width: 0;
    display: block;
}

.home-snapshot-name-link:hover .home-snapshot-name {
    text-decoration: underline;
    color: var(--text-primary);
}

@media (max-width: 767.98px) {
    /* Player Explorer mobile (uiux-audit P0-2): NO transform scaling — the old
       scale(0.52) "zoom-out" produced ~6px text, ~27px rows and click-target
       drift. Instead the grid shows a curated tier-1 column set (clientside
       curation in player_explorer.py reading pe-mobile-cols) at native row
       heights, with horizontal scroll for the rest. */
    #pe-grid {
        width: 100%;
        max-width: 100%;
    }

    #pe-grid.ag-theme-alpine-dark .ag-header-cell {
        font-size: 0.75rem;
    }

    #pe-grid.ag-theme-alpine-dark .ag-cell {
        padding: 8px 6px;
        font-size: 0.8125rem; /* 13px floor for data text */
    }

    #pe-grid .sparkline-cell {
        gap: 6px;
    }

    #pe-grid .sparkline-wrap {
        width: 34px;
        height: 12px;
    }

    #pe-grid .sparkline-svg {
        width: 34px;
        height: 12px;
    }

    #pe-grid .trend-icon {
        font-size: 0.9em;
        margin-left: 4px;
    }

    /* Player Explorer: hide pagination page size selector on mobile. */
    #pe-grid .ag-paging-panel .ag-paging-page-size {
        display: none;
    }

    /* Player name cell renderer: slightly smaller headshot + tighter spacing */
    #pe-grid .pe-player-name-link + img,
    #pe-grid img.w-6.h-6 {
        width: 20px !important;
        height: 20px !important;
        margin-right: 6px !important;
    }

    /* Player Explorer: stat view selector should be dropdown-only on mobile. */
    #pe-view-tabs {
        display: none;
    }

    #pe-view-dropdown {
        display: block;
    }
}

@media (min-width: 768px) {
    /* Player Explorer: show tabs on desktop, hide dropdown.
       flex (not block) so the R0-07 content-sized tab row applies. */
    #pe-view-tabs {
        display: flex;
    }

    #pe-view-dropdown {
        display: none;
    }
}

/* Player Explorer: clickable player name (opens profile modal) */
.pe-player-name-link {
    cursor: pointer;
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.1;
}

.pe-player-name-link:hover {
    text-decoration: underline;
}

/* Per-column Up/Down quick filter controls */
.trend-header {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    line-height: 1.1;
    width: 100%;
}

.trend-header-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.trend-header-controls {
    display: flex;
    gap: 6px;
}

.trend-filter-btn {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
    padding: 0 6px;
    border-radius: 8px;
    font-size: 0.65rem;
    line-height: 1.3;
}

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

.trend-filter-btn.active {
    border-color: var(--accent-color);
    background: var(--hover-bg);
    color: var(--text-primary);
}

/* Avg Percentile Score: per-column add/remove control (inline, right of title). */
.trend-header-title-row {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 100%;
    min-width: 0;
}

.trend-header-title-row .trend-header-title {
    flex: 1 1 auto;
    min-width: 0;
}

.trend-header-title-row .aps-toggle-btn {
    flex: 0 0 auto;
}

.aps-toggle-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    padding: 0;
    border-radius: 4px;
    border: 1px solid var(--border-color);
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    background: transparent;
    color: var(--text-secondary);
    transition: box-shadow 160ms ease, border-color 160ms ease, color 160ms ease,
        background-color 160ms ease, opacity 160ms ease;
}

/* "+" state: highlighted with an accent glow to invite the click. */
.aps-toggle-btn.aps-add-btn {
    border-color: var(--accent-color);
    color: var(--accent-color);
    background: rgba(var(--accent-rgb), 0.12);
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.35),
        0 0 8px rgba(var(--accent-rgb), 0.55);
    animation: aps-add-glow 1.8s ease-in-out infinite;
}

.aps-toggle-btn.aps-add-btn:hover {
    color: var(--text-primary);
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.55),
        0 0 10px rgba(var(--accent-rgb), 0.8);
}

/* "-" state: selected; show a faded/grayed remove control. */
.aps-toggle-btn.aps-remove-btn {
    border-color: var(--border-color);
    color: var(--text-secondary);
    background: transparent;
    box-shadow: none;
    opacity: 0.55;
    animation: none;
}

.aps-toggle-btn.aps-remove-btn:hover {
    opacity: 0.9;
    border-color: var(--accent-color);
    color: var(--text-primary);
}

@keyframes aps-add-glow {
    0%,
    100% {
        box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.35),
            0 0 6px rgba(var(--accent-rgb), 0.45);
    }
    50% {
        box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.5),
            0 0 12px rgba(var(--accent-rgb), 0.85);
    }
}

@media (prefers-reduced-motion: reduce) {
    .aps-toggle-btn.aps-add-btn {
        animation: none;
    }
}

/* Avg Percentile Score column cell. */
.aps-score-cell {
    font-variant-numeric: tabular-nums;
}
.pe-active-filters {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 6px 8px;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: transparent;
}

/* Modal Enhancements */
.modal-content {
    background-color: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 12px !important;
}

.modal-header {
    background-color: var(--primary-color) !important;
    border-bottom: 2px solid var(--accent-color) !important;
    border-radius: 12px 12px 0 0 !important;
}

.modal-title {
    color: var(--text-primary) !important;
    font-weight: 600;
}

.modal-body {
    padding: 1.5rem !important;
}

/* Navbar Enhancements */
.navbar {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    border-bottom: 2px solid var(--accent-color);
}

.navbar-brand {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: 0.5px;
}

.nav-link {
    font-weight: 500;
    transition: color 0.2s ease, transform 0.2s ease;
    padding: 0.5rem 1rem !important;
    margin: 0 0.25rem;
    border-radius: 8px;
}

.nav-link:hover {
    color: var(--accent-color) !important;
    background-color: rgba(var(--accent-rgb), 0.1);
}

/* Loading Indicator */
.custom-spinner {
    display: inline-block;
    width: 40px;
    height: 40px;
    min-width: 40px;
    min-height: 40px;
    flex: 0 0 auto;
    border: 4px solid rgba(var(--accent-rgb), 0.2);
    border-top-color: var(--accent-color);
    border-radius: 50%;
    animation: spinner-rotate 0.8s linear infinite;
}

/* Player Trends: hide the empty-state while the chart callback is loading.
     (Dash sets data-dash-is-loading="true" on outputs while they update.) */
#pt-chart-empty[data-dash-is-loading="true"] {
    display: none !important;
}

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

.loading-container {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 3rem;
}

/* Metric Badges */
.metric-badge {
    display: inline-block;
    padding: 0.25rem 0.75rem;
    border-radius: 12px;
    font-size: 0.875rem;
    font-weight: 600;
    margin: 0.25rem;
}

.metric-badge-high {
    background-color: rgba(225, 87, 89, 0.20);
    border: 1px solid var(--success-color);
    color: var(--success-color);
}

.metric-badge-medium {
    background-color: rgba(255, 193, 7, 0.2);
    border: 1px solid var(--warning-color);
    color: var(--warning-color);
}

.metric-badge-low {
    background-color: rgba(76, 156, 223, 0.20);
    border: 1px solid var(--danger-color);
    color: var(--danger-color);
}

/* Sidebar Enhancements */
.sidebar {
    background-color: var(--card-bg);
    border-radius: 12px;
    padding: 1.5rem;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
}

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

.sidebar::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.05);
    border-radius: 4px;
}

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

.sidebar::-webkit-scrollbar-thumb:hover {
    background: var(--secondary-color);
}

/* Charts */
.plotly-graph-div {
    border-radius: 12px;
    overflow: hidden;
    position: relative;
    z-index: 0;
}

/* Accent glow utilities */
.glow-on-hover:hover {
    filter: drop-shadow(0 0 10px rgba(var(--accent-rgb), 0.45));
}

.glow-on-focus:focus-visible,
.glow-on-focus:focus-within {
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.35);
}

/* Apply glow to key interactive elements already tagged with neo-shadow */
.neo-shadow:hover {
    filter: drop-shadow(0 0 10px rgba(var(--accent-rgb), 0.38));
}

.neo-shadow:focus-visible {
    box-shadow:
        6px 6px 14px rgba(0, 0, 0, 0.45),
        -6px -6px 14px rgba(255, 255, 255, 0.06),
        0 0 0 3px rgba(var(--accent-rgb), 0.30);
}

/* Plotly modebar: make it feel native */
.js-plotly-plot .plotly .modebar {
    background: transparent !important;
}

.js-plotly-plot .plotly .modebar-group {
    background: transparent !important;
}

.js-plotly-plot .plotly .modebar-btn {
    color: var(--text-secondary) !important;
    border-radius: 8px !important;
}

.js-plotly-plot .plotly .modebar-btn:hover {
    color: var(--text-primary) !important;
    background: rgba(255, 255, 255, 0.10) !important;
    filter: drop-shadow(0 0 8px rgba(var(--accent-rgb), 0.20));
}

/* Home CTAs: subtle glow to reinforce clickability */
.home-tile-link:hover .home-link-button {
    filter: drop-shadow(0 0 10px rgba(var(--accent-rgb), 0.28));
}

/* Date Picker */
.DateRangePicker {
    display: flex !important;
    flex-wrap: nowrap;
    align-items: center !important;
    gap: 0.35rem;
    white-space: nowrap;
}

.DateInput {
    background-color: var(--card-bg) !important;
    flex: 1 1 0;
    width: auto !important;
    min-width: 0 !important;
}

/* Date range arrow/separator (React-Dates) */
.DateRangePickerInput {
    background-color: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 8px;
    display: flex !important;
    flex-wrap: wrap;
    align-items: center !important;
    gap: 0.35rem;
    white-space: normal;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    width: 100% !important;
    box-sizing: border-box;
    overflow: hidden;
    min-width: 0;
}

.DateRangePickerInput_arrow {
    color: var(--text-secondary) !important;
    padding: 0 0.25rem;
    flex: 0 0 auto;
}

.DateRangePickerInput_arrow_svg {
    fill: var(--text-secondary) !important;
}

.DateInput_input {
    background-color: var(--card-bg) !important;
    color: var(--text-primary) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 8px;
    padding: 0.35rem 0.5rem;
    height: 36px !important;
    line-height: 1.2 !important;
    font-size: 0.875rem;
    font-family: inherit;
    width: 100% !important;
    max-width: none !important;
    min-width: 0 !important;
}

.DateInput_input:hover {
    border-color: var(--accent-color) !important;
}

.CalendarDay__selected {
    background: var(--accent-color) !important;
    border: 1px solid var(--accent-color) !important;
}

/* Input Fields */
input[type="number"],
input[type="text"] {
    background-color: var(--card-bg) !important;
    color: var(--text-primary) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 8px;
    padding: 0.5rem;
    width: 100%;
    transition: border-color 0.2s ease;
}

/* Prevent global input width rules from breaking 3rd-party controls */
input.DateInput_input {
    width: 100% !important;
}

input[type="number"]:focus,
input[type="text"]:focus {
    border-color: var(--accent-color) !important;
    outline: none;
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.1);
}

/* Page Headers */
.page-header {
    font-size: 2rem;
    font-weight: 700;
    margin-bottom: 1.5rem;
    padding-bottom: 0.75rem;
    border-bottom: 3px solid var(--accent-color);
    background: linear-gradient(135deg, var(--text-primary) 0%, var(--accent-color) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

/* Stats Summary Cards */
.stat-card {
    background: linear-gradient(135deg, var(--card-bg) 0%, var(--primary-color) 100%);
    border-radius: 12px;
    padding: 1.5rem;
    text-align: center;
    border: 1px solid var(--border-color);
    transition: transform 0.2s ease;
}

.stat-card:hover {
    transform: translateY(-4px);
}

.stat-value {
    font-size: 2rem;
    font-weight: 700;
    color: var(--accent-color);
}

.stat-label {
    font-size: 0.875rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* Animations */
@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fade-in {
    animation: fadeIn 0.3s ease-out;
}

/* Homepage "Where do I find this CSV?" help modal. Rendered at the page root so
   it escapes the feature-card stacking contexts (the Player Profiles tile uses
   z-50 for its search dropdown). Forced above all page chrome. */
#home-roster-help-modal.home-roster-help-modal {
    z-index: 2147483647 !important;
}

@keyframes spinSlow {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

.spin-slow {
    display: inline-block;
    transform-origin: 50% 50%;
    animation: spinSlow 10s linear infinite;
}

/* Home hero banner */
.home-hero {
    position: relative;
    border-radius: var(--radius);
    padding: 2.5rem 1.5rem;
    min-height: 282px;
    background-image:
        linear-gradient(180deg, rgba(0, 0, 0, 0.40) 0%, rgba(0, 0, 0, 0.72) 100%),
        url("oracle_park_night.jpeg");
    background-repeat: no-repeat;
    background-size: cover;
    /* Keep home plate near the bottom while showing a bit more above it. */
    background-position: center, 50% 69%;
    border: 1px solid var(--border-color);
    overflow: hidden;
}

@media (max-width: 640px) {
    .home-hero {
        /* On smaller screens, keep the crop slightly lower to preserve the infield. */
        background-position: center, 50% 75%;
    }
}

.home-hero > * {
    position: relative;
    z-index: 1;
}

/* Feature icon hover cue */
.feature-icon {
    transition: color 0.2s ease, filter 0.2s ease;
}

.custom-card:hover .feature-icon {
    color: var(--accent-color) !important;
    filter: drop-shadow(0 0 8px rgba(var(--accent-rgb), 0.35));
}

/* Home page feature tiles: make the whole tile feel clickable.
   Mimic Player Explorer tab hover tint (accent/10) and apply to CTA too. */
.home-tile-link:hover {
    background-color: rgba(var(--accent-rgb), 0.06) !important;
    border-color: rgba(var(--accent-rgb), 0.55) !important;
}

/* Home page: Roto+ snapshot tables
   Goal: keep player names readable on tight widths by shrinking the trendline column. */
.home-snapshot-table {
    table-layout: fixed;
    width: 100%;
}

.home-snapshot-table col.snap-col-rank { width: 2.5rem; }
/* Shrink sparkline/trend/roto columns as the viewport tightens to preserve name width. */
.home-snapshot-table col.snap-col-spark { width: clamp(3.75rem, 10vw, 9rem); }
.home-snapshot-table col.snap-col-trend { width: clamp(3rem, 6vw, 5rem); }
.home-snapshot-table col.snap-col-roto { width: clamp(3.75rem, 7vw, 5rem); }

.home-snapshot-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.home-snapshot-sparkline {
    width: 100%;
    max-width: 64px;
    height: 18px;
}

/* Tight viewports: reduce padding on non-name columns to preserve name width. */
@media (max-width: 950px) {
    .home-snapshot-table th:nth-child(1),
    .home-snapshot-table td:nth-child(1) { padding-right: 0.5rem !important; }

    .home-snapshot-table th:nth-child(3),
    .home-snapshot-table td:nth-child(3),
    .home-snapshot-table th:nth-child(4),
    .home-snapshot-table td:nth-child(4) { padding-right: 0.5rem !important; }
}

@media (max-width: 850px) {
    .home-snapshot-sparkline { max-width: 52px; height: 16px; }
}

@media (max-width: 700px) {
    .home-snapshot-sparkline { max-width: 46px; height: 14px; }
}

/* Player Profiles: percentile slider rows */
.pp-metric-row {
    display: grid;
    grid-template-columns: 160px 1fr 92px;
    gap: 12px;
    align-items: center;
    padding: 10px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.pp-metric-row:last-child {
    border-bottom: none;
}

.pp-percentile-sections {
    display: flex;
    flex-direction: column;
    gap: 14px;
    align-items: center;
    padding-top: 13px;
}

#pp-percentiles {
    padding-left: 10px;
    padding-right: 10px;
    overflow-x: visible;
}

.pp-percentile-section {
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    padding: 10px 12px 6px;
    width: 100%;
    max-width: 560px;
    background: linear-gradient(135deg, var(--pp-section-tint, rgba(127, 157, 187, 0.08)), rgba(0, 0, 0, 0.15));
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.04),
        0 0 11px var(--pp-section-glow, rgba(127, 157, 187, 0.22));
}

.pp-percentile-section-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 8px;
}

.pp-percentile-section-title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-weight: 600;
    color: var(--pp-section-color, var(--accent-color));
    opacity: 0.78;
    white-space: nowrap;
}

.pp-percentile-section-divider {
    width: 100%;
    height: 1px;
    background: linear-gradient(90deg, var(--pp-section-color, var(--accent-color)), rgba(255, 255, 255, 0));
    opacity: 0.5;
}

.pp-percentile-section-body .pp-metric-row {
    padding: 8px 0;
}

/* App-wide widget styling (flat dark surfaces with a subtle hairline border). */
.app-widget {
    box-shadow: none;
}

.app-widget--glass {
    background: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: var(--radius);
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
}

/* App header matches widget styling but stays flush to the viewport edges. */
.app-header {
    background: rgba(14, 17, 23, 0.92) !important;
    border-radius: 0;
    border-left: none;
    border-right: none;
    border-top: none;
    border-bottom: 1px solid var(--border-color) !important;
    box-shadow: none !important;
    backdrop-filter: saturate(140%) blur(8px) !important;
    -webkit-backdrop-filter: saturate(140%) blur(8px) !important;
}

.app-nav-link {
    color: var(--text-primary);
    font-weight: 400;
    letter-spacing: 0.01em;
    background: transparent;
    border: 1px solid transparent;
    box-shadow: none;
    transition: color 160ms ease, background 160ms ease, border-color 160ms ease;
}

.app-nav-link:hover,
.app-nav-link:focus-visible {
    color: var(--text-primary);
    background: rgba(var(--accent-rgb), 0.12);
    border-color: rgba(var(--accent-rgb), 0.45);
    outline: none;
}

.app-nav-menu {
    border: 1px solid var(--border-color);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45) !important;
}

.app-nav-menu-link {
    color: var(--text-primary);
    font-weight: 400;
    transition: color 160ms ease, background 160ms ease;
}

.app-nav-menu-link:hover,
.app-nav-menu-link:focus-visible {
    color: var(--text-primary);
    background: rgba(var(--accent-rgb), 0.14);
    outline: none;
}

/* Feature tiles use the same flat widget styling as primary widgets. */
.home-feature-card {
    box-shadow: none !important;
    transition: border-color 160ms ease, background-color 160ms ease, transform 160ms ease;
}

.app-widget-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 12px;
}

.app-widget-title {
    font-size: 0.95rem;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 600;
    color: rgba(232, 234, 237, 0.95);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.app-widget-title i {
    color: rgba(255, 255, 255, 0.85);
}

.app-widget-header i,
.app-page-title i,
.sub-widget-header i,
.sub-widget-title i,
.app-widget button i,
.app-widget a i,
.app-chip i {
    font-size: 0.95em;
    line-height: 1;
    font-weight: 600;
    text-rendering: geometricPrecision;
}


.app-widget-divider {
    width: 100%;
    height: 1px;
    background: var(--border-color);
    opacity: 1;
}

.app-page-title {
    font-size: 1.5rem;
    text-transform: none;
    letter-spacing: -0.01em;
    font-weight: 700;
    color: #e8eaed;
    display: inline-flex;
    align-items: center;
    gap: 12px;
}

.app-page-title i {
    color: rgba(255, 255, 255, 0.85);
}

/* Thin separators + spacing rhythm helpers. */
.app-divider {
    height: 1px;
    background: var(--border-color);
    opacity: 1;
}

.space-y-12 > * + * {
    margin-top: var(--space-12);
}

.space-y-4 > * + * {
    margin-top: 4px;
}

.space-y-16 > * + * {
    margin-top: var(--space-16);
}

.space-y-24 > * + * {
    margin-top: var(--space-24);
}

.sub-widget-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 8px;
}

.sub-widget-title {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
    color: rgba(155, 161, 173, 0.9);
}

.sub-widget-divider {
    width: 100%;
    height: 1px;
    background: var(--border-color);
    opacity: 1;
}

.pp-metric-name {
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 0.9rem;
}

.pp-metric-raw {
    text-align: right;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.pp-pct-track {
    position: relative;
    height: 14px;
    border-radius: 9999px;
    overflow: visible;
    background: rgba(255, 255, 255, 0.10);
    /* R8: neutral border — the old blue outline put ~150 "poor-colored"
       rings on the splits page. */
    border: 1px solid rgba(255, 255, 255, 0.12);
}

.pp-pct-fill {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    border-radius: 9999px;
    opacity: 0.95;
}

.pp-pct-marker {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    width: auto;
    min-width: 22px;
    height: 22px;
    border-radius: 9999px;
    background: var(--pp-pct-color, var(--accent-color));
    border: 2px solid rgba(10, 25, 41, 0.92);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.10);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    box-sizing: border-box;
    padding: 0 6px;
}

.pp-pct-marker::before {
    content: none;
}

.pp-pct-bubble {
    position: static;
    background: transparent;
    color: var(--text-primary);
    border: none;
    padding: 0;
    font-size: 0.75rem;
    font-weight: 800;
    min-width: 0;
    text-align: center;
    pointer-events: none;
    white-space: nowrap;
    line-height: 1;
}

/* Player Splits: compact table rendering so split columns have room.
   This intentionally does NOT change grid column widths; it only reduces
   internal element sizes to avoid overlap. */
#ps-splits-grid .pp-pct-track {
    height: 9px;
    overflow: visible;
}

/* Player Splits: reserve a small buffer between the bar and the raw value. */
#ps-splits-grid .ps-splits-track {
    margin-right: 6px;
}

#ps-splits-grid .pp-pct-marker {
    /* R8-A3: 12px pill around 12px (0.75rem) digits clipped every bubble
       vertically — 16px clears the type plus the 1px borders. */
    min-width: 16px;
    height: 16px;
    padding: 0 2px;
    border-width: 1px;
    box-shadow: none;
}

/* uiux-audit P0-6: the stat values are the page's whole point — 0.45/0.46rem
   (~7px) made them unreadable on every device. 0.75rem is the data-text
   floor; the grid scrolls horizontally rather than shrinking below it. */
#ps-splits-grid .pp-pct-bubble {
    font-size: 0.75rem;
}

#ps-splits-grid .ps-splits-raw,
#ps-splits-grid .ps-splits-delta {
    font-size: 0.75rem;
    line-height: 1.15;
}

#ps-splits-grid .ps-splits-metric {
    font-size: 0.8125rem;
}

/* Player Splits: metric column blends on desktop; below md it is sticky
   over horizontally-scrolling columns and MUST be opaque (R0-30). */
@media (min-width: 768px) {
    #ps-splits-grid .ps-splits-metric,
    #ps-splits-grid .pc-metric-sticky {
        background: transparent !important;
    }
}

@media (max-width: 767px) {
    #ps-splits-grid .pc-metric-sticky {
        background: var(--card-bg) !important;
    }
}

@media (max-width: 767.98px) {
    /* Player Profiles: Stats selector should be dropdown-only on mobile.
       (Some environments may not include Tailwind responsive utilities.) */
    #pp-stats-tabs {
        display: none;
    }

    #pp-stats-dropdown {
        display: block;
    }

    /* Player Profiles: on very small widths the percentile track can get squeezed
       into a tiny pill by the name/value columns. Stack the track below to give
       it full row width. */
    #pp-percentiles .pp-metric-row {
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "name raw"
            "track track";
        align-items: start;
        gap: 6px 10px;
    }

    #pp-percentiles .pp-metric-name {
        grid-area: name;
        font-size: 0.82rem;
        line-height: 1.15;
    }

    #pp-percentiles .pp-metric-raw {
        grid-area: raw;
        white-space: nowrap;
    }

    #pp-percentiles .pp-metric-row > :nth-child(2) {
        grid-area: track;
    }

    #pp-percentiles .pp-pct-track {
        height: 12px;
    }

    #pp-percentiles .pp-pct-marker {
        min-width: 18px;
        height: 18px;
        padding: 0 5px;
    }

    #pp-percentiles .pp-pct-bubble {
        font-size: 0.65rem;
    }

    /* Player Comparison: tighten the comparison table on mobile. */
    #pc-comparison-bars .pp-metric-name {
        font-size: 0.75rem;
    }

    #pc-comparison-bars .pp-pct-track {
        height: 12px;
    }

    #pc-comparison-bars .pp-pct-marker {
        min-width: 18px;
        height: 18px;
        padding: 0 5px;
    }

    #pc-comparison-bars .pp-pct-bubble {
        font-size: 0.65rem;
    }

    /* Player Comparison: keep the Metric column frozen during horizontal scroll. */
    #pc-comparison-bars .pc-metric-sticky {
        position: sticky;
        left: 0;
        z-index: 20;
        background: var(--dark-bg);
        padding-right: 6px;
    }

    /* Player Splits: match Player Comparison tight mobile layout.
       uiux-audit P0-6: same 0.75rem data-text floor as desktop — the old
       0.4rem (6.4px) bubbles were unreadable; horizontal scroll (with the
       sticky metric column below) is the density valve, not type size. */
    #ps-splits-grid .pp-metric-name {
        font-size: 0.75rem;
    }

    #ps-splits-grid .pp-pct-track {
        height: 10px;
        overflow: visible;
    }

    #ps-splits-grid .ps-splits-track {
        margin-right: 5px;
    }

    #ps-splits-grid .pp-pct-marker {
        /* R8-A3: match desktop — 14px minus borders clipped the 12px digits. */
        min-width: 16px;
        height: 16px;
        padding: 0 2px;
        border-width: 1px;
        box-shadow: none;
    }

    #ps-splits-grid .pp-pct-bubble {
        font-size: 0.75rem;
    }

    /* R0-14: the delta column ran into the right split's raw value
       ("0.415-0.002" read as one number). */
    #ps-splits-grid .ps-splits-delta {
        white-space: nowrap;
        padding-left: 6px;
    }

    #ps-splits-grid .ps-splits-raw {
        padding-right: 4px;
    }

    /* Player Splits: keep the Metric column frozen during horizontal scroll. */
    #ps-splits-grid .pc-metric-sticky {
        position: sticky;
        left: 0;
        z-index: 20;
        background: transparent;
        padding-right: 6px;
    }
}

@media (min-width: 768px) {
    /* Player Profiles: show tabs on desktop, hide dropdown. */
    #pp-stats-tabs {
        display: block;
    }

    #pp-stats-dropdown {
        display: none;
    }
}

/* Responsive Adjustments */
@media (max-width: 767.98px) {
    .sidebar {
        position: relative;
        top: 0;
        max-height: none;
        margin-bottom: 1rem;
    }
    
    .page-header {
        font-size: 1.5rem;
    }
    
    .stat-value {
        font-size: 1.5rem;
    }
}

/* Tooltips */
.custom-tooltip {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

/* Tags */
.tag {
    display: inline-block;
    padding: 0.25rem 0.5rem;
    background-color: rgba(var(--accent-rgb), 0.2);
    border: 1px solid var(--accent-color);
    border-radius: 4px;
    font-size: 0.75rem;
    margin: 0.125rem;
    color: var(--accent-color);
}

/* Empty State */
.empty-state {
    text-align: center;
    padding: 3rem;
    color: var(--text-secondary);
}

.empty-state-icon {
    font-size: 4rem;
    margin-bottom: 1rem;
    opacity: 0.5;
}

.empty-state-text {
    font-size: 1.125rem;
}

/* ===========================================================================
   Touch & type floor (uiux-audit P1-4) — one scoped layer instead of chasing
   sub-44px targets page by page. Applies on coarse pointers and phone
   widths; desktop pointer density is untouched. Kept at the END of this
   sheet so it wins the cascade (several base rules force 36px !important).
   =========================================================================== */
@media (pointer: coarse), (max-width: 767px) {
    /* Dropdowns (react-select v1 + v5) and date inputs: 44px targets. */
    .Select-control,
    .Select__control {
        min-height: 44px !important;
        height: auto !important;
    }

    .Select-placeholder,
    .Select-value {
        line-height: 42px !important;
    }

    .Select-input {
        height: 42px !important;
    }

    .DateInput_input {
        min-height: 44px;
        font-size: 16px;
    }

    /* Text inputs never below 16px (iOS focus-zoom threshold). */
    input[type="text"],
    input[type="number"],
    input[type="email"],
    input[type="password"],
    input[type="search"],
    textarea {
        font-size: 16px;
    }

    /* Buttons and links styled as buttons: 44px hit target. Grid-internal
       icon buttons (AG header/menu) are excluded — rows are 52px so their
       targets are already tall. */
    button:not([class*="ag-"]) {
        min-height: 44px;
    }

    /* Filter/metric chips: 40px min with comfortable padding. */
    .app-chip,
    .pe-controls-chip {
        min-height: 40px;
        padding-left: 12px;
        padding-right: 12px;
    }

    /* Slider handles: 26px grab targets (was 14px). */
    .rc-slider-handle {
        width: 26px !important;
        height: 26px !important;
        margin-top: -11px !important;
    }

    .rc-slider-rail,
    .rc-slider-track {
        height: 6px;
    }

    /* Label floor: form labels never below 13px on touch. (1em = inherited
       size, so already-larger labels are left alone.) */
    label {
        font-size: max(0.8125rem, 1em);
    }
}

/* ===========================================================================
   Responsive-table contract (uiux-audit P1-1) — paired with assets/table_ux.js
   =========================================================================== */
.rt-scroll,
.es-table-wrap {
    position: relative;
}

/* Right-edge fade while a container actually overflows: clipped columns read
   as "more content this way", never as the end of the table. */
.rt-has-overflow {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), rgba(0, 0, 0, 0.25) 100%);
    mask-image: linear-gradient(90deg, #000 calc(100% - 28px), rgba(0, 0, 0, 0.25) 100%);
}

.rt-swipe-hint {
    position: absolute;
    right: 8px;
    top: 8px;
    z-index: 5;
    padding: 4px 10px;
    border-radius: 9999px;
    font-size: 0.72rem;
    color: var(--text-primary);
    background: rgba(var(--card-bg-rgb), 0.9);
    border: 1px solid rgba(255, 255, 255, 0.15);
    pointer-events: none;
    transition: opacity 0.35s ease;
}

.rt-swipe-hint--gone {
    opacity: 0;
}

/* Analyzer positional heatmap: pin the row-label column during horizontal
   scroll (uiux-audit P1-1). */
#fta-heatmap th:first-child,
#fta-heatmap td:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--card-bg);
}

/* Sticky column-header rows on Comparison / Splits (uiux-audit P1-12): the
   labels stay visible while scrolling long metric lists. Offset clears the
   sticky app header via the measured --app-header-h (assets/chat_ux.js). */
.pc-header-sticky {
    position: sticky;
    top: var(--app-header-h, 64px);
    z-index: 25;
    background: var(--card-bg);
}

/* Mobile drawer ergonomics (uiux-audit P1-13). */
@media (max-width: 767px) {
    /* Apply actions pin to the bottom of the scrolling drawer panel — no
       more burying "Apply" under 300+ option chips. */
    #pe-mobile-apply,
    #ps-mobile-apply,
    #pc-mobile-apply,
    #pt-mobile-apply {
        position: sticky;
        bottom: 0;
        z-index: 10;
        box-shadow: 0 -10px 18px rgba(0, 0, 0, 0.45);
    }

    /* Drawer close glyphs: real 44px hit targets. */
    #pe-howto-mobile-close,
    #ps-mobile-close,
    #pc-mobile-close,
    #pt-mobile-close {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 1.1rem;
    }

    /* Splits: the Filters opener floats once the header scrolls away, so
       changing a filter never means scrolling back to the top. Opaque
       accent pill (R0-13 — a transparent quiet-strip once made this an
       invisible floating word blocking the footer links). */
    #ps-open-controls {
        position: fixed;
        right: 14px;
        bottom: 18px;
        z-index: 40;
        border-radius: 9999px;
        min-height: 48px;
        padding-left: 18px;
        padding-right: 18px;
        background: var(--accent-color) !important;
        color: #fff !important;
        border: none !important;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55) !important;
    }

    /* Keep the last content clear of the floating pill. */
    #ps-splits-grid {
        padding-bottom: 84px;
    }
}

/* Tier comparison responsive swap (uiux-audit P1-15): table on md+, stacked
   per-tier cards on phones. */
.tier-cards {
    display: none;
}

@media (max-width: 767px) {
    .tier-table-wrap { display: none; }

    .tier-cards {
        display: flex;
        flex-direction: column;
        gap: 14px;
    }

    .tier-card {
        border: 1px solid rgba(255, 255, 255, 0.1);
        border-radius: 14px;
        background: rgba(var(--card-bg-rgb), 0.6);
        padding: 18px 16px;
    }

    .tier-card--current {
        border-color: rgba(var(--accent-rgb), 0.55);
        box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.3);
    }

    .tier-card-features {
        list-style: none;
        margin: 12px 0 14px;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;
    }

    .tier-card-feature {
        display: flex;
        align-items: baseline;
        gap: 8px;
        font-size: 0.85rem;
        color: var(--text-primary);
    }
}

/* ===========================================================================
   Navigation IA (uiux-audit P1-5/P1-6): grouped dropdowns, active route,
   fixed-overlay mobile drawer, global search hotkey.
   =========================================================================== */
.app-nav-group > summary::-webkit-details-marker {
    display: none;
}

.app-nav-caret {
    font-size: 0.6rem;
    opacity: 0.7;
    transition: transform 0.15s ease;
}

.app-nav-group[open] > summary .app-nav-caret {
    transform: rotate(180deg);
}

/* Active route (set by assets/nav_ux.js with aria-current="page"). */
.app-nav-link--active,
.app-nav-menu-link--active {
    color: var(--text-primary) !important;
    box-shadow: inset 0 -2px 0 0 rgba(var(--accent-rgb), 0.9);
    background: rgba(var(--accent-rgb), 0.08);
}

/* Group summary highlights when a child route is active. */
.app-nav-group--active > summary {
    color: var(--text-primary);
    box-shadow: inset 0 -2px 0 0 rgba(var(--accent-rgb), 0.9);
}

@media (max-width: 899px) {
    /* Fixed overlay drawer replacing the in-flow panel that pushed 1300px of
       content and relocated its own toggle. (F1-09: nav breakpoint is 900 —
       at 768-850 the desktop nav overflowed and hid the sign-in button.) */
    #navbar-collapse.app-nav-open {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        width: min(86vw, 340px);
        z-index: 70;
        margin: 0;
        padding: 12px 14px 24px;
        overflow-y: auto;
        background: rgba(14, 17, 23, 0.97);
        border-left: 1px solid rgba(255, 255, 255, 0.1);
        box-shadow: -18px 0 40px rgba(0, 0, 0, 0.5);
    }

    .nav-drawer-backdrop {
        position: fixed;
        inset: 0;
        z-index: 65;
        border: none;
        background: rgba(5, 6, 9, 0.6);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
    }

    .nav-drawer-close {
        position: sticky;
        top: 0;
        z-index: 5;
        align-self: flex-end;
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 1.15rem;
        border: none;
        border-radius: 10px;
        color: var(--text-primary);
        background: rgba(255, 255, 255, 0.06);
    }

    /* Drawer group menus render in-flow and indented (not floating). */
    #navbar-collapse.app-nav-open .app-nav-menu {
        margin-left: 10px;
    }
}

@media (min-width: 900px) {
    .nav-drawer-close,
    .nav-drawer-backdrop {
        display: none !important;
    }
}

/* The header's backdrop-filter creates a CSS containing block that would
   trap the fixed drawer/backdrop inside the header box — lift it while the
   drawer OR the account popover is open (R0-18: the popover's backdrop was
   trapped to the 72px header strip, so click-outside never dismissed). */
@media (max-width: 899px) {
    .app-header:has(#navbar-collapse.app-nav-open) {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
    }
}

.app-header:has(#profile-popover-wrap[style*="block"]) {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* Deep-link metric toast on Player Trends (uiux-audit P1-8). */
.pt-url-toast {
    display: flex;
    align-items: center;
    margin: 10px 0 0;
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 0.85rem;
    color: var(--warning-color);
    border: 1px solid rgba(255, 193, 7, 0.35);
    background: rgba(255, 193, 7, 0.08);
}

/* Hot/cold badge icons (uiux-audit P2-1) — replace the 🔥/🧊 emoji. */
.hotcold--hot { color: var(--pct-good); }
.hotcold--cold { color: var(--pct-poor); }

/* Provenance line in the footer (uiux-audit P2-6). */
.app-footer-provenance {
    text-align: center;
    font-size: 0.75rem;
    color: var(--text-secondary);
    padding: 6px 16px 2px;
    opacity: 0.85;
}

/* Posts filter disclosure (uiux-audit P2-14): open by default; the toggle
   only exists on phones. Trial-banner icon alignment fix included. */
.posts-filters-toggle {
    list-style: none;
    cursor: pointer;
    display: none;
    margin-top: 10px;
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-weight: 600;
}

.posts-filters-toggle::-webkit-details-marker {
    display: none;
}

@media (max-width: 767px) {
    .posts-filters-toggle {
        display: flex;
        align-items: center;
        min-height: 44px;
    }
}

.profile-sub-status {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.profile-sub-status > i {
    flex: 0 0 auto;
    margin-top: 3px;
}

/* Segmented pills for binary/ternary choices (uiux-audit P2-9): replaces
   two-option dropdowns that hid their choices behind a click. */
.seg-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.seg-pill {
    display: inline-flex;
    align-items: center;
    padding: 8px 14px;
    min-height: 38px;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-secondary);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    user-select: none;
    transition: box-shadow 160ms ease, color 160ms ease, background 160ms ease;
}

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

.seg-pill input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.seg-pill:has(input:checked) {
    color: var(--text-primary);
    background: rgba(var(--accent-rgb), 0.18);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), 0.45);
}

.seg-pill:focus-within {
    box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.55);
}

/* Visually-hidden accessible labels (belt-and-braces for Tailwind sr-only). */
.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;
}

/* Home mobile compaction (uiux-audit P2-7): the hero spent the first fold
   repeating the app name that's already in the header, and each feature
   card was a full screen tall. */
@media (max-width: 767px) {
    .home-hero {
        padding: 20px 16px !important;
    }

    .home-hero h1 {
        font-size: 1.75rem !important;
        margin-bottom: 6px !important;
    }

    .home-feature-card {
        padding: 12px !important;
    }

    .home-feature-card p {
        display: none; /* icon + title carry it at this size */
    }
}

/* League-average pinned row (uiux-audit P2-4). */
.ag-theme-alpine-dark .ag-floating-top .ag-row,
.ag-theme-alpine-dark .ag-row-pinned {
    font-style: italic;
    color: var(--text-secondary);
    background: rgba(255, 255, 255, 0.035);
}

/* Profiles quick-links row (uiux-audit P2-5). */
.pp-quicklink {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    min-height: 36px;
    border-radius: 9999px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-secondary);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.pp-quicklink:hover {
    color: var(--text-primary);
    border-color: rgba(var(--accent-rgb), 0.45);
    background: rgba(var(--accent-rgb), 0.1);
}

/* "On your roster" star in home leader rows (uiux-audit P2-8). */
.home-my-player {
    color: var(--warning-color);
    font-size: 0.7em;
    flex: 0 0 auto;
}

/* Key-stat strip on the Profiles identity header (uiux-audit P2-3). */
.pp-keystat {
    display: inline-flex;
    flex-direction: column;
    line-height: 1.15;
}

.pp-keystat-value {
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--text-primary);
}

.pp-keystat-label {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-secondary);
}

/* R0-19: plotly.js treats displayModeBar:'hover' as ALWAYS-VISIBLE on touch
   devices — the bar parked over chart titles and range chips on every
   chart. scrollZoom is already off; nothing essential is lost on touch. */
@media (pointer: coarse) {
    .js-plotly-plot .modebar {
        display: none !important;
    }
}

/* Profiles/Trends: the rangeslider eats ~90px of a phone chart. */
@media (max-width: 767px) {
    .js-plotly-plot .rangeslider-container {
        display: none;
    }
}

/* R0-08: the sticky must live on the #app-navbar wrapper — the nav's own
   `sticky top-0` could only stick within this 148px wrapper, which is why
   the app header never stuck anywhere. z-80 also puts the header's drawer/
   backdrop children above page content that reached z-50 (R0-17). */
#app-navbar {
    position: sticky;
    top: 0;
    /* z-50, NOT higher: page-level fixed overlays (splits/trends drawers,
       profile modal — all z-50, later in DOM) must win ties so their close
       buttons aren't blocked by the header strip. The home-tile conflict
       that motivated z-80 was solved by dropping the tiles to z-10. */
    z-index: 50;
}

/* R0-22: the fade masks the AG grid root when its center viewport overflows
   (the wrapper-based mask can't see internal scroll). */
.ag-root-wrapper.rt-has-overflow {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), rgba(0, 0, 0, 0.25) 100%);
    mask-image: linear-gradient(90deg, #000 calc(100% - 28px), rgba(0, 0, 0, 0.25) 100%);
}

/* R0-25: Roto+ info disclosure (tap-friendly; title tooltips are dead on touch). */
.roto-info {
    position: relative;
}

.roto-info-toggle {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    min-height: 28px;
    color: var(--text-secondary);
}

.roto-info-toggle::-webkit-details-marker { display: none; }

.roto-info-pop {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 30;
    width: 230px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--card-bg);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
    font-size: 0.78rem;
    color: var(--text-primary);
    text-align: left;
    white-space: normal;
    font-weight: 400;
}

@media (pointer: coarse) {
    .roto-info-toggle { min-width: 44px; min-height: 44px; }
}

/* R1-18: the page must not scroll behind the open drawer. */
body:has(#navbar-collapse.app-nav-open) {
    overflow: hidden;
}

#navbar-collapse.app-nav-open {
    overscroll-behavior: contain;
}

/* R1-20: AG Grid pagination/filter internals join the touch floor (they
   were excluded by the blanket [class*="ag-"] carve-out). */
@media (pointer: coarse), (max-width: 767px) {
    .ag-paging-button {
        min-width: 40px;
        min-height: 40px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .ag-floating-filter-button-button {
        min-width: 36px;
        min-height: 36px;
    }

    .ag-floating-filter-input .ag-input-field-input {
        min-height: 38px;
        font-size: 16px;
    }
}

/* R1-14: Profiles stats table — cap the label-to-value stretch on wide
   screens (values sat ~740px from their labels). */
@media (min-width: 1024px) {
    #pp-stats-table table,
    #pp-stats-table {
        max-width: 640px;
    }
}

/* R2-03: home leader-row links reach the 44px touch floor. */
@media (pointer: coarse), (max-width: 767px) {
    .home-snapshot-name-link {
        display: flex;
        align-items: center;
        min-height: 44px;
    }

    /* R2-06: profile quick pills too. */
    .pp-quicklink {
        min-height: 44px;
        padding: 8px 14px;
    }
}

/* R2-16: ES sticky Split column matches the card surface + edge cue. */
.es-table th:first-child,
.es-table td:first-child {
    background: var(--card-bg);
    box-shadow: 4px 0 8px -4px rgba(0, 0, 0, 0.45);
}

/* R2-20: hide Comparison's stray empty container when it has no content. */
#pc-comparison-bars > div:empty {
    display: none;
}

/* R2-10: metric labels wrap at word boundaries only — "SwingDecisions+"
   left an orphaned "+" on its own line. */
#ps-splits-grid .pp-metric-name {
    overflow-wrap: normal;
    word-break: keep-all;
    hyphens: none;
}

/* R2-19: footer support anchor joins the touch floor. */
@media (pointer: coarse), (max-width: 767px) {
    .app-footer-support-btn {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }
}

/* R2-08: comparison raw values never ellipsize inside ringed cells. */
@media (max-width: 767px) {
    #pc-comparison-bars .pp-metric-raw,
    #pc-comparison-bars .ps-splits-raw {
        overflow: visible;
        text-overflow: clip;
        white-space: nowrap;
    }
}

/* Pitch Arsenal redesign: pitch dots, insight chips. */
.at-pitch-dot {
    width: 10px;
    height: 10px;
    border-radius: 4px;
    display: inline-block;
    flex: 0 0 auto;
}

.at-insight-chip {
    display: inline-flex;
    align-items: center;
    padding: 8px 14px;
    min-height: 38px;
    border-radius: 9999px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-primary);
    background: rgba(var(--accent-rgb), 0.08);
    border: 1px solid rgba(var(--accent-rgb), 0.28);
}

/* ===========================================================================
   Explorer mobile scroll containment (owner-reported): scrolling rows chained
   into PAGE scroll, sliding the column-name row under the sticky nav so
   headers appeared "half cut off". Contain the grid's internal scrollers and
   size the grid to the viewport below the header so the header row stays
   visible during normal row-scrolling.
   =========================================================================== */
@media (max-width: 767px) {
    #pe-grid {
        height: calc(100dvh - var(--app-header-h, 70px) - 150px) !important;
        min-height: 420px;
        scroll-margin-top: calc(var(--app-header-h, 70px) + 8px);
    }

    #pe-grid .ag-body-viewport,
    #pe-grid .ag-center-cols-viewport {
        overscroll-behavior: contain;
    }
}

/* Pinned name column: ellipsize instead of hard-clipping ("Pete Crow-Armstro"). */
#pe-grid .pe-player-name-link {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Explorer mobile: the header quick-filter chips (All/Risers/Fallers) push
   the column title out of the 48px header cell — on phones the chips are
   sub-44px targets anyway; the drawer filters cover the use case. */
@media (max-width: 767px) {
    #pe-grid .trend-header-controls {
        display: none;
    }

    #pe-grid .trend-header {
        justify-content: center;
    }
}

/* ===========================================================================
   Branded boot splash (F1-03): Dash's stock app-entry shows a raw top-left
   "Loading..." string on black for 0.3-2.6s on EVERY cold navigation — the
   most-seen frame in the product. Style it into a real splash: house
   background, wordmark, spinner. Pure CSS; removed automatically when React
   hydrates and replaces the entry node.
   =========================================================================== */
#react-entry-point ._dash-loading {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    background:
        radial-gradient(900px circle at 78% 6%, rgba(107, 138, 255, 0.06), transparent 60%),
        linear-gradient(160deg, #0b0d11 0%, #0e1117 100%);
    /* hide the raw "Loading..." text */
    color: transparent;
    font-size: 0;
    user-select: none;
}

#react-entry-point ._dash-loading::before {
    content: "Baseball Stats Guru";
    font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
    font-size: 22px;
    font-weight: 800;
    letter-spacing: 0.02em;
    color: #e8eaed;
}

#react-entry-point ._dash-loading::after {
    content: "";
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid rgba(107, 138, 255, 0.22);
    border-top-color: #6b8aff;
    animation: bsg-boot-spin 0.85s linear infinite;
}

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

@media (prefers-reduced-motion: reduce) {
    #react-entry-point ._dash-loading::after {
        animation: none;
        border-top-color: rgba(107, 138, 255, 0.6);
    }
}

/* F1-02: dcc.Loading overlays hosting skeleton spinners must never center a
   tall skeleton on a short strip — clip to the region and start at the top.
   (Belt-and-braces beneath the per-component overlay_style props.) */
[class*="dash-default-spinner"],
.dash-spinner {
    width: 100%;
}

/* F1-11: below the nav breakpoint the header row's containing scrollport is
   the horizontal wrapper, so a 74px top offset just displaced it INSIDE the
   table (covering the first rows). Vertical stickiness doesn't exist there
   anyway — zero the offset. */
@media (max-width: 1099.98px) {
    /* G1-10: includes 900-1099 where the two-row app header made the
       measured offset displace the sticky header between data rows. */
    .pc-header-sticky {
        top: 0;
    }
}

/* F1-12: league-load errors get room to breathe (the status line is
   normally a one-line ellipsized whisper). */
.chat-roster-status:has(.text-warning) {
    white-space: normal;
    overflow: visible;
    text-overflow: unset;
    max-width: 420px;
}

/* F1-14: the trend-open icon becomes a real target on touch. */
@media (pointer: coarse) {
    #pe-grid .trend-icon {
        min-width: 36px;
        min-height: 36px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

/* F2-01: Explorer assembles in stages — keep the placeholder pieces quiet.
   "Active filters: None" fades in late so the seeded chip (which lands a
   beat after the columns) replaces it invisibly; empty count pill/title
   collapse instead of rendering ghost chrome. */
.pe-filters-none {
    opacity: 0;
    animation: pe-fade-in 0.3s ease 2.5s forwards;
}
@keyframes pe-fade-in {
    to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .pe-filters-none { animation-delay: 1.5s; }
}
#pe-row-count:empty,
#pe-table-title:empty,
#pe-table-date-range:empty {
    display: none;
}

/* F2-10: skip link — visually hidden until keyboard-focused. */
.bsg-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 10px 16px;
    background: var(--color-accent, #e05a2b);
    color: #fff;
    border-radius: 0 0 8px 0;
    font-weight: 600;
    text-decoration: none;
}
.bsg-skip-link:focus {
    left: 0;
}

/* F2-10: page titles are real h1s now — neutralize UA heading styles so the
   existing .app-page-title look is unchanged. */
h1.app-page-title {
    margin: 0;
    font-size: inherit;
    font-weight: inherit;
}

/* F2-08: overlay close buttons are real touch/click targets (the profile
   modal's ✕ measured 12×26px). */
#pe-profile-close,
#pe-trends-modal button[id$="-close"],
#pe-howto-close,
#pe-howto-mobile-close {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
}
#pe-profile-close:hover,
#pe-howto-close:hover,
#pe-howto-mobile-close:hover {
    background: rgba(255, 255, 255, 0.06);
}

/* F2-13: recently-viewed pills. */
.bsg-recent-pill {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 4px 12px;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    color: var(--color-text-primary, #e8eaed);
    font-size: 0.8rem;
    font-weight: 600;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.bsg-recent-pill:hover {
    background: rgba(255, 255, 255, 0.09);
    border-color: rgba(255, 255, 255, 0.25);
    color: #fff;
}

/* F2-17: copy-to-clipboard affordance beside the saved link. */
.bsg-copy-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    min-height: 36px;
    border-radius: 8px;
    color: var(--color-text-secondary, #9aa2ad);
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}
.bsg-copy-btn:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.08);
}

/* F2-16: on phones the daily-habit leaders sat ~2,300px deep behind
   marketing tiles. Reorder: hero → ask-the-guru → leaders → the rest. */
@media (max-width: 767.98px) {
    #home-sections {
        display: flex;
        flex-direction: column;
        gap: 1.5rem;
    }
    #home-sections > * {
        margin-top: 0 !important; /* neutralize space-y-6 under flex order */
    }
    #home-sections > .home-hero { order: -30; }
    #home-sections > .guru-hero { order: -20; }
    /* R2-05: leaders sit BELOW the feature buttons (owner request), still
       above the posts widget. */
    #home-sections > .grid { order: -10; }
    #home-sections > #home-sec-snapshot { order: -5; }
}

/* F2-23: at 1024 the paired split cards squeezed the trailing EV/HR columns
   out instead of overflowing — keep the table at natural width and let
   .es-table-wrap scroll (fade cue via table_ux.js). */
.es-table {
    min-width: max-content;
}

/* F2-26: at desktop widths the view-tab strip clipped labels mid-word with an
   invisible scrollbar — wrap instead (there's vertical room); below lg keep
   the scroll but with the table_ux fade cue (rt-scroll on the component). */
@media (min-width: 1024px) {
    .pe-view-tabs {
        flex-wrap: wrap;
        overflow-x: visible;
    }
}

/* F2-26: the mixing-rule toast self-dismisses (visually) after a beat. */
.pt-toast-transient {
    animation: pt-toast-fade 0.4s ease 6s forwards;
}
@keyframes pt-toast-fade {
    to { opacity: 0; visibility: hidden; }
}

/* ---- F3 polish batch ---- */

/* F3-13: native widgets (scrollbars, form controls) render dark on
   Windows/Linux instead of glaring light UA chrome. */
:root {
    color-scheme: dark;
}

/* F3-11: Explorer numeric cells right-align like every other stats surface;
   header labels follow. Identity/text columns opt out. */
#pe-grid .ag-cell.trendable-cell,
#pe-grid .ag-cell.aps-score-cell {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
#pe-grid .ag-header-cell[col-id] .ag-header-cell-label {
    justify-content: flex-start;
}
/* Reserve the faller/riser triangle slot so ROTO+ values don't shift. */
#pe-grid .trend-icon {
    display: inline-block;
    min-width: 18px;
}

/* F3-14: drawer + nav dropdowns share the page-transition motion language. */
#navbar-collapse.app-nav-open {
    animation: bsg-slide-in 0.18s ease-out;
}
.app-nav-group[open] > .app-nav-menu {
    animation: bsg-pop-in 0.14s ease-out;
}
@keyframes bsg-slide-in {
    from { transform: translateX(-14px); opacity: 0.4; }
    to   { transform: translateX(0); opacity: 1; }
}
@keyframes bsg-pop-in {
    from { transform: translateY(-4px); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    #navbar-collapse.app-nav-open,
    .app-nav-group[open] > .app-nav-menu { animation: none; }
}

/* F3-18: visible keyboard focus for the quiet-button family + nav controls. */
#pe-export-csv:focus-visible,
#pe-save-view:focus-visible,
#pe-clear-filters:focus-visible,
.app-nav-group summary:focus-visible,
.bsg-copy-btn:focus-visible,
.app-nav-link:focus-visible {
    outline: 2px solid var(--color-accent, #e05a2b);
    outline-offset: 2px;
    border-radius: 8px;
}

/* F3-21 (partial): date-picker popover must clear the sticky navbar (z-50);
   narrow-sidebar date inputs stop truncating ("Jul 07, 2"). */
.DateRangePicker_picker {
    z-index: 60 !important;
}
.DateInput_input {
    font-size: 0.82rem;
    text-overflow: ellipsis;
}
/* Explorer avatar slot is reserved so rows don't reflow when images land. */
#pe-grid img.w-6.h-6 {
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
    background: rgba(255, 255, 255, 0.06);
    border-radius: 9999px;
}

/* F3-02: Profiles mobile quick-link pills wrapped 2-1-1 beside the headshot,
   stranding it — below md the pill row breaks out to full width. */
@media (max-width: 767.98px) {
    #pp-header > .flex {
        flex-wrap: wrap;
    }
    #pp-header .pp-quicklink {
        flex: 0 0 auto;
    }
}

/* ---- R2-09: single progress-bar loading treatment ---- */
.bsg-loading {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 18px 4px;
    max-width: 520px;
}
.loading-status--above {
    margin: 0;               /* caption sits ABOVE the bar */
    text-align: left;
}
.bsg-progress {
    height: 6px;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
    position: relative;
}
.bsg-progress-fill {
    height: 100%;
    width: 0%;
    border-radius: 9999px;
    background: linear-gradient(90deg,
        var(--color-accent, #e05a2b),
        rgba(var(--accent-rgb, 224, 90, 43), 0.75));
    /* Staged milestones: dispatch (fast to ~30%), server compute (crawl to
       ~60%), payload render (ease to 92% and hold — unmount = done). */
    animation: bsg-progress-stages 10s cubic-bezier(0.25, 0.6, 0.35, 1) forwards;
}
.bsg-progress-fill::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.25), transparent);
    animation: skeleton-shimmer 1.4s infinite;
}
@keyframes bsg-progress-stages {
    0%   { width: 2%; }
    12%  { width: 30%; }
    30%  { width: 44%; }
    60%  { width: 60%; }
    85%  { width: 82%; }
    100% { width: 92%; }
}
@media (prefers-reduced-motion: reduce) {
    .bsg-progress-fill {
        width: 60%;
        animation: bsg-progress-pulse 2s infinite ease-in-out;
    }
    .bsg-progress-fill::after { animation: none; }
}
@keyframes bsg-progress-pulse {
    0%, 100% { opacity: 0.5; }
    50%      { opacity: 1; }
}

/* Grid rebuild overlay bar (R2-16) reuses the same visual. */
.bsg-grid-busy-bar {
    width: 220px;
    height: 6px;
    margin: 0 auto;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
    position: relative;
}
.bsg-grid-busy-bar::before {
    content: "";
    position: absolute;
    inset: 0;
    width: 40%;
    border-radius: 9999px;
    background: var(--color-accent, #e05a2b);
    animation: bsg-busy-slide 1.2s infinite ease-in-out;
}
@keyframes bsg-busy-slide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(320%); }
}

/* R2-18: home feature-card CTA pills are one line and one height everywhere. */
.home-link-button {
    white-space: nowrap;
    min-height: 38px;
}
@media (max-width: 480px) {
    .home-link-button {
        font-size: 0.72rem;
        padding-left: 0.75rem;
        padding-right: 0.75rem;
    }
}

/* R2-16: self-managed rebuild veil over the Explorer grid. */
#pe-grid {
    position: relative;
}
.bsg-grid-veil {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(11, 13, 17, 0.6);
    backdrop-filter: blur(2px);
}
.bsg-grid-veil-inner {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 240px;
}
.bsg-grid-veil-msg {
    color: var(--text-secondary, #9aa2ad);
    font-weight: 600;
    font-size: 0.9rem;
    text-align: center;
}

/* R2-22: tab-strip rhythm — consistent gaps when the strip wraps (≥lg),
   comfortable ≥38px targets, breathing room from the content below, and
   no mid-token breaks inside a tab. */
.pe-view-tabs {
    gap: 2px 8px;
    margin-bottom: 10px;
    padding-bottom: 2px;
}
.pe-view-tabs .tab {
    min-height: 38px;
    display: inline-flex !important;
    align-items: center;
    white-space: nowrap;
}

/* R2-03: profile section nav — sticky pill strip that scrolls to sections. */
.pp-section-nav {
    position: sticky;
    top: 64px;                /* just under the app header */
    z-index: 30;
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    gap: 8px;
    padding: 8px 2px;
    margin: 4px 0 14px;
    background: rgba(11, 13, 17, 0.85);
    backdrop-filter: blur(8px);
    border-radius: 12px;
}
.pp-section-nav::-webkit-scrollbar { display: none; }
.pp-secnav-pill {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    padding: 6px 14px;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-secondary, #9aa2ad);
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
    transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.pp-secnav-pill:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.09);
}
.pp-secnav-pill--active {
    color: #fff;
    border-color: rgba(var(--accent-rgb, 224, 90, 43), 0.7);
    background: rgba(var(--accent-rgb, 224, 90, 43), 0.16);
}
/* Anchored sections stop below the sticky header + nav strip. */
#pp-section-percentiles, #pp-section-trend, #pp-section-stats,
#pp-section-situational, #pp-section-arsenal {
    scroll-margin-top: 128px;
}
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* R2-13: strike-zone contact chart. */
#pp-section-zone { scroll-margin-top: 128px; }
.pp-zone-wrap {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 24px;
}
.pp-zone-frame {
    position: relative;
    width: min(340px, 88vw);
    aspect-ratio: 1;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.12);
}
.pp-zone-corner { position: relative; }
.pp-zone-corner .pp-zone-cell {
    position: absolute;
    inset: 0;
    border-radius: 0;
}
/* R4-01 (agent-verified): the centered corner labels geometrically overlapped
   the inner grid at EVERY width — anchor each label to its outer corner. */
.pp-zone-corner .pp-zone-cell { padding: 14px 16px; }
.pp-zone-corner--tl .pp-zone-cell { justify-content: flex-start; align-items: flex-start; }
.pp-zone-corner--tr .pp-zone-cell { justify-content: flex-start; align-items: flex-end; }
.pp-zone-corner--bl .pp-zone-cell { justify-content: flex-end; align-items: flex-start; }
.pp-zone-corner--br .pp-zone-cell { justify-content: flex-end; align-items: flex-end; }
.pp-zone-grid {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 62%;
    height: 62%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    gap: 2px;
    padding: 2px;
    background: rgba(11, 13, 17, 0.9);
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-radius: 8px;
    z-index: 2;
}
.pp-zone-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    border-radius: 4px;
    min-height: 0;
}
.pp-zone-cell--empty {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-secondary, #9aa2ad);
}
.pp-zone-rate { font-weight: 800; font-size: 0.95rem; line-height: 1; }
.pp-zone-corner .pp-zone-rate { font-size: 0.85rem; }
.pp-zone-n { font-size: 0.62rem; opacity: 0.85; line-height: 1.2; }
.pp-zone-caption { max-width: 300px; display: flex; flex-direction: column; gap: 4px; }

/* R2-07: watchlist toggle. */
.pp-watch-btn {
    display: inline-flex;
    align-items: center;
    min-height: 38px;
    padding: 7px 16px;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary, #e8eaed);
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.pp-watch-btn:hover {
    background: rgba(255, 255, 255, 0.1);
}
.pp-watch-btn--on {
    border-color: rgba(var(--accent-rgb, 224, 90, 43), 0.65);
    background: rgba(var(--accent-rgb, 224, 90, 43), 0.15);
    color: #fff;
}
.pp-watch-btn--on .fa-star {
    color: var(--color-accent, #e05a2b);
}
.pp-watch-btn:focus-visible {
    outline: 2px solid var(--color-accent, #e05a2b);
    outline-offset: 2px;
}

/* R2-17: saved-view pills + name input. */
.pe-myview-pill {
    display: inline-flex;
    align-items: center;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.04);
    overflow: hidden;
}
.pe-myview-link {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 4px 6px 4px 12px;
    color: var(--text-primary, #e8eaed);
    font-size: 0.8rem;
    font-weight: 600;
}
.pe-myview-pill:hover {
    background: rgba(255, 255, 255, 0.09);
    border-color: rgba(255, 255, 255, 0.25);
}
.pe-myview-del {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    min-height: 32px;
    color: var(--text-secondary, #9aa2ad);
    background: transparent;
    border: none;
    cursor: pointer;
}
.pe-myview-del:hover { color: #fff; }
.pe-view-name-input {
    min-width: 150px;
    height: 34px;
    padding: 4px 10px;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary, #e8eaed);
    font-size: 0.8rem;
}
.pe-view-name-input:focus {
    outline: 2px solid rgba(var(--accent-rgb, 224, 90, 43), 0.6);
    outline-offset: 1px;
}

/* G1-04: the save-view row (link + copy + name input + Save + close)
   overflowed 390px with the close button off-screen — let it wrap. */
#pe-save-view-zone > div {
    flex-wrap: wrap;
}
#pe-save-view-zone .pe-view-name-input {
    flex: 1 1 140px;
    min-width: 120px;
}
@media (max-width: 520px) {
    #pe-save-view-zone #pe-saved-link {
        flex: 1 1 100%;
    }
}

/* G1-06: card popovers (season/matchup selects, calendars) must layer above
   the sticky profile section-nav while open. */
#pp-controls-card:has(.Select.is-open),
#pp-controls-card:has(.DateRangePicker_picker) {
    position: relative;
    z-index: 40;
}

/* G2-13: copy confirmation. */
.bsg-copied-note {
    color: var(--color-accent, #e05a2b);
    font-size: 0.78rem;
    font-weight: 700;
    opacity: 0;
    transition: opacity 0.25s ease;
    white-space: nowrap;
}

/* G2-46: every ✕ dismiss/remove control is a real 44px target. */
#pe-save-view-close,
#pe-mobile-close, #ps-mobile-close, #pt-mobile-close, #pc-mobile-close,
#pe-howto-mobile-close, #nav-drawer-close,
button[id*="chip-remove"],
button[id*="pe-del-view"] {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* G2-45: at 768-1023 the Risers/Fallers segmented pills sat ON the ROTO+
   header title — hide them there (full sort/filter still available); they
   return at lg where the header has room. */
@media (max-width: 1023.98px) {
    #pe-grid .ag-header-cell .trend-header-controls {
        display: none !important;
    }
}

/* G2-47: dcc.Tabs stacks tabs vertically below its internal 800px breakpoint —
   at 768-799.98 force the single scrollable row (phones use the dropdown). */
@media (min-width: 768px) and (max-width: 833.98px) {
    .pe-view-tabs {
        display: flex !important;
        flex-direction: row !important;
        flex-wrap: nowrap !important;
        overflow-x: auto;
    }
    .pe-view-tabs .tab {
        width: auto !important;
        flex: 0 0 auto !important;
        border-bottom: none;
    }
}

/* G2-16: chase quadrants get visible separators. */
.pp-zone-frame {
    gap: 2px;
    background: rgba(255, 255, 255, 0.18);
}
/* G2-17: real two-column zone layout — caption column takes the freed width. */
.pp-zone-caption {
    max-width: 46ch;
    flex: 1 1 280px;
}

/* G2-18: react-dates weekday header row rendered invisible (zero-height
   band above a calendar starting mid-row). */
.DayPicker_weekHeader {
    color: var(--text-secondary, #9aa2ad);
}
.DayPicker_weekHeader small {
    color: var(--text-secondary, #9aa2ad);
    font-size: 11px;
}

/* G2-32: splits/comparison metric column stays pinned whenever the table
   scrolls sideways — 768/1024 included (was phone-only). */
@media (max-width: 1023.98px) {
    #ps-splits-grid .pc-metric-sticky,
    #pc-comparison-bars .pc-metric-sticky {
        position: sticky;
        left: 0;
        z-index: 20;
        background: var(--card-bg);
        padding-right: 6px;
    }
}

/* G2-33: date-range inputs stopped truncating ("Mar 2...") at mid widths —
   tighter type + let each input flex instead of fixed halves. */
@media (max-width: 1180px) {
    .DateInput {
        width: 46%;
    }
    .DateInput_input {
        font-size: 0.72rem;
        padding: 8px 4px 6px;
        letter-spacing: -0.01em;
    }
    .DateRangePickerInput_arrow {
        padding: 0 2px;
    }
}

/* G2-14: stale content dims while its section refreshes (the dcc.Loading
   overlay wrapper carries data-dash-is-loading on the children). */
[data-dash-is-loading="true"]:not(.bsg-loading):not(.loading-status) {
    opacity: 0.45;
    transition: opacity 0.2s ease;
}

/* G2-30: winner-ringed raw values were ellipsizing their units at 390/768 —
   let values wrap to a second line instead of truncating. */
@media (max-width: 1023.98px) {
    #pc-comparison-bars .pc-raw-value,
    #pc-comparison-bars [class*="tabular-nums"] {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        line-height: 1.15;
    }
}

/* G2-34: FTA Load-a-League row — one 44px control height, one baseline. */
#fta-league-input,
.fta-load-row .Select-control,
.fta-load-row input,
.fta-load-row button {
    height: 44px !important;
    min-height: 44px;
}

/* G2-34: single control height for the FTA load row. */
.fta-ctl { height: 44px; }
.fta-dd .Select-control { height: 44px !important; min-height: 44px; }
.fta-dd .Select-placeholder, .fta-dd .Select-value { line-height: 42px !important; }

/* G2-37: visible form labels (placeholder-only purpose vanished once filled). */
.auth-label {
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary, #9aa2ad);
    margin: 10px 0 4px;
}

/* ---- G3 polish batch ---- */

/* G3-01: the roster Clear control reads as part of the row.
   R9: display comes from the base reveal rule (only when a league is
   loaded) — the unconditional inline-flex here painted an empty-state
   "Clear" squeezed inside the base 26px oval at every viewport. */
.chat-roster-clear--labeled {
    width: auto;
    height: auto;
    align-items: center;
    font-size: 0.78rem;
    padding: 6px 12px;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.15);
}

/* G3-03: leader names flex; the sparkline/value columns hold their width. */
.home-snapshot-name {
    max-width: none !important;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.home-snapshot-dir { font-size: 12px; }  /* G3-05: bigger direction glyphs */

/* G3-04: the Profiles card's search control dresses like its sibling CTAs. */
#home-player-profile-search .Select-control {
    background: rgba(var(--accent-rgb, 224, 90, 43), 0.85) !important;
    border-color: transparent !important;
    border-radius: 9999px !important;
}
#home-player-profile-search .Select-placeholder {
    color: #fff !important;
    font-weight: 600;
}

/* G3-46: chat ordered lists keep their rank numbers. */
.chat-markdown ol {
    list-style: decimal;
    padding-left: 1.4em;
}
.chat-markdown ul {
    list-style: disc;
    padding-left: 1.4em;
}

/* G3-16: header tooltips read as cards, and never linger on touch. */
.ag-tooltip {
    background: #16191f !important;
    border: 1px solid rgba(255, 255, 255, 0.14) !important;
    border-radius: 8px;
    color: var(--text-primary, #e8eaed) !important;
    max-width: 320px;
    padding: 8px 10px !important;
}
@media (pointer: coarse) {
    .ag-tooltip { display: none !important; }
}

/* G3-14 handled in python (tooltip on drag only). G3-15: the Filters drawer
   is a PANEL above phone widths — capped, edged, with visible backdrop. */
@media (min-width: 640px) and (max-width: 1023.98px) {
    #pe-controls-offcanvas > div:last-child,
    #pt-controls-offcanvas > div:last-child,
    #ps-controls-offcanvas > div:last-child,
    #pc-controls-offcanvas > div:last-child {
        max-width: 460px;
        border-right: 1px solid rgba(255, 255, 255, 0.14);
        box-shadow: 24px 0 60px rgba(0, 0, 0, 0.45);
    }
}

/* G3-13: tighter above-grid chrome + slimmer stat columns on phones. */
@media (max-width: 480px) {
    #pe-table-zone .p-4 { padding: 10px; }
    #pe-table-zone .mb-3 { margin-bottom: 8px; }
}

/* G3-17: the profile section-nav hints at overflow. */
.pp-section-nav.rt-has-overflow,
.pp-section-nav {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 22px), rgba(0,0,0,0.2) 100%);
    mask-image: linear-gradient(90deg, #000 calc(100% - 22px), rgba(0,0,0,0.2) 100%);
}
@media (min-width: 480px) {
    .pp-section-nav { -webkit-mask-image: none; mask-image: none; }
}
@media (max-width: 479.98px) {
    .pp-secnav-pill { padding: 6px 10px; font-size: 0.78rem; }
}

/* G3-18: stats tabs wrap tighter at desktop. */
@media (min-width: 1024px) {
    #pp-stats-tabs .tab { padding: 8px 10px !important; }
}

/* G3-21: insight-chip tokens hold together; chips wrap between, not within. */
.es-insight-chip, [class*="insight"] .chip {
    white-space: nowrap;
}

/* G3-34: comparison drawer breathing room under the sticky Apply; solid app
   bar over data tables at tablet widths (bars ghosted through the blur). */
#pc-controls-offcanvas .overflow-y-auto { padding-bottom: 96px; }
@media (max-width: 1099.98px) {
    #app-navbar { background: var(--dark-bg, #0b0d11); }
}

/* G3-37: the right-edge fade lifts once you've scrolled to the end. */
.rt-has-overflow.rt-at-end {
    -webkit-mask-image: none;
    mask-image: none;
}

/* G3-48: chat empty-state clears the floating input bar. */
@media (max-width: 640px) {
    .chat-empty, .chat-hero, .chat-scroll > :last-child {
        padding-bottom: 110px;
    }
}

/* G3-50: chat league combobox matches home's width instead of spanning
   the full 860px column. */
#chat-saved-league-dd {
    max-width: 560px;
}

/* G3-24: brand-cased stat labels escape the uppercase transform. */
.pp-keystat-label--brand {
    text-transform: none !important;
}
/* G3-20: disabled watch button pre-load. */
.pp-watch-btn--disabled {
    opacity: 0.55;
    pointer-events: none;
}

/* G3-30: trends chart card hugs its content on small screens; the loading
   caption centers in the visible card. */
@media (max-width: 767.98px) {
    #pt-chart, #pt-chart-empty { height: 52vh !important; min-height: 300px; }
}
@media (min-width: 768px) and (max-width: 1023.98px) {
    #pt-chart, #pt-chart-empty { height: 60vh !important; }
}

/* R4-05: watchlist scope pill. */
.pe-watchlist-pill {
    display: inline-flex;
    align-items: center;
}
.pe-watchlist-pill-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    padding: 4px 12px;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-secondary, #9aa2ad);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.pe-watchlist-pill-label::before {
    content: "★";
    font-size: 0.85rem;
}
.pe-watchlist-pill:has(input:checked) .pe-watchlist-pill-label,
.pe-watchlist-pill-label:has(input:checked) {
    color: #fff;
    border-color: rgba(var(--accent-rgb, 224, 90, 43), 0.7);
    background: rgba(var(--accent-rgb, 224, 90, 43), 0.16);
}
.pe-watchlist-pill input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

/* R4-07: league-anchor sub-values in the arsenal table. */
.at-lg-sub {
    font-size: 0.68rem;
    color: var(--text-secondary, #9aa2ad);
    opacity: 0.85;
    line-height: 1.1;
}

/* R4-01: three zone charts side by side — each block sizes its own frame. */
.pp-zone-block .pp-zone-frame {
    width: 100%;
    max-width: 320px;
}
@media (max-width: 360px) {
    .pp-zone-n { display: none; }
    .pp-zone-rate { font-size: 0.85rem; }
}

/* R8: "Which split is better" lead chips — pill per lead, ramp dot carries
   the winning split's QUALITY (red = elite, blue = poor), winner-ness
   itself is never a ramp or accent color. */
.ps-lead-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 9999px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.04);
    font-size: 0.78rem;
    line-height: 1.25;
    white-space: nowrap;
}

.ps-lead-dot {
    width: 9px;
    height: 9px;
    border-radius: 9999px;
    flex: none;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}

/* ---- R9: Ask the Guru hero redesign ---- */

/* Kill the double chrome: the global input[type=text] card background +
   border painted a second bordered box INSIDE the gradient ask pill (and a
   second focus ring inside the pill glow). */
.guru-hero-ask .guru-hero-input,
.guru-hero-ask .guru-hero-input:focus {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
}

/* R9b: one helper line carries the subtitle AND the tier badge. */
.guru-hero-subtitle {
    margin: 0 0 10px;
    font-size: 0.88rem;
    color: var(--text-secondary, #9ba1ad);
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 2px 4px;
}

/* Example chips get explicit affordances: capability icon + arrow. */
.guru-hero-sample-icon {
    flex: none;
    font-size: 0.85em;
    color: rgba(var(--accent3-rgb), 0.9);
}

.guru-hero-sample-text {
    min-width: 0;
}

.guru-hero-sample-go {
    flex: none;
    font-size: 0.8em;
    opacity: 0.55;
    margin-left: 6px;
}

.guru-hero-sample {
    gap: 8px;
}

/* League connector: progressive disclosure. */
.guru-hero-league-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 6px auto 0;  /* R9b */
    padding: 6px 14px;
    min-height: 36px;
    border: none;
    border-radius: 9999px;
    background: transparent;
    color: var(--text-secondary, #9ba1ad);
    font-size: 0.85rem;
    cursor: pointer;
    transition: color 0.16s ease, background 0.16s ease;
}

.guru-hero-league-toggle:hover {
    color: var(--text-primary, #e8eaed);
    background: rgba(255, 255, 255, 0.05);
}

.guru-hero-league-chev {
    transition: transform 0.16s ease;
}

.guru-hero-league-toggle--open .guru-hero-league-chev {
    transform: rotate(180deg);
}

.guru-hero-league-wrap {
    display: none;
}

.guru-hero-league-wrap--open {
    display: block;
}

/* R9 mobile chips: proven assistant pattern (Perplexity / ChatGPT mobile) —
   a vertical stack of full-width tappable rows, icon left, one-line
   ellipsized question, arrow right. Nothing hides off-canvas and every row
   clears the 44px touch target. */
@media (max-width: 767.98px) {
    .guru-hero-samples {
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 8px;
        overflow: visible;
        padding-bottom: 0;
    }

    .guru-hero-sample {
        flex: none;
        width: 100%;
        max-width: 100%;
        min-height: 48px;
        justify-content: flex-start;
        text-align: left;
        white-space: nowrap;
        padding: 10px 14px;
    }

    .guru-hero-sample-text {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .guru-hero-sample-go {
        margin-left: auto;
    }

    /* 40px was just under the touch-target floor. */
    .guru-hero-go-btn {
        min-width: 44px;
        min-height: 44px;
    }
}

/* R9b: economical desktop chips — one-line ellipsized pills (~40px) instead
   of two-line 73px cards; the full question still travels in the href and
   the title tooltip. */
@media (min-width: 768px) {
    .guru-hero-sample {
        white-space: nowrap;
        justify-content: flex-start;
        text-align: left;
        padding: 8px 14px;
    }

    .guru-hero-sample .guru-hero-sample-text {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .guru-hero-sample .guru-hero-sample-go {
        margin-left: auto;
    }
}

/* R9b: phones — tighter heading + rows. */
@media (max-width: 767.98px) {
    .guru-hero {
        padding: 16px 14px;
    }

    .guru-hero-sample {
        min-height: 44px;
        padding: 8px 12px;
    }

    .guru-hero-samples {
        gap: 6px;
    }
}

/* R9b: the separator orphans onto the wrapped badge line on phones. */
@media (max-width: 767.98px) {
    .guru-hero-subtitle-sep {
        display: none;
    }
}

/* R9c: give the one-line example pills more breathing room on desktop —
   the inner column stays 900px for everything else (ask pill and league
   row are self-capped at 640px), so only the chips row widens. Height is
   untouched: pills stay single-line. */
@media (min-width: 768px) {
    .guru-hero-inner {
        max-width: 1420px;  /* R9d: +260 again (900 -> 1160 -> 1420) */
    }
}

/* R9c: condensed prompt box — one compact line at rest; guru_hero.js grows
   it with the text (max ~4 lines). The chrome overrides mirror the input
   fix above so no global textarea styling paints a box-in-a-box. */
.guru-hero-ask .guru-hero-input,
.guru-hero-ask .guru-hero-input:focus {
    resize: none;
    overflow-y: hidden;
    line-height: 1.35;
    padding: 8px 2px;
    min-height: 0;
    height: auto;
    font-family: inherit;
}

.guru-hero-ask {
    padding: 6px 6px 6px 16px;
    align-items: flex-end; /* send button hugs the last line as the box grows */
}

.guru-hero-ask .guru-hero-ask-icon {
    align-self: center;
}

@media (min-width: 768px) {
    .guru-hero-go-btn {
        width: 36px;
        height: 36px;
    }
}

/* ---- R11 design-system batch ---- */

/* R11-26: surface ladder tokens — elevation on dark = luminance steps plus
   a hairline, not black shadows (Linear/Vercel). Overlays (menus, modals)
   keep their shadows; in-flow cards use these. */
:root {
    --surface-0: var(--dark-bg, #0e1117);
    --surface-1: var(--card-bg, #161920);
    --surface-2: rgba(255, 255, 255, 0.04);
    --hairline: 1px solid rgba(255, 255, 255, 0.08);
}

/* R11-24: global tabular numerals — numbers align in every table, grid and
   stat tile (Geist: "prefer tabular figures when numbers need to align").
   Replaces the two isolated usages found by the round-3 sweep. */
table td,
table th,
.ag-cell,
.ag-header-cell,
.dash-cell,
.stat-value,
.pp-pct-bubble,
.ps-splits-raw,
.ps-splits-delta {
    font-variant-numeric: tabular-nums;
}

/* R11-28: no-matches empty-state variant. */
.empty-state-constraint {
    font-size: 0.82rem;
    color: var(--text-secondary, #9ba1ad);
    margin: -4px 0 6px;
}

/* R11-29: motion hygiene — shimmer/pulse loops off for users who asked. */
@media (prefers-reduced-motion: reduce) {
    .skeleton,
    .skeleton-row,
    .bsg-busy-bar,
    .chat-pending-avatar {
        animation: none !important;
    }

    html {
        scroll-behavior: auto !important;
    }
}

/* R11-5: 50th-percentile tick on every track (Savant) — average is a
   visible anchor, not an implicit midpoint. Sits above the fill, below
   the marker. */
.pp-pct-track {
    position: relative;
}

.pp-pct-track::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 15%;
    bottom: 15%;
    width: 2px;
    margin-left: -1px;
    border-radius: 1px;
    background: rgba(255, 255, 255, 0.35);
    pointer-events: none;
    z-index: 1;
}

.pp-pct-marker {
    z-index: 2;
}

/* R11-6: NOT QUALIFIED — diagonal hatch keeps the row in position with an
   explicit reason instead of an em-dash void. */
.pp-pct-track--nq {
    background: repeating-linear-gradient(45deg,
        rgba(255, 255, 255, 0.04) 0 6px,
        rgba(255, 255, 255, 0.10) 6px 12px);
}

.pp-pct-track--nq::after {
    display: none;
}

.pp-pct-track--nq .pp-pct-fill {
    display: none;
}

.pp-pct-track--nq .pp-pct-marker {
    display: none;
}

/* R11-13: qualified threshold input — compact, pill-adjacent. */
.pe-qualified-min {
    width: 64px;
    padding: 4px 8px;
    border-radius: 8px;
    font-size: 0.75rem;
    background: var(--card-bg) !important;
    border: 1px solid var(--border-color) !important;
    color: var(--text-primary);
}

/* ---- R14: My Profile collections (watchlist + saved views) ---- */
.pf-collection-rows {
    display: flex;
    flex-direction: column;
    border: var(--hairline);
    border-radius: 10px;
    overflow: hidden;
}

.pf-collection-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    min-height: 48px;
    background: var(--card-bg, #161920);
    transition: background 0.12s ease;
}

.pf-collection-row + .pf-collection-row {
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.pf-collection-row:hover {
    background: rgba(255, 255, 255, 0.04);
}

.pf-collection-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: baseline;
    gap: 8px;
    color: var(--text-primary, #e8eaed);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pf-collection-main:hover {
    color: var(--accent-color, #6b8aff);
}

.pf-collection-meta {
    font-size: 0.72rem;
    color: var(--text-secondary, #9ba1ad);
    flex: none;
}

.pf-wl-headshot {
    width: 32px;
    height: 32px;
    border-radius: 9999px;
    object-fit: cover;
    flex: none;
    background: rgba(255, 255, 255, 0.06);
}

.pf-view-glyph {
    color: var(--text-secondary, #9ba1ad);
    flex: none;
    width: 32px;
    text-align: center;
}

.pf-view-open {
    flex: none;
    display: inline-flex;
    align-items: center;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--accent-color, #6b8aff);
    padding: 6px 10px;
    border-radius: 8px;
    border: 1px solid rgba(var(--accent-rgb), 0.35);
}

.pf-view-open:hover {
    background: rgba(var(--accent-rgb), 0.12);
}

.pf-collection-del {
    flex: none;
    /* 44px touch target on phones; visually compact. */
    width: 36px;
    height: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.pf-collection-empty {
    padding: 18px 14px;
    color: var(--text-secondary, #9ba1ad);
    font-size: 0.9rem;
}

.pf-wl-dd .Select-control,
.pf-wl-dd .Select__control {
    min-height: 44px;
}

@media (max-width: 640px) {
    .pf-collection-del {
        width: 44px;
        height: 44px;
    }

    .pf-view-open {
        padding: 10px 12px;
    }
}

/* R14: touch-floor overrides — the base .pf-icon-btn 32px box loses to the
   44px phone floor, and the search input must be >=16px to stop iOS zoom. */
@media (max-width: 640px) {
    .pf-collection-row .pf-icon-btn.pf-collection-del {
        width: 44px !important;
        height: 44px !important;
    }

    .pf-wl-dd input,
    .pf-wl-dd .Select-placeholder,
    .pf-wl-dd .Select__placeholder {
        font-size: 16px !important;
    }
}

/* R14b: lift the watchlist card above its sibling profile cards while the
   add-player menu is open — backdrop-filter makes every .profile-section a
   stacking context, so the menu's 10061 z-index can never escape the card
   on its own (same failure class as .pt-overlay-card, custom.css ~531). */
.profile-section:has(.pf-wl-dd .is-open),
.profile-section:has(.pf-wl-dd.is-open),
.profile-section:has(.pf-wl-dd .Select--is-open),
.profile-section:has(.pf-wl-dd .Select__control--menu-is-open) {
    position: relative;
    z-index: var(--overlay-search-z, 10060);
}
