/**
 * GEX Components CSS
 * Component-specific styles for the GEX Analysis page
 * Theme-independent styles - theme variables defined in themes.css
 */

/* ========================================
   RESPONSIVE VISIBILITY: TOOLBAR CONTROLS
   ======================================== */

/* Replay bar speed: combobox shown on both mobile and desktop */
.tm-speed-select {
    width: auto;
    min-width: 60px;
    max-width: 70px;
    font-size: 0.875rem;
    padding: 0.25rem 0.5rem;
    flex-shrink: 0;
}

@media (max-width: 767.98px) {
    .tm-speed-select {
        font-size: 0.75rem;
        min-width: 55px;
        max-width: 60px;
        padding: 0.2rem 0.4rem;
    }
}

/* ========================================
   CONTAINER & LAYOUT
   ======================================== */

.gex-container {
    max-width: 100%;
    margin: 0 auto;
    padding: 0;
}

.main-content-full {
    width: 100%;
    max-width: 100%;
}

/* ========================================
   UNIVERSAL FLEX CASCADE (single-screen, no-scroll)
   Locks the GEX Studio page to viewport height and lets the chart
   flex-grow to fill the remaining space. Applies to ALL viewports.
   Mobile-specific quirks (no scrollbars, 25vh markers cap, anti-shrink)
   remain inside @media (max-width: 768px) below.
   ======================================== */

@media (min-height: 480px) {
    html:has(.gex-container),
    body:has(.gex-container) {
        height: 100vh;   /* fallback for engines without dynamic-viewport units */
        /* dvh = the actually-visible height, shrunk by the browser's dynamic
           toolbars. On iPadOS/iOS WebKit (Safari AND Chrome) plain 100vh is the
           LARGE viewport (chrome retracted), so it overshoots the visible area
           and overflow:hidden clips the bottom marker strip. dvh fixes that; on
           desktop it equals vh (no dynamic chrome). */
        height: 100dvh;
        overflow: hidden;
    }
}

/* Flex column always; the height/overflow lock above is guarded by min-height: 480px */
body:has(.gex-container) {
    display: flex;
    flex-direction: column;
}

.gex-container {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-height: 0;
    width: 100%;
}

.main-content-full {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-height: 0;
    width: 100%;
}

.gex-control-toolbar,
.delayed-banner {
    flex-shrink: 0;
}

#chart-widgets-container {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-height: 0;
    overflow-y: auto;
    /* Explicit — without this, the spec auto-promotes overflow-x to 'auto' too
       (an unset axis can't stay 'visible' next to a non-'visible' one), turning
       this into a silent horizontal-scroll region that can clip the chart's
       right-edge price dock. */
    overflow-x: hidden;
}

/* Page-level background — only on the GEX app route (desktop + tablet) */
@media (min-width: 769px) {
    body:has(.gex-container) {
        background-color: var(--theme-bg-page, var(--theme-bg-primary));

        /* GEX Studio is data-dense (chart + side panels): let it use the full
           window minus a small gutter, capped at 2560px so controls don't spread.
           Studio-scoped via :has(.gex-container) so landing / blog / account keep
           their narrow widths. Inherited by .gex-container / .header-bar /
           .main-content-full, which all read var(--layout-max-width). */
        --layout-max-width: min(100% - 2rem, 2560px);
    }
}

/* Desktop + tablet: card chrome with width cap */
@media (min-width: 769px) {
    .gex-container {
        max-width: var(--layout-max-width);
        background-color: var(--theme-bg-primary);
        margin: 6px auto;
        padding: 0 20px 6px;
        border-radius: 16px;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 2px 12px rgba(0, 0, 0, 0.04);
    }

    .main-content-full {
        width: 100%;
        max-width: var(--layout-max-width);
        margin: 0 auto;
    }

    /* Nested cards fill .main-content-full (which already carries the gutter/cap).
       They must NOT re-read --layout-max-width: with the fluid token
       min(100% - 2rem) that subtracts the gutter a second time at this level,
       insetting them ~16px past their siblings (chart / toolbar). */
    .main-content-full .card {
        width: 100%;
        max-width: 100%;
        margin: 0 auto;
        box-sizing: border-box;
    }

    .main-content-full .card-body {
        width: 100%;
        max-width: 100%;
        margin: 0 0;
        box-sizing: border-box;
    }
}

/* Header bar — desktop + tablet card chrome, matches .gex-container breakpoint */
@media (min-width: 769px) {
    .header-bar {
        display: flex;
        justify-content: center;
        width: 100%;
        max-width: var(--layout-max-width);
        margin: 0 auto;
        border-radius: 0 0 16px 16px;
        overflow: visible;
        background: var(--theme-bg-primary);
    }
}

/* On mobile, the overflow-x: hidden on parents blocks horizontal scrolling in child elements
   We need to remove this restriction on mobile to allow the marker cards to scroll */
@media (max-width: 768px) {

    html,
    body {
        overflow-x: visible !important;
    }

    .gex-container {
        overflow-x: visible !important;
    }

    .main-content-full {
        overflow-x: visible !important;
    }

    .main-content-full>.card {
        overflow-x: visible !important;
    }
}

/* --- Mobile Single Page Layout (Flexbox) ---
   NOTE: Most flex declarations below (display:flex, flex-grow:1, min-height:0, etc.)
   duplicate the universal flex cascade defined earlier in this file. The duplicates
   are harmless and intentional — DO NOT remove them without verifying that the
   mobile-specific overrides interleaved here (e.g., min-width:100%, height:100% vs
   universal's height:100vh for iOS Safari, hidden scrollbars, 25vh markers cap)
   still work correctly. The duplication is a known maintenance trade-off. */
@media (max-width: 768px) {

    /* 1. Force Full Height Body & Container (GEX Studio only — not dashboard) */
    html:has(.gex-container) {
        height: 100%;
        overflow: hidden;
        width: 100%;
    }

    body:has(.gex-container) {
        height: 100%;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        width: 100%;
        min-width: 100%;
        /* Prevent shrinking below viewport width */
    }

    /* Header takes natural height */
    .header-bar {
        flex-shrink: 0;
    }

    /* Container fills height, strict no-scroll unless absolutely necessary */
    .gex-container {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        min-height: 0;
        overflow: hidden;
        width: 100%;
        min-width: 100%;
        /* Prevent shrinking below viewport width */
    }

    .main-content-full {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        min-height: 0;
        width: 100%;
        min-width: 100%;
        /* Prevent shrinking below viewport width */
    }

    /* Toolbar is fixed height */
    .gex-control-toolbar {
        flex-shrink: 0;
    }

    /* Delayed Banner fixed height */
    .delayed-banner {
        flex-shrink: 0;
    }

    /* 2. Chart & Widgets Wrapper fills remaining space */
    #chart-widgets-container {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        min-height: 0;
        overflow-y: auto;
        overflow-x: hidden;
        /* Hide scrollbar on mobile - prevents width shift */
        scrollbar-width: none;
        /* Firefox */
        -ms-overflow-style: none;
        /* IE and Edge */
        max-height: 100%;
        width: 100%;
    }

    /* Hide scrollbar for WebKit browsers (Chrome, Safari) */
    #chart-widgets-container::-webkit-scrollbar {
        display: none;
    }

    /* Chart Section takes all available space */
    .chart-section {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        flex-basis: 0;
        min-height: 250px;
        position: relative;
        width: 100%;
    }

    /* 3. Markers Section - Fixed Height Bottom Widget */
    .markers-section {
        flex-shrink: 0;
        height: auto;
        /* Allow adaptive height */
        max-height: 25vh;
        /* Cap at ~25% of viewport (~160px on 667h) */
        min-height: 80px;
        /* Ensure strictly visible */
        overflow-y: hidden;
        /* Scroll handled by inner widget */
        background: var(--theme-bg-primary) !important;
        border-top: none !important;
        z-index: 10;
        margin-bottom: 0 !important;
        display: flex;
        flex-direction: column;
    }

    /* Ensure markers widget fits inside markers section */
    .markers-section .markers-widget {
        height: 100%;
        display: flex;
        flex-direction: column;
    }

    .markers-section .markers-widget-body {
        overflow-y: auto;
        flex-grow: 1;
        min-height: 0;
        /* CRITICAL: Allows shrinking when siblings (totals) expand */
    }
}

/* Chart container — flex-grows to fill .gex-view.active.
   Floor enforced by parent .chart-section min-height: 250px. */
.gex-chart-container,
.gex-ohlc-container {
    flex-grow: 1;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    position: relative;
    /* Match the other widgets' surface treatment (rail cards, markers
       widget, slider) — subtle border + rounded corners so the Plotly
       chart doesn't read as a flat unframed block among the other widgets. */
    border: 1px solid var(--theme-border-primary);
    border-radius: 8px;
    background-color: var(--theme-bg-card);
    /* touch-action handled by Hammer.js - don't restrict here */
}

/* ===========================================
   Chart loading overlay (pseudo-elements)
   Applies to all three chart containers.
   Survives Plotly.purge() — no real DOM nodes.
   =========================================== */

/* Semi-transparent overlay — color adapts to active theme */
.gex-chart-container.gex-chart-loading::before,
.gex-ohlc-container.gex-chart-loading::before,
.gex-term-container.gex-chart-loading::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 200;
    background: var(--gex-loading-overlay-bg, rgba(0, 0, 0, 0.5));
    border-radius: inherit;
    animation: gex-overlay-fade-in 0.12s ease forwards;
}

/* Spinning indicator — color adapts to active theme */
.gex-chart-container.gex-chart-loading::after,
.gex-ohlc-container.gex-chart-loading::after,
.gex-term-container.gex-chart-loading::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 201;
    width: 2.5rem;
    height: 2.5rem;
    margin: -1.25rem 0 0 -1.25rem;
    border: 0.3em solid var(--gex-loading-spinner-track, rgba(255, 255, 255, 0.25));
    border-top-color: var(--gex-loading-spinner-color, #fff);
    border-radius: 50%;
    animation: gex-spin 0.7s linear infinite;
}

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

@keyframes gex-overlay-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (max-width: 768px) {

    /* Mobile: Flex grow to fill available space */
    .gex-view,
    .gex-chart-container {
        flex-grow: 1;
        flex-basis: 0;
        /* FORCE SHIRINKAGE below natural height */
        height: 100% !important;
        /* Use 100% of flex parent */
        min-height: 0 !important;
        /* Let parent .chart-section handle min-height */
        margin-bottom: 0 !important;
    }

    /* Remove padding or margins that affect height */
    .chart-section {
        padding-bottom: 0;
    }
}

.header-menu-dropdown {
    margin-left: 0.5rem;
}

.header-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
}

.header-menu-btn .menu-icon {
    font-size: 1.35rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    transform: translateY(-1px);
}

/* Header dropdowns - default (desktop) - compact sizes */
#main-exchange-select {
    min-width: 100px;
    max-width: 120px;
}

@media (max-width: 768px) {
    .header-menu-dropdown {
        margin-left: 0;
    }

    .header-menu-btn {
        margin-left: 0 !important;
    }

    /* Ensure nav section items wrap properly on very small screens */
    #navAuthSection {
        flex-wrap: wrap;
        gap: 0.35rem !important;
    }
}

/* User Auth Section - Spacing to separate from controls */
@media (min-width: 576px) {

    /* Add extra spacing before auth section on larger screens */
    #loginBtn,
    #userDropdown {
        margin-left: 0.5rem;
        padding-left: 0.5rem;
        border-left: 1px solid var(--theme-border-primary);
        border-left-color: rgba(var(--bs-border-color-rgb), 0.3);
    }
}

/* On mobile, keep compact spacing */
@media (max-width: 575.98px) {

    #loginBtn,
    #userDropdown {
        margin-left: 0.25rem;
    }
}

/* ========================================
   CATEGORY BREADCRUMB (Phase B) — header pill: Studio › [⚡ Now ▾]
   ======================================== */

.gex-crumb-sep {
    color: var(--theme-text-muted);
    opacity: 0.4;
    font-size: 13px;
    user-select: none;
}

/* --- Category tabs visible at all viewport widths. On narrow screens they
       shrink (compact padding + smaller font, icon-only below 380px) instead
       of collapsing into a pill — the 4 categories fit horizontally easily on
       any modern phone, so the pill+dropdown indirection isn't needed. --- */
.gex-category-tabs {
    display: inline-flex;
    gap: 2px;
    background: var(--theme-bg-secondary);
    border: 1px solid var(--theme-border-primary);
    border-radius: 8px;
    padding: 3px;
    flex-shrink: 0;
}

