/* ============================================
   EasyFPL — Sidebar nav + flyout sub-nav + palette
   Scoped entirely to .v2-theme (set on <html> by every page using this
   design) — does not affect any other page sharing common.css.
   ============================================ */

:root {
    --v2-sidebar-w: 232px;
    --v2-sidebar-w-collapsed: 76px;
    --v2-page-title-size: clamp(56px, 7.5vw, 104px);
    --v2-page-title-spacing: -6px;
    --v2-page-gutter: 32px;
    --v2-page-title-top: 40px;
}

/* V2 uses one typeface throughout. This also catches older page-specific and
   dynamically rendered rules that still name Space Grotesk, Georgia, etc. */
html.v2-theme body,
html.v2-theme body * {
    font-family: var(--font-body) !important;
}

/* Keep every tool-page heading on the same grid as the dashboard greeting. */
.v2-theme .v2-main-content > main.main-content,
.v2-theme .v2-main-content > main.content {
    max-width: 1440px !important;
    padding-top: var(--v2-page-title-top) !important;
    padding-right: var(--v2-page-gutter) !important;
    padding-left: var(--v2-page-gutter) !important;
}

.v2-theme .news-page-header {
    max-width: 1440px !important;
    padding: var(--v2-page-title-top) var(--v2-page-gutter) 0 !important;
}

.v2-theme .v2-page-hint {
    display: flex;
    align-items: center;
    min-height: 36px;
    margin: 0 0 14px;
    padding: 8px 14px;
    border: 1px solid rgba(96, 165, 250, 0.15);
    border-radius: var(--radius-md);
    background: rgba(96, 165, 250, 0.06);
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.4;
}

.v2-theme .v2-page-heading {
    font-family: var(--font-display) !important;
    font-size: var(--v2-page-title-size) !important;
    line-height: 0.95 !important;
    font-weight: 600 !important;
    letter-spacing: var(--v2-page-title-spacing) !important;
    color: var(--color-primary-muted) !important;
    opacity: 1;
}

@media (max-width: 768px) {
    :root {
        --v2-page-title-size: clamp(46px, 13vw, 64px);
        --v2-page-gutter: 20px;
        --v2-page-title-top: 28px;
    }
}

/* The page shell owns navigation animation. Disabling the browser snapshot
   transition prevents a second full-page fade from washing over it. */
@view-transition {
    navigation: none;
}

::view-transition-group(root) {
    animation: none;
}

::view-transition-old(root) {
    animation: none;
    mix-blend-mode: normal;
}

::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
}

html.v2-theme-transition::view-transition-old(root) {
    animation: v2-theme-old 620ms cubic-bezier(0.22, 1, 0.36, 1) both;
    mix-blend-mode: normal;
}

html.v2-theme-transition::view-transition-new(root) {
    animation: v2-theme-new 620ms cubic-bezier(0.22, 1, 0.36, 1) both;
    mix-blend-mode: normal;
}

@keyframes v2-theme-old {
    from { opacity: 1; }
    to { opacity: 0; }
}

@keyframes v2-theme-new {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Reserve the final layout before sidebar-nav.js starts the reveal. This is
   what prevents already-visible content from blinking out and back in. */
.v2-theme body:not(.v2-sequence-ready) .v2-page-heading,
.v2-theme body:not(.v2-sequence-ready) .v2-main-content > .tabs-container,
.v2-theme body:not(.v2-sequence-ready) .v2-main-content > .ticker-bar,
.v2-theme body:not(.v2-sequence-ready) .v2-main-content > .news-strip,
.v2-theme body:not(.v2-sequence-ready) .v2-main-content > .price-ticker-bar,
.v2-theme body:not(.v2-sequence-ready) main.main-content > *:not(.header-row):not(.loading-overlay),
.v2-theme body:not(.v2-sequence-ready) main.content > *:not(.v2-page-heading),
.v2-theme body:not(.v2-sequence-ready) .hero-banner .hero-inner > *,
.v2-theme body:not(.v2-sequence-ready) #newsDisplay {
    opacity: 0;
}

/* Shared staged page entrance. Elements are marked by sidebar-nav.js only
   after the sidebar and the page shell both exist, preventing partial paints. */
.v2-enter-sidebar,
.v2-enter-topbar,
.v2-enter-heading,
.v2-enter-block {
    opacity: 0;
    will-change: opacity;
}

.v2-enter-topbar {
    transform: translateY(-6px);
    will-change: opacity, transform;
}

.v2-sequence-ready .v2-enter-sidebar {
    animation: v2-sidebar-enter 720ms cubic-bezier(0.22, 1, 0.36, 1) 20ms both;
}

.v2-sequence-ready .v2-enter-topbar {
    animation: v2-topbar-enter 760ms cubic-bezier(0.22, 1, 0.36, 1) 180ms both;
}

.v2-sequence-ready .v2-enter-heading {
    animation: v2-content-enter 800ms cubic-bezier(0.22, 1, 0.36, 1) 320ms both;
}

.v2-sequence-ready .v2-enter-block {
    animation: v2-content-enter 860ms cubic-bezier(0.22, 1, 0.36, 1)
        calc(480ms + (var(--v2-enter-order, 0) * 90ms)) both;
}

/* Content arriving from an API joins the sequence at once rather than waiting
   through the shell's initial delay again. */
.v2-sequence-ready .v2-enter-block.v2-enter-late {
    animation-delay: calc(40ms + (var(--v2-enter-order, 0) * 80ms));
}