.gex-category-tab {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: transparent;
    border: 0;
    color: var(--theme-text-secondary);
    border-radius: 6px;
    padding: 7px 14px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    white-space: nowrap;
}
.gex-category-tab:hover {
    background: var(--theme-bg-tertiary);
    color: var(--theme-text-primary);
}
.gex-category-tab .cat-ico {
    font-size: 14px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Lucide SVG sizing — lucide injects a 24x24 svg by default; pin to the
   visual weight of the old emoji on desktop and the larger icon on mobile
   (see mobile media block below). */
.gex-category-tab .cat-ico svg {
    width: 16px;
    height: 16px;
    stroke-width: 2;
}
.gex-category-tab .cat-name { font-weight: 600; }

/* GammaFlip brand periwinkle — single source of truth for nav accent.
   Matches the brand signature gradient (#667eea → #764ba2) already used in
   landing.css and the legacy Live/Replay pill-switch. Light-theme variant is
   slightly darker for AA contrast on near-white backgrounds. */
:root {
    --gex-nav-accent: #667eea;
    --gex-nav-accent-rgb: 102, 126, 234;
}
[data-bs-theme="light"] {
    --gex-nav-accent: #4f5fc2;
    --gex-nav-accent-rgb: 79, 95, 194;
}

/* Active tab — brand-gradient underline (#667eea → #764ba2). Matches the
   landing/marketing gradient and feels more "modern app" than a flat
   background tint. We keep a faint background hint for hover continuity. */
.gex-category-tab[aria-selected="true"] {
    background: transparent;
    color: var(--theme-text-primary);
}
.gex-category-tab[aria-selected="true"]::after {
    content: '';
    position: absolute;
    left: 10px;
    right: 10px;
    bottom: 2px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, #667eea, #764ba2);
}
[data-bs-theme="light"] .gex-category-tab[aria-selected="true"]::after {
    background: linear-gradient(90deg, #4f5fc2, #5e3f8a);
}
/* Category icons keep distinct tints as a small orientation hint
   (the icon stays category-colored even when not selected, so the
   user can scan-spot "where am I" without depending on background). */
.gex-category-tab[data-cat="now"]      .cat-ico { color: #4ec9b0; }
.gex-category-tab[data-cat="expiry"]   .cat-ico { color: #f6c177; }
.gex-category-tab[data-cat="history"]  .cat-ico { color: #9cdcfe; }
.gex-category-tab[data-cat="forecast"] .cat-ico { color: #c586c0; }

/* Hide product-switcher separator on mobile (the product H4 is d-none, so
   the separator dangles without a left-hand sibling). */
@media (max-width: 767.98px) {
    .gex-crumb-sep { display: none; }
}

/* Mobile bottom tab bar: iOS-style stacked layout (icon over label) with
   bigger touch targets. The category row is the primary navigation under the
   thumb, so it deserves prominent ~48px tiles instead of cramped 26px pills.
   .gex-category-tabs sheds its container chrome (border/bg) here — the parent
   .gex-nav-bar already provides the bottom-bar surface. */
@media (max-width: 767.98px) {
    .gex-category-tabs {
        background: transparent;
        border: 0;
        padding: 0;
        gap: 2px;
        flex: 1 1 auto;
        justify-content: space-around;
    }
    .gex-category-tab {
        flex-direction: column;
        gap: 2px;
        padding: 6px 10px;
        font-size: 11px;
        line-height: 1.1;
        min-width: 56px;
    }
    .gex-category-tab .cat-ico  { font-size: 20px; }
    .gex-category-tab .cat-ico svg { width: 22px; height: 22px; }
    .gex-category-tab .cat-name { font-weight: 500; }
    /* Underline indicator: re-anchor for stacked layout (bottom of the tile,
       under the label) — desktop uses bottom: 2px which sits below the icon
       in inline layout, wrong place for stacked. */
    .gex-category-tab[aria-selected="true"]::after {
        left: 14px;
        right: 14px;
        bottom: 4px;
    }
}

/* ========================================
   CONTEXT PICKER — pill + 3-column modal (Asset / Exchange / Expiration)
   ======================================== */

.gex-ctx-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: 1px solid var(--theme-border-secondary);
    color: var(--theme-text-primary);
    border-radius: 20px;
    padding: 5px 12px 5px 6px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    flex-shrink: 0;
}
.gex-ctx-pill:hover {
    background: var(--theme-bg-secondary);
    border-color: var(--theme-border-primary);
}
.gex-ctx-pill[aria-expanded="true"] {
    background: var(--theme-bg-secondary);
    border-color: var(--theme-text-secondary);
}
.gex-ctx-pill .ctx-asset-icon { width: 18px; height: 18px; flex-shrink: 0; }
.gex-ctx-pill .ctx-asset { font-weight: 700; }
.gex-ctx-pill .ctx-sep { color: var(--theme-text-muted); opacity: 0.55; }
/* Multi-expiration badge: desktop shows the full "N expirations" label, mobile
   collapses to a compact "×N". Exactly one is visible per breakpoint — the JS
   always emits both spans (gex_ctx_picker.js _renderPill). */
.gex-ctx-pill .exp-compact { display: none; }
/* Dropdown caret — matches Bootstrap's .dropdown-toggle::after exactly so the
   pill caret is visually identical to "GEX Studio ▾" next to it. */
.gex-ctx-pill::after {
    content: "";
    display: inline-block;
    margin-left: 0.5em;
    vertical-align: 0.15em;
    border-top: 0.35em solid;
    border-right: 0.3em solid transparent;
    border-bottom: 0;
    border-left: 0.3em solid transparent;
    opacity: 0.75;
    flex-shrink: 0;
}

/* Mobile: refresh / bell / settings move to hamburger to free space — pill keeps
   full asset · exchange · expiry breadcrumb because there's now room for it. */
@media (max-width: 767.98px) {
    .gex-ctx-pill { padding: 4px 10px 4px 5px; font-size: 12px; }
    .gex-ctx-pill .ctx-asset-icon { width: 16px; height: 16px; }
    /* Swap to the compact "×N" badge on phones. */
    .gex-ctx-pill .exp-full { display: none; }
    .gex-ctx-pill .exp-compact { display: inline; }
    #gex-manual-refresh-btn,
    #changelogBell,
    #header-settings-btn {
        display: none !important;
    }
    /* Tighten the row gap (Bootstrap gap-3 = 16px is too generous when every
       pixel matters) so logo + GEX Studio + ctx-pill don't push the hamburger
       off-screen. */
    .header-container .d-flex.gap-3 { gap: 8px !important; }
    .product-switcher img { height: 28px; }
}

/* Very narrow phones (<=420px): hide the "GEX Studio" label inside the product
   switcher — the microscope icon + caret remain as the visual cue. This gives
   ~80px back to the ctx-pill / hamburger so the header stops overflowing on
   ~360-400px viewports. */
@media (max-width: 420px) {
    .product-switcher-current { font-size: 0; gap: 0; }
    .product-switcher-current i,
    .product-switcher-current svg { font-size: 14px; }
    .product-switcher img { height: 24px; }
}

/* Hide the legacy EAE row — picker now drives its hidden selects */
.toolbar-group.data-sources { display: none !important; }

/* Term Levels view used to surface Drift-Layer checkboxes below the chart;
   the same toggles now live in the ⚙ Controls popover (term_chart.js
   getControlsSchema('levels')). Hide the below-chart widget to drop the
   duplicate — JS that still touches the node (gex_term_mgr.applyTermViewMode,
   gex_plotter_term opacity reset) keeps working harmlessly. */
.term-markers-section { display: none !important; }

/* Chart/Table toggle icons above the Term Levels plot — moved into ⚙
   (term_chart.js getControlsSchema('levels')). gex_term_mgr.applyTermViewMode
   still sets display:flex on this element when entering Levels mode, but
   the CSS override keeps it permanently hidden. */
.term-levels-view-toggle { display: none !important; }

/* --- Modal --- */
.gex-ctx-modal {
    /* Full-screen layer: hosts the transparent click-catcher backdrop. The
       card itself is position:fixed and anchored to the trigger via JS
       (_position), so this layer no longer centers anything. */
    position: fixed;
    inset: 0;
    z-index: 1080;
}
.gex-ctx-modal[hidden] { display: none; }
.gex-ctx-backdrop {
    position: absolute;
    inset: 0;
    /* Invisible click-catcher only — picker is frequent navigation, not a
       commitment, so we don't dim/blur the chart behind on any viewport. */
    background: transparent;
}
.gex-ctx-card {
    /* Anchored popover: top/left set by JS (_position) relative to the
       trigger pill, with viewport flip/shift. */
    position: fixed;
    /* EXPERIMENT (option 1): translucent + blur so the chart shows through
       while switching asset/exchange/expiration. */
    background: color-mix(in srgb, var(--theme-bg-secondary) 82%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transition: opacity 120ms ease, backdrop-filter 120ms ease;
    border: 1px solid var(--theme-border-primary);
    border-radius: 12px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
    width: min(720px, 100%);
    /* Fixed height so the card doesn't jump as the expiration count changes
       per symbol (BTC ~12 rows vs SPX ~30). Columns flex + lists scroll
       internally; viewport cap keeps it on-screen on short displays. */
    height: min(660px, calc(100vh - 96px));
    display: flex;
    flex-direction: column;
    transform-origin: top left;
    animation: gexCtxPop 120ms ease-out;
}
@keyframes gexCtxPop {
    from { opacity: 0; transform: scale(0.97) translateY(-4px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .gex-ctx-card { animation: none; }
}
/* EXPERIMENT (option 4): hold Alt to "peek" — card nearly vanishes so the
   whole chart is visible; release to restore the readable panel. */
.gex-ctx-modal.ctx-peek .gex-ctx-card {
    opacity: 0.22;
    backdrop-filter: blur(0);
    -webkit-backdrop-filter: blur(0);
    pointer-events: none;
}
.gex-ctx-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--theme-border-primary);
}
.gex-ctx-card-header h5 {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--theme-text-primary);
}
.gex-ctx-close {
    border: 0;
    background: transparent;
    color: var(--theme-text-secondary);
    font-size: 22px;
    line-height: 1;
    padding: 0 6px;
    cursor: pointer;
}
.gex-ctx-close:hover { color: var(--theme-text-primary); }

/* Header right cluster — peek hint + close */
.gex-ctx-header-right {
    display: flex;
    align-items: center;
    gap: 12px;
}
/* EXPERIMENT (option 4): tells the user they can hold Alt/Option to peek. */
.gex-ctx-peek-hint {
    font-size: 11px;
    font-weight: 500;
    color: var(--theme-text-muted);
    white-space: nowrap;
}
.gex-ctx-kbd {
    font-family: inherit;
    font-size: 10px;
    font-weight: 600;
    color: var(--theme-text-secondary);
    background: var(--theme-bg-tertiary, var(--theme-bg-primary));
    border: 1px solid var(--theme-border-primary);
    border-radius: 4px;
    padding: 1px 6px;
    margin: 0 1px;
}

/* Header left cluster — title + asset-class segmented toggle */
.gex-ctx-header-left {
    display: flex;
    align-items: center;
    gap: 14px;
}
.gex-ctx-classtoggle {
    display: inline-flex;
    padding: 2px;
    gap: 2px;
    background: var(--theme-bg-tertiary, var(--theme-bg-primary));
    border: 1px solid var(--theme-border-primary);
    border-radius: 8px;
}
.gex-ctx-classbtn {
    border: 0;
    background: transparent;
    color: var(--theme-text-secondary);
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    padding: 5px 12px;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
}
.gex-ctx-classbtn:hover { color: var(--theme-text-primary); }
.gex-ctx-classbtn.is-active {
    color: #fff;
    background: linear-gradient(90deg, #667eea, #764ba2);
}
/* Class-level settlement-time hint (e.g. "Settles 08:00 UTC") */
.gex-ctx-settle-hint {
    font-size: 11px;
    font-weight: 500;
    color: var(--theme-text-muted);
    white-space: nowrap;
    cursor: help;
}
.gex-ctx-settle-hint:empty { display: none; }

.gex-ctx-cols {
    display: grid;
    grid-template-columns: 1fr 1fr 1.4fr;
    gap: 0;
    flex: 1;
    min-height: 0;
}
/* TradFi mode: Exchange column collapses, grid reflows to 2 columns */
.gex-ctx-cols.classmode-tradfi {
    grid-template-columns: 1fr 1.4fr;
}
.gex-ctx-cols.classmode-tradfi .gex-ctx-col[data-col="exchange"] {
    display: none;
}
.gex-ctx-col {
    display: flex;
    flex-direction: column;
    min-height: 0;
    border-right: 1px solid var(--theme-border-primary);
}
.gex-ctx-col:last-child { border-right: 0; }
.gex-ctx-col-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--theme-text-muted);
    padding: 10px 14px 6px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.gex-ctx-cycle-legend {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    font-size: 9.5px;
    color: var(--theme-text-secondary);
}
.gex-ctx-cycle-legend > span {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}
.gex-ctx-list {
    list-style: none;
    margin: 0;
    padding: 0 6px 8px;
    overflow-y: auto;
    flex: 1;
}
.gex-ctx-list li {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    cursor: pointer;
    color: var(--theme-text-primary);
    font-size: 13px;
    user-select: none;
}
.gex-ctx-list li:hover { background: var(--theme-bg-tertiary); }
.gex-ctx-list li.is-active {
    background: rgba(240, 185, 11, 0.12);
    color: #f0b90b;
    font-weight: 600;
}
.gex-ctx-list li.is-disabled {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: auto; /* keep tooltip on hover */
}
.gex-ctx-list li.is-disabled:hover { background: transparent; }

/* Per-expiration |GEX| importance bar — inset pill so adjacent rows don't merge.
   Width is set inline (proportional to |GEX| / max |GEX| in the list). */
.ctx-gex-bar {
    position: absolute;
    left: 4px;
    top: 4px;
    bottom: 4px;
    z-index: 0;
    /* Violet gradient — echoes the Abs.GEX chart fill (bar = |GEX| magnitude) and
       stays distinct from the blue selection accent + amber is-active highlight. */
    background: linear-gradient(90deg,
        rgba(167, 139, 250, 0.30),
        rgba(167, 139, 250, 0.06));
    border-radius: 4px;
    pointer-events: none;
}
/* When a checkbox is present, start the bar to the right of the checkmark column
   (10px row padding + 14px check + 8px gap) so the ✓ reads as separate from the bar. */
.gex-ctx-list li.has-check .ctx-gex-bar { left: 30px; }
/* Row content sits above the bar (the bar is the only positioned child below). */
.gex-ctx-list li > *:not(.ctx-gex-bar) {
    position: relative;
    z-index: 1;
}

/* Expiry cycle dot (colors mirror Term OI/GEX legend) */
.ctx-cycle-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.15);
}
.ctx-cycle-dot.ctx-cycle-none {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--theme-border-primary);
}
/* Expiry cycle letter (Q/M/W/D) — color carries the cycle; replaces the dot */
.ctx-cycle-letter {
    display: inline-block;
    width: 12px;
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    flex-shrink: 0;
}
.ctx-cycle-letter.ctx-cycle-none { color: transparent; }
/* Legend swatch for the gamma-exposure importance bar (mini horizontal bar). */
.ctx-gex-swatch {
    display: inline-block;
    width: 14px;
    height: 6px;
    border-radius: 3px;
    flex-shrink: 0;
    background: linear-gradient(90deg,
        rgba(120, 150, 200, 0.55),
        rgba(120, 150, 200, 0.15));
}
/* Multi-expiration: preset row + checkbox multi-select */
/* Single-line preset row: 4 cumulative presets + Clear. nowrap keeps them on one
   row; buttons may shrink (flex-shrink) and gap/padding stay tight to fit the column. */
.ctx-exp-presets { display:flex; flex-wrap:nowrap; align-items:center; gap:4px; padding:6px 8px; }
.ctx-preset { font-size:11px; padding:3px 7px; border-radius:6px; border:1px solid var(--theme-border-primary);
              background:transparent; color:var(--theme-text-secondary); cursor:pointer;
              white-space:nowrap; flex:0 1 auto; min-width:0; }
.ctx-preset:hover { background:var(--theme-border-primary); }
.ctx-exp-check { display:inline-block; width:14px; text-align:center; color:#60A5FA; }
/* Selected-row signal = crisp blue LEFT accent stripe (+ very faint tint), not a
   full-row blue wash — so it stays distinct from the slate |GEX| data bar. */
.gex-ctx-list li.is-checked {
    background: rgba(96,165,250,0.05);
    box-shadow: inset 3px 0 0 0 #60A5FA;
}
.gex-ctx-list li .ctx-li-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}
/* Instrument-class mark (index / etf / stock) in the TradFi asset list. */
.gex-ctx-list li .ctx-li-kind {
    width: 15px;
    height: 15px;
    flex-shrink: 0;
    opacity: 0.6;
}
.gex-ctx-list li.is-active .ctx-li-kind { opacity: 0.9; }
/* Instrument-class group divider (Indices / ETFs / Stocks) in the TradFi asset
   list: centered caption flanked by hairlines. Inert — no data-value, no hover. */
.gex-ctx-list li.ctx-li-group {
    gap: 8px;
    padding: 10px 8px 4px;
    cursor: default;
    user-select: none;
}
.gex-ctx-list li.ctx-li-group:hover { background: transparent; }
.gex-ctx-list li.ctx-li-group > span {
    flex: 0 0 auto;
    color: var(--theme-text-muted);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.gex-ctx-list li.ctx-li-group::before,
.gex-ctx-list li.ctx-li-group::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--theme-border-primary);
}
.gex-ctx-list li .ctx-li-sub {
    margin-left: auto;
    color: var(--theme-text-muted);
    font-size: 11px;
    font-weight: 400;
}
/* |GEX| value revealed inline on row hover (instant — no native title delay) */
.gex-ctx-list li .ctx-li-gex {
    margin-left: auto;
    color: var(--theme-text-muted);
    font-size: 11px;
    font-weight: 500;
    white-space: nowrap;
    opacity: 0;
    transition: opacity 0.08s ease;
}
.gex-ctx-list li:hover .ctx-li-gex { opacity: 1; }

@media (max-width: 600px) {
    /* Phone: popover becomes a full-width bottom sheet. JS (_position) clears
       its inline top/left at this breakpoint so these rules take over. */
    .gex-ctx-card {
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        width: 100%;
        height: min(80vh, calc(100vh - 56px));
        border-radius: 14px 14px 0 0;
        transform-origin: bottom center;
    }
    @keyframes gexCtxPop {
        from { opacity: 0; transform: translateY(12px); }
        to   { opacity: 1; transform: translateY(0); }
    }
    .gex-ctx-cols { grid-template-columns: 1fr 1fr 1.2fr; }
    .gex-ctx-cols.classmode-tradfi { grid-template-columns: 1fr 1.4fr; }
    .gex-ctx-col-label { padding: 8px 8px 4px; }
    .gex-ctx-list { padding: 0 4px 6px; }
    .gex-ctx-list li { padding: 8px; font-size: 12px; }
    /* Legend doesn't fit alongside header text on phone — hide it.
       Each item's colored dot still communicates the cycle. */
    .gex-ctx-cycle-legend { display: none; }
    /* The settlement hint is nowrap and would push the × close button off the
       right edge on a phone — drop it here (it stays on desktop). */
    .gex-ctx-settle-hint { display: none; }
    /* No physical Alt key on touch devices — hide the peek hint on phone. */
    .gex-ctx-peek-hint { display: none; }
    /* Bottom sheet reads as modal on phone: dim the tap-to-dismiss backdrop so
       it's an obvious close affordance alongside the × button. */
    .gex-ctx-backdrop { background: rgba(0, 0, 0, 0.45); }
}

/* ========================================
   CHART NAV BAR — axis-grouped sub-views + inline ctx-pill
   ======================================== */

.gex-nav-bar {
    width: 100%;
    margin: 0 auto 6px;
    padding: 0;
    /* Fill the parent (.main-content-full already carries the layout gutter/cap) —
       do NOT re-read --layout-max-width here. The fluid token min(100% - 2rem)
       subtracts the gutter a second time at this nested level, insetting the nav
       bar ~16px past the chart/markers below it so their left/right edges (and the
       ⚙ Options trigger) no longer line up. */
    max-width: 100%;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* Desktop: category tabs left, sub-views right, one row */
@media (min-width: 768px) {
    .gex-nav-bar {
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        gap: 16px;
    }
    .gex-nav-bar > .gex-category-tabs { flex: 0 0 auto; }
    .gex-nav-bar > #gex-nav-subs { flex: 1 1 auto; min-width: 0; }
}
/* Mobile: pinned to the bottom of the viewport under the thumb (iOS tab-bar
   pattern). 2-row grid — category tabs + ⚙ gear on row 1, sub-views span full
   width on row 2. The controls bottom sheet (z-index 1100) covers this bar
   when opened, matching Apple Maps / Spotify behavior. */
@media (max-width: 767.98px) {
    .gex-nav-bar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        margin: 0;
        padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
        background: var(--theme-bg-secondary, #161922);
        border-top: 1px solid var(--theme-border-primary, rgba(255, 255, 255, 0.08));
        box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.3);
        z-index: 50;
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-rows: auto auto;
        column-gap: 8px;
        row-gap: 6px;
        align-items: center;
    }
    .gex-nav-bar > .gex-category-tabs {
        grid-column: 1; grid-row: 1;
        justify-self: start;
        min-width: 0;
    }
    .gex-nav-bar > .gex-controls-trigger {
        grid-column: 2; grid-row: 1;
        justify-self: end;
    }
    .gex-nav-bar > #gex-nav-subs {
        grid-column: 1 / -1; grid-row: 2;
    }
    /* Reserve room below the chart so the fixed nav bar doesn't cover it.
       --gex-mobile-nav-h is published by gex_nav.js via ResizeObserver on the
       actual bar (already includes safe-area-inset-bottom from its own
       padding). Fallback covers the first frame before JS runs. */
    body:has(.gex-container) {
        /* Mobile: edge-to-edge, no gutter cap (the desktop min(100% - 2rem)
           token would otherwise subtract a gutter that .gex-container's own
           padding already covers). */
        --layout-max-width: 100%;
        /* +8px so the marker widget's bottom edge clears the fixed nav bar
           instead of butting straight against it (mirrors the gap above it). */
        padding-bottom: calc(var(--gex-mobile-nav-h, 96px) + 8px);
    }
}

/* Row B: axis-grouped sub-views */
.gex-nav-subs {
    display: flex;
    gap: 8px;
    align-items: stretch;
    overflow-x: auto;
    scrollbar-width: none;
}
.gex-nav-subs::-webkit-scrollbar { display: none; }

/* Tighten the gap between the category block and the sub-view strip. This lives
   on #gex-nav-bar itself (the query container), so it must be a @media rule, not
   the @container block below. */
@media (min-width: 768px) and (max-width: 1024px) {
    .gex-nav-bar { gap: 8px; }
}
@container (min-width: 600px) and (max-width: 1023px) {
    .gex-category-tabs { gap: 1px; padding: 2px; }
    .gex-category-tab { padding: 6px 9px; gap: 5px; font-size: 12.5px; }
    .gex-category-tab[aria-selected="true"]::after { left: 7px; right: 7px; }
    .gex-nav-axis { padding: 3px 4px 3px 8px; gap: 4px; }
    .gex-nav-view { padding: 5px 9px; }
    /* Prefer short sub-view labels where provided ("Hedging Pressure" → "Hedging")
       to keep the strip on one screen. Buttons without a short variant render a
       single .label span and are unaffected. */
    .gex-nav-view .label-full  { display: none; }
    .gex-nav-view .label-short { display: inline; }

    /* Edge-fade hints — only on the side that actually has hidden content
       (classes toggled by gex_nav._updateSubsScrollHint), so the flush start
       (incl. the "Window" axis label) is never faded misleadingly. */
    .gex-nav-subs.has-scroll-left:not(.has-scroll-right) {
        -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 100%);
                mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 100%);
    }
    .gex-nav-subs.has-scroll-right:not(.has-scroll-left) {
        -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 16px), transparent 100%);
                mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 16px), transparent 100%);
    }
    .gex-nav-subs.has-scroll-left.has-scroll-right {
        -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
                mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
    }
}

/* iPad portrait — desktop single-row nav at the TOP (iPad's browser chrome is at
   the top, so controls belong there), with ONE adaptation: the sub-view tools
   (#gex-nav-subs) wrap to a second line when they don't fit. flex-wrap + ordering
   does it: categories (order 1) and the ⚙ trigger (order 2) hold line 1; the tools
   (order 3, last) sit beside them when there's room, else wrap to their own full
   line — and because they're ordered last, wrapping never pushes the trigger to a
   third line. min-width:auto lets the tools keep their content width and wrap
   instead of shrink-scrolling.

   Keyed on orientation (not container width): Safari's sidebar can shrink the
   container under 1024px even in landscape; landscape keeps the desktop row.
   min-width:768px excludes phones (their own fixed bottom-bar layout). */
@media (orientation: portrait) and (min-width: 768px) and (max-width: 1024px) {
    .gex-nav-bar { flex-wrap: wrap; }
    /* DOM order is tabs → subs → ⚙ trigger; keep it (no reorder) so the ⚙ stays
       pinned to the RIGHT. subs grows to fill the middle, pushing ⚙ to the edge;
       min-width:auto lets subs wrap to a second line (instead of shrink-scroll)
       if it ever doesn't fit. */
    .gex-nav-bar > #gex-nav-subs { flex: 1 1 auto; min-width: auto; }

    /* Reclaim the horizontal space like iPhone: the desktop "card chrome"
       (@media min-width:769px) was insetting the chart ~52px/side — the
       max-width token's 2rem gutter + 20px .gex-container padding + a doubled
       gutter where .main-content-full re-reads the same token. Go full-bleed. */
    body:has(.gex-container) { --layout-max-width: 100%; }
    .gex-container {
        margin-left: 0;
        margin-right: 0;
        padding-left: 6px;
        padding-right: 6px;
        border-radius: 0;
    }
    .main-content-full { max-width: 100%; }

    /* Hide ONLY the zoom (±%) slider on iPad (matches iPhone). The term/Expiry
       view repurposes the same strip as the max-DTE control (.slider-discrete,
       added by gex_term_mgr.js) — keep that one so DTE stays adjustable. */
    .slider-section-container:not(.slider-discrete) { display: none !important; }
}

/* Mobile: fade-mask on the right edge signals there's more content sideways
   (e.g. the chip-axis "Influence: Standard ▾" on Forecast). Left edge is
   not faded — content always starts at the left, so a left fade would
   misleadingly imply hidden content there. */
@media (max-width: 767.98px) {
    .gex-nav-subs {
        mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 16px), transparent 100%);
        -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 16px), transparent 100%);
        padding-right: 8px;
    }
}

.gex-nav-axis {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--theme-bg-secondary);
    border: 1px solid var(--theme-border-primary);
    border-radius: 8px;
    padding: 3px 4px 3px 10px;
    flex-shrink: 0;
}
.gex-nav-axis-label {
    font-size: 9.5px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--theme-text-muted);
    font-weight: 700;
    white-space: nowrap;
}
.gex-nav-axis-btns {
    display: flex;
    gap: 2px;
    /* Center mismatched-height children on the cross axis (e.g. the embedded
       #modeToggle pill is 26px tall vs ~30px for view buttons; without this
       the pill sits at the top, making the "Live"/"Replay" label visually
       higher than Snapshot/Day/Hour). */
    align-items: center;
}
.gex-nav-axis-sep {
    display: flex;
    align-items: center;
    color: var(--theme-border-primary);
    font-size: 14px;
    line-height: 1;
    user-select: none;
    flex-shrink: 0;
}
.gex-nav-view {
    border: 0;
    background: transparent;
    color: var(--theme-text-secondary);
    padding: 6px 11px;
    border-radius: 6px;
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}
.gex-nav-view:hover {
    color: var(--theme-text-primary);
    background: var(--theme-bg-tertiary);
}
.gex-nav-view.active {
    background: var(--theme-bg-tertiary);
    color: var(--theme-text-primary);
    box-shadow: inset 0 0 0 1px var(--theme-border-primary);
}
/* Active sub-view — same brand periwinkle as the category tab gives the
   toolbar a consistent "selected" look across both rows. */
.gex-nav-view.active {
    color: var(--gex-nav-accent);
    background: rgba(var(--gex-nav-accent-rgb), 0.10);
    box-shadow: inset 0 0 0 1px rgba(var(--gex-nav-accent-rgb), 0.4);
}
/* Legacy #modeToggle pill-switch embedded into the strike-axis button row by
   gex_nav._embedModeToggle. Compact size + small left margin to separate it
   from the last view button (Hour) without a hard divider. */
.gex-nav-axis-btns > .mode-switch {
    height: 26px;
    margin: 0 2px 0 8px;
    padding: 0;
    gap: 6px;
    font-size: 12px;
}
.gex-nav-axis-btns > .mode-switch .mode-switch-track {
    width: 32px;
    height: 18px;
    border-radius: 9px;
}
.gex-nav-axis-btns > .mode-switch .mode-switch-thumb {
    width: 14px;
    height: 14px;
}
.gex-nav-axis-btns > .mode-switch input:checked ~ .mode-switch-track .mode-switch-thumb {
    transform: translateX(14px);
}
.gex-nav-axis-btns > .mode-switch .mode-switch-label {
    font-size: 12px;
    /* Reserve width of the longer of the two states ("Replay") so the row
       doesn't visibly resize when toggling Live → Replay. */
    min-width: 40px;
    text-align: left;
}

/* Responsive sub-view labels: full text on desktop, short on mobile.
   The button is rendered with both spans when `labelShort` is set on the
   NAV_IA item; CSS just toggles which span is visible. */
.gex-nav-view .label-short { display: none; }
.gex-nav-view .label-full  { display: inline; }

/* Mobile: tighter spacing, allow horizontal scroll on sub-views.
   NB: .gex-nav-bar padding/gap are set by the fixed-bottom rule above; don't
   re-declare them here (it would override the bottom-bar chrome). */
@media (max-width: 767.98px) {
    /* Axis labels ("Window", "GEX Influence") are hidden on mobile — the
       sub-view labels (24H/3D/7D/...) are self-explanatory and the row is
       too narrow to spare the space. Chip-axis labels are unaffected (they
       live inside .gex-nav-axis-chip, not this span). */
    .gex-nav-axis { padding: 2px 4px; gap: 4px; }
    .gex-nav-axis-label { display: none; }
    .gex-nav-view { padding: 5px 9px; font-size: 12px; }
    .gex-nav-view .label-full  { display: none; }
    .gex-nav-view .label-short { display: inline; }
}

/* Hide the legacy chart/view/mode selectors in toolbar — driven by .gex-nav-bar now.
   Markup stays in DOM so existing init/sync code doesn't error.
   .mode-wrapper is the old Live/Replay pill duplicated by the new Time axis-group. */
.toolbar-group.view-controls .chart-type-wrapper,
.toolbar-group.view-controls .view-mode-wrapper,
.toolbar-group.view-controls .mode-wrapper {
    display: none !important;
}

/* ========================================
   UNIFIED CONTROL TOOLBAR
   ======================================== */

#gex-manual-refresh-btn.rate-limited {
    opacity: 0.6;
    cursor: not-allowed !important;
    pointer-events: none;
}

#gex-manual-refresh-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.gex-control-toolbar {
    width: 100%;
    margin: 0 auto;
    padding: 0 10px;
    /* Fill parent — do not re-read the fluid gutter token (see .card note above).
       Re-reading it inset the toolbar ~16px past the chart, so the "Now" tabs (left)
       and the controls/options trigger (right) no longer lined up with the chart. */
    max-width: 100%;
}

/* Group Layouts */
.toolbar-group {
    display: flex;
    gap: 8px;
    align-items: flex-end;
    /* Align items to bottom so labels don't mess up input alignment */
}

.control-wrapper {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Heatmap FLIP toggle — pill that visually matches sibling .form-select.control-select */
.heatmap-flip-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    height: 34px; /* match .native-compact form-select height */
    padding: 0 0.5rem;
    border: 1px solid var(--theme-border-primary);
    border-radius: var(--bs-border-radius, 0.375rem);
    background-color: var(--theme-bg-secondary);
    color: var(--theme-text-primary);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    user-select: none;
    box-sizing: border-box;
}

.heatmap-flip-toggle input[type="checkbox"] {
    margin: 0;
    accent-color: #ff00ff; /* matches flip-line color in the rendered PNG */
}

.control-label {
    font-size: 0.65rem;
    font-weight: 700;
    color: var(--theme-text-secondary);
    letter-spacing: 0.5px;
    line-height: 1;
    margin-bottom: 2px;
    padding-left: 2px;
    text-transform: uppercase;
}

/* Mobile: Smaller, more compact labels */
@media (max-width: 767.98px) {
    .control-label {
        font-size: 0.55rem;
        letter-spacing: 0.3px;
        margin-bottom: 1px;
        padding-left: 1px;
        opacity: 0.85;
    }
}

/* Mobile: 2-Row Grid */
@media (max-width: 767.98px) {
    .gex-control-toolbar {
        display: flex;
        flex-direction: column;
        gap: 6px;
        padding: 0 0.5rem;
        /* Use rem for consistency with other containers (0.5rem = 8px) */
    }

    .toolbar-group {
        display: grid;
        gap: 6px;
        width: 100%;
        align-items: stretch;
        /* Reset alignment for grid */
    }

    /* Data Sources: 3 columns (Exchange, Asset, Expiration) */
    .toolbar-group.data-sources {
        grid-template-columns: 1fr 1fr 1fr;
        order: 1;
    }

    /* View Controls: fixed widths for CHART/VIEW/MODE-style controls so the
       row layout stays stable when chart-specific controls appear/disappear.
       The CHART selector in particular must NOT change width when switching
       between Strike (3 controls), Profile (2 controls), Heatmap (4 controls)
       and Monte Carlo (4 controls). */
    .toolbar-group.view-controls {
        display: flex;
        flex-wrap: nowrap;
        gap: 6px;
        order: 2;
        justify-content: flex-start;
    }

    /* Default for chart-specific dropdowns (METRIC, PALETTE, GEX INFLUENCE):
       share whatever space remains after the fixed-width controls below.
       Listed first so the more specific .chart-type-wrapper / .view-mode-wrapper
       / .mode-wrapper / .heatmap-show-flip-wrapper rules below take precedence
       (equal specificity → source order wins). */
    .toolbar-group.view-controls > .control-wrapper {
        flex: 1 1 0;
        min-width: 0;
    }

    /* CHART selector — fixed width that fits the longest option label
       ("🎲 Monte Carlo") with the native chevron, constant across charts. */
    .toolbar-group.view-controls > .chart-type-wrapper {
        flex: 0 0 130px;
    }

    /* VIEW (📊 GEX / 📈 Day / 30D…) — fixed compact width.
       90px so "📊 GEX" / "📈 Day" fit on Strike while leaving Heatmap METRIC
       enough room for "Net GEX". Wider (100px+) starves METRIC. */
    .toolbar-group.view-controls > .view-mode-wrapper {
        flex: 0 0 90px;
    }

    /* On mobile, Bootstrap's default 2.25rem right padding on native selects
       reserves more room than the small chevron icon actually needs and
       starves the option text (e.g., "📊 GEX" becomes "📊 GE", "Net GEX"
       becomes "Net G"). Tighten the reserved space and tuck the chevron
       closer to the edge so labels stay readable in narrow toolbar cells. */
    .toolbar-group.view-controls select.native-compact {
        padding-left: 0.45rem !important;
        padding-right: 1.1rem !important;
        background-position: right 0.2rem center !important;
        background-size: 10px 8px !important;
    }

    /* Monte Carlo PALETTE — hide on mobile, mirrors heatmap-palette behavior.
       Palette is a power-user toggle (Direction/Coolwarm/Viridis/...); on a
       phone-width row, keeping it visible truncates "Direction (R/G)" to
       "Direc" and starves GEX INFLUENCE. The user can still pick a palette
       in settings or on desktop. */
    #mc-palette-wrapper {
        display: none !important;
    }

    /* MODE (Live/Replay toggle pill) — fixed width; pushed to the right edge
       so the Strike toolbar stays visually balanced (CHART left, MODE right)
       and any chart-specific controls in between (none on Strike) sit
       naturally in the middle on Heatmap/MC. */
    .toolbar-group.view-controls > .mode-wrapper {
        flex: 0 0 82px;
        margin-left: auto;
    }

    /* FLIP (□ F) — narrowest, fixed pill width */
    .toolbar-group.view-controls > .heatmap-show-flip-wrapper {
        flex: 0 0 58px;
    }

    .control-wrapper {
        min-width: 0;
        /* Prevent flex overflow */
        gap: 1px;
        /* Tighter gap between label and control on mobile */
    }

    /* Ensure all selectors in toolbar have equal width */
    .gex-control-toolbar .control-select,
    .gex-control-toolbar #main-exchange-select {
        width: 100%;
        min-width: 0;
        max-width: none;
    }
}

/* Desktop: Single Flex Row */
@media (min-width: 768px) {
    .gex-control-toolbar {
        display: flex;
        flex-wrap: nowrap;
        justify-content: space-between;
        align-items: flex-end;
        /* Align groups to bottom */
        gap: 16px;
        padding: 0 0px;
    }

    /* Left Group (Data Sources) */
    .toolbar-group.data-sources {
        flex: 0 1 auto;
    }

    /* Right Group (View Controls) - Now only 2 controls */
    .toolbar-group.view-controls {
        flex: 0 1 auto;
    }

    /* Adjust widths for desktop comfort */
    .exchange-wrapper {
        min-width: 110px;
    }

    .asset-wrapper {
        min-width: 110px;
    }

    .expiration-wrapper {
        min-width: 130px;
    }

    /* Chart and View wrappers get equal space */
    .chart-type-wrapper,
    .view-mode-wrapper {
        min-width: 120px;
    }

    .mode-wrapper {
        min-width: 120px;
    }
}

/* ========================================
   MODE BADGE (Beta/Replay Indicator)
   ======================================== */

.mode-badge {
    position: relative;
    top: -1px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    font-size: 0.5rem;
    font-weight: 700;
    padding: 2px 6px;
    border-radius: 8px;
    letter-spacing: 0.5px;
    z-index: 10;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    pointer-events: none;
    animation: badgePulse 2s ease-in-out infinite;
}

@keyframes badgePulse {

    0%,
    100% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: 0.85;
        transform: scale(1.05);
    }
}

/* Mobile: Adjust badge for smaller screens */
@media (max-width: 767.98px) {
    .mode-badge {
        font-size: 0.45rem;
        padding: 1px 4px;
    }
}

/* ========================================
   MODE TOGGLE SWITCH (Live/Replay)
   ======================================== */

.mode-switch {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    height: 34px;
    user-select: none;
}

.mode-switch input {
    display: none;
}