@keyframes v2-sidebar-enter {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes v2-topbar-enter {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes v2-content-enter {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Older page styles contain their own entrance animations. The shared shell
   replaces them on V2 pages so panels never animate twice. */
.v2-theme .my-team-dashboard-top,
.v2-theme .squad-alerts-panel,
.v2-theme .transfer-rec,
.v2-theme .verdict-section,
.v2-theme .lo-section,
.v2-theme .ts-section,
.v2-theme .na-section,
.v2-theme .so-section,
.v2-theme .ta-section {
    animation: none !important;
}

/* Players and Teams already reserve their final layout with skeleton content.
   Their legacy full-viewport loaders covered that layout during navigation and
   caused the pale/blank flash visible in recordings. */
.v2-theme .v2-main-content > .loading-overlay {
    background: transparent !important;
    backdrop-filter: none !important;
    pointer-events: none !important;
}

@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(root),
    ::view-transition-old(root),
    ::view-transition-new(root) { animation: none; }

    html.v2-theme-transition::view-transition-old(root),
    html.v2-theme-transition::view-transition-new(root) {
        animation: none !important;
    }

    .v2-enter-sidebar,
    .v2-enter-topbar,
    .v2-enter-heading,
    .v2-enter-block {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
}

/* ===== NEW COLOR PALETTE (values only — same variable names as common.css,
   so every existing component picks these up automatically) ===== */
.v2-theme {
    --surface-bg: #EAEAE8;
    --surface-0: #FFFFFF;
    --surface-1: #FFFFFF;
    --surface-2: #F1F1EF;
    --surface-3: #E6E6E3;
    --surface-4: #D3D3D3;

    --color-primary: #10B981;
    --color-primary-hover: #059669;
    --color-primary-muted: rgba(16, 185, 129, 0.10);
    --color-primary-glow: rgba(16, 185, 129, 0.25);
    --color-primary-text: #065F46;

    --text-primary: #100F0F;
    --text-secondary: #636363;
    /* Was #A4A4A4 — 2.49:1 on white, barely half the 4.5:1 WCAG AA needs for
       body text, on the theme that ships by default. Darkened until it clears
       AA on the surfaces it actually sits on (white 5.49, surface-2 4.85,
       page background 4.56). It now sits closer to --text-secondary than a
       'muted' token ideally would; legibility is the better trade.
       Known residual: on --surface-3 (#E6E6E3) this reads 4.39:1, just under
       the 4.5 bar. Going darker would make it indistinguishable from
       --text-secondary (#636363), so the small badges that pair the two are
       left at 4.39 rather than collapsing the hierarchy for 0.11. */
    --text-muted: #696969;

    --border-subtle: #EDEDEB;
    --border-default: transparent;
    --border-emphasis: #E4E4E1;
    --shadow-sm: 0 1px 2px rgba(17, 15, 15, 0.05), 0 1px 3px rgba(17, 15, 15, 0.06);

    /* New secondary accent (maroon) — not in the base palette, used for
       featured/highlight moments (banners, star badges). */
    --color-accent-2: #7A2233;
    --color-accent-2-hover: #631B29;
    --color-accent-2-muted: rgba(122, 34, 51, 0.10);
    --color-accent-2-text: #7A2233;
}

.v2-theme[data-theme="dark"] {
    --surface-bg: #15191F;
    --surface-0: #15191F;
    --surface-1: #1B2027;
    --surface-2: #232A33;
    --surface-3: #2E3742;
    --surface-4: #3A4552;

    --color-primary: #00E57D;
    --color-primary-hover: #2AED97;
    --color-primary-muted: rgba(0, 229, 125, 0.14);
    --color-primary-glow: rgba(0, 229, 125, 0.28);
    --color-primary-text: #00E57D;
    --color-success: #00E57D;
    --color-warning: #FFB000;
    --color-error: #FF4D5A;
    --color-info: #939CAA;

    --text-primary: #F4F5F7;
    --text-secondary: #C5CBD4;
    /* Cleared AA on the base surfaces but fell to 4.35:1 on surface-3 and
       3.52:1 on surface-4, which small badges do use. Lifted to pass on both. */
    --text-muted: #A8B1BF;

    --border-subtle: #20262E;
    --border-default: transparent;
    --border-emphasis: #303944;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.3);

    --color-accent-2: #C1495F;
    --color-accent-2-hover: #D4738A;
    --color-accent-2-muted: rgba(193, 73, 95, 0.18);
    --color-accent-2-text: #D4738A;
}

/* ===== SIDEBAR SHELL ===== */
.v2-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: var(--v2-sidebar-w);
    background: var(--surface-0);
    border-right: 1px solid var(--border-default);
    display: flex;
    flex-direction: column;
    padding: 20px 14px;
    gap: 20px;
    z-index: 50;
    overflow-y: visible;
}

.v2-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    flex-shrink: 0;
}

.v2-sidebar-logo {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 8px;
    font-family: var(--font-display);
    font-size: 18px;
    font-weight: 600;
    color: var(--text-primary);
    text-decoration: none;
    flex-shrink: 0;
}

.v2-sidebar-logo .icon {
    width: 20px;
    height: 20px;
    color: var(--color-primary);
    flex-shrink: 0;
}

.v2-sidebar-logo b {
    color: var(--color-primary);
    font-weight: 600;
}

.v2-sidebar-collapse {
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 180ms ease, color 180ms ease;
}

.v2-sidebar-collapse:hover {
    background: var(--surface-2);
    color: var(--text-primary);
}

.v2-sidebar-collapse .icon {
    width: 17px;
    height: 17px;
}

.v2-sidebar-collapse .v2-expand-icon {
    display: none;
}

/* Width transitions are enabled only for a deliberate toggle click. Keeping
   them off during startup prevents the saved state from widening on load. */
.v2-sidebar-resizing .v2-sidebar {
    transition: width 480ms cubic-bezier(0.22, 1, 0.36, 1),
        padding 480ms cubic-bezier(0.22, 1, 0.36, 1);
}

.v2-sidebar-resizing .v2-main-content {
    transition: margin-left 480ms cubic-bezier(0.22, 1, 0.36, 1);
}

.v2-sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow: visible;
}