.mode-switch-track {
    position: relative;
    width: 40px;
    height: 22px;
    background-color: #388E3C;
    border-radius: 11px;
    transition: background-color 0.25s;
    flex-shrink: 0;
}

.mode-switch input:checked~.mode-switch-track {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.mode-switch-thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    background: white;
    border-radius: 50%;
    transition: transform 0.25s;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

.mode-switch input:checked~.mode-switch-track .mode-switch-thumb {
    transform: translateX(18px);
}

.mode-switch-label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--theme-text-primary);
    white-space: nowrap;
}

/* Disabled state — replay is unavailable while a custom expiration set is active.
   pointer-events:none blocks the label click that would otherwise toggle the switch. */
.mode-switch.is-disabled {
    opacity: 0.4;
    pointer-events: none;
    cursor: not-allowed;
}

/* Premium lock icon (next to disabled features) */
.premium-lock-icon {
    font-size: 0.7rem;
    vertical-align: middle;
    opacity: 0.8;
}

/* Toggle is always clickable — free users see premium modal on click */

/* ========================================
   COMPACT CONTROLS STYLING (UNIFIED)
   ======================================== */

/* 1. Base Height & Alignment */
.native-compact,
.gex-toggle-btn,
.gex-toggle-group {
    height: 34px !important;
    min-height: 34px !important;
    max-height: 34px !important;
    box-sizing: border-box !important;
}

/* 2. Inputs (Selects & Dropdowns) */
select.native-compact {
    line-height: normal;
    /* Form controls align better with normal */
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    padding-left: 0.75rem !important;
    display: flex;
    align-items: center;
}

.asset-select-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
}

.asset-select-icon {
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    height: 16px;
    width: 16px;
    pointer-events: none;
    z-index: 1;
}

select.asset-select-native {
    padding-left: 30px !important;
}

/* 3. Toggle Groups (Chart Type & View Mode) */
.gex-toggle-group {
    background-color: var(--theme-bg-tertiary);
    padding: 3px;
    border-radius: 8px;
    border: 1px solid var(--theme-border-primary);
    display: inline-flex;
    gap: 2px;
    align-items: center;
    vertical-align: middle;
}

/* 4. Toggle Buttons (Labels & Buttons) */
.gex-toggle-btn.btn {
    /* Target with .btn to be specific */
    border-radius: 6px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--theme-text-secondary);
    font-size: 0.85rem !important;
    font-weight: 500;
    padding: 0 0.8rem !important;
    cursor: pointer;
    transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    white-space: nowrap;
    margin: 0 !important;
    height: 100% !important;
    /* Fill the group height */
    box-shadow: none !important;
    /* Reset bootstrap shadow */
    position: relative;
    /* For absolute positioning of badges */
}

/* Beta Badge Styling */
.beta-badge {
    position: absolute;
    top: -6px;
    right: -4px;
    background: linear-gradient(135deg, #ff9800, #f44336);
    color: white;
    font-size: 0.55rem;
    font-weight: 800;
    padding: 1px 4px;
    border-radius: 4px;
    text-transform: uppercase;
    line-height: 1;
    letter-spacing: 0.5px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    z-index: 5;
    pointer-events: none;
}

/* Mobile adjustments for beta badge */
@media (max-width: 768px) {
    .beta-badge {
        font-size: 0.5rem;
        padding: 1px 3px;
        top: -5px;
        right: -3px;
    }
}

/* Override the list 1 rule for toggle group relative height */
.gex-toggle-group {
    height: 34px !important;
}

.gex-toggle-btn.btn:hover {
    color: var(--theme-text-primary);
    background-color: rgba(255, 255, 255, 0.05);
}

/* Active State (Checked Radio + Label OR Active Button) */
.btn-check:checked+.gex-toggle-btn.btn,
.gex-toggle-btn.btn.active {
    background-color: var(--theme-bg-card) !important;
    border-color: var(--theme-border-primary) !important;
    color: var(--theme-text-primary) !important;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) !important;
    font-weight: 600 !important;
}

/* Dark Mode Active */
[data-bs-theme="dark"] .btn-check:checked+.gex-toggle-btn.btn,
[data-bs-theme="dark"] .gex-toggle-btn.btn.active {
    background-color: #2d333b !important;
    border-color: rgba(255, 255, 255, 0.1) !important;
    color: #ffffff !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !important;
}

/* Mobile: Compact View */
@media (max-width: 768px) {
    .gex-toggle-btn.btn {
        padding: 0 0.4rem !important;
        font-size: 0.75rem !important;
        gap: 0.2rem;
    }
}

/* 5. Refresh Button-Specific */
.refresh-wrapper button {
    border-color: var(--theme-border-primary);
    color: var(--theme-text-secondary);
}

.refresh-wrapper button:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

/* ========================================
   DELAYED DATA BANNER
   ======================================== */

.delayed-banner {
    position: sticky;
    top: 56px;  /* Below navbar */
    z-index: 1028;
    margin-bottom: 0.5rem;
    border-radius: 6px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    overflow: hidden;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    animation: slideDown 0.3s ease-out;
}

.delayed-banner-content {
    display: flex;
    align-items: center;
    padding: 0.5rem 1rem;
    gap: 0.5rem;
}

.delayed-icon {
    font-size: 1.25rem;
}

.delayed-text {
    flex: 1;
    font-size: 0.85rem;
    line-height: 1.3;
}

.delayed-banner-actions {
    margin-left: auto;
    display: flex;
    gap: 0.5rem;
}

.delayed-banner button {
    background: white;
    color: #667eea;
    border: none;
    font-weight: 500;
    padding: 0.35rem 0.75rem;
    white-space: nowrap;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
    transition: all 0.2s ease;
}

.delayed-banner button:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

@keyframes slideDown {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Delayed data overlay for OHLC charts */
.delayed-data-overlay {
    position: absolute;
    top: 20%;
    left: 50%;
    transform: translate(-50%, 0) rotate(-30deg);
    font-size: 38px;
    font-weight: 600;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    color: rgba(220, 38, 38, 0.12);
    pointer-events: none;
    z-index: 10;
    white-space: nowrap;
    user-select: none;
}

[data-bs-theme="dark"] .delayed-data-overlay {
    color: rgba(248, 113, 113, 0.10);
}

/* ========================================
   REFRESH BUTTON & INLINE COUNTDOWN
   ======================================== */

/* Refresh icon — ensure spin animation rotates around center */
#refresh-icon {
    transform-origin: center;
    vertical-align: middle;
}

/* Manual-refresh spin lives on the BUTTON (stable), not the icon: lucide's
   global createIcons() swaps the #refresh-icon <svg> mid-refresh, so an inline
   animation on the icon would survive on a detached node and spin forever.
   Targeting the current child via the button class is immune to that swap. */
#gex-manual-refresh-btn.is-refreshing #refresh-icon {
    animation: spin 1s linear infinite;
}

/* Inline countdown text inside refresh button — fixed width to prevent button resizing */
.refresh-countdown-text {
    display: inline-block;
    width: 2.2em;
    text-align: right;
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.3px;
    color: var(--theme-text-secondary);
}

/* Hide empty countdown (no text yet) */
.refresh-countdown-text:empty {
    display: none;
}

/* Premium tier — green countdown text */
.refresh-countdown-text.countdown-premium {
    color: var(--marker-pos-bg);
}

/* Free tier — amber countdown text */
.refresh-countdown-text.countdown-free {
    color: #ff9800;
}

/* Refresh button - rate limited state (free tier) */
#gex-manual-refresh-btn.rate-limited {
    opacity: 0.6;
    cursor: not-allowed;
    pointer-events: auto;
    /* Still allow clicks to show upgrade prompt */
}

#gex-manual-refresh-btn.rate-limited:hover {
    opacity: 0.7;
    transform: none;
    /* Disable hover animations */
}

/* Mobile responsive adjustments */
@media (max-width: 768px) {
    /* Header refresh button - compact on mobile */
    #gex-manual-refresh-btn {
        padding: 0.25rem 0.5rem !important;
        font-size: 0.875rem;
    }

    #gex-manual-refresh-btn span {
        line-height: 1;
    }

    .refresh-countdown-text {
        font-size: 0.7rem;
        width: 2em;
    }
}

/* ========================================
   CARD COMPONENTS
   ======================================== */

/*
 * Only the primary card wrapper in gex_index.html should be transparent so
 * that the full-width layout blends with the surrounding background. Scope
 * the overrides to that wrapper so cards elsewhere use the theme defaults.
 */
.main-content-full>.card {
    border: none;
    margin-bottom: 0;
    max-width: 100%;
    overflow-x: hidden;
    overflow-y: visible;
    background-color: transparent !important;
}

.main-content-full>.card .card-body {
    background-color: transparent !important;
    padding: 0.5rem 0rem 0rem 0rem !important;
    overflow: visible;
}

/* ========================================
   MARKER & ZONE ITEMS
   ======================================== */

/* Note: .marker-item base styles are defined later in the file (line ~814) */

.zone-item {
    border-radius: 4px;
    transition: all 0.2s ease;
}

.zone-item:hover {
    transform: translateX(4px) !important;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
    background-color: var(--zone-hover-color) !important;
}

/* Cliff indicator styling */
.cliff-indicator {
    transition: all 0.2s ease;
}

.cliff-indicator:hover {
    opacity: 1 !important;
    transform: scale(1.1);
}


.key-marker-item {
    transition: all 0.2s ease;
    background-color: var(--theme-bg-card);
    border-color: var(--theme-border-primary);
}

.key-marker-item:hover {
    transform: translateX(2px);
    box-shadow: var(--theme-shadow-md) !important;
}

/* ========================================
   GUIDE MODAL
   ======================================== */

.guide-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    animation: fadeIn 0.2s ease;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.guide-modal-content {
    border-radius: 12px;
    max-width: 900px;
    width: 90%;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    animation: slideIn 0.3s ease;
}

@keyframes slideIn {
    from {
        transform: translateY(-50px);
        opacity: 0;
    }

    to {
        transform: translateY(0);
        opacity: 1;
    }
}

.guide-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 25px;
    border-radius: 12px 12px 0 0;
}

.guide-modal-header h5 {
    margin: 0;
    font-weight: 600;
}

.guide-modal-body {
    padding: 25px;
    overflow-y: auto;
    flex: 1;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

/* ========================================
   SETTINGS DRAWER (right-side, like HelpDrawer)
   ======================================== */

#settingsModal {
    align-items: stretch;
    justify-content: flex-end;
    background-color: rgba(0, 0, 0, 0.4);
    backdrop-filter: none;
    animation: none;
}

#settingsModal .guide-modal-header {
    border-radius: 0;
}

.settings-modal-content {
    max-width: 380px;
    width: 380px;
    max-height: 100vh;
    height: 100%;
    border-radius: 0;
    animation: settingsSlideInRight 0.25s ease;
}

.settings-modal-body {
    padding: 20px 24px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

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

.settings-section:last-child {
    margin-bottom: 0;
}

.settings-section-title {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    opacity: 0.45;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid rgba(128, 128, 128, 0.2);
}

.settings-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.25rem;
    padding: 0.65rem 0;
}

.settings-row + .settings-row {
    border-top: 1px solid rgba(128, 128, 128, 0.12);
}

.settings-row-info {
    flex: 1;
    min-width: 0;
}

.settings-label {
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: 0.3rem;
}

.settings-description {
    font-size: 0.775rem;
    opacity: 0.6;
    line-height: 1.55;
}

.settings-row-control {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding-top: 2px;
}

/* Themed <select> for the Settings timezone picker. Mirrors the .gex-field
   select pattern (gex.css) — color-mix over theme vars so it reads correctly in
   both dark and light themes, with a Lucide chevron-down SVG as the indicator. */