.v2-sidebar-group-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 0 10px;
    margin-bottom: 6px;
}

.v2-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 600;
    white-space: nowrap;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
    font-family: var(--font-body);
    position: relative;
}

.v2-nav-item .icon {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    color: var(--color-primary);
}

.v2-nav-item:hover {
    background: var(--surface-2);
    color: var(--text-primary);
}

.v2-nav-item.active {
    background: var(--color-primary-muted);
    color: var(--color-primary-text);
}

.v2-nav-item.active .icon {
    color: var(--color-primary);
}

.v2-nav-item.active::before {
    content: '';
    position: absolute;
    left: -9px;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 62%;
    border-radius: 0 4px 4px 0;
    background: var(--color-primary);
}

/* ===== FLYOUT SUB-NAV ===== */
.v2-nav-group {
    position: relative;
}

.v2-flyout-toggle {
    margin-left: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 2px;
    cursor: pointer;
    color: var(--text-muted);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}

.v2-flyout-toggle .icon {
    width: 14px;
    height: 14px;
    transition: transform 0.15s ease;
}

.v2-nav-group.open .v2-flyout-toggle .icon {
    transform: rotate(90deg);
}

.v2-flyout-toggle:hover {
    background: var(--surface-3);
}

.v2-flyout-panel {
    position: absolute;
    left: calc(100% + 10px);
    top: 0;
    min-width: 480px;
    background: var(--surface-1);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-lg);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
    padding: 14px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 4px 20px;
    opacity: 0;
    pointer-events: none;
    transform: translateX(-6px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 60;
}

.v2-nav-group.open .v2-flyout-panel {
    opacity: 1;
    pointer-events: auto;
    transform: translateX(0);
}

.v2-flyout-group-title {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 4px 8px;
}

.v2-flyout-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 8px;
    border-radius: var(--radius-md);
    text-decoration: none;
    color: var(--text-primary);
}

.v2-flyout-item:hover {
    background: var(--surface-2);
}

.v2-flyout-icon {
    width: 16px;
    height: 16px;
    color: var(--color-primary);
    flex-shrink: 0;
    margin-top: 1px;
}

.v2-flyout-name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
}

.v2-flyout-desc {
    display: block;
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 1px;
}

/* ===== SIDEBAR BOTTOM (team ID + theme toggle) ===== */
.v2-sidebar-bottom {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 14px;
    border-top: 1px solid var(--border-default);
    flex-shrink: 0;
}

.v2-sidebar-team-id #navTidInput {
    padding: 0 2px;
}

.v2-tid-form {
    display: flex;
    gap: 6px;
}

.v2-tid-form input {
    flex: 1;
    min-width: 0;
    padding: 7px 10px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-default);
    background: var(--surface-2);
    color: var(--text-primary);
    font-size: 12px;
}

.v2-sidebar-team-id #navTidBadge {
    padding: 0 2px;
}

.v2-sidebar-team-id .nav-tid-badge {
    width: 100%;
    justify-content: space-between;
}

.v2-theme-switch {
    width: 100%;
    height: 38px;
    padding: 4px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 3px;
    border: 1px solid var(--border-emphasis);
    border-radius: var(--radius-full);
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: pointer;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04);
    position: relative;
    overflow: hidden;
}

.v2-theme-switch::before {
    content: '';
    position: absolute;
    top: 4px;
    left: 4px;
    width: calc((100% - 11px) / 2);
    height: 28px;
    border-radius: var(--radius-full);
    background: var(--surface-0);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
    transform: translateX(calc(100% + 3px));
    transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1),
        background-color 260ms ease, box-shadow 260ms ease;
}

[data-theme="dark"] .v2-theme-switch::before {
    transform: translateX(0);
    background: #343D49;
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
}

.v2-theme-option {
    height: 28px;
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 260ms ease, background 260ms ease, box-shadow 260ms ease;
    position: relative;
    z-index: 1;
}

.v2-theme-option .icon {
    width: 15px;
    height: 15px;
}

html:not([data-theme="dark"]) .v2-theme-light,
[data-theme="dark"] .v2-theme-dark {
    color: var(--text-primary);
}

[data-theme="dark"] .v2-theme-switch {
    background: #202730;
    border-color: #343E4A;
}

[data-theme="dark"] .v2-theme-dark {
    color: var(--color-primary);
}

/* ===== MAIN CONTENT OFFSET ===== */
html.v2-theme body {
    background: var(--surface-0);
}