.settings-tz-select {
    appearance: none;
    -webkit-appearance: none;
    font-size: 13px;
    color: var(--gex-fg, #cfd6e4);
    background-color: color-mix(in srgb, var(--gex-surface, #161922) 94%, var(--gex-fg, #cfd6e4) 6%);
    border: 1px solid var(--gex-border, #2a2f3a);
    border-radius: 8px;
    padding: 8px 36px 8px 12px;
    max-width: 260px;
    cursor: pointer;
    line-height: 1.2;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237d8597' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px 16px;
    transition: border-color 120ms ease, background-color 120ms ease;
}
.settings-tz-select:hover {
    border-color: color-mix(in srgb, var(--gex-border, #2a2f3a) 70%, var(--gex-fg, #cfd6e4) 30%);
}
.settings-tz-select:focus {
    outline: none;
    border-color: var(--gex-accent, #6366f1);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--gex-accent, #6366f1) 25%, transparent);
}

@keyframes settingsSlideInRight {
    from {
        transform: translateX(100%);
    }
    to {
        transform: translateX(0);
    }
}

/* --- Mobile: Settings drawer full-width --- */
@media (max-width: 767.98px) {
    .settings-modal-content {
        max-width: 100%;
        width: 100%;
    }

    .settings-row {
        flex-direction: column;
        gap: 0.5rem;
    }

    .settings-row-control {
        align-self: flex-start;
    }
}

/* ========================================
   TABLE MARKERS LAYOUT (DESKTOP & MOBILE)
   ======================================== */

.markers-grouped-desktop {
    display: block;
    /* Show on both desktop and mobile */
}

.marker-section-header {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--theme-text-secondary);
    letter-spacing: 0.5px;
    margin-top: 12px;
    margin-bottom: 8px;
    padding-bottom: 4px;
    border-bottom: 2px solid var(--theme-border-primary);
}

/* Markers table styling */
.markers-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    background: var(--theme-bg-card);
    border: 1px solid var(--theme-border-primary);
    border-radius: 6px;
    overflow: hidden;
}

.markers-table thead {
    background: var(--theme-bg-tertiary);
    border-bottom: 2px solid var(--theme-border-primary);
}

.markers-table th {
    padding: 8px 12px;
    text-align: left;
    font-weight: 600;
    font-size: 0.75rem;
    color: var(--theme-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.markers-table tbody tr {
    border-bottom: 1px solid var(--theme-border-primary);
    transition: all 0.2s ease;
}

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

.markers-table tbody tr:hover {
    background: var(--theme-hover-bg);
    cursor: pointer;
}

.markers-table td {
    padding: 8px 12px;
}

.marker-price-cell {
    font-weight: 700;
    color: var(--theme-text-primary);
}

.marker-value-cell {
    font-weight: 600;
}

.marker-table-row .badge {
    font-size: 0.7rem;
    padding: 3px 8px;
}

/* Mobile-specific table adjustments */
@media (max-width: 768px) {
    .markers-table {
        font-size: 0.8rem;
    }

    .markers-table th {
        padding: 6px 8px;
        font-size: 0.7rem;
    }

    .markers-table td {
        padding: 8px 8px;
    }

    .marker-table-row .badge {
        font-size: 0.65rem;
        padding: 2px 6px;
    }

    /* Larger touch targets on mobile */
    .markers-table tbody tr {
        min-height: 44px;
    }

    .marker-section-header {
        font-size: 0.7rem;
        margin-top: 8px;
        margin-bottom: 6px;
    }
}

/* ========================================
   MARKER WIDGET
   ======================================== */

/* New layout: markers below chart */
#chart-widgets-container {
    display: flex;
    flex-direction: column;
    /* 8px matches the gap between the strike summary rail and the chart's
       plot area (rail.right → #gex-chart's padding-left = 8px), so all gaps
       around the rail look uniform. */
    gap: 8px;
}

.chart-section {
    width: 100%;
    overflow: visible;
    /* Allow full chart visibility */
    position: relative;
    /* Ensure absolute children position relative to this */
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    flex-basis: 0;
    min-height: 250px;
    /* Floor for the chart on very short viewports */
}

.markers-section {
    width: 100%;
    min-height: auto;
    box-shadow: none !important;
    position: relative;
    z-index: 1;
    box-sizing: border-box;
    /* Ensure padding is included in width calculation */
}

/* Remove all shadows from markers section children */
.markers-section * {
    box-shadow: none !important;
}

.marker-tools-container {
    align-items: stretch;
}

.markers-widget {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid var(--theme-border-primary);
    border-radius: 8px;
    background-color: var(--theme-bg-card);
    box-shadow: none;
    overflow: visible;
    box-sizing: border-box;
    /* Ensure border is included in width calculation */
}

[data-bs-theme="dark"] .markers-widget {
    box-shadow: none;
}

.markers-widget-header {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--theme-border-primary);
}

.markers-widget-icon {
    font-size: 1.15rem;
    opacity: 0.7;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.markers-widget-icon svg {
    width: 18px;
    height: 18px;
    stroke-width: 2;
}

.marker-toggle-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    justify-content: flex-start;
    flex: 1 1 auto;
}

.marker-toggle {
    padding: 2px 9px;
    font-size: 0.7rem;
    border: 1px solid var(--theme-border-primary);
    border-radius: 16px;
    background-color: var(--theme-bg-card);
    color: var(--theme-text-primary);
    cursor: pointer;
    transition: all 0.2s ease;
    white-space: nowrap;
    flex: 0 0 auto;
}

.marker-toggle:hover {
    background-color: var(--theme-hover-bg);
}

/* Instant press feedback on mobile — shows immediately on pointerdown,
   before the JS handler runs, so the button feels responsive even when
   the main thread is busy with Plotly rendering */
.marker-toggle:active {
    transform: scale(0.93);
    opacity: 0.8;
    transition: transform 0.05s ease, opacity 0.05s ease;
}

.marker-toggle.active {
    background: linear-gradient(135deg, var(--theme-header-start), var(--theme-header-end));
    color: #ffffff;
    border-color: transparent;
}

.marker-toggle-separator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.25rem;
    color: var(--theme-text-secondary);
    opacity: 0.4;
    font-size: 0.75rem;
    user-select: none;
    pointer-events: none;
}

.markers-widget-body {
    flex: 1;
    overflow-y: auto;
    padding: 0.25rem 0rem 0.25rem 0rem;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

#gex-markers-container {
    display: block;
    min-height: 0;
}

.marker-display {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0.45rem;
    padding: 0rem 0.5rem 0rem 0.5rem;
    overflow-x: auto;
    overflow-y: visible;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scroll-behavior: smooth;
    touch-action: pan-x;
    scroll-snap-type: x proximity;
    /* Gentle snap - "proximity" is less aggressive than "mandatory" */
    scroll-padding-left: 0.5rem;
    /* Preserve left padding when snapping */
    scroll-padding-right: 0.5rem;
    /* Preserve right padding when snapping */
}

.marker-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 0.2rem;
    padding: 0.4rem 0.6rem 0.4rem 0.6rem;
    border-radius: 8px;
    background-color: rgba(0, 0, 0, 0.02);
    border: 1px solid rgba(0, 0, 0, 0.08);
    min-height: 0;
    scroll-snap-align: start;
    /* Snap to start of each marker item */
}

[data-bs-theme="dark"] .marker-item {
    background-color: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
}

.marker-item.max_pain {
    border-color: color-mix(in srgb, var(--marker-mp-bg) 40%, transparent);
}

.marker-item.positive {
    border-color: color-mix(in srgb, var(--marker-pos-bg) 40%, transparent);
}

.marker-item.negative {
    border-color: color-mix(in srgb, var(--marker-neg-bg) 40%, transparent);
}

.marker-item.absolute {
    border-color: color-mix(in srgb, var(--marker-abs-bg) 40%, transparent);
}

.marker-item.flip {
    border-color: color-mix(in srgb, var(--marker-flip-bg) 40%, transparent);
}

/* Price color matches marker type */
.marker-item.max_pain .marker-price {
    color: var(--marker-mp-bg);
}

.marker-item.positive .marker-price {
    color: var(--marker-pos-bg);
}

.marker-item.negative .marker-price {
    color: var(--marker-neg-bg);
}

.marker-item.absolute .marker-price {
    color: var(--marker-abs-bg);
}

[data-bs-theme="dark"] .marker-item.absolute .marker-price {
    color: #d0a6ff;
}

.marker-item.flip .marker-price {
    color: var(--marker-flip-bg);
}

.marker-item.stability .marker-price {
    color: var(--marker-pos-bg);
}

.marker-item.volatility .marker-price {
    color: var(--marker-neg-bg);
}

.marker-label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 600;
    font-size: 0.7rem;
    line-height: 1;
}

.marker-line {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 600;
    font-size: 0.7rem;
    line-height: 1.1;
    width: 100%;
}

/* Light theme: darker subtitle for contrast on white */
.marker-subtitle {
    font-weight: 400;
    color: #7a7a7a;
    font-size: 0.65rem;
    /* Single line always: a wrapping subtitle (e.g. "Regime Change" on a narrow
       mobile card) makes that card taller, and align-items:stretch then pads
       every other card with dead space. Ellipsis is the safety net for any
       future label too long to fit. */
    display: block;
    max-width: 100%;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Dark theme: brighter subtitle for contrast on dark background */
[data-bs-theme="dark"] .marker-subtitle {
    color: #b0b0b0;
}

/* Top row: badge (left) + reach-probability chip (right) on a single baseline.
   space-between keeps the badge left and the chip pinned right; when no chip is
   shown the lone badge sits left. align-items:center guarantees the badge and
   chip are vertically aligned regardless of their differing line-heights. */
.marker-badge-line {
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

.marker-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    line-height: 1;
    flex-shrink: 0;
    position: relative;
    z-index: 1;
}


.marker-price {
    font-weight: 700;
    font-size: 0.7rem;
    color: var(--theme-text-secondary);
    line-height: 1;
}

.marker-value {
    font-size: 0.67rem;
    color: var(--theme-text-secondary);
    line-height: 1;
}

[data-bs-theme="dark"] .marker-value {
    color: var(--theme-text-primary);
}

/* ── Pulse-on-change ─────────────────────────────────────────────────────────
   When a marker's strike or exposure number changes on a data refresh, the
   cell flashes once — green if the value rose, red if it fell — then eases back
   to its normal colour. Mirrors the live-price line pulse, but per number.
   The flash uses box-shadow (not padding) so it never shifts the layout. */
.marker-price,
.marker-value {
    /* Light theme: darker green/red for contrast on light background */
    --marker-pulse-up: #1a9d8f;
    --marker-pulse-up-bg: rgba(38, 166, 154, 0.22);
    --marker-pulse-down: #e53935;
    --marker-pulse-down-bg: rgba(239, 83, 80, 0.22);
}

[data-bs-theme="dark"] .marker-price,
[data-bs-theme="dark"] .marker-value {
    /* Dark theme: brighter tints so the flash reads on dark chips */
    --marker-pulse-up: #4fd1c5;
    --marker-pulse-up-bg: rgba(38, 166, 154, 0.32);
    --marker-pulse-down: #ff6b68;
    --marker-pulse-down-bg: rgba(239, 83, 80, 0.32);
}

.marker-num-pulse-up {
    animation: marker-num-pulse-up 0.5s ease-out;
}

.marker-num-pulse-down {
    animation: marker-num-pulse-down 0.5s ease-out;
}

@keyframes marker-num-pulse-up {
    0% {
        color: var(--marker-pulse-up);
        box-shadow: 0 0 0 3px var(--marker-pulse-up-bg);
        background-color: var(--marker-pulse-up-bg);
        border-radius: 4px;
    }
    100% {
        color: inherit;
        box-shadow: 0 0 0 3px transparent;
        background-color: transparent;
        border-radius: 4px;
    }
}

@keyframes marker-num-pulse-down {
    0% {
        color: var(--marker-pulse-down);
        box-shadow: 0 0 0 3px var(--marker-pulse-down-bg);
        background-color: var(--marker-pulse-down-bg);
        border-radius: 4px;
    }
    100% {
        color: inherit;
        box-shadow: 0 0 0 3px transparent;
        background-color: transparent;
        border-radius: 4px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .marker-num-pulse-up,
    .marker-num-pulse-down {
        animation: none;
    }
}

/* Default width for all marker items */
.marker-display .marker-item {
    min-width: 100px;
    flex: 0 0 100px;
}


/* Width override for zone cards on desktop */
.marker-display .gamma-zone-card {
    min-width: 145px;
    flex: 0 0 145px;
}

.marker-display .gamma-zone-card .marker-price {
    font-size: 0.65rem;
    white-space: nowrap;
}

.gamma-zone-card .marker-line {
    justify-content: center;
}

.gamma-current-price-indicator .marker-line:nth-child(2) {
    margin-top: auto;
    margin-bottom: auto;
    justify-content: center;
    width: 100%;
}

.marker-meta {
    font-size: 0.6rem;
    font-weight: 600;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--theme-text-secondary);
    opacity: 0.75;
    line-height: 1;
}

[data-bs-theme="dark"] .marker-meta {
    color: rgba(255, 255, 255, 0.65);
}

.marker-meta-caption {
    opacity: 0.65;
    font-weight: 500;
}

.marker-meta-label {
    opacity: 0.85;
}

.marker-status {
    font-size: 0.9rem;
    font-weight: 700;
    opacity: 0.85;
    line-height: 1;
    margin-left: auto;
}

.gamma-marker-empty {
    padding: 0.75rem 0.5rem;
}

@media (max-width: 992px) and (min-width: 769px) {

    /* Tablet-specific styles (769px-992px) */
    .markers-widget {
        height: auto;
        width: 100%;
    }

    .markers-widget-header {
        padding: 0.45rem 0.65rem;
        gap: 0.4rem;
    }

    .marker-toggle-group {
        justify-content: flex-start;
        flex-wrap: wrap;
        width: 100%;
        overflow: hidden;
    }

    #chart-widgets-container {
        flex-direction: column;
        align-items: stretch !important;
    }
}

@media (max-width: 768px) {
    .markers-widget {
        border-radius: 12px;
        height: auto;
        width: 100% !important;
        /* Full width — aligned to the chart edges via the card-body inset.
           Keep the card surface + border (like desktop) so the cards read as
           "inside" a container instead of floating loose on the page. */
        background-color: var(--theme-bg-card);
    }

    .markers-widget-header {
        padding: 0.4rem 0.6rem;
    }

    .marker-toggle-group {
        justify-content: flex-start;
        flex-wrap: wrap;
        width: 100%;
        overflow: hidden;
    }

    #chart-widgets-container {
        flex-direction: column;
        align-items: stretch !important;
    }

    .markers-widget-icon {
        font-size: 1rem;
    }

    .marker-toggle {
        font-size: 0.65rem;
        padding: 2px 6px;
    }

    .markers-widget-body {
        padding: 0.25rem 0rem 0.25rem 0rem;
        /* symmetric with top; bottom keeps cards off the widget's bottom border */
        overflow: visible;
    }

    .marker-display {
        gap: 0.35rem;
        padding: 0rem 0.5rem 0rem 0.5rem;
        /* L/R inset so cards float inside the container surface, not on its border.
           The container itself is what aligns with the chart edges. */
        position: relative;
        z-index: 1;
        /* keep marker bar above chart margin but below chart canvas */
    }

    .marker-display .marker-item {
        padding: 0.4rem 0.4rem 0.4rem 0.4rem;
        /* tighter L/R inset so single-line subtitles like "Regime Change" fit */
        min-width: 95px;
        flex: 0 0 95px;
        border-radius: 8px;
        /* smaller than the container's 12px → clean concentric nesting */
    }

    /* Width override for zone cards on mobile */
    .marker-display .gamma-zone-card {
        min-width: 135px;
        flex: 0 0 135px;
    }

    .marker-price {
        font-size: 0.68rem;
    }

    .marker-value {
        font-size: 0.62rem;
    }

    .marker-badge {
        font-size: 0.6rem;
        padding: 3px 7px;
    }
}

/* Old markers-sidebar desktop width - no longer needed */

/* ========================================
   COMMON WIDGET ITEM STYLES (GEX TOTALS & BIAS)
   ======================================== */

/* Common container for both widgets */
.widget-info-container {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: nowrap;
    font-size: 0.82rem;
    line-height: 1.2;
    overflow: hidden;
    padding-left: 0.5rem;
}

/* Common item wrapper (each label:value pair) */
.widget-info-item {
    display: inline-flex;
    align-items: baseline;
    gap: 0.25rem;
    white-space: nowrap;
}

/* Common label style (grey, normal weight) */
.widget-info-label {
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.2px;
    color: var(--theme-text-secondary);
    line-height: 1.2;
}

/* Common value style (bold, colored) */
.widget-info-value {
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--theme-text-primary);
}

/* Color variants for values */
.widget-info-value--call {
    color: var(--theme-positive);
}

.widget-info-value--put {
    color: var(--theme-negative);
}

.widget-info-value--net {
    color: var(--color-info);
}

/* ========================================
   TOTAL GEX PANEL
   ======================================== */

.widget-panel-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding-left: 0.5rem;
    /* Match marker display left padding */
}

.widget-panel-title {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--theme-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 2px 0;
    line-height: 1;
    white-space: nowrap;
    flex-shrink: 0;
}

.gex-totals-panel {
    display: none;
    background-color: var(--theme-bg-card);
    border: 1px solid var(--theme-border-primary);
    border-radius: 8px;
    padding: 4px 0px;
    margin-top: 0.45rem;
    margin-left: 0.5rem;
    margin-right: 0.5rem;
    transition: opacity 0.3s ease-in-out;
}

/* Legacy classes - map to common classes */
.gex-totals-inline {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: nowrap;
    font-size: 0.82rem;
    line-height: 1.2;
    overflow: hidden;
}

.gex-totals-inline span {
    display: inline-flex;
    align-items: baseline;
    gap: 0.25rem;
    white-space: nowrap;
}

.gex-totals-tag {
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.2px;
    color: var(--theme-text-secondary) !important;
}

.gex-totals-tag::after {
    content: ": ";
}

.gex-total-inline {
    display: flex;
    align-items: baseline;
    gap: 0.25rem;
}

.gex-total-inline span:not(.gex-totals-tag) {
    font-weight: 600;
    font-size: 0.8rem;
    color: var(--theme-text-primary);
}

.gex-total-inline--call span:not(.gex-totals-tag) {
    color: var(--theme-positive);
}

.gex-total-inline--put span:not(.gex-totals-tag) {
    color: var(--theme-negative);
}

.gex-total-inline--abs span:not(.gex-totals-tag) {
    color: var(--color-info);
}

@media (max-width: 992px) {

    /* Show totals and bias panels inside markers widget on mobile */
    .markers-section .gex-totals-panel,
    .markers-section #gex-bias-panel {
        display: block;
        width: auto;
        margin-top: 0.35rem;
        margin-bottom: 0.35rem;
        margin-left: 0.5rem;
        margin-right: 0.5rem;
    }
}

/* Very narrow phones (<=480px): hide GEX U/D + Total/C-P panels entirely so
   the marker cards (V, A1/A2, N1/N2, P1/P2…) get the full vertical space and
   don't feel squeezed beneath two extra rows. The same data is still surfaced
   via tooltips on the markers themselves and via the Term chart. */
@media (max-width: 480px) {
    .markers-section .gex-totals-panel,
    .markers-section #gex-bias-panel {
        display: none !important;
    }
}

@media (max-width: 992px) {

    /* Unified font sizing for both panels on mobile */
    .gex-totals-inline,
    .bias-header {
        font-size: 0.72rem;
        gap: 0.45rem;
    }

    .gex-totals-inline span,
    .bias-value-item {
        gap: 0.2rem;
    }

    .gex-totals-tag,
    .bias-ratio-label,
    .bias-value-label {
        font-size: 0.7rem;
    }

    .gex-total-inline span,
    .bias-ratio-value,
    .bias-value-number {
        font-size: 0.72rem;
    }

    .widget-panel-title {
        font-size: 0.68rem;
    }
}

/* ========================================
   ASYMMETRY CARD
   ======================================== */

.asymmetry-card {
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 8px;
    text-align: center;
}

.asymmetry-icon {
    font-size: 2.5rem;
    margin-bottom: 6px;
}

.asymmetry-label {
    font-size: 1.05rem;
    font-weight: 700;
    text-transform: uppercase;
    margin-bottom: 8px;
    letter-spacing: 0.5px;
}

.asymmetry-ratio {
    font-size: 0.85rem;
    margin-bottom: 8px;
}

.asymmetry-detail {
    font-size: 0.75rem;
    opacity: 0.85;
    margin-bottom: 4px;
}

.collapsible-header {
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    user-select: none;
    padding: 4px 0;
}

.collapse-icon {
    transition: transform 0.2s ease;
    font-weight: bold;
}

.collapse-icon.collapsed {
    transform: rotate(-90deg);
}

/* Visual-only hide — opacity fade for the slider's enter/leave transition.
   This DOES NOT remove the slider from layout: its ~150px footprint remains
   in the flex column. Charts that never use the zoom slider (heatmap,
   montecarlo) must also set `display: none` on .slider-section-container,
   which Shell._syncToolbar does based on adapter.id. If you add a new chart
   that doesn't call shell.slider.show(), update that allowlist or you'll get
   a dead band under the chart. */
.slider-section-container.slider-hidden {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

.slider-section-container.slider-discrete .noUi-marker,
.slider-section-container.slider-discrete .noUi-marker-sub {
    display: none;
}

.slider-section-container.slider-discrete .noUi-marker.noUi-marker-large {
    display: block;
}

/* ========================================
   SLIDER STYLES
   ======================================== */

/* Highlight selected slider tick */
#gexThresholdSlider .noUi-value {
    cursor: pointer;
}

#gexThresholdSlider .noUi-value.active-tick {
    font-weight: bold;
    font-size: 1.1em;
}

/* ========================================
   BIAS PANEL
   ======================================== */

#gex-bias-panel {
    margin-top: 0.45rem;
    margin-left: 0.5rem;
    margin-right: 0.5rem;
}

.gex-bias-panel-content {
    border-radius: 8px;
    padding: 4px 0px;
    background-color: var(--theme-bg-card);
    border: 1px solid var(--theme-border-primary);
}

.bias-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0;
    font-size: 0.82rem;
    line-height: 1.2;
}

.bias-icon {
    display: none;
}

.bias-info {
    flex: 1;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
}

/* Legacy bias classes - map to common widget classes */
.bias-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.2px;
    line-height: 1.2;
    color: var(--theme-text-primary);
}

.bias-ratio-line {
    display: flex;
    align-items: baseline;
    gap: 0.25rem;
}

.bias-ratio-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--theme-text-secondary);
    line-height: 1.2;
    letter-spacing: 0.2px;
}

.bias-ratio-value {
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--theme-text-primary);
}

.bias-values {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.bias-value-item {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: 0.25rem;
}

.bias-value-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--theme-text-secondary);
    letter-spacing: 0.2px;
    line-height: 1.2;
}

.bias-value-number {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--theme-text-primary);
    line-height: 1.2;
}

/* ========================================
   RESPONSIVE SLIDER (SINGLE SLIDER)
   ======================================== */

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

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

.slider-track {
    flex: 1;
}

.slider-value {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.25rem 0.75rem;
    min-width: 64px;
    /* Keep badge width stable as value changes */
    text-align: center;
    font-variant-numeric: tabular-nums;
    /* Use tabular numbers to avoid width jitter */
    transition: none;
    /* Prevent CSS transition-induced width changes */
}

/* Desktop: horizontal layout with label on left */
@media (min-width: 769px) {
    .slider-section-container {
        margin: 0 auto 0;
        padding: 0.75rem 1.5rem 0.5rem 1.5rem;
        border: 1px solid var(--theme-border-primary);
        border-radius: 8px;
        background: var(--theme-bg-card);
        display: grid;
        grid-template-columns: auto 1fr;
        align-items: center;
        gap: 0.75rem;
        /* Fill the parent (which already carries the layout gutter/cap) — do NOT
           re-read --layout-max-width here. With the fluid token min(100% - 2rem),
           consuming it again at this nested level subtracted the gutter a second
           time, insetting the zoom card ~16px past its siblings (chart + markers
           cards), so its borders no longer lined up with the other controls. */
        max-width: 100%;
        width: 100%;
        box-sizing: border-box;
    }

    .slider-header {
        justify-content: flex-start;
        gap: 0.5rem;
    }

    .slider-track {
        /* Reserves room for noUiSlider's pip labels below the track. The pips
           are `position: absolute` (out of flow), so they don't grow this
           box's own auto height — a mismatched padding here doesn't clip
           them visually (nothing sits directly below to reveal it), but it
           does leave them poking past this box's bottom edge. Any ancestor
           that later gains `overflow-y: auto` (e.g. #chart-widgets-container)
           then counts that invisible overhang in its scrollable area, forcing
           scroll that shouldn't be needed. Must stay in sync with the
           .noUi-pips-horizontal height override below (44px box + margin). */
        padding-bottom: 46px;
    }

    /* noUiSlider ships .noUi-pips-horizontal at a fixed 80px, but its real
       content (10px top padding + tick marks + value labels) ends at ~41px —
       the lower half is empty space. Since the pips box is position:absolute,
       that phantom half still counts toward ancestors' scroll overflow (and
       forces the card's padding to over-reserve). Trim the box to content.
       Scoped to .slider-track so the Time Machine slider (.tm-slider-wrapper),
       which has its own pips styling, is untouched. */
    .slider-track .noUi-pips-horizontal {
        height: 44px;
    }
}

/* Mobile: vertical layout, centered label, outside main-content */
@media (max-width: 768px) {
    .slider-section-container {
        /* position: fixed; removed for flex layout */
        /* bottom: 0; removed for flex layout */
        /* left: 0; removed for flex layout */
        /* right: 0; removed for flex layout */
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 0.45rem;
        /* padding: 0.55rem 0.85rem calc(0rem + env(safe-area-inset-bottom, 0px)); */
        padding: 0.55rem 0.5rem calc(0.55rem + env(safe-area-inset-bottom, 10px));
        /* Restore safe area padding */
        /* Strike/profile slider hidden on mobile; term DTE slider shown via .slider-discrete */
        display: none;
        background: var(--theme-bg-card);
        /* border-top: 1px solid var(--theme-border-primary); removed */
        border: 1px solid var(--theme-border-primary);
        /* Add full border */
        border-radius: 8px;
        /* Rounded corners */
        box-shadow: none;
        /* z-index: 1100; removed */
        flex-shrink: 0;
        /* Prevent shrinking */
        margin: 0;
        /* Align edges with the chart (like the markers widget) and let the
           body's reserved bottom space be the only gap to the fixed nav, so the
           gap matches the other tabs (was 16px here vs 8px elsewhere). */
    }

    .slider-header {
        margin-bottom: 0;
    }

    .slider-label {
        font-size: 0.9rem;
        font-weight: 600;
        letter-spacing: 0.4px;
    }

    .slider-wrapper {
        align-items: center;
        gap: 0.45rem;
    }

    .slider-track {
        padding-bottom: 30px;
    }

    .slider-value {
        font-size: 0.82rem;
        padding: 0.25rem 0.65rem;
        min-width: 60px;
        /* Fixed width to prevent layout shift */
        width: 60px;
        text-align: center;
        flex-shrink: 0;
        font-variant-numeric: tabular-nums;
        /* Monospace numbers */
    }

    /* Larger touch targets for mobile */
    #gexThresholdSlider .noUi-handle {
        width: 30px !important;
        height: 30px !important;
        right: -15px !important;
        top: -13px !important;
        border-radius: 50%;
        cursor: pointer;
        touch-action: none;
        box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
    }

    #gexThresholdSlider .noUi-target {
        height: 7px;
        touch-action: none;
    }

    #gexThresholdSlider .noUi-base {
        touch-action: none;
    }

    #gexThresholdSlider .noUi-pips {
        font-size: 0.55rem;
    }

    #gexThresholdSlider .noUi-value {
        padding: 1px 2px;
    }

    #gexThresholdSlider .noUi-marker-large {
        height: 6px;
    }

    /* Show slider on mobile only for term chart (DTE filter) */
    .slider-section-container.slider-discrete {
        display: flex;
    }

    /* Extra right padding so last DTE pip label doesn't overflow panel border */
    .slider-section-container.slider-discrete {
        padding-right: 1.2rem;
    }
}

@media (max-width: 768px) {
    .gex-container {
        padding-bottom: 0 !important;
        /* Force remove fixed padding */
    }

    .gex-totals-row {
        gap: 0.35rem;
    }

    .gex-total-chip {
        padding: 0.22rem 0.35rem;
        gap: 0.25rem;
    }

    .gex-total-title {
        font-size: 0.7rem;
    }

    .gex-total-label {
        font-size: 0.6rem;
    }

    .gex-total-value {
        font-size: 0.78rem;
    }
}

/* Hide vertical toolbar on mobile */
@media (max-width: 768px) {
    .vertical-toolbar {
        display: none;
    }
}

/* Very small phones - wrap GEX totals into 2 rows */
/* Very small phones - wrap GEX totals into 2 rows */
@media (max-width: 380px) {

    .gex-totals-inline,
    .bias-info {
        flex-wrap: wrap !important;
        gap: 0.4rem 0.5rem !important;
        /* vertical gap, horizontal gap */
        justify-content: space-between;
    }

    .gex-total-inline,
    .bias-value-item {
        flex: 0 0 48%;
        /* Each item takes ~48% width, creates 2x2 grid */
        min-width: 0;
        /* Allow text truncation if needed */
        justify-content: flex-start;
        /* Ensure items align left */
    }

    .gex-totals-panel,
    .gex-bias-panel-content {
        padding: 6px 8px !important;
        /* Slightly more padding for wrapped layout */
    }

    /* Adjust bias header to allow wrapping if needed, or keep label on top */
    .bias-header {
        flex-wrap: wrap;
    }

    .bias-info {
        display: flex;
        /* Ensure flex behavior */
        width: 100%;
        /* Take full width to force wrapping */
    }
}

/* ========================================
   RESPONSIVE DESIGN
   ======================================== */

/* ========================================
   MOBILE LAYOUT - CONSISTENT 8px (0.5rem) PADDING
   ========================================
   Strategy: All content elements use 8px horizontal padding
   - Card body provides base padding
   - chart-widgets-container breaks out with negative margins
   - All child elements add padding back for consistent alignment
   ======================================== */

@media (max-width: 768px) {
    .main-content-full {
        padding: 0;
        overflow-x: visible !important;
        /* Allow content to use margins */
    }

    .main-content-full>.card {
        margin-bottom: 0.5rem;
        border-radius: 0;
        overflow-x: visible !important;
        /* Allow markers-widget margins to show */
    }

    .main-content-full>.card .card-body {
        padding: 0.5rem 0.5rem !important;
        /* Base 8px padding - matches toolbar */
    }

    /* Compact spacing for chart widgets container - stays within card-body padding */
    #chart-widgets-container {
        margin-bottom: 0 !important;
        padding: 0 !important;
        gap: 0.25rem !important;
        /* Reduced gap for mobile */
        overflow: hidden !important;
        /* Override overflow-y: auto — force flex to constrain chart for slider space */
    }

    /* Chart section - no padding needed, charts extend to card-body edges */
    .chart-section {
        padding: 0 !important;
        box-sizing: border-box !important;
    }

    /* Markers section - edges align with the chart (which sits at the
       card-body 8px inset). */
    .markers-section {
        padding: 0 !important;
        /* No extra inset: the card-body 8px already matches the chart edges */
        box-sizing: border-box !important;
    }

    /* Term container - no padding at container level, handled by child views */
    .gex-term-container {
        padding: 0 !important;
    }

    /* #gex-term-chart-view styling moved to Term Structure section below */

    /* term-marker-widget padding now handled by parent .markers-section */

    /* Delayed banner - ensure it extends to edges with proper padding */
    .delayed-banner {
        margin-left: -0.5rem;
        margin-right: -0.5rem;
        border-radius: 0;
        /* Full width on mobile */
    }

    .delayed-banner-content {
        padding: 0.5rem;
        /* Consistent 8px padding to match toolbar */
    }

    /* Chart containers should use full width */
    .gex-chart-container {
        width: 100% !important;
        padding: 0 !important;
        margin: 0 !important;
    }

    /* Smaller logo on mobile */
    #header-logo {
        height: 32px !important;
    }
}

/* ========================================
   GEX TERM STRUCTURE STYLES
   ======================================== */

/* Term Container - flex column to participate in the chart-section flex chain.
   When JS hides it via inline style="display:none", the inline rule wins; when
   JS clears the inline style (display=''), this CSS display:flex applies. */
.gex-term-container {
    padding: 0;
    width: 100%;
    margin: 0;
    position: relative; /* required for loading overlay pseudo-elements */
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    flex-basis: 0;
    min-height: 0;
    /* Clip the +title overflow from #gex-term-plot (height:100% inside a
       flex column with a sibling title). Mirrors .gex-chart-container's
       overflow:hidden. */
    overflow: hidden;
}

/* =====================================================================
   View Controls Row (Container for view switcher + expiration controls)
   ===================================================================== */

/* View switcher container - aligns switcher to start */
.view-switcher-container {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    margin-bottom: 0;
}

/* =====================================================================
   View Switcher (Compact toggle buttons)
   ===================================================================== */

.view-switcher {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.3rem;
    border-radius: 999px;
    border: 1px solid var(--theme-border-primary);
    background: var(--theme-bg-secondary);
    max-width: 280px;
    flex-wrap: nowrap;
}

/* GEX View Containers — apply flex-item properties to ALL .gex-view elements,
   not just .gex-view.active. JS toggles inline `style.display` to switch
   views but does NOT toggle the .active class, so #gex-ohlc-view and
   #gex-heatmap-view never match a .gex-view.active selector. Hidden views
   still have inline display:none which wins over display:flex. The
   flex-item properties (flex-grow, flex-basis, min-height) must apply to
   whichever view is currently visible so it gets a definite height from
   .chart-section's flex layout. Without this, LightweightCharts (OHLC)
   sees an auto-sized parent and enters a ResizeObserver feedback loop,
   growing the container unbounded. */
.gex-view {
    width: 100%;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    flex-basis: 0;
    min-height: 0;
}

.gex-ohlc-container {
    position: relative;
    background: var(--theme-bg-card);
    border-radius: 0.75rem;
    border: 1px solid var(--theme-border-primary);
    padding: 0rem 0.6rem 1.4rem 0.6rem;
    /* extra bottom padding so x-axis labels aren't clipped */
    width: 100%;
    max-width: 100%;
    overflow: hidden;
}

/* OHLC Metadata Overlay - displays chart info at top-left */
.gex-ohlc-metadata-overlay {
    position: absolute;
    top: 12px;
    left: 12px;
    /* Moved right to avoid Y-axis overlap */
    z-index: 10;
    padding: 6px 12px;
    background: rgba(var(--theme-bg-card-rgb), 0.85);
    backdrop-filter: blur(4px);
    border: 1px solid var(--theme-border-secondary);
    border-radius: 6px;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--theme-text-primary);
    pointer-events: none;
    white-space: nowrap;
    line-height: 1.4;
}

/* Specific override for GEX by Strike view to avoid Y-axis overlap */
.gex-strike-metadata-overlay {
    left: 100px;
}

/* Dark mode specific adjustments */
[data-theme="dark"] .gex-ohlc-metadata-overlay {
    background: rgba(30, 30, 35, 0.9);
    border-color: rgba(255, 255, 255, 0.15);
}

/* Light mode specific adjustments */
[data-theme="light"] .gex-ohlc-metadata-overlay {
    background: rgba(255, 255, 255, 0.9);
    border-color: rgba(0, 0, 0, 0.1);
}

/* Static Chart Title (replaces overlay) - Two-line, left-aligned */
.gex-chart-title {
    display: block;
    width: 100%;
    padding: 4px 0 2px 8px;
    margin-bottom: 0;
    background: transparent;
    border-bottom: none;
    font-size: 12px;
    font-weight: normal;
    color: var(--theme-text-primary);
    white-space: normal;
    line-height: 1.4;
    box-sizing: border-box;
    text-align: left;
}

/* Align the chart title with the chart's plot area when the rail occupies
   one side (332 px including the 8 px gap). */
#gex-bars-view.with-summary-rail-left > .gex-chart-title {
    margin-left: 332px;
    padding-left: 8px;
}
#gex-bars-view.with-summary-rail-right > .gex-chart-title {
    margin-right: 332px;
}

/* GEX C/P / U/D summary panels are hidden by default everywhere — the
   summary rail (desktop) already surfaces Flip Point / Hedging Pressure /
   Absolute GEX, and on mobile the totals strip duplicates info already
   visible in marker chips above. Freed pixels flow back to chart-section. */
.markers-section .gex-totals-panel,
.markers-section #gex-bias-panel {
    display: none !important;
}
[data-theme="dark"] .gex-chart-title {
    color: #e0e0e0;
}

[data-theme="light"] .gex-chart-title {
    color: #333333;
}

/* Responsive styles for view controls */
@media (max-width: 768px) {
    .view-controls-row {
        gap: 0.5rem;
        padding: 0 0.75rem;
        /* Match card-body horizontal padding */
        margin-bottom: 0.35rem;
    }

    #strike-profile-view-controls-row {
        margin-bottom: 0.35rem;
    }

    .view-switcher-container {
        margin-bottom: 0;
    }

    .view-switcher {
        max-width: 100%;
        padding: 0.2rem;
        gap: 0.2rem;
    }

    .expiration-controls {
        gap: 0.4rem;
        justify-content: flex-end;
    }

    /* Make expiration selector wider on mobile to show full dates */
    .expiration-controls .gex-expiration-select {
        max-width: 160px !important;
        min-width: 120px !important;
        font-size: 0.8rem;
    }

    .gex-ohlc-container {
        height: 455px !important;
        /* Match Plotly chart height */
        width: 100% !important;
        max-width: 100% !important;
        padding: 0;
        /* Remove padding to match Plotly width */
        margin: 0 auto;
    }

    .gex-ohlc-metadata-overlay {
        font-size: 0.65rem;
        padding: 4px 6px;
        top: 6px;
        left: 6px;
        /* Moved right for mobile too */
    }

    .gex-strike-metadata-overlay {
        left: 60px;
    }
}

/* Very small screens - keep in one row but make everything smaller */
@media (max-width: 576px) {
    .view-controls-row {
        gap: 0.4rem;
    }

    .expiration-controls .gex-expiration-select {
        max-width: 140px !important;
        min-width: 110px !important;
    }
}



/* Old View Button Styles Removed (Unified) */

/* Responsive styles for view buttons */
@media (max-width: 768px) {
    .view-btn {
        font-size: 0.8rem;
        padding: 0.25rem 0.5rem;
    }
}

/* Table View */
#gex-term-table-view {
    padding: 0 0.5rem;
    overflow-x: hidden;
    background: var(--theme-bg-card);
    border-radius: 0.75rem;
    border: 1px solid var(--theme-border-primary);
}

.gex-term-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin-top: 1rem;
}