.v2-main-content {
    margin-left: var(--v2-sidebar-w);
    min-height: 100vh;
    background: linear-gradient(160deg, #DDEFE4 0%, #F1FAF5 48%, #FFFFFF 100%);
    background-clip: padding-box;
}
[data-theme="dark"] .v2-main-content {
    background: linear-gradient(160deg, #15191F 0%, #17201D 52%, #18241F 100%);
}

/* The shell used to be a rounded card with a 32px curve down its left edge,
   and the first marquee or tab strip inside it had to be given the same curve
   so it did not paint a square corner over one. It made the top-left of every
   dashboard page a notch — one rounded corner on a page that is otherwise all
   square edges, and the only place the gradient behind showed through. Square
   now, and there is nothing for a child to match. */

/* User-controlled desktop icon rail. */
.v2-sidebar-collapsed .v2-sidebar {
    width: var(--v2-sidebar-w-collapsed);
    padding: 20px 10px;
    align-items: center;
}

.v2-sidebar-collapsed .v2-sidebar-header {
    width: 100%;
    justify-content: center;
    gap: 2px;
}

.v2-sidebar-collapsed .v2-sidebar-logo {
    padding: 0;
}

.v2-sidebar-collapsed .v2-sidebar-logo span,
.v2-sidebar-collapsed .v2-nav-item > span,
.v2-sidebar-collapsed .v2-sidebar-group-label,
.v2-sidebar-collapsed .v2-sidebar-team-id {
    display: none;
}

.v2-sidebar-collapsed .v2-sidebar-bottom {
    width: 52px;
}

.v2-sidebar-collapsed .v2-theme-switch {
    height: 34px;
    padding: 3px;
    gap: 2px;
}

.v2-sidebar-collapsed .v2-theme-option {
    height: 26px;
}

.v2-sidebar-collapsed .v2-theme-switch::before {
    top: 3px;
    left: 3px;
    width: calc((100% - 8px) / 2);
    height: 26px;
    transform: translateX(calc(100% + 2px));
}

[data-theme="dark"].v2-sidebar-collapsed .v2-theme-switch::before {
    transform: translateX(0);
}

.v2-sidebar-collapsed .v2-theme-option .icon {
    width: 13px;
    height: 13px;
}

.v2-sidebar-collapsed .v2-nav-item {
    justify-content: center;
    padding: 10px;
    width: 44px;
}

.v2-sidebar-collapsed .v2-flyout-toggle {
    display: none;
}

.v2-sidebar-collapsed .v2-sidebar-collapse .v2-collapse-icon {
    display: none;
}

.v2-sidebar-collapsed .v2-sidebar-collapse .v2-expand-icon {
    display: block;
}

.v2-sidebar-collapsed .v2-main-content {
    margin-left: var(--v2-sidebar-w-collapsed);
}

/* ===== LIGHT CARD-AESTHETIC BOOST (scoped, doesn't touch other pages) ===== */
.v2-main-content .hss-card,
.v2-main-content .hero-squad-panel,
.v2-main-content .hero-deadline-banner,
.v2-main-content .rec-card,
.v2-main-content .route-card,
.v2-main-content .chart-card,
.v2-main-content .stats-container,
.v2-main-content .teams-grid > * {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
    border-radius: var(--radius-xl);
}

[data-theme="dark"] .v2-main-content .hss-card,
[data-theme="dark"] .v2-main-content .hero-squad-panel,
[data-theme="dark"] .v2-main-content .hero-deadline-banner,
[data-theme="dark"] .v2-main-content .rec-card,
[data-theme="dark"] .v2-main-content .route-card,
[data-theme="dark"] .v2-main-content .chart-card,
[data-theme="dark"] .v2-main-content .stats-container {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* ===== RESPONSIVE: icon-only rail on narrow screens ===== */
@media (max-width: 900px) {
    .v2-sidebar-collapse {
        display: none;
    }

    .v2-sidebar {
        width: var(--v2-sidebar-w-collapsed);
        padding: 20px 10px;
        align-items: center;
    }

    .v2-sidebar-logo span,
    .v2-nav-item span,
    .v2-sidebar-group-label {
        display: none;
    }

    .v2-nav-item {
        justify-content: center;
        padding: 10px;
        width: 44px;
    }

    .v2-flyout-toggle {
        display: none;
    }

    .v2-nav-group:hover .v2-flyout-panel {
        opacity: 1;
        pointer-events: auto;
        transform: translateX(0);
    }

    .v2-main-content {
        margin-left: var(--v2-sidebar-w-collapsed);
    }

    /* Team ID widget stays usable in collapsed mode — stacked, full-width
       within the narrow rail, instead of being hidden with no alternative. */
    .v2-tid-form {
        flex-direction: column;
    }

    .v2-tid-form input {
        width: 56px;
        font-size: 10px;
        padding: 5px 6px;
        text-align: center;
    }

    .v2-tid-form .btn {
        padding: 5px 6px;
        font-size: 11px;
    }

    .v2-sidebar-team-id .nav-tid-badge {
        flex-direction: column;
        align-items: center;
        gap: 2px;
        padding: 6px 4px;
        font-size: 9px;
    }
}

/* ===== STICKY-OFFSET FIX =====
   Several shared/page components are position:sticky with a hardcoded
   top offset sized to clear the old 56px .top-nav bar (e.g. tabs-container
   at top:56px, filter-bar at top:91px = 56 + tabs-container's own height).
   The sidebar layout has no top bar, so every one of these offsets is
   subtracted by exactly 56px here — preserving how they stack relative
   to each other, just removing the space that used to be reserved for
   the nav that no longer exists in this layout. */
.v2-main-content .tabs-container {
    top: 0;
}

.v2-main-content .tabs-container.tabs-hidden ~ .filter-bar {
    top: 0;
}

.v2-main-content .filter-bar {
    top: 35px; /* was 91px (56px nav + 35px tabs-container height) */
}

.v2-main-content .tw-budget-bar-top {
    top: 0;
}

.v2-main-content .tw-scout-col {
    top: 64px; /* was 120px (56px nav + 64px budget bar) */
}

/* ===== Touch targets =====
   Measured at a 500px viewport: seven classes of control rendered under the
   44px minimum, the worst being icon buttons at 18x18 and 22x15. Rather than
   inflate them visually, an ::after overlay extends the hit area beyond the
   painted box — the control looks identical and the thumb gets a real target.
   Pointer-coarse only, so mouse layouts are untouched. */
@media (pointer: coarse), (max-width: 767px) {
    .nav-tid-change,
    .v2-theme-switch,
    .footer-mail,
    .footer-links a { position: relative; }

    .nav-tid-change::after,
    .v2-theme-switch::after,
    .footer-mail::after,
    .footer-links a::after {
        content: ''; position: absolute; left: 50%; top: 50%;
        transform: translate(-50%, -50%);
        width: 100%; height: 44px; min-width: 44px;
    }

    .v2-nav-item { min-height: 44px; }
}

/* ============================================================
   CLEAN SURFACE PASS

   The dashboard had accumulated three habits that read as noise rather
   than information: a green wash behind every page, page titles at 104px
   in 10%-opacity green (a decorative ghost, not a heading), and cards that
   each announced themselves with a different coloured edge.

   The fix is to spend contrast where it carries meaning. The page ground
   goes flat and neutral so a white card is legible as a card; headings go
   solid and small so they read as labels; the accent green is reserved for
   state that matters — the active nav item, a sorted column, a positive
   number. Nothing here changes what any colour *means*: FDR scales,
   position colours and verdict pills are untouched.

   Everything is scoped to .v2-main-content or .v2-theme, so the one page
   that is not a dashboard — the logged-out landing on index.html — keeps
   its own look via the explicit exception below.
   ============================================================ */

:root {
    /* The ground a card sits on. Neutral, not tinted: a green wash under a
       white card leaves too little separation to see the card's edge. */
    --v2-ground: #F5F6F8;
    --v2-card-border: rgba(17, 24, 39, 0.07);
    --v2-card-radius: 16px;
    /* Two shadows doing separate jobs: a 1px contact shadow that defines the
       edge, and a wide, very soft ambient one that lifts the card off the
       ground without a visible grey halo. */
    --v2-card-shadow: 0 1px 2px rgba(16, 24, 40, 0.04),
                      0 10px 28px -14px rgba(16, 24, 40, 0.12);
}

[data-theme="dark"] {
    --v2-ground: #12161B;
    --v2-card-border: rgba(255, 255, 255, 0.07);
    --v2-card-shadow: 0 1px 2px rgba(0, 0, 0, 0.30),
                      0 10px 28px -14px rgba(0, 0, 0, 0.55);
}

/* ----- Page ground ----- */

.v2-main-content {
    background: var(--v2-ground);
}

[data-theme="dark"] .v2-main-content {
    background: var(--v2-ground);
}

/* The logged-out landing is not a dashboard page and is out of scope for
   this pass. It is the only place a .hero-banner appears without
   .hero-logged-in, so that absence identifies it without a new flag for
   index.html's state toggle to keep in sync. */
.v2-main-content:has(.hero-banner:not(.hero-logged-in)) {
    background: linear-gradient(160deg, #DDEFE4 0%, #F1FAF5 48%, #FFFFFF 100%);
}

[data-theme="dark"] .v2-main-content:has(.hero-banner:not(.hero-logged-in)) {
    background: linear-gradient(160deg, #15191F 0%, #17201D 52%, #18241F 100%);
}

/* ----- Headings -----
   The old title was clamp(56px, 7.5vw, 104px) in --color-primary-muted,
   which is green at 10% alpha — a watermark you read past rather than
   with. At 32px solid it is a heading again, and the ~70px of vertical
   space it gives back is the single largest source of the reference
   layouts' calm. */
:root {
    --v2-page-title-size: clamp(26px, 2.4vw, 32px);
    --v2-page-title-spacing: -0.5px;
    --v2-page-title-top: 32px;
}

@media (max-width: 768px) {
    :root {
        --v2-page-title-size: 24px;
        --v2-page-title-top: 24px;
    }
}

.v2-theme .v2-page-heading {
    line-height: 1.25 !important;
    font-weight: 650 !important;
    color: var(--text-primary) !important;
}

/* Lucide icons in a heading were sized against the old 104px title. */
.v2-theme .v2-page-heading .icon,
.v2-theme .v2-page-heading [data-lucide] {
    width: 22px;
    height: 22px;
    vertical-align: -3px;
    color: var(--color-primary);
}

/* Section headings inside a page: one step down from the page title, and
   the same size wherever they appear. Several pages had these at 22-28px,
   close enough to the page title to compete with it. */
.v2-main-content main h2,
.v2-main-content .section-title,
.v2-main-content .card-title {
    font-size: 17px;
    font-weight: 650;
    letter-spacing: -0.2px;
    line-height: 1.35;
    color: var(--text-primary);
}

/* ----- Cards -----
   One surface treatment, applied to the containers that were already
   carrying a card-like look with slightly different values each. */
.v2-main-content .hss-card,
.v2-main-content .hero-squad-panel,
.v2-main-content .hero-deadline-banner,
.v2-main-content .rec-card,
.v2-main-content .rec-card-v2,
.v2-main-content .route-card,
.v2-main-content .chart-card,
.v2-main-content .stats-container,
.v2-main-content .soft-card,
.v2-main-content .pp-card,
.v2-main-content .price-card,
.v2-main-content .rising-card,
.v2-main-content .swing-card,
.v2-main-content .tm-summary-card,
.v2-main-content .fx-split-card,
.v2-main-content .teams-grid > * {
    background: var(--surface-1);
    border: 1px solid var(--v2-card-border);
    border-radius: var(--v2-card-radius);
    box-shadow: var(--v2-card-shadow);
}

/* ----- Tables -----
   The bones were already right — 14px padding, small caps headers. What
   made them look busy was a filled grey header band and a 2px rule under
   it. A flat header on the card surface, one hairline, and a tinted hover
   row is enough structure to track a row across twenty columns. */
.v2-main-content .data-table thead th,
.v2-main-content table:not(.matrix-table) thead th {
    background: var(--surface-1);
    border-bottom: 1px solid var(--border-emphasis);
    color: var(--text-muted);
    font-size: 10.5px;
    letter-spacing: 0.6px;
    padding: 13px 16px;
}

.v2-main-content .data-table thead th:hover,
.v2-main-content table:not(.matrix-table) thead th:hover {
    background: var(--surface-2);
    color: var(--text-primary);
}

.v2-main-content .data-table td,
.v2-main-content table:not(.matrix-table) td {
    border-bottom: 1px solid var(--border-subtle);
}

/* The hover tint is the accent at 5% rather than a grey step: it reads as
   "this row is live" instead of "this row is disabled". */
.v2-main-content .data-table tbody tr:hover,
.v2-main-content table:not(.matrix-table) tbody tr:hover {
    background: color-mix(in srgb, var(--color-primary) 5%, transparent);
}

.v2-main-content .data-table tbody tr:hover td.col-player {
    background: color-mix(in srgb, var(--color-primary) 5%, var(--surface-1));
}

/* The frozen identity column sat on --surface-2, a visibly different grey
   from the rows it belongs to. */
.v2-main-content .data-table th.col-player {
    background: var(--surface-1);
}

/* The last row's hairline doubles up with the card edge below it. */
.v2-main-content .data-table tbody tr:last-child td,
.v2-main-content table:not(.matrix-table) tbody tr:last-child td {
    border-bottom: none;
}

/* ============================================================
   DASHBOARD FOOTER

   The four-column footer is a landing-page component: it exists to
   introduce the site to someone who has just arrived. Inside the dashboard
   it earns none of that height. The Tools column is a second copy of the
   sidebar the manager is already looking at, and the brand block introduces
   a product they are demonstrably already using. Three things survive
   because they still do work anywhere: where the data comes from, the two
   link groups that are *not* in the sidebar, and the legal + freshness line.

   It also stops being a dark slab. On a light dashboard #111827 was the
   heaviest element on the page and it sat under content it had nothing to
   do with; a hairline and the page ground put it in the same design as
   everything above it.

   Scoped away from the logged-out landing on index.html by the same
   hero-banner test used for the page ground above, so that page keeps the
   full footer it was designed with. Every rule carries the same prefix
   rather than being undone afterwards, so there is one description of the
   dashboard footer rather than two that have to agree.
   ============================================================ */

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .site-footer {
    background: transparent;
    /* No rule across the top. The footer already separates itself by sitting
       on the page ground below the last panel, and a full-width hairline under
       a row of cards reads as the start of something rather than the end. */
    border-top: none;
    color: var(--text-muted);
    margin-top: 36px;
    /* loadFooter() appends to <body>, outside .v2-main-content, so the
       footer does not inherit the main column's offset and would otherwise
       run underneath the fixed sidebar. */
    margin-left: var(--v2-sidebar-w);
}

.v2-sidebar-collapsed .site-footer {
    margin-left: var(--v2-sidebar-w-collapsed);
}

/* One row instead of a grid: badge on the left, link groups trailing right. */
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-top {
    max-width: 1440px;
    padding: 16px var(--v2-page-gutter);
    display: flex;
    align-items: center;
    gap: 12px 28px;
    flex-wrap: wrap;
}

/* The Learn/Company groups run inline — title, then its links as a row. */
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col {
    display: flex;
    align-items: center;
    gap: 8px 14px;
    flex-wrap: wrap;
    margin: 0;
}

/* After .footer-col, not before: the two carry equal specificity, so the
   one that hides has to be the one the cascade reaches last. */
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col--tools,
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-brand-name,
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-tagline {
    display: none;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col--learn {
    margin-left: auto;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col-title {
    margin: 0;
    font-size: 10px;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    opacity: 0.75;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-links {
    display: flex;
    /* common.css stacks these into a column for the tall landing footer. */
    flex-direction: row;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin: 0;
    list-style: none;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-links li {
    margin: 0;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-links a,
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-mail {
    font-size: 12px;
    color: var(--text-secondary);
    margin: 0;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-links a:hover,
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-mail:hover {
    color: var(--color-primary);
}

/* The API badge keeps its pill, at the size of the row it now sits in. */
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-api-badge {
    margin: 0;
    padding: 5px 12px;
    font-size: 11.5px;
    color: var(--color-primary-text);
    background: color-mix(in srgb, var(--color-primary) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-primary) 20%, transparent);
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-bottom {
    max-width: 1440px;
    padding: 12px var(--v2-page-gutter) 16px;
    border-top: 1px solid var(--border-subtle);
    font-size: 11.5px;
    color: var(--text-muted);
}

@media (max-width: 900px) {
    .v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .site-footer {
        margin-left: var(--v2-sidebar-w-collapsed);
    }

    .v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col--learn {
        margin-left: 0;
    }
}

/* ----- Footer: telling the categories from the links -----
   Inline, the group labels scanned as more links: "FAQ COMPANY Contact Us"
   read as one run. Three things separate them now — the labels are smaller,
   tracked wider and lower in contrast; the gap inside a group is tighter
   than the gap between groups; and a rule sits between the two groups so
   the boundary is drawn rather than implied.

   The email stops being a link with an icon stuck to it and becomes the
   pill it always was in intent — which also balances the row, since the
   API badge is the same shape at the other end of it. */

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col-title {
    font-size: 9.5px;
    font-weight: 700;
    /* common.css tracks everything matching [class*="title"] to -0.5px with
       !important. That rule is aimed at headings; a small-caps category label
       is the one place on the page that needs tracking to open up rather than
       tighten, and negative tracking is exactly what made these read as links.
       The original 1.5px in common.css was being overridden the same way. */
    letter-spacing: 0.12em !important;
    opacity: 0.55;
}

/* Tighter within a group than between groups: 12px against the row's 26px. */
.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col {
    gap: 8px 12px;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-links {
    gap: 12px;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col--company {
    border-left: 1px solid var(--border-emphasis);
    padding-left: 26px;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-mail {
    margin: 0 0 0 6px;
    padding: 5px 12px;
    border: 1px solid var(--border-emphasis);
    border-radius: var(--radius-full);
    background: var(--surface-1);
    color: var(--text-secondary);
    transition: border-color 160ms ease, color 160ms ease;
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-mail:hover {
    border-color: color-mix(in srgb, var(--color-primary) 40%, transparent);
    color: var(--color-primary);
}

.v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-mail .icon {
    width: 13px;
    height: 13px;
    opacity: 0.7;
}

/* The divider only makes sense while the groups sit side by side. */
@media (max-width: 900px) {
    .v2-theme body:not(:has(.hero-banner:not(.hero-logged-in))) .footer-col--company {
        border-left: none;
        padding-left: 0;
    }
}

/* ----- Section icons -----
   One small outline mark in front of each panel heading. The set is drawn in
   v2Icon() in common.js; this is only how it sits and how big it is.

   stroke-width is set here rather than left to each source, because these
   arrive two ways — inline from v2Icon() on panels that re-render, and from
   lucide on the static ones — and lucide's own default is 2. Normalising it
   in CSS is what keeps a heading rendered by JS and one written in HTML from
   drifting a quarter-pixel apart. */
.v2-main-content :is(.md-title, .mk-title, .eo-title, .v2-pitch-title, .v2-feed-title) {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.v2-sec-icon,
.v2-main-content :is(.md-title, .mk-title, .eo-title, .v2-pitch-title, .v2-feed-title) > svg {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    stroke-width: 1.8;
    /* The accent carries "this is a section", the same job the emoji does in
       the reference. It is the one place green appears without meaning good. */
    color: var(--color-primary);
}

/* ----- Top bars: grow into place instead of appearing under the cursor -----
   #tickerBar, #newsStrip and #priceTickerBar each start .hidden and drop that
   class independently, whenever their own data lands. Every one of them is
   display:none until that moment, so each arrival shoved the whole page down
   by its own height — three separate jolts of 30-32px, arriving over about a
   second, which is most of what reads as the dashboard loading "glitchy".

   Reserving the space up front would trade the jolt for up to ~94px of empty
   strip on a load where a bar never populates. Animating the height costs
   nothing in that case — a bar that never arrives stays at zero — and turns
   the ones that do arrive into a movement the eye can follow rather than a
   snap it can only notice after the fact. */
.v2-main-content > :is(.ticker-bar, .news-strip, .price-ticker-bar) {
    transition: height 300ms cubic-bezier(0.22, 1, 0.36, 1),
                opacity 300ms ease;
    will-change: height;
}

.v2-main-content > :is(.ticker-bar, .news-strip, .price-ticker-bar).hidden {
    /* .hidden is display:none !important in common.css — there is no way to
       animate out of that, so these three opt out of it and collapse instead. */
    display: flex !important;
    height: 0 !important;
    min-height: 0 !important;
    padding-top: 0;
    padding-bottom: 0;
    border-bottom-width: 0;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .v2-main-content > :is(.ticker-bar, .news-strip, .price-ticker-bar) {
        transition: none;
    }
}

/* ============================================================
   PLAYER IDENTITY — face, badge, position edge

   One set of marks, used by the dashboard pitch, the squad pitch, the draft
   planner, the lineup wizard and both transfer views. Drawn by v2IdentityHTML()
   in common.js.
   ============================================================ */

/* Two sizes are driven from here rather than being restated at every call
   site: a row wants the mark small and beside the name, a pitch card wants the
   face to be the card. Contexts override the two variables, nothing else. */
.v2-pid {
    --v2-pid-face: 30px;
    --v2-pid-crest: 18px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

.v2-pid-avatar {
    position: relative;
    width: var(--v2-pid-face); height: var(--v2-pid-face);
    border-radius: 50%;
    background: rgba(15, 23, 42, 0.06);
    overflow: hidden;
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
}

[data-theme="dark"] .v2-pid-avatar { background: rgba(255, 255, 255, 0.07); }

.v2-pid-initials {
    font-size: 11px;
    font-weight: 700;
    color: var(--text-muted);
}

/* The club photos are cut-outs on transparency framed head-and-shoulders, so
   the circle crops high rather than centring on the chest. */
.v2-pid-face {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 12%;
}

/* Only ever seen when no photo arrives — see .has-photo, set on load. */
.v2-pid-avatar.has-photo .v2-pid-initials { display: none; }

.v2-pid-crest {
    position: relative;
    width: var(--v2-pid-crest); height: var(--v2-pid-crest);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}

.v2-pid-crest img {
    position: relative; z-index: 1;
    width: 100%; height: 100%;
    object-fit: contain;
}

.v2-pid-crest-fallback {
    position: absolute; z-index: 0;
    font-size: 7.5px; font-weight: 700;
    color: var(--text-muted);
}

/* ===== The pitch form =====
   Face and club badge side by side, both larger than a row's. The portrait
   form below hangs the crest off the face's corner and puts the score on the
   other one, which reads well but leaves the number small and half over a
   photo — on a pitch the two figures you scan are the projection and the score,
   and they had become the least legible things on the card. Here the pair is
   the identity and nothing else, and the number gets a line of its own beneath
   at a size worth reading. */
.v2-pid-pitch {
    --v2-pid-face: 38px;
    --v2-pid-crest: 24px;
    gap: 6px;
    align-self: center;
}
.v2-pid-pitch .v2-pid-avatar {
    background: rgba(15, 23, 42, 0.07);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 1px 4px rgba(0, 0, 0, 0.16);
}
.v2-pid-pitch .v2-pid-initials { font-size: 13px; }

/* ===== The portrait form =====
   On a pitch card the face is the subject, not a bullet beside the name — so
   the mark grows and the crest stops taking half the row: it becomes a small
   disc overlapping the portrait's lower-right, the way a club badge sits on a
   shirt. The card gets its whole width back for the face and the name, and
   "who, and for whom" is still one glance.

   Applied by context, since the markup is the same v2IdentityHTML() everywhere.
   The initials underneath are unchanged and still carry the no-photo case. */
.v2-pid-portrait {
    --v2-pid-face: 46px;
    --v2-pid-crest: 21px;
    position: relative;
    display: block;
    /* Width plus a square ratio rather than width and height, so --v2-pid-face
       may be a percentage: the dashboard's cards are a percentage of the pitch
       and the face has to track them, or a tablet gets a 44px head on a 64px
       card. */
    width: var(--v2-pid-face);
    aspect-ratio: 1;
    margin: 0 auto;
}
.v2-pid-portrait .v2-pid-avatar {
    width: 100%; height: 100%;
    background: rgba(15, 23, 42, 0.07);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9), 0 2px 5px rgba(0, 0, 0, 0.18);
}
.v2-pid-portrait .v2-pid-initials { font-size: 14px; }
.v2-pid-portrait .v2-pid-crest {
    position: absolute;
    right: calc(var(--v2-pid-crest) * -0.19);
    bottom: calc(var(--v2-pid-crest) * -0.09);
    z-index: 2;
    border-radius: 50%;
    background: #fff;
    padding: 2px;
    box-sizing: content-box;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
}
.v2-pid-portrait .v2-pid-crest-fallback { font-size: calc(var(--v2-pid-crest) * 0.42); }

/* The other corner. A pitch card has one number worth scanning — what this
   player is projected to score, or what he actually scored — and below the
   name it was competing with the fixture for a line neither of them fitted on.
   As a pill on the portrait's lower-left it mirrors the crest, reads at a
   glance across a whole XI, and gives the row back. Cards opt in by putting
   their points element inside .v2-pid-portrait. */
.v2-pid-portrait .v2-pid-num {
    position: absolute;
    left: -5px;
    bottom: -2px;
    z-index: 2;
    display: inline-flex; align-items: baseline; gap: 1px;
    padding: 1px 5px;
    border-radius: 999px;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
    font-family: var(--font-mono, monospace);
    font-size: 10px;
    font-weight: 800; line-height: 1.4;
    color: #0F172A;
    white-space: nowrap;
}
.v2-pid-portrait .v2-pid-num .u {
    font-family: var(--font-body, inherit);
    font-size: 0.62em; font-weight: 700;
    text-transform: uppercase; letter-spacing: .02em;
    opacity: .62;
}

/* ----- Position as an edge, not a label -----
   GK/DEF/MID/FWD as text costs a column on every row and repeats what a
   colour can say in three pixels. The colours are the site's existing
   --position-* tokens, so the edge, the pitch and the charts agree. */
.v2-pos-edge {
    position: relative;
}

/* Wide enough to hold the position's initial, so the edge names the position
   as well as colouring it. A 3px stripe asked you to have learnt the palette;
   a letter does not, and it costs far less room than the GK/DEF/MID/FWD pill
   this replaced. The letter is set through content on the pseudo-element, so
   no row markup has to carry it. */
.v2-pos-edge::before {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md) 0 0 var(--radius-md);
    background: var(--v2-pos-color, var(--position-mid));
    color: #FFFFFF;
    font-size: 10px;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0;
}

.v2-pos-edge.pos-gk  { --v2-pos-color: var(--position-gk); }
.v2-pos-edge.pos-def { --v2-pos-color: var(--position-def); }
.v2-pos-edge.pos-mid { --v2-pos-color: var(--position-mid); }
.v2-pos-edge.pos-fwd { --v2-pos-color: var(--position-fwd); }

.v2-pos-edge.pos-gk::before  { content: 'G'; }
.v2-pos-edge.pos-def::before { content: 'D'; }
.v2-pos-edge.pos-mid::before { content: 'M'; }
.v2-pos-edge.pos-fwd::before { content: 'F'; }

/* A pseudo-element's text is not dependable for a screen reader, so the row's
   own tooltip and its player detail still carry the position in words. */

/* ----- Fixture difficulty, one ramp everywhere -----
   The same five steps the squad table uses: dark green, light green, grey,
   orange, dark red. It moves in lightness as well as hue, so it survives
   being printed in black and white, and the two ends — the ones that change
   a decision — are the two darkest chips in any row. */
/* The literals moved to --fdr-* in styles/common.css, which is now the only
   place the ramp is written down. */
.v2-fdr-1 { background: var(--fdr-1) !important; color: var(--fdr-1-ink) !important; }
.v2-fdr-2 { background: var(--fdr-2) !important; color: var(--fdr-2-ink) !important; }
.v2-fdr-3 { background: var(--fdr-3) !important; color: var(--fdr-3-ink) !important; }
.v2-fdr-4 { background: var(--fdr-4) !important; color: var(--fdr-4-ink) !important; }
.v2-fdr-5 { background: var(--fdr-5) !important; color: var(--fdr-5-ink) !important; }

[data-theme="dark"] .v2-fdr-2 { background: #4ADE80 !important; color: #08240F !important; }
[data-theme="dark"] .v2-fdr-3 { background: #3A424D !important; color: #D5DAE2 !important; }