.gex-term-table thead {
    position: sticky;
    top: 0;
    background: var(--theme-bg-card);
    z-index: 10;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.gex-term-table th,
.gex-term-table td {
    padding: 0.75rem;
    text-align: right;
    border-bottom: 1px solid var(--theme-border-primary);
    white-space: nowrap;
}

.gex-term-table th:first-child,
.gex-term-table td:first-child {
    text-align: left;
    font-weight: 600;
}

.gex-term-table td.strike-cell {
    cursor: pointer;
    transition: background 0.2s;
}

.gex-term-table td.strike-cell:hover {
    background: var(--hover-bg);
}

.gex-term-table tr.total-row {
    font-weight: 700;
    background: var(--theme-bg-tertiary);
}

/* Marker column coloring */
.gex-term-table thead .marker-max-pain {
    color: var(--marker-mp-bg);
}

.gex-term-table thead .marker-positive {
    color: var(--marker-pos-bg);
}

.gex-term-table thead .marker-negative {
    color: var(--marker-neg-bg);
}

.gex-term-table thead .marker-absolute {
    color: var(--marker-abs-bg);
}

.gex-term-table thead .marker-flip {
    color: var(--marker-flip-bg);
}

@media (max-width: 768px) {
    #gex-term-table-view {
        padding: 0 0.25rem;
        overflow-x: auto;
    }

    .gex-term-table {
        width: auto;
        min-width: 100%;
    }

    .gex-term-table th,
    .gex-term-table td {
        padding: 0.5rem 0.35rem;
        font-size: 0.78rem;
    }
}

/* Chart View */
#gex-term-chart-view {
    padding: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    flex-basis: 0;
    min-height: 0;
}

#gex-term-plot {
    width: 100%;
    /* Plotly writes inline `style="height: …px"` on render and doesn't
       update it when the flex layout reflows. !important overrides that
       stale value. height:100% + flex-grow:1 mirrors how the strike chart
       container works (.gex-chart-container) — the resulting overflow into
       the title's row is clipped by overflow:hidden on .gex-term-container. */
    height: 100% !important;
    flex-grow: 1 !important;
    min-height: 0;
    margin: 0;
    padding: 0;
}

/* Ensure Plotly fills its container */
#gex-term-plot .plotly,
#gex-term-plot .plot-container,
#gex-term-plot .js-plotly-plot {
    width: 100% !important;
    height: 100% !important;
    margin: 0;
    padding: 0;
}

/* term-marker-widget is now wrapped by .markers-section, spacing handled by parent */

.term-marker-widget .markers-widget-body {
    padding: 0.5rem 0.75rem 0.6rem;
    overflow: visible;
}

.term-widget-header {
    justify-content: flex-start;
    gap: 0.5rem;
    padding: 0.45rem 0.75rem;
}

.term-widget-title {
    font-weight: 600;
    font-size: 0.82rem;
    color: var(--text-primary);
}

/* Marker Toggle Panel - Badge Style */
.term-marker-toggle-panel {
    padding: 0;
}

.term-badge-scroll-container {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    padding-bottom: 0.25rem;
}

.term-badge-scroll-container::-webkit-scrollbar {
    height: 6px;
}

.term-badge-scroll-container::-webkit-scrollbar-track {
    background: var(--theme-bg-card);
    border-radius: 3px;
}

.term-badge-scroll-container::-webkit-scrollbar-thumb {
    background: var(--theme-border-primary);
    border-radius: 3px;
}

.term-badge-scroll-container::-webkit-scrollbar-thumb:hover {
    background: var(--accent-primary);
}

.term-marker-badge {
    padding: 2px 9px;
    white-space: nowrap;
}

.term-marker-badge.active {
    background: linear-gradient(135deg, var(--theme-header-start), var(--theme-header-end));
    color: #ffffff;
    border-color: transparent;
}

/* Marker badges - active state with specific colors matching chart traces */
.term-badge-max-pain.active {
    background: var(--marker-mp-bg);
    border-color: color-mix(in srgb, var(--marker-mp-bg) 50%, transparent);
    color: #ffffff;
}

.term-badge-flip-points.active {
    background: var(--marker-flip-bg);
    border-color: color-mix(in srgb, var(--marker-flip-bg) 50%, transparent);
    color: #ffffff;
}

.term-badge-positive.active {
    background: var(--marker-pos-bg);
    border-color: color-mix(in srgb, var(--marker-pos-bg) 50%, transparent);
    color: #ffffff;
}

.term-badge-negative.active {
    background: var(--marker-neg-bg);
    border-color: color-mix(in srgb, var(--marker-neg-bg) 50%, transparent);
    color: #ffffff;
}

.term-badge-absolute.active {
    background: var(--marker-abs-bg);
    border-color: color-mix(in srgb, var(--marker-abs-bg) 50%, transparent);
    color: #ffffff;
}

/* Mobile Responsive */
@media (max-width: 768px) {
    /* Override general .chart-section overflow:visible for mobile —
       prevents Plotly x-axis labels from overlapping the markers widget below */
    .chart-section {
        overflow: hidden;
    }
}

/* ========================================
   REPLAY CONTROLS (TIME MACHINE) - MOBILE
   ======================================== */

@media (max-width: 768px) {

    /* Increase Replay Controls Size */
    /* Increase Replay Controls Size */
    .tm-playback-controls button {
        padding: 0.35rem 0.7rem !important;
        font-size: 1.0rem !important;
        min-width: 30px;
        min-height: 30px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Increase Timeline Slider Toggle Size */
    #tm-slider .noUi-handle {
        width: 28px !important;
        height: 28px !important;
        right: -14px !important;
        top: -11px !important;
        box-shadow: 0 0 5px rgba(0, 0, 0, 0.4);
    }

    /* Ensure slider track accommodates larger handle */
    #tm-slider {
        height: 8px !important;
    }

    /* Increase Spacing Between Timeline and Controls */
    .tm-slider-wrapper {
        margin-top: 0.5rem !important;
    }

    /* Term View (Chart/Table) should fill available space */
    .term-view {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        flex-basis: 0;
        min-height: 0;
        margin: 0;
    }

    #gex-term-plot {
        flex-grow: 1;
        flex-basis: 0;
        min-height: 0;
        height: 100% !important;
        /* Override desktop fixed height */
        margin: 0;
    }

    /* Ensure Plotly chart fills container on mobile */
    #gex-term-plot .main-svg,
    #gex-term-plot .js-plotly-plot,
    #gex-term-plot .plot-container,
    #gex-term-plot .plotly {
        width: 100% !important;
        height: 100% !important;
    }

    #gex-term-plot .main-svg {
        border-radius: 0;
    }

    /* OHLC Container specific flex rules */
    .gex-ohlc-container {
        display: flex;
        flex-direction: column;
        height: 100% !important;
        min-height: 0 !important;
        flex-grow: 1;
        margin: 0;
        padding: 0;
    }

    /* Ensure the wrapper also expands */
    #gex-ohlc-view {
        display: flex;
        flex-direction: column;
        height: 100% !important;
        flex-grow: 1;
    }

    #gex-term-container .view-controls-row {
        margin-bottom: 0.35rem;
        padding: 0 0.75rem;
    }

    #gex-term-chart-view {
        padding: 0 0.5rem;
        /* Horizontal padding for toolbar alignment */
        height: 100% !important;
        flex-grow: 1;
        flex-basis: 0;
        min-height: 0;
    }

    /* #gex-term-plot { min-height: 300px; } Removed to allow flex shrinking */

    /* .term-marker-widget margin now handled by parent .term-markers-section */

    .gex-term-table {
        font-size: 0.75rem;
    }

    .gex-term-table th,
    .gex-term-table td {
        padding: 0.5rem 0.25rem;
    }

    .term-marker-toggle-panel {
        grid-template-columns: 1fr;
    }
}

/* ========================================
   MARKER BADGE UTILITIES (Centralized)
   ======================================== */
.marker-badge-pos {
    background-color: var(--marker-pos-bg) !important;
    color: var(--marker-pos-text) !important;
}

.marker-badge-neg {
    background-color: var(--marker-neg-bg) !important;
    color: var(--marker-neg-text) !important;
}

.marker-badge-abs {
    background-color: var(--marker-abs-bg) !important;
    color: var(--marker-abs-text) !important;
}

.marker-badge-flip {
    background-color: var(--marker-flip-bg) !important;
    color: var(--marker-flip-text) !important;
}

.marker-badge-mp {
    background-color: var(--marker-mp-bg) !important;
    color: var(--marker-mp-text) !important;
}

/* Status indicator removed - integrated into chart title */
/* Initialization: Fade in controls to prevent flickering.
   Uses opacity-only (no visibility:hidden) to preserve layout space and prevent layout shift. */
.gex-controls-init-hidden {
    opacity: 0 !important;
    transition: opacity 0.2s ease-in;
}

.gex-controls-visible {
    opacity: 1;
}

/* ========================================
   TIME MACHINE (REPLAY)
   ======================================== */

/* Time Machine Controls Bar (replay timeline only, hidden in live mode) */
.tm-controls-bar {
    padding: 4px var(--toolbar-px, 12px) 20px;
}

/* Playback buttons */
.tm-playback-controls {
    display: flex;
    gap: 2px;
    flex-shrink: 0;
}

.tm-playback-controls .btn {
    font-size: 0.75rem;
    padding: 0.2rem 0.45rem;
    line-height: 1;
}

.tm-playback-controls .btn:active {
    transform: scale(0.9);
    opacity: 0.75;
}

/* Share replay link button */
#tm-share-btn {
    flex-shrink: 0;
    padding: 0.2rem 0.4rem;
    line-height: 1;
}

/* Speed control buttons removed - now using select/combobox */

/* Timeline slider */
.tm-slider-wrapper {
    flex: 1;
    min-width: 120px;
    padding: 0 4px;
}

.tm-slider-wrapper .noUi-target {
    height: 6px;
    border: none;
    box-shadow: none;
    background: var(--bs-border-color, #dee2e6);
}

.tm-slider-wrapper .noUi-connect {
    background: var(--bs-primary, #0d6efd);
}

.tm-slider-wrapper .noUi-handle {
    width: 16px;
    height: 16px;
    right: -8px;
    top: -6px;
    border-radius: 50%;
    background: var(--bs-primary, #0d6efd);
    border: 2px solid #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    cursor: pointer;
}

.tm-slider-wrapper .noUi-handle::before,
.tm-slider-wrapper .noUi-handle::after {
    display: none;
}

/* Slider tooltip */
.tm-slider-wrapper .noUi-tooltip {
    display: none;
    /* Hidden by default, shown only during drag */
    background: rgba(0, 0, 0, 0.9);
    color: #fff;
    border: none;
    border-radius: 4px;
    padding: 6px 10px;
    font-size: 0.66rem;
    font-weight: 500;
    white-space: nowrap;
    bottom: 125%;
    /* Closer to handle than 200% */
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    transition: transform 0.15s ease-out;
}

/* Tooltip positioning when near left edge */
.tm-slider-wrapper .noUi-tooltip.align-left {
    transform: translateX(0);
    left: 0;
}

/* Tooltip positioning when near right edge */
.tm-slider-wrapper .noUi-tooltip.align-right {
    transform: translateX(-100%);
    left: 0;
}

/* Slider pips (day/4h tick marks) */
.tm-slider-wrapper .noUi-pips {
    font-size: 0.5rem;
    padding: 3px 0 0;
    height: 24px;
    color: var(--theme-text-secondary, #6c757d);
}

.tm-slider-wrapper .noUi-pips .noUi-marker-large {
    height: 8px;
    width: 1px;
    background: var(--theme-text-secondary, #6c757d);
}

.tm-slider-wrapper .noUi-pips .noUi-marker-normal,
.tm-slider-wrapper .noUi-pips .noUi-marker-sub {
    height: 4px;
    width: 1px;
    background: var(--theme-text-muted, #adb5bd);
}

.tm-slider-wrapper .noUi-pips .noUi-value {
    font-size: 0.5rem;
    color: var(--theme-text-secondary, #6c757d);
    padding-top: 1px;
    cursor: pointer;
    transition: color 0.15s;
}

.tm-slider-wrapper .noUi-pips .noUi-value:hover {
    color: var(--theme-text-primary, #fff);
}

.tm-slider-wrapper .noUi-pips .noUi-value-sub {
    display: none;
}

.tm-date-picker {
    width: auto;
    max-width: 140px;
    font-size: 0.75rem;
    flex-shrink: 0;
}

/* Hide clear/reset button on date picker */
.tm-date-picker::-webkit-clear-button,
.tm-date-picker::-ms-clear {
    display: none;
}

/* Speed select styling removed - now handled in responsive section above */


/* Disabled chart/view mode buttons during replay */
.gex-toggle-btn.tm-disabled {
    opacity: 0.35;
    pointer-events: none;
    cursor: not-allowed;
}

/* Mobile: Stack replay bar */
@media (max-width: 767px) {
    .tm-controls-bar {
        padding-bottom: 2rem;
        /* Increased spacing between timeline and chart on mobile */
    }

    .tm-controls-bar .d-flex {
        flex-wrap: wrap;
        gap: 6px;
    }

    .tm-slider-wrapper {
        min-width: 100%;
        order: 10;
        overflow: visible !important;
        /* Ensure handle isn't clipped */
        padding: 0 10px;
        /* Add padding for handle overhang */
    }

    .tm-date-picker {
        max-width: 150px;
    }
}


/* ========================================
   TIPPY.JS TOOLTIP THEMES
   Contextual tooltips for UI controls and
   chart markers (Phase 1 Help System)
   ======================================== */

/* --- Light Theme --- */
.tippy-box[data-theme~='gex-light'] {
    background-color: #ffffff;
    color: #212529;
    border: 1px solid #dee2e6;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    font-size: 0.8125rem;
    line-height: 1.4;
    border-radius: 6px;
}

.tippy-box[data-theme~='gex-light'][data-placement^='top'] > .tippy-arrow::before {
    border-top-color: #ffffff;
}

.tippy-box[data-theme~='gex-light'][data-placement^='bottom'] > .tippy-arrow::before {
    border-bottom-color: #ffffff;
}

.tippy-box[data-theme~='gex-light'][data-placement^='left'] > .tippy-arrow::before {
    border-left-color: #ffffff;
}

.tippy-box[data-theme~='gex-light'][data-placement^='right'] > .tippy-arrow::before {
    border-right-color: #ffffff;
}

/* --- Dark Theme --- */
.tippy-box[data-theme~='gex-dark'] {
    background-color: #161b22;
    color: #e6edf3;
    border: 1px solid #30363d;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    font-size: 0.8125rem;
    line-height: 1.4;
    border-radius: 6px;
}

.tippy-box[data-theme~='gex-dark'][data-placement^='top'] > .tippy-arrow::before {
    border-top-color: #161b22;
}

.tippy-box[data-theme~='gex-dark'][data-placement^='bottom'] > .tippy-arrow::before {
    border-bottom-color: #161b22;
}

.tippy-box[data-theme~='gex-dark'][data-placement^='left'] > .tippy-arrow::before {
    border-left-color: #161b22;
}

.tippy-box[data-theme~='gex-dark'][data-placement^='right'] > .tippy-arrow::before {
    border-right-color: #161b22;
}

/* --- Mobile --- */
@media (max-width: 767.98px) {
    .tippy-box[data-theme~='gex-light'],
    .tippy-box[data-theme~='gex-dark'] {
        font-size: 0.75rem;
        max-width: 240px;
    }
}


/* ========================================
   HELP DRAWER (Phase 2 Help System)
   Searchable side panel using Bootstrap
   Offcanvas + Fuse.js fuzzy search
   ======================================== */

/* --- Offcanvas Override --- */
.help-drawer {
    width: 380px;
    border-left: 1px solid var(--theme-border-color, #dee2e6);
    background-color: var(--theme-bg-secondary);
    color: var(--theme-text-primary);
    z-index: 10050;
}

.help-drawer-header {
    border-bottom: 1px solid var(--theme-border-color, #dee2e6);
    padding: 16px 20px;
    background-color: var(--theme-bg-secondary);
}

.help-drawer-header .offcanvas-title {
    font-weight: 600;
    font-size: 1.1rem;
}

.help-drawer-body {
    padding: 16px 20px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* --- Search Input --- */
.help-search-container .form-control {
    background-color: var(--theme-bg-primary);
    border-color: var(--theme-border-color);
    color: var(--theme-text-primary);
    font-size: 0.875rem;
}

.help-search-container .form-control::placeholder {
    color: var(--theme-text-secondary);
}

.help-search-container .form-control:focus {
    border-color: var(--theme-accent-color, #0d6efd);
    box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.15);
}

/* --- Category Accordion --- */
.help-accordion {
    margin-top: 4px;
}

.help-category {
    margin-bottom: 2px;
}

.help-category-header {
    font-weight: 600;
    font-size: 0.9rem;
    cursor: pointer;
    padding: 10px 0;
    display: flex;
    align-items: center;
    gap: 8px;
    border-bottom: 1px solid var(--theme-border-subtle, rgba(128,128,128,0.15));
    user-select: none;
    transition: opacity 0.15s;
}

.help-category-header:hover {
    opacity: 0.8;
}

.help-category-icon {
    font-size: 1rem;
    flex-shrink: 0;
}

.help-category-label {
    flex: 1;
}

.help-category-count {
    font-size: 0.7rem;
    font-weight: 500;
    padding: 2px 6px;
}

.help-category-chevron {
    font-size: 0.75rem;
    color: var(--theme-text-secondary);
    flex-shrink: 0;
}

/* --- Category Body (entries container) --- */
.help-category-body {
    padding-left: 12px;
    border-left: 2px solid var(--theme-border-subtle, rgba(128,128,128,0.18));
    margin-left: 6px;
}

/* --- Entry Card --- */
.help-entry,
.help-search-result {
    padding: 8px 0;
    border-bottom: 1px solid var(--theme-border-subtle, rgba(128,128,128,0.1));
    cursor: pointer;
    transition: background-color 0.15s;
}

.help-entry:last-child,
.help-search-result:last-child {
    border-bottom: none;
}

.help-entry:hover,
.help-search-result:hover {
    background-color: rgba(128,128,128,0.05);
}

.help-entry-title {
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--theme-text-primary);
    margin-bottom: 2px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.help-entry-color {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Marker color classes for inline text references */
.mk-pos  { color: #28a745; font-weight: 600; }
.mk-neg  { color: #dc3545; font-weight: 600; }
.mk-abs  { color: #6c00cd; font-weight: 600; }
.mk-flip { color: #ff00ff; font-weight: 600; }
.mk-mp   { color: #007bff; font-weight: 600; }
.mk-gc   { color: #ff8c00; font-weight: 600; }

.help-entry-summary {
    font-size: 0.8rem;
    color: var(--theme-text-secondary);
    margin-bottom: 0;
    line-height: 1.4;
}

.help-entry-body {
    display: none;
    font-size: 0.8rem;
    color: var(--theme-text-primary);
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--theme-border-subtle, rgba(128,128,128,0.1));
    line-height: 1.5;
}

.help-entry-body p {
    margin-bottom: 8px;
}

.help-entry-body ul {
    padding-left: 18px;
    margin-bottom: 8px;
}

.help-entry-body li {
    margin-bottom: 4px;
}

.help-entry-body kbd {
    background-color: rgba(128,128,128,0.15);
    border: 1px solid rgba(128,128,128,0.3);
    border-radius: 3px;
    padding: 1px 5px;
    font-size: 0.8em;
    font-family: monospace;
}

.help-entry.expanded .help-entry-body,
.help-search-result.expanded .help-entry-body {
    display: block;
}

.help-entry.expanded,
.help-search-result.expanded {
    background-color: var(--theme-help-expanded-bg);
    border-radius: 4px;
    padding-left: 8px;
    padding-right: 6px;
    border-left: 2px solid var(--theme-help-expanded-border);
}

.help-entry.expanded .help-entry-title,
.help-search-result.expanded .help-entry-title {
    color: var(--theme-help-expanded-title);
}

/* --- Related Links --- */
.help-entry-related {
    margin-top: 8px;
    padding-top: 6px;
    border-top: 1px solid var(--theme-border-subtle, rgba(128,128,128,0.1));
}

.help-related-label {
    font-size: 0.75rem;
    color: var(--theme-text-secondary);
    margin-right: 4px;
}

.help-related-link {
    font-size: 0.75rem;
    color: #58a6ff;
    cursor: pointer;
}

.help-related-link:hover {
    text-decoration: underline;
}

/* --- Scroll-to-Entry Highlight --- */
.help-entry-highlight {
    animation: helpEntryFlash 1.5s ease;
}

@keyframes helpEntryFlash {
    0% { background-color: rgba(13, 110, 253, 0.2); }
    100% { background-color: transparent; }
}

/* --- Tour CTA in Help Drawer --- */
.help-tour-cta-row {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
}

.help-tour-cta-row .help-tour-cta {
    flex: 1;
    margin-bottom: 0;
    min-width: 0;
}

.help-tour-cta {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    margin-bottom: 12px;
    border-radius: 8px;
    cursor: pointer;
    background-color: rgba(108, 92, 231, 0.1);
    border: 1px solid rgba(108, 92, 231, 0.25);
    transition: background-color 0.15s ease;
}

@media (max-width: 480px) {
    .help-tour-cta-row {
        flex-direction: column;
    }
}

.help-tour-cta:hover {
    background-color: rgba(108, 92, 231, 0.18);
}

.help-tour-cta-icon {
    font-size: 1.3rem;
    flex-shrink: 0;
}

.help-tour-cta-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-width: 0;
}

.help-tour-cta-text strong {
    font-size: 0.875rem;
    color: var(--theme-text-primary, #212529);
}

.help-tour-cta-text span {
    font-size: 0.75rem;
    color: var(--theme-text-secondary, #6c757d);
}

.help-tour-cta-arrow {
    font-size: 1.2rem;
    color: var(--theme-text-secondary, #6c757d);
    flex-shrink: 0;
}

/* --- Search Results --- */
.help-search-result .help-entry-category {
    font-size: 0.7rem;
    color: var(--theme-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 2px;
}

.help-search-result mark {
    background-color: rgba(255, 193, 7, 0.3);
    color: inherit;
    padding: 0 1px;
    border-radius: 2px;
}


/* --- Tippy "Learn more" link --- */
.tippy-learn-more {
    margin-top: 6px;
    padding-top: 4px;
    border-top: 1px solid rgba(128,128,128,0.3);
    font-size: 0.75rem;
    color: #58a6ff;
    cursor: pointer;
}

.tippy-learn-more:hover {
    text-decoration: underline;
}

/* --- Mobile: Full-width drawer + larger help button tap target --- */
@media (max-width: 767.98px) {
    .help-drawer {
        width: 100% !important;
    }

    #gex-manual-refresh-btn {
        min-width: 36px;
        height: 36px;
        padding: 0.3rem 0.6rem;
        justify-content: center;
    }

    .header-menu-btn {
        height: 36px;
    }

    #changelogBell {
        height: 36px;
        min-width: 36px;
        justify-content: center;
    }
}

/* ========================================
   DRIVER.JS TOUR THEME (Phase 3 Help System)
   ======================================== */

/* --- Dark theme (default) --- */
.driver-popover.gex-tour {
    background-color: #1e1e2e;
    color: #e0e0e0;
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
    border-radius: 10px;
    max-width: 340px;
}

.driver-popover.gex-tour .driver-popover-title {
    color: #ffffff;
    font-size: 1rem;
    font-weight: 600;
}

.driver-popover.gex-tour .driver-popover-description {
    color: #c0c0d0;
    font-size: 0.875rem;
    line-height: 1.5;
}

.driver-popover.gex-tour .driver-popover-description kbd {
    background-color: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 3px;
    padding: 1px 5px;
    font-size: 0.8em;
    color: #e0e0e0;
}

.driver-popover.gex-tour .driver-popover-progress-text {
    color: #888;
    font-size: 0.75rem;
}

.driver-popover.gex-tour .driver-popover-navigation-btns button {
    border-radius: 6px;
    font-size: 0.8rem;
    font-weight: 500;
    padding: 6px 16px;
    text-shadow: none;
}

.driver-popover.gex-tour .driver-popover-next-btn,
.driver-popover.gex-tour .driver-popover-close-btn {
    background-color: #6c5ce7;
    color: #ffffff;
    border: none;
}

.driver-popover.gex-tour .driver-popover-next-btn:hover,
.driver-popover.gex-tour .driver-popover-close-btn:hover {
    background-color: #7c6cf7;
}

.driver-popover.gex-tour .driver-popover-prev-btn {
    background-color: transparent;
    color: #c0c0d0;
    border: 1px solid rgba(255, 255, 255, 0.15);
}

.driver-popover.gex-tour .driver-popover-prev-btn:hover {
    background-color: rgba(255, 255, 255, 0.05);
}

/* Dark theme arrows */
.driver-popover.gex-tour .driver-popover-arrow-side-left {
    border-left-color: #1e1e2e;
}
.driver-popover.gex-tour .driver-popover-arrow-side-right {
    border-right-color: #1e1e2e;
}
.driver-popover.gex-tour .driver-popover-arrow-side-top {
    border-top-color: #1e1e2e;
}
.driver-popover.gex-tour .driver-popover-arrow-side-bottom {
    border-bottom-color: #1e1e2e;
}

/* --- Light theme --- */
[data-bs-theme="light"] .driver-popover.gex-tour {
    background-color: #ffffff;
    color: #1a1a2e;
    border: 1px solid rgba(0, 0, 0, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-title {
    color: #1a1a2e;
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-description {
    color: #4a4a5a;
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-description kbd {
    background-color: rgba(0, 0, 0, 0.06);
    border: 1px solid rgba(0, 0, 0, 0.15);
    color: #1a1a2e;
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-progress-text {
    color: #888;
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-next-btn,
[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-close-btn {
    background-color: #6c5ce7;
    color: #ffffff;
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-next-btn:hover,
[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-close-btn:hover {
    background-color: #5b4bd6;
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-prev-btn {
    background-color: transparent;
    color: #4a4a5a;
    border: 1px solid rgba(0, 0, 0, 0.15);
}

[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-prev-btn:hover {
    background-color: rgba(0, 0, 0, 0.04);
}

/* Light theme arrows */
[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-arrow-side-left {
    border-left-color: #ffffff;
}
[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-arrow-side-right {
    border-right-color: #ffffff;
}
[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-arrow-side-top {
    border-top-color: #ffffff;
}
[data-bs-theme="light"] .driver-popover.gex-tour .driver-popover-arrow-side-bottom {
    border-bottom-color: #ffffff;
}

/* ========================================
   FEEDBACK MODAL
   ======================================== */

.feedback-modal-content {
    max-width: 500px;
    margin: 0 auto;
}

.feedback-type-btn.active {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
    color: #fff;
}

.feedback-drop-zone {
    border: 2px dashed rgba(128, 128, 128, 0.4);
    border-radius: 8px;
    padding: 20px;
    text-align: center;
    cursor: pointer;
    transition: border-color 0.2s, background-color 0.2s;
    position: relative;
    min-height: 80px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.feedback-drop-zone:hover {
    border-color: var(--bs-primary);
    background-color: rgba(var(--bs-primary-rgb), 0.04);
}

.feedback-drop-zone.drag-active {
    border-color: var(--bs-primary);
    background-color: rgba(var(--bs-primary-rgb), 0.08);
}

.feedback-preview-img {
    max-width: 100%;
    max-height: 150px;
    border-radius: 4px;
}

.feedback-remove-img {
    position: absolute;
    top: 6px;
    right: 6px;
    font-size: 16px;
    line-height: 1;
    padding: 2px 6px;
}

/* ========================================
   CHANGELOG DRAWER (WHAT'S NEW)
   ======================================== */

/* Badge dot on bell button */
.changelog-badge-dot {
    width: 8px;
    height: 8px;
    background-color: #dc3545;
    border-radius: 50%;
    position: absolute;
    top: 2px;
    right: 2px;
    border: 2px solid var(--theme-bg-secondary, #fff);
    box-sizing: content-box;
}

/* Drawer width */
.changelog-drawer {
    width: 380px !important;
}

@media (max-width: 767.98px) {
    .changelog-drawer {
        width: 100% !important;
    }

    /* Match mobile tap target to other header buttons */
    #changelogBell {
        min-width: 36px;
        min-height: 36px;
        justify-content: center;
    }
}

/* Release blocks */
.changelog-release {
    padding: 12px 0;
}

.changelog-release-new {
    border-left: 3px solid #0d6efd;
    padding-left: 12px;
    margin-left: -12px;
}

.changelog-release-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
}

.changelog-release-date {
    font-size: 0.75rem;
    opacity: 0.6;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.changelog-new-badge {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 1px 6px;
    border-radius: 3px;
    background-color: rgba(13, 110, 253, 0.15);
    color: #0d6efd;
}

.changelog-release-title {
    font-size: 0.95rem;
    font-weight: 600;
    margin-bottom: 8px;
}

/* Entry list */
.changelog-entry-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.changelog-entry-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 0.85rem;
    line-height: 1.4;
}

.changelog-entry-text {
    flex: 1;
}

/* Type badges */
.changelog-type-badge {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 1px 6px;
    border-radius: 3px;
    flex-shrink: 0;
    margin-top: 2px;
}

.changelog-type-added {
    background-color: rgba(25, 135, 84, 0.15);
    color: #198754;
}

.changelog-type-improved {
    background-color: rgba(13, 110, 253, 0.15);
    color: #0d6efd;
}

.changelog-type-fixed {
    background-color: rgba(255, 152, 0, 0.15);
    color: #e68a00;
}

.changelog-type-removed {
    background-color: rgba(220, 53, 69, 0.15);
    color: #dc3545;
}

/* Links inside entries */
.changelog-entry-text a {
    color: #0d6efd;
    text-decoration: none;
}

.changelog-entry-text a:hover {
    text-decoration: underline;
}

/* Divider between releases */
.changelog-divider {
    margin: 4px 0;
    opacity: 0.15;
}

/* Toggle button for showing/hiding older releases */
.changelog-toggle-button {
    display: block;
    width: 100%;
    margin: 16px 0 8px 0;
    padding: 8px 12px;
    background: transparent;
    border: 1px solid rgba(127, 127, 127, 0.3);
    border-radius: 6px;
    color: rgba(127, 127, 127, 1);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.changelog-toggle-button:hover {
    background: rgba(127, 127, 127, 0.08);
    border-color: rgba(127, 127, 127, 0.5);
    color: rgba(127, 127, 127, 1);
}

/* ── Term OI Metric Toggle ──────────────────────────────────────────── */

.term-oi-metric-toggle {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 6px 0;
    padding: 8px 0 4px 0;
}

.term-oi-metric-toggle .btn-group .btn {
    font-size: 0.75rem;
    padding: 2px 12px;
    border-radius: 0;
    font-weight: 500;
}

/* Mobile: switch from wrap to a single-line horizontal scroll rail.
   Fade-mask on both edges signals scrollability; the active chip is
   auto-centred from JS (_updateToggleUI). */
@media (max-width: 768px) {
    .term-oi-metric-toggle {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding: 8px 12px 4px 12px;
        mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
        -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
    }
    .term-oi-metric-toggle::-webkit-scrollbar {
        display: none;
    }
    .term-oi-metric-toggle .btn-group {
        flex-shrink: 0;
    }
    .term-oi-metric-toggle .btn-group .btn {
        white-space: nowrap;
    }
}

.term-oi-metric-toggle .btn-group .btn:first-child {
    border-top-left-radius: 20px;
    border-bottom-left-radius: 20px;
}

.term-oi-metric-toggle .btn-group .btn:last-child {
    border-top-right-radius: 20px;
    border-bottom-right-radius: 20px;
}

.term-oi-metric-toggle .btn-group .btn.active {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
    color: #fff;
}

/* Summary bar toggles (Σ All / Σ Filtered) */
.term-oi-summary-toggles {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: 12px;
}

.term-oi-summary-toggle {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--bs-secondary);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.term-oi-summary-toggle input[type="checkbox"] {
    margin: 0;
    cursor: pointer;
}

/* Levels Chart/Table view toggle — inline bar above chart */
.term-levels-view-toggle {
    display: flex;
    gap: 2px;
    justify-content: flex-end;
    align-items: center;
    padding: 2px 4px;
}

.term-oi-gex-toggle-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 1px solid var(--border-primary, #444);
    border-radius: 4px;
    background: transparent;
    color: var(--text-muted, #888);
    cursor: pointer;
    transition: all 0.15s ease;
}

.term-oi-gex-toggle-btn:hover {
    color: var(--text-primary, #fff);
    border-color: var(--text-primary, #fff);
}

.term-oi-gex-toggle-btn.active {
    color: var(--bs-primary, #3b82f6);
    border-color: var(--bs-primary, #3b82f6);
    background: rgba(59, 130, 246, 0.1);
}

/* Mobile: summary toggles wrap to second row */
@media (max-width: 576px) {
    .term-oi-summary-toggles {
        margin-left: 0;
        width: 100%;
        justify-content: center;
    }
}

/* ========================================
   MONTE CARLO TOOLBAR CONTROLS
   ======================================== */

/* Re-run button wrapper has no label, so on mobile (where view-controls
   stretches its children) push the button to the bottom edge so it lines
   up with sibling selects. On desktop the parent uses align-items: flex-end
   so the wrapper already sits at the bottom — justify-content is a no-op there. */
.mc-run-wrapper {
    justify-content: flex-end;
}

@media (max-width: 767.98px) {
    /* Let the Re-run button size to its content rather than steal
       an equal flex share from CHART/PRESET/PALETTE. */
    .toolbar-group.view-controls > .mc-run-wrapper {
        flex: 0 0 auto;
    }
}

/* ========================================
   MONTE CARLO CONTROLS PANEL
   ======================================== */

/* Sits between the main toolbar and the chart — should read as a
   continuation of the toolbar, not a separate card. Mirrors
   .gex-control-toolbar's transparent / theme-aware look. */
.mc-controls-panel {
    width: 100%;
    /* Fill parent — do not re-read the fluid gutter token (see .card note above). */
    max-width: 100%;
    margin: 6px auto 8px;
    padding: 0 10px;
    font-size: 0.85rem;
}

.mc-controls-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    padding: 0;
    background: transparent;
}

.mc-advanced-panel {
    margin-top: 6px;
    padding: 6px 0;
    background: transparent;
    border-top: 1px solid var(--theme-border-secondary);
}

.mc-stats-bar {
    margin-top: 4px;
    padding: 2px 0;
    font-family: monospace;
    font-size: 0.8rem;
    color: var(--theme-text-secondary);
}

.mc-advanced-meta {
    font-size: 0.85rem;
    color: var(--theme-text-secondary);
    line-height: 1.5;
}
.mc-advanced-meta div { white-space: nowrap; }

