/* ==========================================================================
   revamp.css — the v2 trade page (app2.html)

   Loaded last among the stylesheets, so it wins at equal specificity.
   Everything is scoped `body.v2` and, where it touches layout, gated at
   >=992px: below that mobile.css serves the unchanged phone UI.

   Two house rules carried over from app.css:
     - a component sets colour, spacing and layout — never font-size,
       weight, family, tracking or line-height. Those come from the .t-*
       classes (app.css:156+) and the v2 additions in §1.
     - numbers are var(--num) with tabular-nums; --mono is for addresses.

   A note on `!important`: app.css's "Square grid" section runs a desktop
   radius-zeroing sweep at specificity (0,0,0). Any v2 element that should
   stay rounded has to out-rank it, and the honest way to do that from a
   later sheet is an explicit `!important` on the radius. The sweep section
   ALSO carries the desktop grid layout the v2 grid builds on — a W7 attempt
   to delete it broke the page frame, so it stays; unpicking radii from
   layout there is its own future task.
   ========================================================================== */

/* TABLE OF CONTENTS ---------------------------------------------------------
   §1  tokens (body.v2 palette + --v2-* names, breakpoint bands)
   §2  topbar (wordmark, nav line, 30px/r8 control family)
   §3  paper banner (#v2-comp-line — v2-owned, mirrors the hidden app strip)
   §4  grid + legacy neutralizations + 4b/4c breakpoint reflows
   §5  column-1 chrome (asset strip, serif head, view region layers)
   §6  wells / the quote ladder
   §7  slider + chain tables
   §8  ticket (decide zone, amount, presets, params, BUY, scenarios)
   §9  column-3 rail (news card, docked trollbox)
   §10-13 board-reconciliation rounds (later rules win; consolidate into the
          sections above opportunistically — never re-order blindly, cascade
          order is load-bearing for same-specificity overrides)
   --------------------------------------------------------------------------- */

/* ==========================================================================
   1. TOKENS
   The design boards run a darker, cooler ground than today's app and a
   softer green/red pair. Rather than restyle every component, v2 REDEFINES
   the app's own custom properties on the body: anything already reading
   var(--background) / var(--card-bg) / var(--positive) re-tones for free.
   ========================================================================== */
/* The app's own token names are re-toned at the DESKTOP breakpoint only.
   `body.v2` is stamped at every width (the class is static markup), so an
   ungated override here re-themed every phone screen — --background,
   --card-bg, --positive, --call-green and the rest — while the PR promised
   phones untouched. The --v2-* names below stay ungated: they have no app.css
   counterpart, so on a phone they define nothing the mobile sheet reads. */
@media (min-width: 992px) {
    body.v2 {
        /* --- the board palette, as the app's own token names --- */
        --background: #0B0F19;          /* page ground */
        --panel-sunken: #070A11;        /* deepest; sits inside a card */
        --card-bg: #0E1322;             /* the card / pane surface */
        --secondary: #141927;           /* raised chip */
        --surface: #1B2234;             /* chip, hovered */

        --text-primary: #F5F7FA;
        --text-secondary: #C2CBD8;
        --text-muted: #7E8A9C;

        --border-color: rgba(255, 255, 255, .06);
        --border-light: rgba(255, 255, 255, .13);

        --primary: var(--v2-sky);
        --primary-dark: #38BDF8;
        --positive: #5EDD9C;
        --negative: #E86A62;
        --call-green: var(--positive);
        --put-red: var(--negative);
        --accent: var(--v2-amber);
        --warning: var(--v2-amber);
    }
}

body.v2 {
    /* --- v2-only names (no app.css counterpart) --- */
    --v2-chip: #232C42;             /* round 10: raised control, solid fill */
    --v2-chip-hover: #2C3752;
    --v2-chip-inset: #141927;       /* INSET surfaces only: bar tracks, the amount field */
    --v2-chip-dim: #161D30;         /* disabled / waiting fill */
    --v2-chip-lift: inset 0 1px 0 rgba(255, 255, 255, .07);
    --v2-hair: rgba(255, 255, 255, .06);
    --v2-hair-strong: rgba(255, 255, 255, .13);
    --v2-sky: #7DD3FC;
    --v2-sky-fill: rgba(125, 211, 252, .13);
    --v2-call-fill: rgba(94, 221, 156, .13);
    --v2-put-fill: rgba(232, 106, 98, .13);
    --v2-on-green: #07120B;         /* ink on a solid --positive fill */
    --v2-on-sky: #07131C;           /* ink on a solid --v2-sky fill */

    --v2-paper: #E7E6E2;            /* the competition banner */
    --v2-ink: #0F1520;
    --v2-amber: #D9A83C;            /* bars only — never words */
    --v2-on-negative: #1A0908;      /* ink on a solid --negative fill */
    --v2-primary-bg: #FDFDFD;       /* the one white button */
    --v2-ink-soft: rgba(15, 21, 32, .62);
    --v2-ink2: rgba(15, 21, 32, .62);   /* the boards' --ink2; was an undefined var falling back cooler */

    --v2-r-card: 16px;              /* modules, wells, cards */
    --v2-r-ctl: 8px;
    --v2-r-card-sm: 12px;   /* round 11: the one card radius on the peripheral pages */                /* buttons, chips, tiles — the board's radius */
    --v2-r-tile: 7px;               /* ladder tiles */

    --v2-display: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;   /* round 10: the serif retired */
    --v2-brand: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    /* Layout metrics the grid and the wells read. Overridden per breakpoint
       in §4 so the columns compress rather than break. */
    --v2-ticket-w: 380px;
    --v2-rail-w: 320px;
    --v2-wells-w: 400px;
    --v2-view-h: 504px;
}

/* Type variants v2 introduces. Components reference these; they never set
   font properties inline. (Mirrors the .t-* contract in app.css:156.) */
/* Hero figures (round 10): Geist, tabular, coloured by meaning at the call site. */
body.v2 .v2-hero-num {
    font-family: var(--v2-display);
    font-weight: 600;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

/* The page ground itself. app.css paints .app-container from --background,
   but the body behind it shows through on short pages. */
body.v2 {
    background: var(--background);
}

/* ==========================================================================
   2. TOPBAR
   The existing <nav> IS the topbar — it already carries the brand, the
   section links and the wallet cluster. v2 re-tones and re-spaces it rather
   than building a second one, so every wallet/nav handler keeps its element.
   ========================================================================== */
@media (min-width: 992px) {

    body.v2 .navbar {
        background: var(--background);
        border-bottom: 1px solid var(--v2-hair);
        padding: 0;
        min-height: 0;
    }

    body.v2 .navbar > .container-fluid {
        gap: 2px;
        padding: 10px 16px;
    }

    /* The mark: one colour, slightly transparent — it reads as part of the
       surface rather than a badge. */
    body.v2 .navbar-brand {
        margin: 0 36px 0 0; /* after Hyperliquid: logo → first item ~35px */
        padding: 0;
        display: inline-flex;
        align-items: center;
        height: 32px; /* the brand box the header height was tuned on (grid constant 116px) */
    }

    body.v2 .v2-wordmark {
        font-family: var(--v2-brand);
        font-size: 15px; /* two points under the old 17: level with the 13px nav */
        font-weight: 900;
        letter-spacing: -0.045em;
        line-height: 1;
        color: rgba(245, 247, 250, .6);
        /* The wordmark and the nav are different faces at different sizes — Geist 900
           15px lowercase here, Inter 500 13px sentence-case in the nav (§the topbar:
           nav is text, no pills) — so their baselines do not coincide under the
           container's align-items:center. Measured over CDP at 1440px, the wordmark's
           baseline sat 2.6px BELOW the nav's.

           display:inline-block is load-bearing: a <span> is display:inline by default
           and CSS transforms DO NOT apply to non-replaced inline boxes. The earlier
           translateY(-1px) and translateY(-3px) were silently no-ops — computed style
           reported the matrix, the glyphs never moved. Verified: -30px on the inline
           span shifted nothing. */
        display: inline-block;
        transform: translateY(-2px); /* at 15px: optically centred on the nav text (zoomed and compared -1 / -2) */
    }

    body.v2 .navbar-brand:hover .v2-wordmark {
        color: rgba(245, 247, 250, .85);
    }

    /* Section links, flush left beside the mark. */
    body.v2 .navbar-nav {
        flex-direction: row;
        gap: 2px;
        align-items: center;
    }

    body.v2 .navbar-nav .nav-item {
        margin: 0;
    }

    body.v2 .navbar-nav .nav-link {
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 500;
        letter-spacing: 0.06em;
        line-height: 1;
        text-transform: uppercase;
        color: var(--text-muted);
        padding: 7px 12px;
        border: 0;
        border-radius: var(--v2-r-ctl) !important;
        background: transparent;
        transition: color 140ms ease, background-color 140ms ease;
    }

    body.v2 .navbar-nav .nav-link:hover {
        color: var(--text-primary);
        background: var(--v2-chip-hover);
        box-shadow: var(--v2-chip-lift);
    }

    body.v2 .navbar-nav .nav-link.active {
        color: var(--text-primary);
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
    }

    /* Positions is retired on desktop (app.css RETIRE_POSITIONS) — the v2
       bar carries the four that route somewhere. */
    body.v2 .navbar-nav #nav-positions {
        display: none;
    }

    body.v2 .hdr-tools {
        gap: 6px;
    }

    body.v2 .v2-balance-chip {
        align-items: center;
        border-radius: var(--v2-r-ctl) !important;
        border: 0;
        line-height: 1;
    }

    body.v2 .v2-balance-chip {
        gap: 5px;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        padding: 7px 12px;
    }

    body.v2 .v2-balance-num {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.75rem;
        font-weight: 600;
        color: var(--text-primary);
    }

    body.v2 .v2-balance-unit {
        font-family: var(--sans);
        font-size: 0.75rem;
        font-weight: 400;
        color: var(--text-secondary); /* on a chip, muted is 3.97:1 — the system's own rule says secondary */
    }

    /* The header pill keeps its behaviour; only its skin changes. */
    body.v2 .header-wallet-pill {
        background: var(--v2-chip);
        border: 0;
        border-radius: var(--v2-r-ctl) !important;
        padding: 7px 12px;
    }
}

/* ==========================================================================
   3. THE COMPETITION BANNER
   #top-strip now runs full width under the topbar. The competition half is
   the paper band; the events half rides along hidden, feeding the news card
   in column 3. One shared baseline: the strip's line-height IS its height,
   so the serif and the sans sit on the same line.
   ========================================================================== */
@media (min-width: 992px) {

    /* Flex for the same reason as #top-strip below: the markup has whitespace
       between children, and a block box turns that into an anonymous line
       box — ~18px of dead paper under the strip. */
    body.v2 #v2-banner {
        display: flex;
        flex-direction: column;
        background: var(--v2-paper);
        color: var(--v2-ink);
    }

    /* The band container itself carries no chrome in v2 — the paper does.
       Flex, not block: the markup has whitespace between the children and a
       block container turns that into an anonymous line box, which was
       adding ~18px of dead paper under the strip. */
    body.v2 #v2-banner #top-strip {
        /* .tstrip sizes itself from its own tokens (app.css:16394) — height is
           var(--ts-h), horizontal padding var(--ts-pad). Retuning the tokens
           re-sizes the band cleanly; overriding the rules that read them would
           leave the two halves disagreeing. 52px buys room for a two-line
           events item, and v2 does not show those here. */
        --ts-h: 32px;   /* the board's banner line */
        --ts-pad: 16px;
        display: flex !important;
        flex-direction: column;
        background: transparent;
        border: 0;
        margin: 0;
        padding: 0;
        min-height: 0;
    }

    /* One shared baseline: the band's line-height IS its height, so the
       serif title, the sans labels and the tabular numbers all sit on the
       same line instead of each centring in its own box. */
    body.v2 #v2-banner .ts-comp {
        display: flex;
        align-items: baseline;
        gap: 14px;
        line-height: var(--ts-h);
        background: transparent;
        border: 0;
        cursor: pointer;
    }

    body.v2 #v2-banner .ts-comp:hover {
        background: rgba(15, 21, 32, .05);
    }

    body.v2 #v2-banner .ts-trophy {
        display: none;
    }

    body.v2 #v2-banner .cm-title {
        font-family: var(--v2-display);
        font-size: 0.78125rem;
        font-weight: 600;
        letter-spacing: -0.02em;
        letter-spacing: 0;
        text-transform: none;
        color: var(--v2-ink);
    }

    body.v2 #v2-banner .cm-lab {
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 400;
        letter-spacing: 0;
        text-transform: none;
        color: var(--v2-ink-soft);
    }

    body.v2 #v2-banner .cm-pool {
        font-family: var(--v2-display);
        font-size: 0.75rem;
        font-weight: 600;
        color: var(--v2-ink);
    }

    body.v2 #v2-banner .cm-time,
    body.v2 #v2-banner .cm-rank {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.6875rem;
        font-weight: 600;
        color: var(--v2-ink);
    }

    /* The vertical rules between pairs read as clutter on paper; the gap
       already separates them. */
    body.v2 #v2-banner .cm-rule {
        display: none;
    }

    body.v2 #v2-banner .cm-pair {
        display: inline-flex;
        align-items: baseline;
        gap: 5px;
    }

    body.v2 #v2-banner .cm-pair-pool {
        margin-left: auto;
    }

    /* The leaderboard link becomes the ink button; it is the strip's own
       click-through, so no new handler is needed. */
    body.v2 #v2-banner .cm-cta {
        align-self: center;
        display: inline-flex;
        align-items: center;
        gap: 4px;
        background: var(--v2-ink);
        color: var(--v2-primary-bg);
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        line-height: 1;
        padding: 5px 11px;
        border-radius: 6px;
    }

    body.v2 #v2-banner .ts-chev {
        font-size: 0.625rem;
    }

    /* The events half feeds the news card in column 3 instead of scrolling
       here. Kept in the DOM so top-strip.js and calendar-events.js run
       untouched. */
    body.v2 #v2-banner #ts-events,
    body.v2 #v2-banner #ts-empty,
    body.v2 #v2-banner .ts-notice {
        display: none !important;
    }
}

/* ==========================================================================
   4. THE GRID
   app.css builds the desktop trade page as two tracks with the ticket taken
   out of flow (position:absolute, width 0) and squeezed in by animating
   padding-right on the main panel (app.css:17581-17703). v2 wants three real
   columns with the ticket always open, so those rules are unwound here
   rather than edited there.
   ========================================================================== */
@media (min-width: 992px) {

    /* --- unwind the shell app.css wraps the trade page in --- */
    body.v2 #trade-section > .container,
    body.v2 #trade-section .row,
    body.v2 #trade-section .col-12 {
        max-width: none;
        width: 100%;
        margin: 0;
        padding: 0;
    }

    body.v2 .professional-asset-header {
        border: 0;
        border-radius: 0 !important;
        background: transparent;
        padding: 0;
        margin: 0;
    }

    /* NOT display:none — .trade-unified-layout is a child of this wrapper,
       not a sibling. With the competition band lifted out to the banner the
       wrapper has no content of its own left, so it just stops taking space. */
    body.v2 .asset-selector-wrapper {
        padding: 0;
        margin: 0;
        border: 0;
        background: transparent;
    }

    /* --- the three columns --- */
    body.v2 .trade-unified-layout {
        display: grid;
        grid-template-columns: minmax(0, 1fr) var(--v2-ticket-w) var(--v2-rail-w);
        grid-template-rows: auto;
        column-gap: 0;
        row-gap: 0;
        height: auto;
        /* syncTicketHeight() writes a min-height inline for the old absolute
           ticket; in a real grid that would stretch the page. Author
           !important beats an inline declaration, which is the only way to
           neutralise it without touching ui_interactions.js. */
        min-height: 0 !important;
        border: 0;
        border-top: 1px solid var(--v2-hair);
        overflow: visible;
        position: relative;
    }

    body.v2 #v2-col1 {
        grid-column: 1;
        display: flex;
        flex-direction: column;
        min-width: 0;
        border-right: 1px solid var(--v2-hair);
    }

    body.v2 #v2-col2 {
        grid-column: 2;
        display: flex;
        flex-direction: column;
        min-width: 0;
    }

    body.v2 #v2-col3 {
        grid-column: 3;
        display: flex;
        flex-direction: column;
        min-width: 0;
        border-left: 1px solid var(--v2-hair);
    }

    /* --- the ticket becomes an ordinary column ---
       These selectors carry the layout class deliberately: app.css sizes the
       open ticket through `.trade-unified-layout.ticket-open
       .trade-panel-preview` (0,3,0), and a plainer `body.v2 .trade-panel-preview`
       would lose to it and leave a 460px panel inside a 352px column. */
    body.v2 .trade-unified-layout .trade-panel-preview,
    body.v2 .trade-unified-layout.ticket-open .trade-panel-preview {
        position: static;
        width: auto;
        min-width: 0;
        height: auto;
        max-height: none;
        opacity: 1;
        overflow: visible;
        pointer-events: auto;
        background: transparent;
        border: 0;
        transform: none;
        transition: none;
        z-index: auto;
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

    /* app.css hides the ticket's children while collapsed so a TradingView
       iframe never measures zero. v2 boots with .ticket-open set, but keep
       the children visible regardless — the ticket has no collapsed state. */
    body.v2 .trade-unified-layout:not(.ticket-open) .trade-panel-preview > * {
        display: block;
    }

    body.v2 .trade-unified-layout .trade-preview-sidebar,
    body.v2 .trade-unified-layout #price-chart {
        width: auto;
        max-width: none;
        min-width: 0;
        flex: 1 1 auto;
    }

    /* --- the squeeze, off --- */
    body.v2 .trade-panel-main,
    body.v2 #trade-positions-block,
    body.v2 .trade-unified-layout.ticket-open .trade-panel-main,
    body.v2 .trade-unified-layout.ticket-open #trade-positions-block {
        padding-right: 0 !important;
        transition: none !important;
    }

    body.v2 .trade-panel-main {
        grid-column: auto;
        grid-row: auto;
        width: auto;
        min-width: 0;
        flex: 0 0 auto;
    }

    body.v2 #trade-positions-block {
        grid-column: auto;
        grid-row: auto;
        margin: 0;
        flex: 1 1 auto;
        min-height: 0;
    }

    /* --- chrome the v2 layout replaces --- */
    body.v2 .trade-vertical-divider,
    body.v2 #ticket-reopen-tab,
    body.v2 .ticket-collapse-btn,
    body.v2 .asset-sidebar,
    body.v2 .spot-ticker-bar {
        display: none !important;
    }

    /* .trade-panel-main-inner is `display: contents` in app.css so the old
       grid could reach through it; in the v2 column it is an ordinary box. */
    body.v2 .trade-panel-main-inner {
        display: block;
    }

    body.v2 .trade-content {
        display: flex;
        flex-direction: column;
        overflow: visible;
        padding: 0;
    }
}

/* --------------------------------------------------------------------------
   4b. Widths per breakpoint. The columns compress; they do not drop. Below
   992px none of this applies and mobile.css serves the phone UI unchanged.
   -------------------------------------------------------------------------- */
@media (min-width: 992px) and (max-width: 1439.98px) {
    body.v2 {
        --v2-wells-w: clamp(232px, 22vw, 300px);
        --v2-view-h: 452px;
    }
}

@media (min-width: 1440px) and (max-width: 1679.98px) {
    /* Round-7 rebalance: the ticket and rail slim, the plot yields its empty
       margin, and the ladder gets it all — tiles come back to ~76px with
       premiums fitting at this band's most common window (~1571px). */
    body.v2 {
        --v2-ticket-w: 300px;
        --v2-rail-w: 264px;
        --v2-wells-w: 492px;
        --v2-view-h: 476px;
    }
}

@media (min-width: 1920px) {
    body.v2 {
        --v2-ticket-w: 400px;
        --v2-rail-w: 340px;
        --v2-wells-w: 462px;
        --v2-view-h: 540px;
    }
}

/* ==========================================================================
   5. COLUMN 1 — asset strip, section head, the fixed view region
   ========================================================================== */
@media (min-width: 992px) {

    /* --- the asset rail becomes a horizontal chip strip ---
       .asset-sidebar is force-hidden in app.css (twice, once !important)
       because the rail was retired; v2 gives it a new job as the strip the
       design asks for, so it has to be un-hidden just as forcefully. */
    body.v2 #v2-col1 .asset-sidebar {
        display: block !important;
        position: static !important;
        width: auto !important;
        max-width: none !important;
        height: auto !important;
        padding: 10px 16px !important;
        margin: 0 !important;
        border: 0 !important;
        border-bottom: 1px solid var(--v2-hair) !important;
        background: transparent !important;
        overflow: visible !important;
        opacity: 1 !important;
        visibility: visible !important;
    }

    body.v2 #v2-col1 .asset-selection-buttons {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 6px;
        width: auto;
        padding: 0;
        margin: 0;
        overflow: visible;
    }

    body.v2 #v2-col1 .asset-selection-btn {
        display: inline-flex;
        width: auto;
        min-width: 0;
        margin: 0;
        padding: 6px 12px;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        border: 0;
        border-radius: var(--v2-r-ctl) !important;
        color: var(--text-secondary);
        transition: background-color 140ms ease, color 140ms ease;
    }

    body.v2 #v2-col1 .asset-selection-btn:hover {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }

    /* selected = solid sky (round 10) — every descendant takes the ink */
    body.v2 #v2-col1 .asset-selection-btn.selected,
    body.v2 #v2-col1 .asset-selection-btn.selected .asset-name,
    body.v2 #v2-col1 .asset-selection-btn.selected .v2-asset-price {
        background: var(--v2-sky);
        box-shadow: none;
        color: var(--v2-on-sky);
        opacity: 1;
    }

    body.v2 #v2-col1 .asset-selection-btn .asset-content {
        display: inline-flex;
        flex-direction: row;
        align-items: center;
        gap: 6px;
        width: auto;
    }

    body.v2 #v2-col1 .asset-selection-btn .asset-icon {
        width: 14px;
        height: 14px;
        margin: 0;
        font-size: 0.75rem;
    }

    body.v2 #v2-col1 .asset-selection-btn .asset-name {
        font-family: var(--sans);
        font-size: 12px;
        font-weight: 400;   /* board: only the selected chip carries weight */
        letter-spacing: 0;
        line-height: 1;
        color: inherit;
    }

    /* Price rides beside the symbol; revamp.js keeps it current. */
    body.v2 #v2-col1 .asset-selection-btn .v2-asset-price {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 12px;
        font-weight: 500;
        line-height: 1;
        color: inherit;
        opacity: .72;
    }

    body.v2 #v2-col1 .asset-selection-btn.selected .v2-asset-price {
        opacity: 1;
    }

    body.v2 #v2-col1 .asset-selection-btn.selected .asset-name {
        font-weight: 600;
    }

    /* --- title row + expiry tabs --- */
    body.v2 .trade-title-row {
        padding: 10px 16px 0;
        margin: 0;
    }

    body.v2 .expiry-filter-section {
        padding: 8px 16px 10px;
        margin: 0;
    }

    /* --- section head: the live prompt in the display face, and the
           three views as one segmented control --- */
    body.v2 #basic-view-container {
        background: transparent;
        border: 0;
        border-radius: 0;
        padding: 0;
        margin: 0;
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    body.v2 .filter-label-section {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 9px 16px;
        margin: 0;
        border-top: 1px solid var(--v2-hair);
        border-bottom: 1px solid var(--v2-hair);
    }

    /* Round 7: the question is the page's headline — 26px serif with the
       live spot beside it (painted by V2Column1.headLine). */
    body.v2 #desktop-prediction-prompt,
    body.v2 #desktop-prediction-prompt span {
        font-family: var(--v2-display);
        font-size: 1.375rem;
        font-weight: 600;
        letter-spacing: -0.02em;
        line-height: 1.1;
        color: var(--text-primary);
        text-transform: none;
    }

    body.v2 #v2-head-line {
        display: flex;
        align-items: baseline;
        gap: 10px;
    }

    body.v2 #v2-head-line .v2-head-spot {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.75rem;
        font-weight: 400;
        letter-spacing: 0;
        color: var(--text-muted);
    }

    body.v2 #v2-head-line .v2-head-spot b {
        color: var(--text-secondary);
        font-weight: 600;
    }

    body.v2 .filter-label-right {
        margin-left: auto;
    }

    body.v2 .view-text-links {
        display: inline-flex;
        gap: 2px;
        padding: 2px;
        background: var(--panel-sunken);
        border-radius: var(--v2-r-ctl);
    }

    body.v2 .view-text-links .view-link {
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        line-height: 1;
        color: var(--text-muted);
        padding: 5px 11px;
        border: 0;
        border-radius: 7px !important;
        background: transparent;
        text-decoration: none;
        transition: color 140ms ease, background-color 140ms ease;
    }

    body.v2 .view-text-links .view-link:hover {
        color: var(--text-secondary);
    }

    body.v2 .view-text-links .view-link.active {
        background: var(--v2-sky);
        color: var(--v2-on-sky);
    }

    /* --- the fixed view region ---
       One height for all three views, so the positions strip beneath never
       moves. Dense views (the chain, the slider's info table) scroll inside
       it; the chart fills it. */
    body.v2 #v2-view-region {
        position: relative;
        height: var(--v2-view-h);
        min-height: var(--v2-view-h);
        overflow: hidden;
        border-bottom: 1px solid var(--v2-hair);
    }

    /* The chart owns the region outright. */
    body.v2 #v2-view-region #target-chart {
        height: 100%;
        padding: 0;
        margin: 0;
    }

    body.v2 #v2-view-region .tc-tv-wrap {
        height: 100%;
        min-height: 0;
        border: 0;
        border-radius: 0 !important;
    }

    /* Scrolling views get the region's height and a fade at the cut, so a
       clipped row reads as "there is more" rather than as the end. */
    /* height:auto, not 100% — .strike-slider-track lays its rail, ticks and
       ranger zones out against its own box, so stretching it to the region
       height spreads them down the page. The region does the clipping; the
       view keeps its natural height and scrolls when it exceeds it. */
    body.v2 #v2-view-region .strike-slider-track,
    body.v2 #v2-view-region #v2-chain,
    body.v2 #v2-view-region .options-table-container {
        height: auto;
        max-height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        margin: 0;
        /* Horizontal padding is fine now that the spot marker shares the
           ticks' coordinate system (the flag-gated remap in
           setupStrikeSlider) — both percents resolve against this same
           content box. Stripping it instead knocked the rail geometry off. */
        padding: 14px 16px 40px;
        scrollbar-width: thin;
    }

    body.v2 #v2-view-region .options-table-container {
        padding-top: 0;
    }

    body.v2 #v2-view-region::after {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 44px;
        background: linear-gradient(to bottom, rgba(11, 15, 25, 0), var(--background) 88%);
        pointer-events: none;
        opacity: 0;
        transition: opacity 160ms ease;
    }

    body.v2 #v2-view-region[data-v2-scrollable="1"]::after {
        opacity: 1;
    }

    /* The chart paints to its own edge; no fade over it. */
    body.v2 #v2-view-region[data-v2-view="chart"]::after {
        opacity: 0;
    }

    body.v2 .v2-scroll-pill {
        position: absolute;
        left: 50%;
        bottom: 8px;
        transform: translateX(-50%);
        z-index: 3;
        display: none;
        align-items: center;
        gap: 5px;
        background: var(--v2-chip);
        color: var(--text-muted);
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 500;
        line-height: 1;
        padding: 4px 12px;
        border-radius: var(--v2-r-ctl);
        pointer-events: none;
    }

    body.v2 #v2-view-region[data-v2-scrollable="1"] .v2-scroll-pill {
        display: inline-flex;
    }

    /* --- positions strip --- */
    body.v2 #trade-positions-block .user-positions-table-container {
        background: transparent;
        border: 0;
        border-radius: 0 !important;
        padding: 0;
    }
}

/* ==========================================================================
   6. THE DAY WELLS
   One shallow card per expiry beside the plot: strike tiles and range cells
   at their true price y, so the ladder IS the axis. Positioning is done in
   revamp.js from lwSeries.priceToCoordinate — the same call the engine's own
   overlays use — and applied as transforms, which keeps a tile move off the
   layout path and out of any ResizeObserver's way.
   ========================================================================== */
@media (min-width: 992px) {

    body.v2 #v2-chart-row {
        display: flex;
        align-items: stretch;
        height: 100%;
        min-width: 0;
    }

    body.v2 #v2-chart-row #target-chart {
        flex: 1 1 auto;
        min-width: 0;
    }

    body.v2 #v2-wells {
        flex: 0 0 var(--v2-wells-w);
        display: flex;
        gap: 8px;
        padding: 6px 10px 0 4px;   /* round 10: the side hairlines run to the region's bottom edge */
        min-width: 0;
    }

    body.v2 .v2-well {
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        min-width: 0;
        background: rgba(255, 255, 255, .02);
        border: 1px solid var(--v2-hair);
        border-radius: 14px;
        overflow: hidden;
    }

    /* The day in play is one step brighter — the others are legible, not
       disabled: their tiles are live. */
    body.v2 .v2-well.is-primary {
        background: rgba(255, 255, 255, .035);
        border-color: var(--v2-hair-strong);
    }

    body.v2 .v2-well-head {
        display: flex;
        align-items: baseline;
        justify-content: center;
        gap: 5px;
        height: 20px;
        padding: 0 6px;
        border-bottom: 1px solid var(--v2-hair);
        white-space: nowrap;
        overflow: hidden;
    }

    body.v2 .v2-well.is-primary .v2-well-head {
        border-bottom-color: var(--v2-hair-strong);
    }

    body.v2 .v2-well-day {
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.08em;
        line-height: 1;
        color: var(--text-muted);
    }

    body.v2 .v2-well.is-primary .v2-well-day {
        color: var(--v2-sky);
    }

    body.v2 .v2-well-clock {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 500;
        line-height: 1;
        color: var(--text-muted);
        opacity: .85;
    }

    body.v2 .v2-well.is-primary .v2-well-clock {
        color: rgba(125, 211, 252, .8);
    }

    body.v2 .v2-well-cols {
        display: flex;
        gap: 4px;
        padding: 4px 4px 2px;
    }

    body.v2 .v2-well-col {
        flex: 1 1 0;
        text-align: center;
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.1em;
        line-height: 1;
        color: var(--text-muted);
        white-space: nowrap;
        overflow: hidden;
    }

    body.v2 .v2-well-col.is-range {
        flex: 0 0 34%;
        color: rgba(125, 211, 252, .7);
    }

    body.v2 .v2-well-body {
        position: relative;
        flex: 1 1 auto;
        display: flex;
        gap: 4px;
        padding: 0 4px 4px;
        min-height: 0;
    }

    body.v2 .v2-well-strikes,
    body.v2 .v2-well-ranges {
        position: relative;
        min-width: 0;
    }

    body.v2 .v2-well-strikes { flex: 1 1 0; }
    body.v2 .v2-well-ranges  { flex: 0 0 34%; }

    /* clipped-strikes chips — pinned to the ladder's edges */
    body.v2 .v2-well-overflow {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        z-index: 3;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        line-height: 1;
        color: var(--text-muted);
        background: var(--v2-chip);
        border: 1px solid var(--v2-hair);
        border-radius: 999px;
        padding: 2px 7px;
        pointer-events: none;
        white-space: nowrap;
    }

    body.v2 .v2-well-overflow.is-up { top: 2px; }
    body.v2 .v2-well-overflow.is-dn { bottom: 2px; }

    body.v2 .v2-well-empty {
        position: absolute;
        inset: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        font-family: var(--sans);
        font-size: 0.625rem;
        letter-spacing: 0.06em;
        color: var(--text-muted);
        opacity: 1;
        pointer-events: none;
    }

    /* --- tiles: the strike is the hero; calls and puts differ only in
           tint, because the side is already told by which side of spot the
           tile sits on --- */
    body.v2 .v2-tile {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 15px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v2-r-tile);
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        line-height: 1;
        cursor: pointer;
        white-space: nowrap;
        transition: background-color 120ms ease, color 120ms ease;
    }

    body.v2 .v2-tile.is-call {
        background: var(--v2-call-fill);
        color: var(--positive);
    }

    body.v2 .v2-tile.is-put {
        background: var(--v2-put-fill);
        color: #F4CBC8;
    }

    body.v2 .v2-tile.is-call:hover { background: rgba(94, 221, 156, .22); }
    body.v2 .v2-tile.is-put:hover  { background: rgba(232, 106, 98, .22); }

    body.v2 .v2-tile.is-selected {
        background: var(--positive);
        color: var(--v2-on-green);
        box-shadow: 0 0 0 2px rgba(94, 221, 156, .35);
    }

    body.v2 .v2-tile.is-put.is-selected {
        background: var(--negative);
        color: var(--v2-on-negative);
        box-shadow: 0 0 0 2px rgba(232, 106, 98, .35);
    }

    /* --- range cells: the cell spans its own price band, so the geometry
           explains the product --- */
    body.v2 .v2-range {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        padding: 2px;
        border: 0;
        border-radius: var(--v2-r-tile);
        background: var(--v2-sky-fill);
        cursor: pointer;
        overflow: hidden;
        text-align: center;
        transition: background-color 120ms ease;
    }

    body.v2 .v2-range:hover { background: rgba(125, 211, 252, .22); }

    body.v2 .v2-range.is-selected {
        background: var(--v2-sky);
        box-shadow: 0 0 0 2px rgba(125, 211, 252, .35);
    }

    body.v2 .v2-range-bounds {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 700;
        line-height: 1.15;
        color: var(--v2-sky);
    }

    body.v2 .v2-range-max {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        line-height: 1;
        color: rgba(125, 211, 252, .75);
    }

    body.v2 .v2-range.is-selected .v2-range-bounds,
    body.v2 .v2-range.is-selected .v2-range-max {
        color: var(--v2-on-sky);
    }
}

/* The engine's STRIKES / RANGES toggle is redundant in v2: both products
   are on screen at once in the wells, so there is no mode to be in. */
@media (min-width: 992px) {
    body.v2 #v2-view-region .tc-tv-segment:first-child,
    body.v2 #v2-view-region .tc-tv-tools .tc-tv-divider:first-of-type {
        display: none;
    }
}

/* A cross-day pick has to refetch the book before the contract exists in
   state, so the tile says it heard the click while that happens. */
@media (min-width: 992px) {
    body.v2 .v2-tile.is-pending,
    body.v2 .v2-range.is-pending {
        outline: 1px dashed var(--v2-sky);
        outline-offset: 1px;
        opacity: .75;
    }
}

/* ==========================================================================
   7. THE TWO TABLE VIEWS
   Both read the same rows; only the arrangement differs. The legacy table
   stays in the DOM (it is what these read from) but is not shown.
   ========================================================================== */
@media (min-width: 992px) {

    body.v2 #v2-view-region .options-table {
        display: none;
    }

    /* --- shared row rhythm --- */
    /* Board: five EQUAL columns, rows sharing the slider's 48px gutter. */
    body.v2 .v2-tbl-head,
    body.v2 .v2-tbl-row {
        display: grid;
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: 10px;
        align-items: center;
        padding: 5px 48px;
    }

    body.v2 .v2-tbl-head,
    body.v2 .v2-chain-head {
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        line-height: 1;
        color: var(--text-muted);
        border-bottom: 1px solid var(--v2-hair);
        position: sticky;
        top: 0;
        background: var(--background);
        z-index: 2;
    }

    body.v2 .v2-tbl-head span:not(:first-child),
    body.v2 .v2-tbl-row span:not(:first-child) {
        text-align: right;
    }

    body.v2 .v2-tbl-row {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.6875rem;
        font-weight: 500;
        line-height: 1;
        color: var(--text-secondary);
        border-bottom: 1px solid var(--v2-hair);
        cursor: pointer;
        transition: background-color 120ms ease;
    }

    body.v2 .v2-tbl-row:hover { background: rgba(255, 255, 255, .03); }

    body.v2 .v2-tbl-row.is-selected {
        background: rgba(94, 221, 156, .07);
    }

    body.v2 .v2-tbl-head {
        font-size: 0.625rem;
        font-weight: 400;
    }

    body.v2 .v2-tbl-strike {
        font-weight: 600;
        color: var(--text-primary);
        text-align: left !important;
    }

    body.v2 .v2-tbl-strike.is-call { color: var(--positive); }
    body.v2 .v2-tbl-strike.is-put  { color: var(--negative); }

    /* --- the caption: the trade in one sentence --- */
    body.v2 #v2-slider-caption {
        margin: 14px 0 10px;
        text-align: center;
        font-family: var(--sans);
        font-size: 0.75rem;
        font-weight: 400;
        line-height: 1.5;
        color: var(--text-muted);
    }

    body.v2 #v2-slider-caption:empty { display: none; }

    body.v2 #v2-slider-caption b {
        font-weight: 600;
        color: var(--text-primary);
    }

    /* the payout expression reads green; the strike stays white */
    body.v2 #v2-slider-caption b.v2-cap-pay {
        color: var(--positive);
    }

    /* --- the chain: calls and puts either side of the strike ---
       Board proportions: 140px fixed greeks flanks, fluid quote columns,
       gap 12, 16px side padding. */
    body.v2 .v2-chain-head,
    body.v2 .v2-chain-row {
        display: grid;
        grid-template-columns: 140px minmax(0, 1fr) 96px minmax(0, 1fr) 140px;
        gap: 12px;
        align-items: center;
        padding: 4px 16px;
    }

    body.v2 .v2-chain-row {
        border-bottom: 1px solid var(--v2-hair);
    }

    /* Head labels align INWARD, toward the strike spine (board). */
    body.v2 .v2-chain-head .v2-chain-call { text-align: right; }
    body.v2 .v2-chain-head .v2-chain-put { text-align: left; }

    body.v2 .v2-chain-head .v2-chain-call { color: var(--positive); }
    body.v2 .v2-chain-head .v2-chain-put  { color: var(--negative); }
    body.v2 .v2-chain-head .v2-chain-strike { text-align: center; color: var(--text-secondary); }

    body.v2 .v2-chain-greeks {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 400;
        line-height: 1;
        color: var(--text-muted);
        text-align: right;
    }

    body.v2 .v2-chain-greeks.is-right { text-align: left; }

    body.v2 .v2-chain-call,
    body.v2 .v2-chain-put {
        display: flex;
        justify-content: center;
    }

    body.v2 .v2-chain-quote {
        width: 100%;
        border: 1px solid transparent;
        border-radius: 8px;
        padding: 4px 0;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.6875rem;
        font-weight: 600;
        line-height: 1;
        cursor: pointer;
        transition: background-color 120ms ease;
    }

    body.v2 .v2-chain-quote.is-call {
        background: rgba(94, 221, 156, .10);
        border-color: rgba(94, 221, 156, .35);
        color: var(--positive);
    }

    body.v2 .v2-chain-quote.is-put {
        background: rgba(232, 106, 98, .10);
        border-color: rgba(232, 106, 98, .35);
        color: var(--negative);
    }

    body.v2 .v2-chain-quote.is-call:hover { background: rgba(94, 221, 156, .2); }
    body.v2 .v2-chain-quote.is-put:hover  { background: rgba(232, 106, 98, .2); }

    body.v2 .v2-chain-quote.is-selected.is-call {
        background: var(--positive);
        border-color: var(--positive);
        color: var(--v2-on-green);
    }

    body.v2 .v2-chain-quote.is-selected.is-put {
        background: var(--negative);
        border-color: var(--negative);
        color: var(--v2-on-negative);
    }

    /* A strike quotes on one side only; the other says so rather than
       printing a zero. */
    body.v2 .v2-chain-none {
        color: var(--text-muted);
        opacity: .7;
    }

    /* a fully one-sided book dims its dead side and names it */
    body.v2 .v2-chain.is-no-puts .v2-chain-row .v2-chain-put,
    body.v2 .v2-chain.is-no-puts .v2-chain-row .v2-chain-greeks.is-right,
    body.v2 .v2-chain.is-no-puts .v2-chain-head .v2-chain-put,
    body.v2 .v2-chain.is-no-calls .v2-chain-row .v2-chain-call,
    body.v2 .v2-chain.is-no-calls .v2-chain-row .v2-chain-greeks:first-child,
    body.v2 .v2-chain.is-no-calls .v2-chain-head .v2-chain-call {
        opacity: .4;
    }

    body.v2 .v2-chain-oneside {
        padding: 10px 16px;
        text-align: center;
        font-size: 0.6875rem;
        color: var(--text-muted);
    }

    body.v2 .v2-chain-strike {
        text-align: center;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        line-height: 1.2;
    }

    body.v2 .v2-chain-strike b {
        font-size: 0.75rem;
        font-weight: 700;
        color: var(--text-primary);
    }

    /* strike and distance ride one line (board) */
    body.v2 .v2-chain-dist {
        display: inline;
        margin-left: 6px;
        font-size: 0.625rem;
        font-weight: 400;
        color: var(--text-muted);
    }

    body.v2 .v2-chain-spot {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 3px 12px;
    }

    body.v2 .v2-chain-spot::before,
    body.v2 .v2-chain-spot::after {
        content: "";
        flex: 1 1 auto;
        border-top: 1px dashed rgba(125, 211, 252, .45);
    }

    body.v2 .v2-chain-spot span {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        line-height: 1;
        color: var(--v2-on-sky);
        background: var(--v2-sky);
        padding: 2px 8px;
        border-radius: 5px;
    }
}

/* The chain is always displayed and always laid out; §5's layer rules decide
   whether it is the visible one. */
@media (min-width: 992px) {
    body.v2 #v2-chain { display: block; }
}

/* The three views are absolutely-stacked layers inside the region, and the
   inactive ones are hidden with visibility rather than display.

   That is not a style choice. A Lightweight Charts instance mounted inside a
   display:none box measures zero and never re-measures itself when the box
   later grows, so its price scale answers priceToCoordinate with null — which
   reads downstream as "the chart is not ready" and leaves the wells
   permanently empty. visibility:hidden keeps the box laid out at full size,
   so the chart is correct the moment it is shown.

   switchView() still writes its own inline display on these elements, so each
   layer's display is forced here; the layer's visibility is what actually
   decides which view the reader sees. */
@media (min-width: 992px) {

    body.v2 #v2-view-region > #v2-chart-row,
    body.v2 #v2-view-region > .strike-slider-track,
    body.v2 #v2-view-region > #v2-chain,
    body.v2 #v2-view-region > .options-table-container {
        position: absolute;
        inset: 0;
        visibility: hidden;
        pointer-events: none;
    }

    body.v2 #v2-view-region > #v2-chart-row { display: flex !important; }

    body.v2 #v2-view-region[data-v2-view="chart"] > #v2-chart-row,
    body.v2 #v2-view-region[data-v2-view="basic"] > .strike-slider-track,
    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chain {
        visibility: visible;
        pointer-events: auto;
        z-index: 1;
    }

    body.v2 #v2-view-region[data-v2-view="chart"] > #v2-chart-row #target-chart {
        display: block !important;
    }

    /* The legacy table is never shown; it is only the source the chain reads. */
    body.v2 #v2-view-region > .options-table-container {
        visibility: hidden !important;
        pointer-events: none !important;
    }
}

/* The ranger zone buttons are hardcoded purple in app.css (the token
   --ranger-purple plus several literals). v2 gives ranges one identity —
   sky — so the slider view and the wells say the same thing. */
@media (min-width: 992px) {
    body.v2 .ranger-zone-button,
    body.v2 .ranger-zones-container.dimmed .ranger-zone-button,
    body.v2 .ranger-zone-button.dimmed {
        background: var(--v2-sky-fill);
        border-left-color: rgba(125, 211, 252, .7);
        border-right-color: rgba(125, 211, 252, .7);
        box-shadow: none;
    }

    body.v2 .ranger-zone-button:hover,
    body.v2 .ranger-zones-container.dimmed .ranger-zone-button:hover,
    body.v2 .ranger-zone-button.dimmed:hover {
        background: rgba(125, 211, 252, .22);
        border-left-color: var(--v2-sky);
        border-right-color: var(--v2-sky);
        box-shadow: none;
    }

    body.v2 .ranger-zone-button.selected {
        background: rgba(125, 211, 252, .3);
        border-left-color: var(--v2-sky);
        border-right-color: var(--v2-sky);
        box-shadow: none;
    }

    body.v2 .ranger-btn-label,
    body.v2 .ranger-zone-button.selected .ranger-btn-label {
        color: var(--v2-sky);
    }

    body.v2 .ranger-btn-multiplier,
    body.v2 .ranger-zone-button.selected .ranger-btn-multiplier {
        color: rgba(125, 211, 252, .8);
    }

    body.v2 .ranger-badge {
        background: var(--v2-sky);
        color: var(--v2-on-sky);
    }
}

/* ==========================================================================
   8. THE TICKET
   The shipped ticket keeps its structure, its payoff chart and its buy flow.
   v2 adds a side and a strike control, and lifts the settlement scenarios
   out of the confirm step so they are visible while deciding.
   ========================================================================== */
@media (min-width: 992px) {

    body.v2 .trade-preview-card {
        /* The board's ticket column sits on the page's own ground — the
           card tone was the deviation. The divider is the column rail. */
        background: var(--background);
        border: 0;
        border-radius: 0 !important;
    }

    body.v2 .v2-decide {
        padding: 0 14px 12px;
    }

    body.v2 .v2-side {
        display: flex;
        gap: 6px;
        margin-bottom: 12px;
    }

    body.v2 .v2-side-btn {
        flex: 1 1 0;
        padding: 9px 0;
        border: 0;
        border-radius: var(--v2-r-ctl);
        background: transparent;
        color: var(--text-muted);
        font-family: var(--sans);
        font-size: 0.75rem;
        font-weight: 600;
        line-height: 1;
        cursor: pointer;
        transition: background-color 140ms ease, color 140ms ease, border-color 140ms ease;
    }

    body.v2 .v2-side-btn:hover:not(:disabled) {
        border-color: transparent;
    }

    body.v2 .v2-side-btn.is-call:hover:not(:disabled) { background: var(--v2-call-fill); color: var(--positive); }
    body.v2 .v2-side-btn.is-put:hover:not(:disabled)  { background: var(--v2-put-fill);  color: var(--negative); }

    body.v2 .v2-side-btn.is-call.is-active {
        background: var(--positive);
        border-color: var(--positive);
        color: var(--v2-on-green);
    }

    body.v2 .v2-side-btn.is-put.is-active {
        background: var(--negative);
        border-color: var(--negative);
        color: var(--v2-on-negative);
    }

    /* Nothing to buy on that side — said, not hidden. */
    body.v2 .v2-side-btn:disabled {
        opacity: .4;
        cursor: not-allowed;
    }

    body.v2 .v2-stepper {
        display: flex;
        gap: 6px;
    }

    body.v2 .v2-step {
        width: 38px;
        border: 0;
        border-radius: 7px;
        background: var(--v2-chip);
        color: var(--text-secondary);
        font-size: 0.875rem;
        line-height: 1;
        cursor: pointer;
        transition: background-color 140ms ease;
    }

    body.v2 .v2-step:hover:not(:disabled) { background: var(--v2-chip-hover); }
    body.v2 .v2-step:disabled { opacity: .35; cursor: not-allowed; }

    body.v2 .v2-step-value {
        flex: 1 1 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        background: var(--v2-chip);
        border-radius: var(--v2-r-ctl);
        padding: 9px 0;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.9375rem;
        font-weight: 600;
        line-height: 1;
        color: var(--text-primary);
    }

    /* --- scenarios, visible while deciding --- */
    body.v2 #v2-scenarios {
        padding: 10px 14px 14px;
        border-top: 1px solid var(--v2-hair);
    }

    body.v2 #v2-scenarios[hidden] { display: none; }

    body.v2 .v2-scen-head {
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        line-height: 1;
        color: var(--text-muted);
        margin-bottom: 6px;
    }

    body.v2 .v2-scen-table {
        width: 100%;
        border-collapse: collapse;
    }

    body.v2 .v2-scen-table th {
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 400;
        letter-spacing: 0;
        color: var(--text-muted);
        text-align: right;
        padding: 0 0 4px;
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .v2-scen-table th:first-child { text-align: left; }

    body.v2 .v2-scen-table td {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.6875rem;
        font-weight: 500;
        line-height: 1;
        color: var(--text-secondary);
        text-align: right;
        padding: 4px 0;
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .v2-scen-table td:first-child { text-align: left; }
    body.v2 .v2-scen-table tr:last-child td { border-bottom: 0; }

    /* renderSettlementScenarios paints the traffic-light classes; v2 only
       supplies what they should look like on this ground. */
    body.v2 .v2-scen-table .text-success,
    body.v2 .v2-scen-table .profit { color: var(--positive); }
    body.v2 .v2-scen-table .text-danger,
    body.v2 .v2-scen-table .loss { color: var(--negative); }
    body.v2 .v2-scen-table .breakeven { color: var(--text-muted); }
}

/* ==========================================================================
   9. COLUMN 3 — news and chat as two matching modules
   Hairline, rounded, no surface fill: the pair reads as one rail rather than
   two panels competing with the ticket beside them.
   ========================================================================== */
@media (min-width: 992px) {

    body.v2 #v2-col3 {
        position: relative;
        display: block;
        padding: 0;
    }

    /* Absolute, so the rail contributes no height of its own: it takes the
       height the grid row already has from column 1. The chat's message list
       has no natural cap and would otherwise stretch the page to its content. */
    body.v2 #v2-col3-inner {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        gap: 10px;
        padding: 10px;
        min-height: 0;
    }

    body.v2 #v2-news,
    body.v2 #v2-chat > .trollbox-widget {
        border: 1px solid var(--v2-hair-strong);
        border-radius: var(--v2-r-card) !important;
        background: transparent;
        overflow: hidden;
    }

    body.v2 #v2-news {
        flex: 0 0 auto;
        display: flex;
        flex-direction: column;
    }

    body.v2 #v2-chat {
        flex: 1 1 auto;
        display: flex;
        min-height: 0;
    }

    body.v2 .v2-mod-head {
        display: flex;
        align-items: baseline;
        gap: 10px;
        padding: 9px 14px;
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .v2-mod-title {
        font-family: var(--sans);
        font-size: 12px;
        font-weight: 600;
        line-height: 1;
        color: var(--text-primary);
    }

    body.v2 .v2-mod-sub {
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 400;
        line-height: 1;
        color: var(--text-muted);
    }

    body.v2 .v2-mod-meta {
        margin-left: auto;
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 400;
        line-height: 1;
        color: var(--text-muted);
    }

    body.v2 .v2-news-list {
        list-style: none;
        margin: 0;
        padding: 4px 14px 10px;
    }

    body.v2 .v2-news-item {
        display: flex;
        gap: 10px;
        padding: 6px 0;
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .v2-news-item:last-child { border-bottom: 0; }

    body.v2 .v2-news-when {
        flex: 0 0 auto;
        min-width: 56px;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        line-height: 1.4;
        color: var(--text-muted);
        white-space: nowrap;
    }

    /* The next one due is the one that can move the price under you. */
    body.v2 .v2-news-item.is-next .v2-news-when { color: var(--accent); }

    body.v2 .v2-news-name {
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 400;
        line-height: 1.4;
        color: var(--text-secondary);
    }

    body.v2 .v2-news-approx {
        font-size: 0.625rem;
        color: var(--text-muted);
    }

    body.v2 .v2-news-none {
        padding: 8px 0;
        font-family: var(--sans);
        font-size: 0.6875rem;
        color: var(--text-muted);
    }

    body.v2 .v2-news-note {
        margin: 0;
        padding: 8px 14px;
        border-top: 1px solid var(--v2-hair);
        font-family: var(--sans);
        font-size: 0.625rem;
        line-height: 1.45;
        color: var(--text-muted);
    }

    body.v2 .v2-news-note[data-level="warn"] { color: var(--accent); }

    /* --- the docked trollbox ---
       trollbox.js writes inline display/height and app.css floats the widget
       fixed at the corner. Author !important is what beats an inline style,
       which is why every one of these carries it. */
    body.v2 #v2-chat > .trollbox-widget {
        position: static !important;
        display: flex !important;
        flex-direction: column;
        width: 100% !important;
        height: auto !important;
        max-height: none !important;
        min-height: 0 !important;
        flex: 1 1 auto;
        inset: auto !important;
        z-index: auto !important;
        box-shadow: none !important;
        resize: none !important;
    }

    body.v2 #v2-chat > .trollbox-widget.minimized {
        height: auto !important;
    }

    body.v2 #v2-chat .trollbox-content {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    body.v2 #v2-chat #trollbox-messages {
        flex: 1 1 auto;
        min-height: 0;
    }

    /* Window furniture has no meaning in a docked column. */
    body.v2 #v2-chat #trollbox-minimize,
    body.v2 #v2-chat #trollbox-close,
    body.v2 #v2-chat #trollbox-resize-handle,
    body.v2 #trollbox-toggle {
        display: none !important;
    }

    body.v2 #v2-chat #trollbox-header {
        border-bottom: 1px solid var(--v2-hair);
        border-radius: 0;
    }

    /* The tab strip replaces the static title (board: Trollbox | Fills). */
    body.v2 #v2-chat .trollbox-title > i,
    body.v2 #v2-chat .trollbox-title > span:not(.online-count) {
        display: none;
    }

    body.v2 #v2-chat-tabs {
        display: inline-flex;
        gap: 2px;
    }

    body.v2 .v2-chat-tab {
        border: 0;
        background: transparent;
        color: var(--text-muted);
        font-family: var(--sans);
        font-size: 12px;
        font-weight: 600;
        line-height: 1;
        padding: 4px 8px;
        border-radius: 6px;
        cursor: pointer;
    }

    body.v2 .v2-chat-tab.is-active {
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-primary);
    }

    body.v2 .v2-chat-tab b {
        font-weight: 500;
        color: var(--positive);
        margin-left: 3px;
    }

    /* the online count speaks the head's own family */
    body.v2 #v2-chat .online-count {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 500;
        color: var(--text-muted);
        background: transparent;
        margin-left: auto;
    }

    /* ---- the Fills pane: the standing open book, dense bar-rows ---- */
    body.v2 #v2-fills-pane {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 6px 8px;
    }

    body.v2 #v2-fills-pane[hidden] { display: none; }

    body.v2 #v2-chat.v2-showfills #trollbox-messages,
    body.v2 #v2-chat.v2-showfills .trollbox-input-container {
        display: none !important;
    }

    body.v2 #trollbox-content { position: relative; }

    body.v2 .v2-fill-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas: 'what prem' 'who when';
        gap: 2px 8px;
        align-items: baseline;
        width: 100%;
        border: 0;
        border-left: 2px solid var(--text-muted);
        background: rgba(255, 255, 255, 0.02);
        border-radius: 0 6px 6px 0;
        padding: 6px 8px;
        margin-bottom: 4px;
        font-size: 0.6875rem;
        color: var(--text-secondary);
        text-align: left;
        cursor: pointer;
    }

    body.v2 .v2-fill-row.is-call { border-left-color: var(--positive); }
    body.v2 .v2-fill-row.is-put { border-left-color: var(--negative); }
    body.v2 .v2-fill-row.is-range { border-left-color: var(--v2-sky); }

    body.v2 .v2-fill-row b {
        grid-area: who;
        font-weight: 500;
        font-size: 0.625rem;
        color: var(--text-muted);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    body.v2 .v2-fill-row span {
        grid-area: what;
        color: var(--text-primary);
        font-weight: 600;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    body.v2 .v2-fill-row em { grid-area: prem; font-style: normal; }

    body.v2 .v2-fill-row i {
        grid-area: when;
        justify-self: end;
        font-style: normal;
        font-size: 0.625rem;
        color: var(--text-muted);
    }

    body.v2 .v2-fills-none {
        padding: 18px 10px;
        text-align: center;
        font-size: 12px;
        color: var(--text-muted);
    }

    /* ---- the new-messages jump chip ---- */
    body.v2 #v2-chat-jump {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 58px;
        z-index: 5;
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift), 0 4px 14px rgba(0, 0, 0, 0.4);
        color: var(--text-primary);
        font-size: 0.625rem;
        font-weight: 600;
        padding: 5px 11px;
        border-radius: 999px;
        cursor: pointer;
        box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
    }

    body.v2 #v2-chat-jump[hidden] { display: none; }
}

/* --------------------------------------------------------------------------
   4c. Narrow desktop: two columns, rail beneath the ticket.

   Three columns stop being honest below ~1440px. At 992 the arithmetic is
   1280 - ticket - rail, which leaves the chart under 100px — a price line
   with no room to be a price line. So the rail drops under the ticket and
   the chart takes the width back, which is what the approved narrow board
   shows too.
   -------------------------------------------------------------------------- */
@media (min-width: 992px) and (max-width: 1439.98px) {

    body.v2 {
        --v2-ticket-w: clamp(300px, 26vw, 352px);
        --v2-rail-w: auto;
    }

    body.v2 .trade-unified-layout {
        grid-template-columns: minmax(0, 1fr) var(--v2-ticket-w);
        grid-template-rows: auto auto;
    }

    body.v2 #v2-col1 {
        grid-column: 1;
        grid-row: 1 / span 2;
    }

    body.v2 #v2-col2 {
        grid-column: 2;
        grid-row: 1;
    }

    body.v2 #v2-col3 {
        grid-column: 2;
        grid-row: 2;
        border-left: 0;
        border-top: 1px solid var(--v2-hair);
        /* The rail's frame is absolute, so this row needs a height of its
           own or it collapses to nothing. */
        min-height: 320px;
    }
}

/* ==========================================================================
   10. CORRECTIONS AGAINST THE APPROVED BOARDS
   Everything here is a discrepancy between what shipped in §1-9 and the
   signed-off design, found by putting the two side by side.
   ========================================================================== */
@media (min-width: 992px) {

    /* --- the stray blue bar in the asset row ---
       .asset-slide-indicator is a scroll cue for the old VERTICAL asset rail.
       The rail is a horizontal strip now and scrolls nothing, so the cue has
       nothing to say — and the v2 palette had turned it sky blue, which read
       as a UI element rather than a leftover. */
    body.v2 .asset-slide-indicator {
        display: none !important;
    }

    /* --- the ticket ---
       app.css paints the ticket's boxes with literal rgba() values rather
       than tokens: a milky white overlay for the stat grid and an amber
       (253,224,71) hairline on the belief card, which is the OLD accent and
       does not exist in the v2 palette. Both are restated here on the v2
       surfaces, and every radius in the ticket is brought onto the one
       control radius so the boxes stop disagreeing edge to edge. */
    body.v2 .trade-preview-card .select-amount-section,
    body.v2 .trade-preview-card .ticket-amount-field {
        background: transparent;
        border-color: var(--v2-hair);
    }

    body.v2 .trade-preview-card #ticket-amount-field,
    body.v2 .trade-preview-card .ticket-amount-field {
        background: var(--v2-chip-inset);
        border: 0;
        border-radius: var(--v2-r-ctl) !important;
    }

    body.v2 .trade-preview-card #trade-now-btn {
        border-radius: var(--v2-r-ctl) !important;
    }

    /* The belief card restated everything already on screen — the side is in
       the CALL badge, the strike in the stepper below it, the countdown in
       the expiry tabs — inside an amber-edged box the design never had. */
    body.v2 #trade-preview-profit-statement {
        display: none;
    }

    /* --- wells: align the cards with the PLOT, not the region ---
       The chart carries its own toolbar row, so a well starting at the top of
       the region floats beside that toolbar instead of beginning where the
       price scale begins. revamp.js measures the toolbar and writes the
       offset; this is the fallback until it does. */
    body.v2 #v2-wells {
        padding-top: var(--v2-wells-top, 6px);
    }

    /* A well is ~86px wide at the narrow breakpoint and "TODAY 03:37:54" is
       87px — it was clipping the T. Let the header wrap to a second line when
       it must, and stay on one when it fits. */
    body.v2 .v2-well-head {
        flex-wrap: wrap;
        height: auto;
        min-height: 20px;
        padding: 3px 6px;
        row-gap: 1px;
    }

    /* --- positions / history tabs ---
       These still wore the old chrome: 13px pure-white labels on a 2px sky
       underline. They are the same control as the view switcher, so they
       look like it. */
    body.v2 .trade-strip-tabs {
        gap: 2px;
        padding: 8px 16px 0;
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .trade-strip-tab {
        border: 0;
        border-radius: var(--v2-r-ctl) var(--v2-r-ctl) 0 0;
        background: transparent;
        padding: 7px 12px;
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        line-height: 1;
        color: var(--text-muted);
        transition: color 140ms ease, background-color 140ms ease;
    }

    body.v2 .trade-strip-tab:hover {
        color: var(--text-secondary);
        background: rgba(255, 255, 255, .03);
    }

    body.v2 .trade-strip-tab.active {
        color: var(--text-primary);
        background: var(--v2-chip);
    }
}

/* Two more literals app.css paints without tokens, both from the pre-v2
   palette: the funding link's amber (#FDE047) and the identity badge's
   green (#86EFAC). Restated on the v2 pair. */
@media (min-width: 992px) {

    body.v2 #get-more-dropdown,
    body.v2 .get-more-inline,
    body.v2 .get-more-inline .bi {
        color: var(--v2-sky) !important;
        border-color: rgba(125, 211, 252, .28) !important;
        background: rgba(125, 211, 252, .08) !important;
    }

    body.v2 .preview-option-type.is-call {
        background: var(--v2-call-fill);
        border-color: rgba(94, 221, 156, .4);
        color: var(--positive);
    }

    body.v2 .preview-option-type.is-put {
        background: var(--v2-put-fill);
        border-color: rgba(232, 106, 98, .4);
        color: var(--negative);
    }

    body.v2 .preview-option-type.is-ranger,
    body.v2 .preview-option-type.is-range {
        background: var(--v2-sky-fill);
        border-color: rgba(125, 211, 252, .4);
        color: var(--v2-sky);
    }

    /* 6.5px was below the floor for a label anyone is expected to read. */
    body.v2 .v2-well-col {
        font-size: 0.625rem;
        letter-spacing: 0.08em;
    }
}

/* At the narrow band a well is ~92px and "CALL / PUT" with full tracking
   does not fit its share — the tracking yields (the board's spaces stay). */
@media (min-width: 992px) and (max-width: 1679.98px) {
    body.v2 .v2-well-col {
        letter-spacing: 0.02em;
    }
}

/* ==========================================================================
   §11 · BOARD RECONCILIATION, ROUND 2 — the mockup is the source of truth.
   Main.dc.html col1: asset strip → serif head → pays line + toolbar → chart.
   ========================================================================== */
@media (min-width: 992px) {

    /* Chrome the board dropped outright: the ETH⌄ dropdown + big spot price
       row, and the 1 Day/2 Days/3 Days toggle. Day switching happens by
       tapping another day's well; the hidden radios/buttons stay in the DOM
       because the wells' cross-day path still drives them programmatically. */
    body.v2 .trade-title-row,
    body.v2 .expiry-filter-section {
        display: none !important;
    }

    /* The board's serif line is "Where does ETH close?". The app rewrites its
       own span every second (updateDesktopPredictionPrompt), so that span
       hides and the v2 line beside it paints instead — same serif styles via
       the #desktop-prediction-prompt rules in §5. */
    body.v2 #desktop-prediction-prompt > span {
        display: none;
    }
}

/* --- §11 · the board's ticket anatomy (Main.dc.html col2) ----------------- */
@media (min-width: 992px) {

    /* The board's ticket has no identity header, no AMOUNT header row, no
       percent presets and no stat boxes. Hidden, not removed: the app keeps
       writing into their ids and #v2-params reads the values back out. */
    body.v2 .preview-card-identity,
    body.v2 .amount-header-row,
    body.v2 .trade-preview-card .ticket-stats,
    body.v2 .trade-preview-card .amount-presets {
        display: none !important;
    }

    /* BASIC | ADVANCED — how much the ticket says. */
    body.v2 .v2-ticket-tabs {
        display: flex;
        gap: 6px;
        padding: 14px 14px 0;
        margin-bottom: 12px;
    }

    body.v2 .v2-ticket-tab {
        flex: 1 1 0;
        padding: 7px 0;
        border: 0;
        border-radius: 7px;
        background: transparent;
        color: var(--text-muted);
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 500;
        letter-spacing: 0.05em;
        line-height: 1;
        cursor: pointer;
    }

    body.v2 .v2-ticket-tab.is-active {
        background: var(--v2-sky);
        color: var(--v2-on-sky);
        font-weight: 600;
    }

    /* The plain question the ticket answers. */
    /* TicketB: the question is the ticket's serif headline. */
    body.v2 .v2-question {
        padding: 0 14px;
        margin-bottom: 14px;
        font-family: var(--v2-display);
        font-size: 1.1875rem;
        font-weight: 600;
        line-height: 1.3;
        letter-spacing: -0.02em;
        color: var(--text-primary);
    }

    body.v2 .v2-question b {
        font-weight: 600;
    }

    /* ADVANCED swaps the question/side/stepper for identity + greeks. */
    body.v2 .v2-adv-ident {
        display: none;
        align-items: center;
        gap: 8px;
        padding: 0 14px;
        margin-bottom: 10px;
    }

    body.v2 .v2-adv-greeks {
        display: none;
        gap: 12px;
        padding: 0 14px;
        margin-bottom: 12px;
        font-size: 12px;
        color: var(--text-muted);
    }

    body.v2.v2-adv .v2-adv-ident { display: flex; }
    body.v2.v2-adv .v2-adv-greeks { display: flex; }
    body.v2.v2-adv .v2-question,
    body.v2.v2-adv .v2-side,
    body.v2.v2-adv .v2-strike-row,
    body.v2.v2-adv .v2-stepper { display: none; }

    body.v2 .v2-adv-badge {
        font-size: 0.6875rem;
        font-weight: 600;
        line-height: 1;
        padding: 4px 10px;
        border-radius: 6px;
        border: 1px solid rgba(94, 221, 156, .45);
        background: var(--v2-call-fill);
        color: var(--positive);
    }

    body.v2 .v2-adv-badge.is-put {
        border-color: rgba(232, 106, 98, .45);
        background: var(--v2-put-fill);
        color: var(--negative);
    }

    body.v2 .v2-adv-badge.is-range {
        border-color: rgba(125, 211, 252, .45);
        background: var(--v2-sky-fill);
        color: var(--v2-sky);
    }

    body.v2 .v2-adv-name {
        font-size: 0.875rem;
        font-weight: 600;
        color: var(--text-primary);
    }

    /* Amount as the board's single chip row: label left, value right. */
    body.v2 .trade-preview-card #ticket-amount-field {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 9px 12px;
        margin-bottom: 8px;
    }

    body.v2 .v2-amt-label {
        color: var(--text-muted);
        font-size: 12px;
    }

    body.v2 .trade-preview-card .ticket-amt-input {
        flex: 1 1 auto;
        min-width: 0;
        background: transparent;
        border: 0;
        padding: 0;
        text-align: right;
        font-size: 0.9375rem;
        font-weight: 600;
        color: var(--text-primary);
    }

    body.v2 .trade-preview-card .ticket-amt-unit {
        font-size: 0.6875rem;
        color: var(--text-muted);
    }

    /* Dollar presets. */
    body.v2 .v2-presets {
        display: flex;
        gap: 6px;
        margin-bottom: 14px;
    }

    body.v2 .v2-preset {
        flex: 1 1 0;
        padding: 6px 0;
        border: 0;
        border-radius: 7px;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-size: 0.6875rem;
        font-weight: 500;
        line-height: 1;
        cursor: pointer;
    }

    body.v2 .v2-preset:hover {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }

    body.v2 .v2-preset.is-active {
        background: var(--v2-sky);
        box-shadow: none;
        color: var(--v2-on-sky);
        font-weight: 600;
    }

    /* The parameter list — rows, not boxes. */
    body.v2 .v2-params {
        margin-bottom: 2px;
    }

    body.v2 .v2-param {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 12px;
        margin-bottom: 4px;
        font-size: 0.75rem;
    }

    body.v2 .v2-param-k {
        color: var(--text-muted);
        white-space: nowrap;
    }

    body.v2 .v2-param-v {
        color: var(--text-secondary);
        text-align: right;
    }

    body.v2 .v2-param-v.is-pos {
        color: var(--positive);
        font-weight: 600;
    }

    /* BUY — solid green per the board. The non-ready states (LOADING, NEED
       MORE, PAUSED) keep their muted face; only .btn-primary goes green. */
    body.v2 .trade-preview-card #trade-now-btn {
        padding: 12px 0;
        border: 0;
        font-size: 0.78125rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        line-height: 1;
    }

    body.v2 .trade-preview-card #trade-now-btn.btn-primary {
        background: var(--positive);
        color: var(--v2-on-green);
    }

    body.v2 .trade-preview-card #trade-now-btn.btn-primary:hover {
        filter: brightness(1.06);
    }

    /* The resting/disabled button is a quiet chip, not Bootstrap's grey
       pill — this is the first control every new user reads. */
    body.v2 .trade-preview-card #trade-now-btn:disabled,
    body.v2 .trade-preview-card #trade-now-btn.disabled {
        background: var(--v2-chip-dim) !important;
        border-color: transparent !important;
        color: var(--text-muted) !important;
        opacity: 1 !important;
    }
}

/* --- §11 · payoff zone (Main.dc.html col2, PAYOFF block) ------------------ */
@media (min-width: 992px) {

    /* One pane on the board: the PAYOFF | PRICE CHART tabs and the 1m/30m/
       1h/4h buttons retire. The PRICE pane never activates, so its TradingView
       widget is never built. The calc's own header row and the COST/PAYOUT/
       NET P&L strip hide too — their ids keep being written and the readout
       chip below mirrors them. */
    body.v2 .ticket-analysis .ticket-tabs,
    body.v2 #pane-price,
    body.v2 #payout-calculator .ticket-pane-head,
    body.v2 #payout-calculator .ticket-readouts {
        display: none !important;
    }

    body.v2 .v2-payoff-head {
        display: flex;
        align-items: baseline;
        gap: 8px;
        padding: 10px 14px 0;
        margin-bottom: 6px;
    }

    body.v2 .v2-payoff-label {
        font-size: 0.65625rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        color: var(--text-primary);
    }

    body.v2 .v2-payoff-readout {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 10px;
        margin: 0 14px 5px;
        padding: 6px 10px;
        background: var(--v2-chip);
        border-radius: var(--v2-r-ctl);
        font-size: 0.65625rem;
        color: var(--text-muted);
    }

    body.v2 .v2-payoff-readout[hidden] {
        display: none;
    }

    body.v2 .v2-payoff-readout b {
        font-weight: 600;
        color: var(--text-primary);
    }

    body.v2 .v2-payoff-readout .is-pos { color: var(--positive); }
    body.v2 .v2-payoff-readout .is-neg { color: var(--negative); }
}

/* --- §11 · one control height in the topbar ------------------------------- */
@media (min-width: 992px) {

    /* Every control on the topbar's right side sits on the same 30px line —
       the board draws them all with the same 7px pad + 8px radius, and the
       user can see a 1px difference. Height beats padding so differing font
       sizes cannot re-open the gap. */
    body.v2 .hdr-tools .hdr-pill,
    body.v2 #nav-alert-btn,
    body.v2 #v2-balance-chip,
    body.v2 .header-wallet-pill,
    body.v2 #wallet-help-icon {
        box-sizing: border-box;
        height: var(--v2-ctl-h, 30px);
        display: inline-flex;
        align-items: center;
        padding-top: 0;
        padding-bottom: 0;
        border-radius: var(--v2-r-ctl) !important;
    }
}

/* --- §11 · chart annotations (Main.dc.html:97-126) ------------------------ */
@media (min-width: 992px) {

    /* The pays line sits at the left of the toolbar row; margin-right:auto
       pushes the engine's own button groups to the right, matching the
       board's single line. */
    body.v2 #v2-pays-line {
        margin-right: auto;
        align-self: center;
        padding-left: 6px;
        font-size: 0.75rem;
        color: var(--text-secondary);
        pointer-events: none;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    body.v2 #v2-pays-line b { color: var(--text-primary); font-weight: 600; }
    /* the side is a word here ("above 2,560"), not money: white, bold (critique 2026-09-04) */
    body.v2 #v2-pays-line .is-pos,
    body.v2 #v2-pays-line .is-neg,
    body.v2 #v2-pays-line .is-sky { color: var(--text-primary); font-weight: 600; }
    body.v2 #v2-pays-line .v2-pays-exp { color: var(--text-muted); font-weight: 400; }

    /* The solid tag pinned just under the selected strike's price line. */
    body.v2 #v2-pays-tag {
        position: absolute;
        left: 14px;
        top: 0;
        z-index: 7;
        padding: 2px 8px;
        border-radius: 4px;
        font-size: 0.625rem;
        font-weight: 600;
        line-height: 1.5;
        letter-spacing: 0.02em;
        pointer-events: none;
        white-space: nowrap;
    }

    body.v2 #v2-pays-tag.is-call { background: var(--positive); color: var(--v2-on-green); }
    body.v2 #v2-pays-tag.is-put { background: var(--negative); color: var(--v2-on-negative); }
    body.v2 #v2-pays-tag.is-range { background: var(--v2-sky); color: #071018; }
    body.v2 #v2-pays-tag[hidden] { display: none; }

    /* The engine's breakeven label becomes the board's small chip:
       "BE 2,509.81" — the percent-from-spot copy retires, the word shrinks
       to the chip's BE via ::before (the engine writes "Breakeven"). */
    body.v2 #tc-tv-be-label {
        background: var(--card-bg);
        border: 1px solid var(--v2-hair-strong);
        border-radius: 3px;
        padding: 1px 5px;
        font-size: 0.625rem;
        color: var(--text-secondary);
    }

    body.v2 #tc-tv-be-label::before {
        content: 'BE';
        margin-right: 4px;
        color: var(--text-muted);
        font-weight: 600;
    }

    body.v2 #tc-tv-be-label .tc-tv-be-name,
    body.v2 #tc-tv-be-label .tc-tv-be-from {
        display: none;
    }
}

/* The board's toolbar row is LIVE/1D/2D/3D · zoom · FIT — the STRIKES/RANGES
   overlay toggle isn't on it, and with the pays line added the row must not
   wrap: the line yields (ellipsis) before the buttons do. */
@media (min-width: 992px) {
    body.v2 #v2-chart-row .tc-tv-tools {
        flex-wrap: nowrap;
    }

    body.v2 #v2-chart-row .tc-tv-tools > .tc-tv-segment:not(.tc-tv-zoom) {
        display: none;
    }

    body.v2 #v2-pays-line {
        min-width: 0;
        flex: 0 1 auto;
    }
}

/* --- §11 · measured sweep against the boards ------------------------------ */
@media (min-width: 992px) {

    /* Asset chips: the board sets 11.5px — the strip was drifting at 12. */
    body.v2 .asset-selection-btn {
        font-size: 12px;
    }

    /* View switcher inner chips: r6 and the board's 4px vertical pad. */
    body.v2 .view-text-links .view-link {
        padding: 4px 11px;
        border-radius: 6px !important;
    }

    /* Chart toolbar buttons carry the board's chartbtn spec: 20px line,
       9.5px/500 at .06em tracking, 5px radius. */
    body.v2 #v2-chart-row .tc-tv-tool {
        min-height: 20px;
        line-height: 20px;
        padding: 0 8px;
        border-radius: 5px !important;
        font-size: 0.625rem;
        font-weight: 500;
        letter-spacing: 0.06em;
    }
}

/* --- §11 · 1:1 pass against the rendered board ---------------------------- */
@media (min-width: 992px) {

    /* Coin logos ON, reversing round 10's text-only chips (user, 2026-09-09).
       app.js already builds an <img class="asset-icon"> for every canonical
       asset from CANONICAL_ASSETS[sym].icon, so this needs no new markup and
       no new files — every asset in config.js ships an icon, DOGE included,
       and a new one inherits this the day it is listed.

       14px to match the 12px label's cap height rather than the 24px the
       markup asks for, and flex:none so the icon never absorbs the width
       ratchet revamp.js writes onto the chip. */
    body.v2 .asset-selection-btn img.asset-icon {
        display: block;
        flex: none;
        width: 14px;
        height: 14px;
        margin: 0;
        border-radius: 50%;
        object-fit: contain;
    }

    /* Positions strip tabs are sentence case on the board. */
    body.v2 .trade-strip-tab {
        text-transform: none;
        letter-spacing: 0.01em;
    }
}

/* The board's stepper value: "2,500 +1.0% away" with a 6px breath. */
@media (min-width: 992px) {
    body.v2 .v2-step-value {
        gap: 6px;
        align-items: baseline;
    }
}

/* ==========================================================================
   §12 · FULL-SCREEN ROUND — found on the user's 2560×1440 window.
   ========================================================================== */
@media (min-width: 992px) {

    /* B · The board's columns run the full height of the frame. 114px =
       topbar 54 + banner 32 + the fixed status bar 30, all v2 constants
       (the grid's measured top is exactly 86). min-height, not height, so
       short windows keep sizing from content. */
    body.v2 .trade-unified-layout {
        /* !important for the same reason as the §4 neutralization this
           overrides: syncTicketHeight() writes an inline min-height, and
           only an important author declaration beats it. Later in the file,
           so it also wins the tie against §4's `min-height: 0 !important`. */
        min-height: calc(100vh - 116px - var(--v2-notice-h, 0px)) !important;
    }

    /* Route the extra height to the chart: every wrapper between the column
       and the view region learns to stretch, and the region's old fixed
       height becomes its floor. The chart follows through its own
       ResizeObserver; the wells re-sync through theirs. */
    body.v2 #v2-col1 > .trade-panel-main {
        flex: 1 1 auto;
        min-height: 0;
    }

    body.v2 .trade-panel-main-inner {
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    body.v2 .trade-panel-main-inner > .trade-content {
        min-height: 0;
    }

    body.v2 #basic-view-container {
        flex: 1 1 auto;
        min-height: 0;
    }

    body.v2 #v2-view-region {
        height: auto;
        flex: 1 1 auto;
        /* NO FLOOR — flex already sizes this correctly. All four view children
           are position:absolute inset:0, so the region's flex-basis is 0 and
           the column hands it exactly `frame − strip − chrome`.

           The clamp that used to live here (min 400, "capped at 540") did two
           wrong things. It re-derived what flex computes, using a stale 117
           (93px head + a 24px gap under the region that has not existed since
           the strip became a flush grid row); and because clamp() sat on
           min-height, the 540 capped the FLOOR, never the height — on a tall
           screen the region is ~983px, so that cap never once applied. What
           remained in practice was a bare 400px floor.

           Under this frame a floor is incoherent: .trade-unified-layout and
           #v2-col1..3 are hard-capped at calc(100vh - 116px - var(--v2-notice-h, 0px)) (§13), so a floor
           bigger than the column's remainder cannot scroll — it can only
           overflow the column and paint over the positions/history strip.
           Measured at 1470x705: region 400px in a 327px slot, 73px of overlap.
           Anything under ~777px of viewport height overlapped. */
        min-height: 0;
    }

    /* C · One inset. The card carries the board's 14px and every nested
       wrapper stops adding its own — measured before this fix the column
       held three different left edges (+18 / +30 / +44). */
    body.v2 .trade-preview-card {
        padding: 14px 14px 12px;
    }

    body.v2 .trade-preview-card .ticket-decision {
        padding: 0;
    }

    body.v2 .v2-decide {
        padding: 0;
    }

    body.v2 .v2-ticket-tabs,
    body.v2 .v2-question,
    body.v2 .v2-adv-ident,
    body.v2 .v2-adv-greeks {
        padding-left: 0;
        padding-right: 0;
    }

    body.v2 .v2-ticket-tabs {
        padding-top: 0;
    }

    body.v2 #pane-payoff {
        padding: 10px 0 0;
    }

    body.v2 .v2-payoff-head {
        padding: 10px 0 0;
    }

    body.v2 .v2-payoff-readout {
        margin: 0 0 5px;
    }

    body.v2 #v2-scenarios {
        padding: 10px 0 0;
    }
}

/* The column grew but the card inside it didn't: the ticket card now fills
   its grid track the way col3's rail does, so the panel reads as one
   full-height column instead of a floating rectangle. */
@media (min-width: 992px) {
    body.v2 #v2-col2 .trade-panel-preview {
        height: 100%;
        margin: 0;
    }

    body.v2 #v2-col2 .trade-preview-sidebar {
        height: 100%;
        display: flex;
        flex-direction: column;
    }

    body.v2 #v2-col2 .trade-preview-section.option-preview {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
        min-height: 0;
        margin: 0;
    }

    body.v2 #v2-col2 .trade-preview-card {
        flex: 1 1 auto;
        margin: 0;
    }
}

/* app.css gives .main-layout a fixed viewport-derived height that lands 8px
   past the window here, leaving a phantom scrollbar. The v2 grid sizes
   itself (min-height above), so the wrapper can defer to content. */
@media (min-width: 992px) {
    body.v2 .main-layout,
    body.v2 .app-container > main {
        height: auto !important;
    }
}

/* Two leftovers that kept the column from sitting flush: app.css's 36px
   foot spacer (the v2 grid already ends at the status bar's top edge) and
   the ticket section's translateY(10px) entrance offset, which shoved the
   card 10px below its column and past the grid's bottom. */
@media (min-width: 992px) {
    body.v2 #trade-section.content-section {
        margin-bottom: 0;
    }

    body.v2 #v2-col2 .trade-preview-section.option-preview {
        transform: none !important;
    }
}

/* ==========================================================================
   §13 · THE BANNER, V2-OWNED — restyling the app's strip in place lost the
   cascade war twice; #v2-comp-line is v2 markup styled only here, fed by
   revamp.js mirroring the (hidden) app strip's pool/rank values.
   ========================================================================== */
@media (min-width: 992px) {

    /* The whole app strip shell is a data source now — trade-motivation and
       top-strip keep writing into it, revamp.js mirrors the values out. Any
       visible residue of it would stack under the v2 line and re-open the
       page scrollbar. */
    body.v2 #v2-banner #top-strip {
        display: none !important;
    }

    body.v2 .v2-comp-line {
        display: flex;
        align-items: center;
        gap: 14px;
        height: 32px;
        padding: 0 16px;
        background: var(--v2-paper);
        color: var(--v2-ink);
    }

    body.v2 .v2-comp-title {
        font-family: var(--v2-display);
        font-weight: 600;
        letter-spacing: -0.02em;
        font-size: 0.78125rem;   /* 12.5px, the board's Geist line */
        line-height: 1;
        white-space: nowrap;
    }

    body.v2 .v2-comp-tag {
        font-family: var(--sans);
        font-size: 0.6875rem;
        color: var(--v2-ink2, rgba(11, 15, 25, .62));
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        min-width: 0;
    }

    body.v2 .v2-comp-item {
        font-size: 0.6875rem;
        color: var(--v2-ink2, rgba(11, 15, 25, .62));
        white-space: nowrap;
    }

    body.v2 .v2-comp-first {
        margin-left: auto;
    }

    body.v2 .v2-comp-item b {
        font-weight: 600;
        color: var(--v2-ink);
    }

    body.v2 .v2-comp-item .v2-comp-pool {
        font-family: var(--v2-display);
        font-size: 0.75rem;
        font-weight: 600;
    }

    body.v2 .v2-comp-cta {
        border: 0;
        background: var(--v2-ink);
        color: var(--v2-primary-bg);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        line-height: 1;
        padding: 5px 11px;
        border-radius: 6px;
        cursor: pointer;
        white-space: nowrap;
    }
}

/* --- §13 · one header family when disconnected ---------------------------
   Measured before: CONNECT WALLET 24px/r10/solid sky, Continue with Base the
   same, Use Quick Wallet 32px/r10 — three families beside the 30px/r8 chips,
   which is also the "blue box" that lands over the asset strip when the
   header wraps. One family: 30px, r8, white-solid primary, chip secondaries,
   and the row never wraps. */
@media (min-width: 992px) {

    body.v2 #connect-web3modal-btn,
    body.v2 [id^="connect-base-account-btn"],
    body.v2 #use-in-browser-wallet-btn {
        box-sizing: border-box !important;
        height: var(--v2-ctl-h, 30px) !important;
        display: inline-flex;
        align-items: center;
        padding: 0 14px !important;
        border: 0;
        border-radius: var(--v2-r-ctl, 8px);
        font-family: var(--sans);
        font-size: 0.6875rem !important;
        font-weight: 600;
        letter-spacing: 0.05em;
        line-height: 1;
        text-transform: uppercase;
        white-space: nowrap;
        /* .wp-connect-btn ships a persistent scale(.96) and a min-width;
           both defeat the shared 30px line. */
        transform: none !important;
        min-width: 0 !important;
        width: auto !important;
    }

    body.v2 #connect-web3modal-btn {
        background: var(--v2-primary-bg) !important;
        color: var(--v2-ink, #0B0F19) !important;
    }

    body.v2 #connect-web3modal-btn:hover {
        filter: brightness(0.95);
    }

    body.v2 [id^="connect-base-account-btn"],
    body.v2 #use-in-browser-wallet-btn {
        background: var(--v2-chip) !important;
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary) !important;
    }

    body.v2 [id^="connect-base-account-btn"]:hover,
    body.v2 #use-in-browser-wallet-btn:hover {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }

    body.v2 .hdr-tools,
    body.v2 .hdr-tools .wallet-section {
        flex-wrap: nowrap;
        white-space: nowrap;
    }

    /* ...but the popovers are not part of that row. Every .hdr-pop dialog is a
       DESCENDANT of .hdr-tools, so it inherited the nowrap meant to keep the
       control line on one line — and these dialogs hold prose. Measured: the
       bell's empty state overflowed its own box by 143px, and an activity
       title grew past its flex track and printed underneath the timestamp
       (.v2-bell-msg already had min-width: 0; nowrap defeated it). The control
       line keeps nowrap, the dialogs it contains do not. */
    body.v2 .hdr-tools .hdr-pop {
        white-space: normal;
    }

    /* Nav links share the control line — only the active chip paints it. */
    body.v2 header .nav-link,
    body.v2 [id^="nav-"][id$="-btn"]:not(#nav-alert-btn) {
        box-sizing: border-box;
        height: var(--v2-ctl-h, 30px);
        display: inline-flex;
        align-items: center;
        border-radius: var(--v2-r-ctl, 8px) !important;
    }
}

/* ==========================================================================
   §14 · THE QUOTE LADDER — the settled canvas design (build round 2).
   Later-in-file rules deliberately override §6's first-generation wells.
   ========================================================================== */
@media (min-width: 992px) {

    /* Wells sit on the chart's own ground: open rails, no box. */
    body.v2 .v2-well,
    body.v2 .v2-well.is-primary {
        background: transparent;
        border: 0;
        border-left: 1px solid var(--v2-hair);
        border-right: 1px solid var(--v2-hair);
        border-radius: 0;
    }

    /* Two-line spoken header: day over words; sky underline on the live day;
       amber words inside the final hour. */
    body.v2 .v2-well-head {
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        height: 34px;
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .v2-well.is-primary .v2-well-head {
        border-bottom-color: rgba(125, 211, 252, .45);
    }

    body.v2 .v2-well-clock {
        font-size: 0.65625rem;
        font-weight: 600;
        color: var(--text-secondary);
        opacity: 1;
    }

    body.v2 .v2-well.is-primary .v2-well-clock {
        color: var(--text-primary);
    }

    body.v2 .v2-well-clock.is-urgent {
        color: var(--v2-amber) !important;
    }

    /* Quote-ladder cells: flush, squared, bounded in their side colour,
       strike left and premium right. */
    body.v2 .v2-tile {
        left: 0;
        right: 0;
        width: auto;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0 6px;
        box-sizing: border-box;
        border: 0;
        border-radius: 0;
        line-height: 1;
    }

    body.v2 .v2-tile.is-call {
        background: rgba(94, 221, 156, .13);
        border-top: 1px solid rgba(94, 221, 156, .35);
        border-bottom: 1px solid rgba(94, 221, 156, .35);
        color: var(--positive);
    }

    body.v2 .v2-tile.is-put {
        background: rgba(232, 106, 98, .13);
        border-top: 1px solid rgba(232, 106, 98, .35);
        border-bottom: 1px solid rgba(232, 106, 98, .35);
        color: #F4CBC8;
    }

    body.v2 .v2-tile .v2-prem {
        font-size: 0.625rem;
        font-weight: 500;
        opacity: .85; /* the price paid — reads ≥4.5:1 on the tile tint (.55 read 3.7) */
    }

    body.v2 .v2-tile.is-call:hover {
        background: rgba(94, 221, 156, .22);
        box-shadow: inset 0 0 0 1px rgba(94, 221, 156, .4);
    }

    body.v2 .v2-tile.is-put:hover {
        background: rgba(232, 106, 98, .22);
        box-shadow: inset 0 0 0 1px rgba(232, 106, 98, .4);
    }

    body.v2 .v2-tile.is-selected,
    body.v2 .v2-tile.is-call.is-selected {
        background: var(--positive) !important;
        border-color: var(--positive) !important;
        color: var(--v2-on-green) !important;
        box-shadow: 0 0 0 2px rgba(94, 221, 156, .35);
        z-index: 1;
    }

    body.v2 .v2-tile.is-put.is-selected {
        background: var(--negative) !important;
        border-color: var(--negative) !important;
        color: var(--v2-on-negative) !important;
        box-shadow: 0 0 0 2px rgba(232, 106, 98, .35);
    }

    body.v2 .v2-tile.is-selected .v2-prem {
        opacity: 1;
    }

    /* Empty grid levels: the grid stays complete; unbounded = no market. */
    body.v2 .v2-cell-empty {
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        box-sizing: border-box;
        border-top: 1px solid rgba(255, 255, 255, .08);
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        color: rgba(126, 138, 156, .68); /* un-quoted rungs recede to ~3:1, never below the UI floor */
        pointer-events: none;
    }

    body.v2 .v2-cell-empty.is-last {
        border-bottom: 1px solid rgba(255, 255, 255, .08);
    }

    /* Zones: bounded in sky, spanning strike line to strike line. */
    body.v2 .v2-range {
        box-sizing: border-box;
        border: 0;
        border-top: 1px solid rgba(125, 211, 252, .4);
        border-bottom: 1px solid rgba(125, 211, 252, .4);
        border-radius: 0;
    }

    /* The chart dissolves into the ladder — no hard pane edge. */
    body.v2 #v2-chart-row {
        position: relative;
    }

    body.v2 #v2-chart-row::after {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        /* Fallback 0px, NOT --v2-wells-w: that token resolves to 440px on
           #v2-chart-row (body.v2 scope) while the real ladder is 640px
           (the override at "one book width for every asset" is scoped to
           #v2-wells), so the old fallback failed OPEN — 200px inside the
           plot — on every load before alignToPlot() stamps the real value.
           0px fails CLOSED: the scrim tucks under the ladder, invisible.
           Same reasoning V2Wells.leaderW already applies to this token. */
        right: var(--v2-wells-total, 0px);
        /* Sized to the PLOT, not fixed. 90px was ~22% of the dissolve's
           width when the ladder was 440 and the plot ~410. The ladder grew
           to 640 and the plot shrank to ~265 at 1470px without this being
           re-tuned, so a fixed 90px washed out 34% of the chart — measured
           — and it is the RIGHT third, exactly where the newest candles and
           the spot sit. That is why it reads as "zoom broke the chart". */
        width: min(90px, calc((100% - var(--v2-wells-total, 0px)) * 0.18));
        background: linear-gradient(90deg, rgba(11, 15, 25, 0), var(--background) 88%);
        pointer-events: none;
        z-index: 2;
    }

    /* Leader lines: solid to the selected toggle, dashed on hover. */
    body.v2 .v2-leader {
        position: absolute;
        left: 0;
        height: 0;
        border-top: 1.5px solid var(--positive);
        pointer-events: none;
        z-index: 3;
    }

    /* The leader STOPS at the ladder's left edge — see V2Wells.leaderW in
       revamp.js, which is the single place that width is computed. Deliberately
       not a max-width here: a CSS clip would have to name the ladder's width as
       a custom property, and --v2-wells-total is unset until alignToPlot runs
       while its fallback is 200px short of the real ladder, so the clip would
       fail open exactly when the token is missing. One mechanism, measured. */

    body.v2 .v2-leader.is-hover {
        border-top-width: 1px;
        border-top-style: dashed;
    }

    /* the dashed preview does not name itself: the dash is the word (user, 2026-09-07) */
    body.v2 .v2-leader.is-hover::after { content: none; display: none; }

    body.v2 .v2-leader[hidden] {
        display: none;
    }
}

/* The premium is the first thing to go when a tile runs out of room, and the
   ruling is MEASURED, not breakpoint-guessed: V2Wells.alignToPlot stamps
   .is-tight on #v2-wells whenever the strike column drops under 66px (the
   floor at which strike + premium stop fitting). A two-line tile was
   considered and rejected — tile height is pinned to the chart's price-row
   pitch (~20px), which has no room for a second line. */
body.v2 #v2-wells.is-tight .v2-tile .v2-prem {
    display: none;
}

body.v2 #v2-wells.is-tight .v2-tile {
    justify-content: center;
}

/* --- §14 · lean ticket ---------------------------------------------------- */
@media (min-width: 992px) {

    /* A real seam before PAYOFF — and flex, not block: whitespace between
       the (mostly hidden) children was rendering as anonymous line boxes and
       opening a ~34px dead zone under the header. */
    body.v2 .ticket-analysis {
        display: flex;
        flex-direction: column;
        margin-top: 14px;
        border-top: 1px solid var(--v2-hair-strong);
        padding-top: 12px;
    }

    /* The payoff diagram's axis labels are drawn inside its own svg
       (ticket-payoff.js stays untouched) — the margin keeps the axis row
       clear of the scenarios block beneath. */
    body.v2 #payout-calculator svg {
        display: block;
        margin-bottom: 12px;
    }

    /* Scenarios read as four rows: loss, breakeven, two profit points. */
    body.v2 #v2-scenario-profit3,
    body.v2 #v2-scenario-profit4,
    body.v2 #v2-scenario-profit5 {
        display: none !important;
    }
}

/* --- §14 · chain view in the ladder language ------------------------------ */
@media (min-width: 992px) {

    /* Quotes are flat flush cells — the row hairlines are the bounds, the
       graded tint (inline, distance-scaled) is the gradient. */
    body.v2 .v2-chain-row {
        padding-top: 0;
        padding-bottom: 0;
        align-items: stretch;
    }

    body.v2 .v2-chain-row > span {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Greeks hug the quotes — aligned inward, toward the strike spine. */
    body.v2 .v2-chain-row > .v2-chain-greeks {
        justify-content: flex-end;
    }

    body.v2 .v2-chain-row > .v2-chain-greeks.is-right {
        justify-content: flex-start;
    }

    /* Quotes cap at 170px and sit flush inward: calls right, puts left. */
    body.v2 .v2-chain-row > .v2-chain-call { justify-content: flex-end; }
    body.v2 .v2-chain-row > .v2-chain-put { justify-content: flex-start; }
    body.v2 .v2-chain-quote { max-width: 170px; }

    /* Chain head at 10px (the shared .v2-tbl-head stays 9px). */
    body.v2 .v2-chain-head { font-size: 0.625rem; }

    body.v2 .v2-chain-quote {
        border: 0;
        border-radius: 0;
        padding: 8px 0;
        align-self: stretch;
        height: 100%;
    }

    body.v2 .v2-chain-quote.is-call { border-color: transparent; color: var(--positive); }
    body.v2 .v2-chain-quote.is-put { border-color: transparent; color: #F4CBC8; }

    body.v2 .v2-chain-quote.is-call:hover { box-shadow: inset 0 0 0 1px rgba(94, 221, 156, .4); }
    body.v2 .v2-chain-quote.is-put:hover { box-shadow: inset 0 0 0 1px rgba(232, 106, 98, .4); }

    body.v2 .v2-chain-quote.is-selected.is-call {
        background: var(--positive) !important;
        color: var(--v2-on-green) !important;
    }

    body.v2 .v2-chain-quote.is-selected.is-put {
        background: var(--negative) !important;
        color: var(--v2-on-negative) !important;
    }

    /* Worded day tabs — free chips in the SECTION HEAD, shown only while
       the chain view is open (board: solid-sky active). */
    body.v2 #v2-day-chips {
        display: none;
        gap: 6px;
        align-items: center;
        margin-right: 10px;
    }

    body.v2 #basic-view-container:has(#v2-view-region[data-v2-view="advanced"]) #v2-day-chips,
    body.v2 #basic-view-container:has(#v2-view-region[data-v2-view="basic"]) #v2-day-chips {
        display: inline-flex;
    }

    body.v2 .v2-chain-tab {
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        line-height: 1;
        height: 26px;
        padding: 0 11px;
        border-radius: var(--v2-r-ctl);
        cursor: pointer;
    }

    body.v2 .v2-chain-tab.is-active {
        background: var(--v2-sky);
        box-shadow: none;
        color: var(--v2-on-sky);
    }

    /* The strip's corner label — advanced view only. */
    body.v2 #v2-strip-corner { display: none; }

    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chart-row #v2-strip-corner {
        display: block;
        position: absolute;
        left: 10px;
        top: 8px;
        z-index: 3;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        color: var(--text-muted);
        pointer-events: none;
    }

    /* The board's Advanced layout: a 120px chart strip above the chain —
       same chart instance, resized by its own observer. Wells, leaders and
       the scrim sit this view out. */
    body.v2 #v2-view-region[data-v2-view="advanced"] {
        --v2-strip-h: 240px;   /* round 11: twice the board's strip — the line has to read */
    }

    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chart-row {
        visibility: visible;
        pointer-events: auto;
        inset: 0 0 auto 0;
        height: var(--v2-strip-h);
        z-index: 1;
    }

    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chart-row #target-chart {
        display: block !important;
    }

    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chart-row #v2-wells,
    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chart-row .v2-leader {
        display: none !important;
    }

    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chart-row::after {
        display: none;
    }

    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chain {
        inset: var(--v2-strip-h) 0 0 0;
    }
}

/* --- §14 · toasts (the States board's four-intent system) ----------------- */
@media (min-width: 992px) {

    body.v2 #notification-container {
        position: fixed !important;
        bottom: 40px !important;
        left: 16px !important;
        top: auto !important;
        right: auto !important;
        z-index: 9999 !important;
        display: flex;
        flex-direction: column;
        gap: 8px;
        max-width: 340px !important;
    }

    body.v2 .v2-toast {
        position: relative;
        display: flex;
        align-items: flex-start;
        gap: 10px;
        width: 340px;
        padding: 10px 12px 12px;
        background: var(--card-bg);
        border: 1px solid var(--v2-hair-strong);
        border-radius: var(--v2-r-ctl);
        overflow: hidden;
        animation: v2-toast-in 180ms ease-out;
    }

    @keyframes v2-toast-in {
        from { opacity: 0; transform: translateY(8px); }
        to { opacity: 1; transform: none; }
    }

    body.v2 .v2-toast.is-leaving {
        opacity: 0;
        transform: translateY(6px);
        transition: opacity 240ms ease, transform 240ms ease;
    }

    body.v2 .v2-toast-icon {
        flex: none;
        width: 26px;
        height: 26px;
        border-radius: 6px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    body.v2 .v2-toast.is-success .v2-toast-icon { background: rgba(94, 221, 156, .14); }
    body.v2 .v2-toast.is-error .v2-toast-icon { background: rgba(232, 106, 98, .14); }
    body.v2 .v2-toast.is-info .v2-toast-icon { background: rgba(125, 211, 252, .14); }
    body.v2 .v2-toast.is-warning .v2-toast-icon { background: rgba(217, 168, 60, .14); }

    body.v2 .v2-toast-msg {
        flex: 1 1 auto;
        min-width: 0;
        font-family: var(--sans);
        font-size: 12px;
        line-height: 1.4;
        color: var(--text-secondary);
        padding-top: 4px;
        overflow-wrap: break-word;
    }

    body.v2 .v2-toast-msg a {
        color: var(--v2-sky);
    }

    body.v2 .v2-toast-tx {
        white-space: nowrap;
        font-size: 0.65625rem;
    }

    body.v2 .v2-toast-share {
        display: inline-block;
        margin-top: 6px;
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-primary);
        font-size: 0.625rem;
        font-weight: 700;
        letter-spacing: 0.07em;
        padding: 3px 9px;
        border-radius: 999px;
        cursor: pointer;
        width: max-content;
    }

    body.v2 .v2-toast-close {
        flex: none;
        border: 0;
        background: transparent;
        color: var(--text-muted);
        font-size: 0.75rem;
        line-height: 1;
        padding: 4px 2px;
        cursor: pointer;
    }

    body.v2 .v2-toast-progress {
        position: absolute;
        left: 0;
        bottom: 0;
        height: 2px;
        background: rgba(125, 211, 252, .5);
        animation: v2-toast-drain 5s linear forwards;
    }

    body.v2 .v2-toast.is-success .v2-toast-progress { background: rgba(94, 221, 156, .5); }
    body.v2 .v2-toast.is-warning .v2-toast-progress { background: rgba(217, 168, 60, .5); }

    @keyframes v2-toast-drain {
        from { width: 100%; }
        to { width: 0%; }
    }

    body.v2 .v2-toast-spin {
        width: 12px;
        height: 12px;
        border: 2px solid rgba(125, 211, 252, .25);
        border-top-color: var(--v2-sky);
        border-radius: 50%;
        animation: v2-spin .8s linear infinite;
    }

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

    /* The legacy Bootstrap alert never renders under v2 (the producer is
       wrapped), but belt over braces if one slips through a direct call. */
    body.v2 #notification-container > .alert {
        display: none !important;
    }
}

/* --- §14 · state faces ---------------------------------------------------- */
@media (min-width: 992px) {

    /* Ladder skeleton while the first book loads. */
    body.v2 .v2-skel-cell {
        position: absolute;
        left: 4px;
        right: 4px;
        height: 22px;
        background: linear-gradient(90deg, var(--v2-chip) 25%, var(--v2-chip-hover) 50%, var(--v2-chip) 75%);
        background-size: 200% 100%;
        animation: v2-shimmer 1.4s infinite;
    }

    @keyframes v2-shimmer {
        0% { background-position: 200% 0; }
        100% { background-position: -200% 0; }
    }

    /* Designed empty-book state. */
    body.v2 .v2-well-empty.is-designed {
        flex-direction: column;
        gap: 7px;
        opacity: 1;
        pointer-events: auto;
        padding: 0 8px;
        text-align: center;
        font-size: 0.65625rem;
        color: var(--text-muted);
    }

    body.v2 .v2-well-empty.is-designed .num {
        font-size: 0.625rem;
        color: var(--text-secondary);
    }

    body.v2 .v2-well-goto {
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        padding: 5px 10px;
        border-radius: 7px;
        cursor: pointer;
    }

    body.v2 .v2-well-goto:hover {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }

    /* Trading gates: keep the ticket on screen (the app hides the whole card)
       and give TRADING PAUSED its amber face. */
    body.v2 .trading-disabled .trade-preview-section .trade-preview-card {
        display: block !important;
    }

    body.v2 .trade-unified-layout.trading-disabled #trade-now-btn {
        background: rgba(217, 168, 60, .14) !important;
        border: 0 !important;
        color: var(--v2-amber) !important;
    }

    /* Zero balance, strike picked: the button IS the message (round 10). */
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face,
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face:disabled {
        background: var(--v2-primary-bg) !important;
        color: var(--v2-ink) !important;
        cursor: pointer !important;
        pointer-events: auto !important;
    }

    body.v2 .v2-step-value.is-resting { color: var(--text-muted); }

    body.v2 .v2-balance-line {
        text-align: right;
        font-size: 0.625rem;
        color: var(--text-muted);
        margin: -8px 2px 8px 0;
        min-height: 11px;
    }

    body.v2 .v2-balance-line b { font-weight: 500; color: var(--text-secondary); }

    body.v2.v2-no-wallet .v2-balance-line { visibility: hidden !important; }

    /* the settles row's amber time bar — remaining share of the day */
    body.v2 .v2-param-v { position: relative; }

    body.v2 .v2-param-v.has-bar::after {
        content: '';
        position: absolute;
        right: 0;
        bottom: -3px;
        height: 2px;
        width: calc(var(--v2-timebar, 0) * 100%);
        background: var(--v2-sky);
        border-radius: 1px;
    }

    body.v2 .v2-param-v.is-urgent::after { background: var(--v2-amber); }

    body.v2 #v2-footer-gate {
        margin-left: 6px;
        color: var(--v2-amber);
        font-size: 0.625rem;
    }

    body.v2 #status-bar-liquidity.v2-liq-locked {
        color: var(--v2-amber) !important;
    }

    body.v2 #trade-maintenance-preview {
        background: transparent;
        border: 0;
        color: var(--text-muted);
        font-size: 12px;
    }

    /* Wrong network: the app's alert becomes the amber notice, BUY yields to
       a white SWITCH TO BASE. */
    body.v2 #connection-alert {
        background: rgba(217, 168, 60, .08) !important;
        border: 1px solid rgba(217, 168, 60, .3) !important;
        border-radius: var(--v2-r-ctl) !important;
        color: var(--text-secondary) !important;
    }

    body.v2 .v2-switch-base {
        display: none;
        width: 100%;
        border: 0;
        padding: 12px 0;
        border-radius: var(--v2-r-ctl);
        background: var(--v2-primary-bg);
        color: var(--v2-ink, #0B0F19);
        font-size: 0.75rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        cursor: pointer;
    }

    body.v2.v2-wrong-net .v2-switch-base { display: block; }
    body.v2.v2-wrong-net #trade-now-btn { display: none; }

    /* Confirm-stage faces: the app's own Checking/Processing strings get the
       spinner treatment. */
    body.v2 [data-v2-stage]::before {
        content: '';
        display: inline-block;
        width: 11px;
        height: 11px;
        margin-right: 8px;
        vertical-align: -2px;
        border: 2px solid rgba(255, 255, 255, .2);
        border-top-color: currentColor;
        border-radius: 50% !important;
        animation: v2-spin .8s linear infinite;
    }

    /* FILLED flash + the new position row's one-time glow. */
    body.v2 #trade-now-btn.v2-filled {
        background: var(--positive) !important;
        color: var(--v2-on-green) !important;
    }

    body.v2 #trade-positions-block tr.v2-row-glow {
        animation: v2-row-glow 1.6s ease-out;
    }

    @keyframes v2-row-glow {
        0% { background: rgba(94, 221, 156, .18); }
        100% { background: transparent; }
    }

    /* Quotes refreshing: the ladder dims for the repricing beat, and a
       spinner pill names the beat (States board). */
    body.v2 #v2-wells.v2-refreshing::after {
        content: 'refreshing\2026';
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        z-index: 4;
        font-family: var(--sans);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        color: var(--text-secondary);
        background: var(--v2-chip);
        border: 0;
        box-shadow: var(--v2-chip-lift);
        border-radius: 999px;
        padding: 5px 12px;
    }

    body.v2 #v2-wells.v2-refreshing {
        opacity: .45;
        transition: opacity 200ms ease;
    }

    /* Book renewal notice. */
    body.v2 #v2-renewal-chip {
        position: absolute;
        left: 14px;
        top: 40px;
        z-index: 4;
        background: var(--v2-chip);
        border: 0;
        box-shadow: var(--v2-chip-lift);
        border-radius: var(--v2-r-ctl);
        color: var(--v2-sky);
        font-size: 0.65625rem;
        font-weight: 600;
        padding: 5px 10px;
        pointer-events: none;
    }

    /* Any app countdown goes amber inside the final 15 minutes. */
    body.v2 .v2-urgent {
        color: var(--v2-amber) !important;
    }
}

/* --- §14 · no-wallet gating ----------------------------------------------- */
@media (min-width: 992px) {

    body.v2 .v2-connect-stack {
        display: none;
    }

    body.v2.v2-no-wallet .v2-connect-stack {
        display: block;
    }

    body.v2.v2-no-wallet #trade-now-btn {
        display: none;
    }

    /* Direction and sizing sleep — visible, honest, inert. */
    body.v2.v2-no-wallet .v2-decide,
    body.v2.v2-no-wallet #ticket-amount-field,
    body.v2.v2-no-wallet #v2-presets {
        opacity: .45;
        pointer-events: none;
    }

    body.v2 .v2-connect-main {
        width: 100%;
        border: 0;
        padding: 12px 0;
        border-radius: var(--v2-r-ctl);
        background: var(--v2-primary-bg);
        color: var(--v2-ink, #0B0F19);
        font-size: 0.75rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        cursor: pointer;
    }

    body.v2 .v2-connect-main:hover {
        filter: brightness(0.95);
    }

    body.v2 .v2-connect-alts {
        display: flex;
        gap: 6px;
        margin-top: 8px;
    }

    body.v2 .v2-connect-alt {
        flex: 1 1 0;
        border: 0;
        padding: 8px 0;
        border-radius: 7px;
        background: var(--v2-chip);
        color: var(--text-secondary);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.04em;
        cursor: pointer;
    }

    body.v2 .v2-connect-alt:hover {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }
}

/* --- §14 · narrow band (992-1439) ----------------------------------------- */
@media (min-width: 992px) and (max-width: 1439.98px) {
    /* Strike-only cells (premiums hide above); the spoken countdown shrinks
       a step but stays words. */
    body.v2 .v2-well-clock {
        font-size: 0.625rem;
    }

    body.v2 .v2-tile {
        font-size: 0.625rem;
        padding: 0 3px;
    }

    body.v2 .v2-cell-empty {
        font-size: 0.625rem;
    }
}

/* --- §14 · range hover band ------------------------------------------------ */
@media (min-width: 992px) {
    /* Hovering a zone previews its area on the chart: dashed boundary lines
       and a translucent band running to the cell's edge. */
    body.v2 .v2-zone-band {
        position: absolute;
        left: 0;
        box-sizing: border-box;
        border-top: 1px dashed rgba(125, 211, 252, .5);
        border-bottom: 1px dashed rgba(125, 211, 252, .5);
        background: rgba(125, 211, 252, .06);
        pointer-events: none;
        z-index: 3;
    }

    body.v2 .v2-zone-band[hidden] {
        display: none;
    }
}

/* --- §14 · crosshair price chip ------------------------------------------- */
@media (min-width: 992px) {
    body.v2 .v2-cross-price {
        position: absolute;
        left: 6px;
        z-index: 5;
        background: #F5F7FA;
        color: #0B0F19;
        font-size: 0.625rem;
        font-weight: 600;
        line-height: 1;
        padding: 3px 6px;
        border-radius: 3px;
        pointer-events: none;
    }

    body.v2 .v2-cross-price[hidden] {
        display: none;
    }
}

/* --- §14 · slider geometry restored ---------------------------------------
   app.css gives .slider-inner-container flex:1 and anchors .slider-ticks at
   top:50% — sane in app.html's content-sized track, but v2's track is a
   full-height view layer, so the container inflated (~295px) and the ticks,
   labels and spot marker detached ~135px below the rail. Pin the container
   to the rail's own scale and everything re-attaches. */
@media (min-width: 992px) {
    body.v2 #v2-view-region .slider-inner-container {
        flex: 0 0 auto;
        height: 64px;
        display: flex;
        align-items: center;
    }

    /* round 11 (issue 5): the range input — whose background IS the red/green
       fill — sat in normal flow at the top of the 64px box while the ticks,
       the disabled track and the spot marker hang at top:50%. Centre it on
       the same line. */
    body.v2 #v2-view-region #strike-slider {
        position: absolute;
        top: 50%;
        left: 0;
        right: 0;
        width: 100%;
        margin: 0;
        transform: translateY(-50%);
    }
}


/* --- §14 · ticket B — stat tiles ------------------------------------------
   The decide zone re-cut to the chosen board: the strike is a 34px hero
   numeral between 40px steppers with its context on a subline; direction is
   a segmented yes/no; the parameter list becomes a 2×2 tile grid with a
   fourth SETTLES tile. Overrides §8/§11's first-generation rules by cascade
   position, per the file's convention. */
@media (min-width: 992px) {

    body.v2 .v2-decide {
        display: flex;
        flex-direction: column;
        gap: 0;
    }

    body.v2 .v2-stepper {
        display: flex;
        align-items: center;
        gap: 10px;
        background: transparent;
        border: 0;
        padding: 0;
    }

    body.v2 .v2-step {
        flex: none;
        width: 40px;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: var(--v2-chip);
        border: 0;
        border-radius: var(--v2-r-ctl);
        color: var(--text-secondary);
        font-size: 15px;
        line-height: 1;
        cursor: pointer;
    }

    body.v2 .v2-step:hover:not(:disabled) {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }

    body.v2 .v2-step:disabled {
        opacity: .35;
        cursor: default;
    }

    body.v2 .v2-step-value {
        flex: 1;
        text-align: center;
        font-family: var(--v2-display);
        font-variant-numeric: tabular-nums;
        font-size: 2.125rem;
        font-weight: 600;
        letter-spacing: -0.02em;
        line-height: 1;
        color: var(--text-primary);
        background: transparent;
        border: 0;
        padding: 0;
    }

    body.v2 .v2-step-sub {
        text-align: center;
        font-variant-numeric: tabular-nums;
        font-size: 0.6875rem;
        line-height: 1;
        color: var(--text-muted);
        margin: 7px 0 12px;
        min-height: 11px;
    }

    /* Segmented side control: one sunken track, the active half filled. */
    body.v2 .v2-side {
        display: flex;
        gap: 2px;
        padding: 2px;
        background: var(--panel-sunken);
        border-radius: 9px;
    }

    body.v2 .v2-side-btn,
    body.v2 .v2-side-btn.is-call,
    body.v2 .v2-side-btn.is-put {
        flex: 1;
        background: transparent;
        border: 0;
        border-radius: 7px;
        padding: 9px 0;
        font-size: 0.75rem;
        font-weight: 600;
        letter-spacing: 0.02em;
        color: var(--text-muted);
        cursor: pointer;
    }

    body.v2 .v2-side-btn.is-call.is-active {
        background: var(--positive);
        color: var(--v2-on-green);
        font-weight: 700;
    }

    body.v2 .v2-side-btn.is-put.is-active {
        background: var(--negative);
        color: var(--v2-on-negative);
        font-weight: 700;
    }

    body.v2 .v2-side-btn:disabled {
        opacity: .4;
        cursor: default;
    }

    /* The detail LIST (user's call — the 2×2 tiles are retired): four
       hairline rows, label left, value right. */
    body.v2 .v2-params {
        display: block;
        border: 0;
        padding: 0;
        border-top: 1px solid var(--v2-hair);
    }

    body.v2 .v2-param {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 10px;
        background: transparent;
        border: 0;
        border-bottom: 1px solid var(--v2-hair);
        border-radius: 0;
        padding: 7px 0;
        min-width: 0;
    }

    body.v2 .v2-param:last-child {
        border-bottom: 0;
    }

    body.v2 .v2-param-k {
        font-family: var(--sans);
        font-size: 12px;
        font-weight: 400;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text-muted);
        flex: none;
    }

    body.v2 .v2-param-v {
        font-size: 0.75rem;
        font-weight: 600;
        color: var(--text-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        text-align: right;
        min-width: 0;
    }

    body.v2 .v2-param-v.is-pos {
        color: var(--positive);
    }

}


/* --- §14 · E1 empty payoff ------------------------------------------------
   No strike picked: the diagram waits in outline. The pane keeps its height
   (the ghost overlays the calculator) so picking a strike never reflows. */
@media (min-width: 992px) {

    body.v2 #pane-payoff {
        position: relative;
    }

    body.v2 .v2-payoff-ghost {
        position: absolute;
        inset: 0;
        z-index: 2;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    body.v2 .v2-payoff-ghost[hidden] {
        display: none;
    }

    body.v2 .v2-payoff-ghost svg {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
    }

    body.v2 .v2-ghost-copy {
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 3px;
        text-align: center;
    }

    body.v2 .v2-ghost-copy b {
        font-size: 0.75rem;
        font-weight: 500;
        color: var(--text-secondary);
    }

    body.v2 .v2-ghost-copy span {
        font-size: 0.65625rem;
        color: var(--text-muted);
    }

    /* The calculator stands down behind the ghost but keeps its height. */
    body.v2 #pane-payoff.is-empty #payout-calculator {
        visibility: hidden;
    }

    body.v2 #v2-scenarios.is-empty {
        display: none;
    }
}


/* (round 11: the competition banner shows on every route — the scoreboard's
   stage is dark now, so nothing is said twice in the same material) */


/* --- §14 · trollbox restyle ------------------------------------------------
   Chat and fills as one stream. Fills are side-coloured cubes announced only
   when a NEW position appears between polls; mentions wash amber; MOD is a
   chip; the docked column collapses to a header rail with an unread badge. */
@media (min-width: 992px) {

    body.v2 .message .admin-badge {
        display: inline-block;
        background: var(--v2-chip);
        color: var(--v2-amber);
        font-size: 0.625rem;
        font-weight: 700;
        letter-spacing: 0.06em;
        padding: 1px 5px;
        border-radius: 4px;
        vertical-align: middle;
    }

    body.v2 .message.is-mention {
        background: rgba(217, 168, 60, 0.08);
        border-left: 2px solid rgba(217, 168, 60, 0.5);
        border-radius: 0 7px 7px 0;
        padding-left: 9px;
        margin-left: -11px;
    }

    body.v2 .message .message-time {
        margin-left: auto;
        font-size: 0.625rem;
        color: var(--text-muted);
        font-variant-numeric: tabular-nums;
    }

    body.v2 .v2-fill-msg {
        display: flex;
        align-items: baseline;
        gap: 5px;
        font-size: 11px;
        color: var(--text-muted);
        border-radius: 0 7px 7px 0;
        padding: 6px 9px;
        cursor: pointer;
    }

    body.v2 .v2-fill-msg b { font-weight: 600; }
    body.v2 .v2-fill-msg i {
        margin-left: auto;
        font-style: normal;
        font-size: 0.625rem;
        white-space: nowrap;
    }

    body.v2 .v2-fill-msg.is-call {
        background: rgba(94, 221, 156, 0.07);
        border-left: 2px solid rgba(94, 221, 156, 0.5);
    }
    body.v2 .v2-fill-msg.is-call b { color: var(--positive); }

    body.v2 .v2-fill-msg.is-put {
        background: rgba(232, 106, 98, 0.07);
        border-left: 2px solid rgba(232, 106, 98, 0.5);
    }
    body.v2 .v2-fill-msg.is-put b { color: var(--negative); }

    body.v2 .v2-fill-msg.is-range {
        background: rgba(125, 211, 252, 0.07);
        border-left: 2px solid rgba(125, 211, 252, 0.5);
    }
    body.v2 .v2-fill-msg.is-range b { color: var(--v2-sky); }

    body.v2 .v2-fill-msg:hover { color: var(--text-secondary); }

    /* ---- the collapsed rail ---- */
    body.v2 #v2-chat-rail {
        display: flex;
        align-items: center;
        gap: 8px;
        width: 100%;
        background: transparent;
        border: 1px solid var(--v2-hair-strong);
        border-radius: 16px;
        padding: 9px 14px;
        color: var(--text-primary);
        font-size: 11.5px;
        font-weight: 600;
        cursor: pointer;
        text-align: left;
    }

    body.v2 #v2-chat-rail[hidden] { display: none; }

    body.v2 #v2-chat-rail i {
        font-style: normal;
        font-weight: 400;
        color: var(--text-muted);
        font-size: 11px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        min-width: 0;
    }

    body.v2 #v2-chat-rail .v2-chat-n {
        background: var(--v2-sky);
        color: #0B0F19;
        font-size: 0.625rem;
        font-weight: 700;
        padding: 1px 6px;
        border-radius: 4px;
    }

    body.v2 #v2-chat-rail .v2-chat-n.is-mention { background: var(--v2-amber); }

    body.v2 #v2-chat-rail .v2-chat-caret {
        margin-left: auto;
        color: var(--text-muted);
    }

    body.v2 #v2-chat.v2-collapsed #trollbox-widget {
        display: none !important;
    }
}


/* --- §14 · wallet + funding faces ------------------------------------------
   The popover's export-key row nag, and the zero-balance nudge that sits
   above BUY while the account cannot trade. */
@media (min-width: 992px) {

    body.v2 .wp-badge-warn {
        background: rgba(217, 168, 60, 0.15);
        color: var(--v2-amber);
        border: 0;
    }

    /* (the fund nudge card retired in round 10 — see .v2-fund-face) */

}


/* --- §14 · the bell's Activity pane ---------------------------------------
   The toast stream made persistent: two tabs in the alert popover, items
   grouped by day, unread dotted sky. When Activity is up, the price-alert
   chrome stands down. */
@media (min-width: 992px) {

    body.v2 .v2-bell-tabs {
        display: flex;
        align-items: center;
        gap: 2px;
        padding: 8px 14px 0;
    }

    body.v2 .v2-bell-tabs[hidden] { display: none; }

    body.v2 .v2-bell-tab {
        background: transparent;
        border: 0;
        color: var(--text-muted);
        font-size: 12px;
        font-weight: 600;
        padding: 6px 10px;
        border-radius: 7px;
        cursor: pointer;
    }

    body.v2 .v2-bell-tab.is-active {
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-primary);
    }

    body.v2 .v2-bell-read {
        margin-left: auto;
        background: none;
        border: 0;
        color: var(--v2-sky);
        font-size: 0.65625rem;
        cursor: pointer;
        display: none;
    }

    body.v2 #alert-pop.show-activity .v2-bell-read { display: inline; }

    body.v2 .v2-bell-feed {
        max-height: 340px;
        overflow-y: auto;
        padding: 6px 8px 10px;
    }

    body.v2 .v2-bell-feed[hidden] { display: none; }

    /* Activity up: the alert form and list stand down. */
    body.v2 #alert-pop.show-activity > *:not(.alp-head):not(.v2-bell-tabs):not(.v2-bell-feed) {
        display: none;
    }

    body.v2 .v2-bell-day {
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        color: var(--text-muted);
        padding: 8px 6px 3px;
    }

    body.v2 .v2-bell-item {
        display: flex;
        align-items: baseline;
        gap: 8px;
        padding: 7px 6px;
        border-bottom: 1px solid var(--v2-hair);
        font-size: 12px;
        color: var(--text-secondary);
    }

    body.v2 .v2-bell-item:last-child { border-bottom: 0; }

    body.v2 .v2-bell-dot {
        flex: none;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: transparent;
        align-self: center;
    }

    body.v2 .v2-bell-item.is-new .v2-bell-dot { background: var(--v2-sky); }
    body.v2 .v2-bell-item.is-error .v2-bell-dot { background: var(--negative); }

    /* overflow-wrap: anywhere — a wallet/RPC error lands in the activity
       buffer verbatim, and a 66-char hex run has NO break opportunity, so
       `white-space: normal` (and even break-word) leave it whole: measured
       436px of content in a 233px box, which the popover clipped and the feed
       grew a horizontal scrollbar for. `anywhere` breaks only where nothing
       else can, so ordinary words are untouched; it inherits, so the <b> title
       is covered too.

       An earlier version of this comment claimed wrapping beat clamping
       because "the actionable part sits at the END". That was true of the
       hand-typed string it was tested against and false of every real one:
       V2Toasts stores `.slice(0, 160)` (revamp.js) while an ethers rejection
       runs ~330 chars and a viem one ~400, so the tail — including
       code=ACTION_REJECTED — is already gone before this rule is reached, and
       what remains ends mid-calldata. Wrapping is a display choice, not a
       preservation one: it stops the row overflowing, and nothing here can
       recover a tail the store dropped. The honest fix lives upstream, at the
       four producers that pass a raw error.message to showSimpleNotification
       (ui_interactions.js, wallet.js) — deliberately not done here. */
    body.v2 .v2-bell-msg { min-width: 0; overflow-wrap: anywhere; }
    body.v2 .v2-bell-msg a { color: var(--v2-sky); text-decoration: none; }

    body.v2 .v2-bell-when {
        margin-left: auto;
        flex: none;
        font-size: 0.625rem;
        color: var(--text-muted);
    }

    body.v2 .v2-bell-empty {
        text-align: center;
        padding: 26px 20px;
        color: var(--text-secondary);
        font-size: 0.75rem;
    }

    body.v2 .v2-bell-empty span {
        display: block;
        margin-top: 3px;
        color: var(--text-muted);
        font-size: 0.65625rem;
    }
}


/* --- §14 · position drawer + share card ------------------------------------
   The position modal docks right as a full-height drawer; the share card is
   a 1200×630-aspect surface with a share sheet under it. Losses share in
   neutral tones — never blocked. */
@media (min-width: 992px) {

    body.v2 #position-detail-modal .modal-dialog {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        margin: 0;
        /* !important: app.css:18826 pins the v1 dialog to 760px !important */
        width: 430px !important;
        max-width: none !important;
        display: flex;
        transform: translateX(24px);
        transition: transform .18s ease;
    }

    /* The v1 body is a two-column grid (app.css:18853 !important); the
       drawer is single-column — everything stacks. */
    body.v2 #position-detail-modal .position-detail-modal-body {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    body.v2 #position-detail-modal.show .modal-dialog {
        transform: none;
    }

    body.v2 #position-detail-modal .modal-content {
        height: 100%;
        border-radius: 0 !important;
        border: 0;
        border-left: 1px solid var(--v2-hair-strong);
        overflow-y: auto;
    }

    body.v2 .v2-pd-btn {
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-size: 0.65625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        padding: 8px 13px;
        border-radius: 8px;
        cursor: pointer;
    }

    /* Board: SHARE + TRADE THIS STRIKE ride equal weight, both chips. */
    body.v2 .v2-pd-btn.is-pri {
        color: var(--text-primary);
    }

    /* app.css:19007 hides the footer while the Settle button (once its only
       child) is hidden — the v2 footer carries SHARE / TRADE THIS STRIKE and
       must show regardless. History (settled) keeps SHARE; the strike is
       gone, so the trade button yields. */
    body.v2 #position-detail-modal .modal-footer:has(#v2-pd-share) {
        display: flex !important;
        gap: 8px;
        padding: 12px 16px;
        border-top: 1px solid var(--v2-hair);
    }

    body.v2 #position-detail-modal .v2-pd-btn { flex: 1; }

    body.v2 #position-detail-modal.pd-history #v2-pd-trade { display: none; }

    /* The legacy P/L summary card duplicates the new P&L tile. Hidden, not
       removed: #position-modal-pnl stays in the DOM as the data source the
       tile and the share card read. */
    body.v2 #position-detail-modal .modal-summary-card:has(#position-modal-pnl) {
        display: none;
    }

    /* ---- drawer contents (V2Drawer.enrich) ---- */
    body.v2 #v2-pd-tiles {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
        margin-bottom: 14px;
    }

    body.v2 #v2-pd-tiles .v2-pd-tile {
        background: var(--v2-chip);
        border: 1px solid var(--v2-hair);
        border-radius: 10px;
        padding: 10px 12px;
    }

    body.v2 #v2-pd-tiles .v2-pd-tile b {
        display: block;
        font-size: 0.625rem;      /* 8.5px caps label */
        font-weight: 600;
        letter-spacing: 0.09em;
        color: var(--text-muted);
        margin-bottom: 4px;
    }

    body.v2 #v2-pd-tiles .v2-pd-tile em {
        font-style: normal;
        font-size: 0.9375rem;       /* 15px value */
        font-weight: 700;
        color: var(--text-primary);
    }

    body.v2 #v2-pd-tiles .v2-pd-tile em.is-up { color: var(--positive); }
    body.v2 #v2-pd-tiles .v2-pd-tile em.is-dn { color: var(--text-secondary); }

    body.v2 #v2-pd-terms {
        margin: 14px 0 4px;
    }

    body.v2 #v2-pd-terms .v2-pd-row {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 12px;
        padding: 7px 0;
        border-top: 1px solid var(--v2-hair);
        font-size: 12px;      /* 11.5px */
    }

    body.v2 #v2-pd-terms .v2-pd-row span { color: var(--text-muted); }

    body.v2 #v2-pd-terms .v2-pd-row em {
        font-style: normal;
        color: var(--text-primary);
    }

    body.v2 #v2-pd-terms .v2-pd-row em a {
        color: var(--v2-sky);
        text-decoration: none;
    }

    body.v2 #v2-pd-payoff {
        position: relative;
        height: 96px;
        margin: 14px 0 6px;
        background: var(--panel-sunken);
        border: 1px solid var(--v2-hair);
        border-radius: 10px;
        overflow: hidden;
    }

    body.v2 #v2-pd-payoff svg {
        display: block;
        width: 100%;
        height: 100%;
    }

    body.v2 #v2-pd-payoff i {
        position: absolute;
        right: 8px;
        top: 6px;
        font-style: normal;
        font-size: 0.625rem;
        color: var(--text-muted);
    }

    /* ---- the share card ---- */
    body.v2 #v2-share-ov {
        position: fixed;
        inset: 0;
        z-index: 2000;
        background: rgba(4, 6, 12, 0.7);
        display: flex;
        align-items: center;
        justify-content: center;
    }

    body.v2 .v2-share-box {
        display: flex;
        flex-direction: column;
        gap: 12px;
        width: 480px;
    }

    body.v2 .v2-share-card {
        position: relative;
        width: 480px;
        height: 252px;
        border-radius: 14px;
        overflow: hidden;
        border: 1px solid var(--v2-hair-strong);
        background:
            radial-gradient(ellipse at 85% 15%, rgba(94, 221, 156, 0.12), transparent 55%),
            linear-gradient(135deg, #0B0F19 0%, #0E1626 55%, #0B2018 100%);
        padding: 18px 20px;
    }

    body.v2 .v2-share-card.is-loss {
        background:
            radial-gradient(ellipse at 85% 15%, rgba(126, 138, 156, 0.10), transparent 55%),
            linear-gradient(135deg, #0B0F19 0%, #10141F 60%, #131722 100%);
    }

    body.v2 .v2-sc-brand {
        font-weight: 900;
        letter-spacing: -0.045em;
        font-size: 17px;
        color: rgba(245, 247, 250, 0.75);
    }

    body.v2 .v2-sc-date {
        position: absolute;
        right: 20px;
        top: 20px;
        font-size: 10px;
        color: var(--text-muted);
    }

    body.v2 .v2-sc-idrow {
        margin-top: 22px;
        display: flex;
        align-items: center;
        gap: 8px;
    }

    body.v2 .v2-sc-chip {
        font-size: 0.625rem;
        font-weight: 700;
        letter-spacing: 0.08em;
        padding: 2px 7px;
        border-radius: 999px;
        background: rgba(94, 221, 156, 0.14);
        color: var(--positive);
    }

    body.v2 .v2-sc-chip.is-put {
        background: rgba(232, 106, 98, 0.14);
        color: var(--negative);
    }

    body.v2 .v2-sc-chip.is-range {
        background: rgba(125, 211, 252, 0.14);
        color: var(--v2-sky);
    }

    body.v2 .v2-sc-name {
        font-size: 14px;
        font-weight: 600;
        color: var(--text-primary);
    }

    body.v2 .v2-sc-addr {
        position: absolute;
        left: 20px;
        bottom: 30px;
        font-size: 10px;
        color: var(--text-muted);
    }

    body.v2 .v2-sc-addr[hidden] { display: none; }

    body.v2 .v2-share-addr {
        display: flex;
        align-items: center;
        gap: 7px;
        color: var(--text-secondary);
        font-size: 12px;
    }

    body.v2 .v2-sc-pnl {
        margin-top: 8px;
        font-family: var(--v2-display);
        font-size: 50px;
        font-weight: 600;
        letter-spacing: -0.02em;
        line-height: 1;
        color: var(--positive);
    }

    body.v2 .is-loss .v2-sc-pnl { color: var(--text-secondary); }

    body.v2 .v2-sc-flow {
        margin-top: 10px;
        font-size: 13px;
        color: var(--text-secondary);
    }

    body.v2 .v2-sc-meta {
        position: absolute;
        left: 20px;
        bottom: 14px;
        font-size: 10px;
        color: var(--text-muted);
    }

    body.v2 .v2-sc-link {
        position: absolute;
        right: 20px;
        bottom: 14px;
        font-size: 10px;
        font-weight: 600;
        color: var(--v2-sky);
    }

    body.v2 .v2-share-ref {
        display: flex;
        align-items: center;
        gap: 7px;
        color: var(--text-secondary);
        font-size: 12px;
    }

    body.v2 .v2-share-ref[hidden] { display: none; }

    /* the two toggles: 12px squares, chip at rest, sky when on (round 10) */
    body.v2 .v2-share-ref input,
    body.v2 .v2-share-addr input {
        appearance: none;
        -webkit-appearance: none;
        width: 12px;
        height: 12px;
        margin: 0;
        border: 0;
        border-radius: 3px !important;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        cursor: pointer;
    }

    body.v2 .v2-share-ref input:checked,
    body.v2 .v2-share-addr input:checked {
        background: var(--v2-sky);
        box-shadow: none;
    }

    /* the per-row share glyph (ledger rows) */
    body.v2 .v2-pos-share {
        background: none;
        border: 0;
        padding: 0;
        color: var(--text-muted);
        cursor: pointer;
        text-align: right;
        line-height: 1;
    }

    body.v2 .v2-pos-share:hover { color: var(--text-primary); }
    body.v2 .v2-pos-share svg { display: inline-block; vertical-align: middle; }

    body.v2 .v2-share-actions {
        display: flex;
        gap: 6px;
    }

    body.v2 .v2-share-actions button {
        flex: 1;
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-size: 0.65625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        padding: 9px 0;
        border-radius: 8px;
        cursor: pointer;
    }

    body.v2 .v2-share-actions button:first-child {
        background: var(--v2-primary-bg);
        box-shadow: none;
        color: var(--v2-ink);
    }
}


/* Short windows: the fixed view heights above were tuned for >=900px-tall
   screens. Below that the view region yields (the chart gives ground first,
   never the ticket or the positions strip) instead of opening a page
   scrollbar. Floor 400px — under ~780px-tall windows a scrollbar is the
   honest outcome. */
/* --- §14 · footer status bar (board: 30px, sunken ground) ---------------- */
@media (min-width: 992px) {

    body.v2 .status-bar {
        height: 30px;
        background: var(--panel-sunken);
    }

    /* the chart's data-source note, bottom-right of the plot */
    /* the toolbar never wraps its tools — the pays line is the yielder */
    body.v2 #v2-chart-row .tc-tv-tool,
    body.v2 #v2-chart-row .tc-tv-fit { white-space: nowrap; }

    body.v2 #v2-chart-source {
        display: inline-flex;
        align-items: center;
        flex: 0 0 auto;
        height: 20px;
        line-height: 1;
        margin-left: 10px;
        white-space: nowrap;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 0.625rem;
        font-weight: 500;
        letter-spacing: 0.04em;
        color: var(--text-muted);
        pointer-events: none;
    }

    /* the news card's closing reveal link */
    body.v2 .v2-news-all { list-style: none; }

    body.v2 #v2-news-all-btn {
        border: 0;
        background: transparent;
        padding: 6px 0 2px;
        font-family: var(--sans);
        font-size: 0.6875rem;
        font-weight: 600;
        color: var(--v2-sky);
        cursor: pointer;
    }
}

/* At the narrow band the footer sheds its softest fields (board: NarrowFit)
   so the load-bearing ones — status, network, liquidity, latency — keep
   their room. */
@media (min-width: 992px) and (max-width: 1579.98px) {
    body.v2 .status-bar-item:has(.bi-clock),
    body.v2 .status-bar-sep:has(+ .status-bar-item .bi-clock),
    body.v2 .status-bar-feedback,
    body.v2 .status-bar-sep:has(+ .status-bar-feedback),
    body.v2 .status-bar-powered,
    body.v2 .status-bar-sep:has(+ .status-bar-powered) {
        display: none;
    }
}

/* Threshold 910: the un-clamped layout's fixed bands (30px footer) add to
   910px — thinner windows need the ticket cap below. */
@media (min-width: 992px) and (max-height: 909.98px) {
    /* The view region used to re-declare its clamped floor here, to soften
       §12's floor on short windows. §12 has no floor any more (min-height: 0,
       flex sizes the region), so this override had nothing left to soften —
       it only reinstated the 400px floor that causes the overlap. Removed
       2026-09-08; the region needs no rule at this breakpoint. */

    /* The other resister is the TICKET: syncTicketHeight measures its real
       height and stretches the grid to fit it, which on a short window is
       taller than the viewport. Here the page frame wins and the ticket
       scrolls inside its own column instead. !important beats the inline
       min-height write. */
    body.v2 .trade-unified-layout,
    body.v2 .trade-unified-layout.ticket-open {
        min-height: calc(100vh - 116px - var(--v2-notice-h, 0px)) !important;
        max-height: calc(100vh - 116px - var(--v2-notice-h, 0px));
    }

    /* One grid row: the tallest column sets the row, and the 783px ticket
       was dragging every column past the viewport. Cap all three columns at
       the frame; the ticket scrolls inside its own card. */
    body.v2 #v2-col1,
    body.v2 #v2-col2,
    body.v2 #v2-col3 {
        max-height: calc(100vh - 116px - var(--v2-notice-h, 0px));
        min-height: 0;
    }

    body.v2 #v2-col2 {
        overflow: hidden;
    }

    body.v2 .trade-preview-card {
        overflow-y: auto;
        max-height: 100%;
    }
}


/* --- §14 · toast + bell anatomy (title over detail) ------------------------ */
@media (min-width: 992px) {

    body.v2 .v2-toast-msg {
        display: flex;
        flex-direction: column;
        gap: 1px;
        min-width: 0;
    }

    body.v2 .v2-toast-title {
        font-size: 0.75rem;
        font-weight: 600;
        line-height: 1.3;
        color: var(--text-primary);
    }

    body.v2 .v2-toast-body {
        font-size: 0.6875rem;
        line-height: 1.4;
        color: var(--text-muted);
    }

    body.v2 .v2-toast-body[hidden] { display: none; }

    body.v2 #v2-toast-more {
        align-self: flex-start;
        background: var(--v2-chip);
        color: var(--text-muted);
        font-size: 0.625rem;
        font-weight: 600;
        padding: 3px 10px;
        border-radius: 9px;
        margin-top: 2px;
    }

    body.v2 .v2-bell-item.is-read { opacity: 1; }
    body.v2 .v2-bell-item.is-read, body.v2 .v2-bell-item.is-read * { color: var(--text-muted); } /* read = quiet by colour, still ≥4.5:1 */

    body.v2 .v2-bell-msg { display: flex; flex-direction: column; gap: 1px; }
    body.v2 .v2-bell-msg b {
        font-weight: 600;
        color: var(--text-primary);
        font-size: 12px;
        line-height: 1.3;
    }
    body.v2 .v2-bell-msg span {
        font-size: 0.625rem;
        color: var(--text-muted);
        line-height: 1.4;
        font-variant-numeric: tabular-nums;
    }
}


/* --- §14 · the positions strip (Main board) -------------------------------
   Six tracks, composed position cell, COST → VALUE, dotted-underline P&L
   with its hover panel, a 3px sky time-bar (amber inside 15 min), ✕. The
   legacy table underneath is the data source and hides while rows exist. */
@media (min-width: 992px) {

    body.v2 #v2-pos-head {
        display: flex;
        align-items: baseline;
        gap: 14px;
        padding: 6px 16px 2px;
        font-size: 12px;
        color: var(--text-muted);
    }

    body.v2 .v2-pos-count { color: var(--text-secondary); }

    body.v2 .v2-pos-net { margin-left: auto; }
    body.v2 .v2-pos-net b.is-up { color: var(--positive); }
    body.v2 .v2-pos-net b.is-dn { color: var(--negative); }

    body.v2 #v2-pos-strip[hidden] { display: none; }

    body.v2 .v2-pos-cols {
        display: grid;
        grid-template-columns: var(--v2-tbl-grid, 170px minmax(0, 1fr) 150px 130px 150px 40px);
        gap: 10px;
        padding: 4px 16px;
        font-size: 0.625rem;
        letter-spacing: 0.05em;
        color: var(--text-muted);
        border-bottom: 1px solid var(--v2-hair);
    }

    body.v2 .v2-pos-row {
        display: grid;
        grid-template-columns: var(--v2-tbl-grid, 170px minmax(0, 1fr) 150px 130px 150px 40px);
        gap: 10px;
        align-items: center;
        padding: 6px 16px;
        border-bottom: 1px solid var(--v2-hair);
        font-size: 0.75rem;
        cursor: pointer;
    }

    body.v2 .v2-pos-row:hover { background: rgba(255, 255, 255, 0.02); }

    /* ONE line per row (round 10): cells clip with an ellipsis, nothing wraps.
       The P&L cell keeps overflow visible for its hover panel. */
    body.v2 .v2-pos-cols > *,
    body.v2 .v2-pos-row > * {
        min-width: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    body.v2 .v2-pos-row > .v2-pos-pnl { overflow: visible; }

    body.v2 .v2-pos-status { color: var(--text-muted); }
    body.v2 .v2-pos-status.is-paid { color: var(--positive); }
    body.v2 .v2-pos-status.is-open { color: var(--v2-sky); }
    body.v2 .v2-pos-status.is-warn { color: var(--v2-amber); }

    /* return magnitude bars share the expiry cell's anatomy */
    body.v2 .v2-pos-exp.is-pos .v2-pos-bar > span { background: var(--positive); }
    body.v2 .v2-pos-exp.is-neg .v2-pos-bar > span { background: var(--negative); }

    /* the empty face: glyph · bold line · quiet line · at most one action */
    body.v2 .v2-pos-empty {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 7px;
        padding: 26px 16px 22px;
        text-align: center;
    }

    body.v2 .v2-pos-empty b {
        font-size: 0.78125rem;
        font-weight: 600;
        color: var(--text-primary);
    }

    body.v2 .v2-pos-empty > span {
        font-size: 0.65625rem;
        color: var(--text-muted);
    }

    body.v2 .v2-pos-empty-act {
        margin-top: 4px;
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        padding: 8px 16px;
        border-radius: var(--v2-r-ctl);
        cursor: pointer;
    }

    body.v2 .v2-pos-empty-act.is-pri { background: var(--v2-primary-bg); box-shadow: none; color: var(--v2-ink); }

    body.v2 .v2-pos-foot {
        display: block;
        width: 100%;
        border: 0;
        background: transparent;
        color: var(--v2-sky);
        font-size: 0.65625rem;
        font-weight: 600;
        padding: 9px 16px;
        text-align: center;
        cursor: pointer;
    }

    body.v2 #v2-hist-strip[hidden] { display: none; }
    body.v2 #v2-pos-head[hidden] { display: none; }

    body.v2 .v2-pos-id i { font-style: normal; color: var(--text-muted); }
    body.v2 .v2-pos-id b.is-pos { color: var(--positive); }
    body.v2 .v2-pos-id b.is-neg { color: var(--negative); }
    body.v2 .v2-pos-id b.is-sky { color: var(--v2-sky); }
    body.v2 .v2-pos-id em {
        font-style: normal;
        color: var(--text-primary);
        font-weight: 600;
    }

    body.v2 .v2-pos-size { color: var(--text-muted); }

    body.v2 .v2-pos-cv { color: var(--text-secondary); }
    body.v2 .v2-pos-cv b { color: var(--text-primary); font-weight: 600; }

    body.v2 .v2-pos-pnl { position: relative; font-weight: 600; }
    body.v2 .v2-pos-pnl.is-up { color: var(--positive); }
    body.v2 .v2-pos-pnl.is-dn { color: var(--negative); }
    body.v2 .v2-pos-pnl u {
        text-decoration: none;
        border-bottom: 1px dotted currentColor;
    }
    body.v2 .v2-pos-pnl i {
        font-style: normal;
        font-weight: 400;
        color: var(--text-muted);
        font-size: 0.6875rem;
    }

    /* the per-row PnL panel, on hover of the dotted figure */
    body.v2 .v2-pos-tip {
        display: none;
        position: absolute;
        left: 0;
        bottom: 22px;
        width: 230px;
        background: var(--card-bg);
        border: 1px solid var(--v2-hair-strong);
        border-radius: 9px;
        padding: 8px 11px;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
        z-index: 5;
        font-weight: 400;
        cursor: default;
    }


    body.v2 .v2-pos-tip-h {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 3px;
    }

    body.v2 .v2-pos-tip-h b {
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
    }

    body.v2 .v2-pos-tip-h em {
        font-style: normal;
        font-size: 0.625rem;
        font-weight: 600;
        padding: 1px 7px;
        border-radius: 5px;
    }

    body.v2 .is-up .v2-pos-tip-h em { background: rgba(94, 221, 156, .15); }
    body.v2 .is-dn .v2-pos-tip-h em { background: rgba(232, 106, 98, .15); }

    body.v2 .v2-pos-tip-s {
        display: block;
        color: var(--text-muted);
        font-size: 0.625rem;
        line-height: 1.45;
    }

    body.v2 .v2-pos-exp {
        display: flex;
        align-items: center;
        gap: 6px;
        min-width: 0;
    }

    body.v2 .v2-pos-bar {
        flex: 1;
        height: 3px;
        border-radius: 2px;
        background: var(--v2-chip-inset);
        overflow: hidden;
    }

    body.v2 .v2-pos-bar > span {
        display: block;
        height: 100%;
        background: var(--v2-sky);
    }

    body.v2 .v2-pos-exp em {
        font-style: normal;
        color: var(--text-muted);
        font-size: 0.65625rem;
        white-space: nowrap;
    }

    body.v2 .v2-pos-exp.is-urgent .v2-pos-bar > span { background: var(--v2-amber); }
    /* urgency is the bar's colour, never the words (round 10) */

    body.v2 .v2-pos-x {
        background: none;
        border: 0;
        color: var(--text-muted);
        font-size: 0.6875rem;
        cursor: pointer;
        text-align: right;
    }

    body.v2 .v2-pos-x:hover { color: var(--text-secondary); }
}


/* --- §14 · the wallet popover + FUND lanes (FundFlowFinal board) ----------- */
@media (min-width: 992px) {

    body.v2 .wp-avatar-gradient {
        width: 28px;
        height: 28px;
        border-radius: 8px;
        background: linear-gradient(135deg, #5EDD9C, #7DD3FC);
        flex: none;
    }

    body.v2 .wp-avatar-gradient i { display: none; }

    body.v2 .wp-addr-col .wp-addr {
        font-size: 0.78125rem;
        font-weight: 600;
        color: var(--text-primary);
        font-variant-numeric: tabular-nums;
    }

    body.v2 .wp-kind { color: var(--text-muted); font-size: 0.625rem; }
    body.v2 .wp-kind-chain { color: var(--positive); }

    body.v2 .wp-copy {
        margin-left: auto;
        background: none;
        border: 0;
        color: var(--text-muted);
        font-size: 0.6875rem;
        cursor: pointer;
    }

    body.v2 .wp-copy:hover { color: var(--text-secondary); }

    body.v2 .wp-balance-card {
        background: transparent;
        border: 0;
        border-top: 1px solid var(--v2-hair);
        border-bottom: 1px solid var(--v2-hair);
        border-radius: 0 !important;
        padding: 13px 0;
        text-align: left;
    }

    body.v2 .wp-balance-label {
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.08em;
        color: var(--text-muted);
        margin-bottom: 3px;
    }

    body.v2 .wp-balance-value {
        font-size: 1.375rem;
        font-weight: 700;
        line-height: 1;
        color: var(--text-primary);
        text-align: left;
        font-variant-numeric: tabular-nums;
    }

    body.v2 .wp-cta-row {
        display: flex;
        gap: 6px;
        margin-top: 10px;
    }

    body.v2 .wp-cta {
        flex: 1;
        text-align: center;
        border: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
        font-size: 0.65625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        padding: 7px 0;
        border-radius: 7px;
        cursor: pointer;
    }

    body.v2 .wp-cta-pri {
        background: var(--v2-primary-bg);
        box-shadow: none;
        color: var(--v2-ink);
    }

    body.v2 .wp-menu { padding: 6px 0 0; }

    body.v2 .wp-row {
        display: flex;
        align-items: center;
        width: 100%;
        background: none;
        border: 0;
        text-align: left;
        padding: 7px 2px;
        font-size: 12px;
        color: var(--text-secondary);
        cursor: pointer;
        text-decoration: none;
    }

    body.v2 .wp-row:hover { color: var(--text-primary); }

    body.v2 .wp-row-end { margin-left: auto; color: var(--text-muted); font-size: 0.625rem; }

    body.v2 .wp-row-danger,
    body.v2 .wp-row-danger:hover { color: var(--negative); }

    /* ---- the FUND modal's lanes ---- */
    body.v2 .v2-fund-tabs {
        display: flex;
        gap: 6px;
        margin-bottom: 12px;
    }

    body.v2 .v2-fund-tabs[hidden] { display: none; }

    body.v2 .v2-fund-tab {
        flex: 1;
        text-align: center;
        background: transparent;
        border: 0;
        color: var(--text-muted);
        font-size: 0.65625rem;
        font-weight: 600;
        letter-spacing: 0.03em;
        padding: 7px 0;
        border-radius: 7px;
        cursor: pointer;
    }

    body.v2 .v2-fund-tab.is-active {
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-primary);
    }
}


/* --- §14 · the insufficient face (the honest button keeps the number) ------ */
@media (min-width: 992px) {
    body.v2 #v2-need-row {
        display: flex;
        gap: 6px;
    }

    body.v2 #v2-need-row[hidden] { display: none; }

    body.v2 .v2-need {
        flex: 1.6;
        text-align: center;
        background: rgba(94, 221, 156, 0.13);
        border: 0;
        color: var(--positive);
        font-size: 12px;
        font-weight: 600;
        letter-spacing: 0.04em;
        padding: 12px 0;
        border-radius: 8px;
    }

    body.v2 .v2-need-fund {
        flex: 1;
        text-align: center;
        background: var(--v2-primary-bg);
        border: 0;
        color: var(--v2-ink);
        font-size: 12px;
        font-weight: 600;
        letter-spacing: 0.05em;
        padding: 12px 0;
        border-radius: 8px;
        cursor: pointer;
    }
}


/* Range products are SKY in the v2 palette. The app-wide token stays purple
   for the phone; every desktop consumer (row bands, counts, keys) follows
   this one override. */
@media (min-width: 992px) {
    body.v2 {
        --ranger-purple: var(--v2-sky);
    }
}

/* ==========================================================================
   §15 · MOBILE GUARD — v2 markup that app.html now carries at every width.
   Everything above is gated >=992px; these are the v2-only nodes that would
   otherwise render unstyled inside the mobile layout. The legacy #top-strip
   stays visible below 992 (it is mobile's own banner).
   ========================================================================== */
@media (max-width: 991.98px) {
    body.v2 #v2-comp-line,
    body.v2 #v2-news {
        display: none;
    }
    /* the wordmark replaced the old ODETTE.FI span in shared markup */
    body.v2 .v2-wordmark {
        font-size: 16px;
        font-weight: 900;
        letter-spacing: -.045em;
        color: rgba(245, 247, 250, .85);
    }
}

/* --- §14 · overlapping ranges: band + edge bracket + foot tab + picker ------ */
@media (min-width: 992px) {
    body.v2 .v2-range-bracket {
        position: absolute;
        top: 0;
        right: 0;
        width: 5px;
        border: 0;
        padding: 0;
        border-radius: 2px 0 0 2px;
        background: var(--v2-sky);
        opacity: .75;
        cursor: pointer;
        z-index: 2;
    }

    body.v2 .v2-range-bracket:hover { opacity: 1; }

    body.v2 .v2-range-bracket.is-selected {
        opacity: 1;
        box-shadow: 0 0 0 2px rgba(125, 211, 252, .35);
    }

    body.v2 .v2-range-foot {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 2px;
        height: 15px;
        border: 0;
        padding: 0;
        border-radius: 3px;
        background: var(--v2-sky);
        color: var(--v2-on-sky);
        font-size: 0.625rem;
        font-weight: 700;
        letter-spacing: 0.04em;
        line-height: 15px;
        text-align: center;
        cursor: pointer;
        z-index: 3;
    }

    body.v2 #v2-range-pick {
        position: absolute;
        width: 240px;
        z-index: 6;
        background: var(--card-bg);
        border: 1px solid var(--v2-hair-strong);
        border-radius: 10px;
        padding: 10px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
    }

    body.v2 #v2-range-pick[hidden] { display: none; }

    body.v2 .v2-rp-head {
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.09em;
        text-transform: uppercase;
        color: var(--text-muted);
        margin-bottom: 8px;
    }

    body.v2 .v2-rp-row {
        display: grid;
        grid-template-columns: 8px 1fr auto;
        gap: 10px;
        align-items: center;
        width: 100%;
        border: 0;
        background: transparent;
        border-radius: 8px;
        padding: 8px;
        text-align: left;
        cursor: pointer;
    }

    body.v2 .v2-rp-row:hover { background: rgba(255, 255, 255, .04); }
    body.v2 .v2-rp-row.is-band { background: rgba(125, 211, 252, .08); }
    body.v2 .v2-rp-row.is-selected { box-shadow: inset 0 0 0 1px rgba(125, 211, 252, .5); }

    body.v2 .v2-rp-span {
        position: relative;
        display: block;
        width: 4px;
        height: 30px;
        border-radius: 2px;
        background: rgba(255, 255, 255, .06);
    }

    body.v2 .v2-rp-span i {
        position: absolute;
        left: 0;
        right: 0;
        border-radius: 2px;
        background: var(--v2-sky);
    }

    body.v2 .v2-rp-b { font-size: 0.65625rem; font-weight: 600; color: var(--text-primary); }
    body.v2 .v2-rp-m { font-size: 0.625rem; font-weight: 700; color: var(--positive); }
}


/* ==========================================================================
   ROUND 11 — the user's numbered fixes on the trade page (desktop ≥992).
   Later in the file than every rule it overrides; the numbers are the
   user's list (1a resting sides … 24b scrolling history).
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 { --v2-strip-block-h: 248px; }

    /* ---- 1a · resting YES / NO are visible chips; disabled = dim chip ---- */
    body.v2 .v2-side-btn,
    body.v2 .v2-side-btn.is-call,
    body.v2 .v2-side-btn.is-put {
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        color: var(--text-secondary);
    }
    body.v2 .v2-side-btn.is-call:hover:not(:disabled):not(.is-active),
    body.v2 .v2-side-btn.is-put:hover:not(:disabled):not(.is-active) {
        background: var(--v2-chip-hover);
        color: var(--text-primary);
    }
    body.v2 .v2-side-btn.is-call.is-active { background: var(--positive); box-shadow: none; color: var(--v2-on-green); }
    body.v2 .v2-side-btn.is-put.is-active  { background: var(--negative); box-shadow: none; color: var(--v2-on-negative); }
    body.v2 .v2-side-btn:disabled,
    body.v2 .v2-side-btn.is-call:disabled,
    body.v2 .v2-side-btn.is-put:disabled {
        opacity: 1;
        background: var(--v2-chip-dim);
        box-shadow: none;
        color: var(--text-muted);
        cursor: default;
    }

    /* ---- 1b · the detail list has no divider lines; Settles moved up ---- */
    body.v2 .v2-params { border-top: 0; padding: 2px 0 0; }
    body.v2 .v2-param { border-bottom: 0; padding: 3px 0; }
    body.v2 .v2-param.v2-param-settles-row { display: none; }

    /* ---- 7a · the expiry line above YES / NO ---- */
    body.v2 .v2-expiry-line {
        position: relative;
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 10px;
        margin: 2px 0 10px;
        padding-bottom: 7px;
        min-height: 24px;
        white-space: nowrap;
        /* The safety valve. `nowrap` on two items that cannot shrink below
           their text made this row's min-content wider than the 300px ticket
           column at the 1440-1679px band, and the countdown was clipped at the
           panel edge (user, 2026-09-10). V2U.tight() is what actually brings
           the string inside 272px; this is what stops any future string from
           being cut instead of shown. It costs nothing while the line fits —
           one flex line is one flex line — so the row keeps its 24px geometry
           for every tenor the book quotes. */
        flex-wrap: wrap;
    }
    body.v2 .v2-expiry-line b {
        font-family: var(--v2-display);
        font-size: 0.875rem;
        font-weight: 600;
        letter-spacing: -0.01em;
        color: var(--text-muted);
    }
    body.v2 .v2-expiry-line.is-set b { color: var(--text-primary); }
    body.v2 .v2-expiry-line span {
        font-size: 12px;
        font-weight: 500;
        color: var(--text-secondary);
        font-variant-numeric: tabular-nums;
    }
    body.v2 .v2-expiry-bar {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 3px;
        border-radius: 2px;
        background: rgba(255, 255, 255, 0.06);
        overflow: hidden;
    }
    body.v2 .v2-expiry-bar > i {
        display: block;
        height: 100%;
        width: 100%;
        transform: scaleX(var(--v2-timebar, 0));
        transform-origin: left center;
        background: var(--v2-sky);
        transition: transform 400ms ease; /* compositor-only: no layout per tick */
    }
    body.v2 .v2-expiry-line.is-urgent .v2-expiry-bar > i { background: var(--v2-amber); }

    /* ---- 7b · the payoff readout: three aligned cells, fixed height ---- */
    body.v2 .v2-payoff-readout {
        display: grid;
        grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
        align-items: end;
        column-gap: 14px;
        height: 38px;
        box-sizing: border-box;
        padding: 5px 10px;
    }
    body.v2 .v2-payoff-readout[hidden] { display: none; }
    body.v2 .v2-payoff-readout .v2-ro {
        display: flex;
        flex-direction: column;
        gap: 1px;
        min-width: 0;
    }
    body.v2 .v2-payoff-readout .v2-ro i {
        font-style: normal;
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--text-muted);
    }
    body.v2 .v2-payoff-readout .v2-ro b {
        font-size: 0.6875rem;
        font-weight: 600;
        color: var(--text-primary);
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    body.v2 .v2-payoff-readout .v2-ro b.is-pos { color: var(--positive); }
    body.v2 .v2-payoff-readout .v2-ro b.is-neg { color: var(--negative); }

    /* ---- 8 / 24b · the strip block is a fixed-height panel; rows scroll ---- */
    body.v2 #trade-positions-block {
        flex: 0 0 var(--v2-strip-block-h);
        height: var(--v2-strip-block-h);
        min-height: var(--v2-strip-block-h);
        max-height: var(--v2-strip-block-h);
        overflow: hidden;
    }
    body.v2 #trade-positions-block > .col-12 {
        height: 100%;
        display: flex;
        flex-direction: column;
        min-height: 0;
    }
    body.v2 #trade-positions-block .user-positions-table-container {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }
    body.v2 .trade-strip-tabs { flex: 0 0 auto; }
    body.v2 .trade-strip-pane {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overflow-x: hidden;
        scrollbar-width: thin;
        scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
    }
    body.v2 .v2-pos-cols {
        position: sticky;
        top: 0;
        z-index: 2;
        background: var(--background);
    }
    body.v2 .v2-pos-empty { min-height: 0; padding: 12px 0 10px; gap: 6px; justify-content: center; }

    /* ---- 24b · the way to the full page ---- */
    body.v2 .trade-strip-tabs { align-items: center; }
    body.v2 #v2-strip-portfolio {
        margin-left: auto;
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--text-muted);
        text-decoration: none;
        padding: 6px 2px;
        white-space: nowrap;
    }
    body.v2 #v2-strip-portfolio:hover { color: var(--text-primary); }

    /* ---- 9 · the one floating P&L box ---- */
    body.v2 .v2-pos-tip { display: none; }
    #v2-tipbox {
        position: fixed;
        z-index: 80;
        width: 230px;
        background: var(--card-bg, #0E1322);
        border: 1px solid var(--v2-hair-strong, rgba(255, 255, 255, .13));
        border-radius: 0;
        padding: 8px 11px;
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
        font-size: 0.75rem;
        font-weight: 400;
        color: var(--text-primary);
        pointer-events: none;
    }
    #v2-tipbox[hidden] { display: none; }
    #v2-tipbox .v2-pos-tip-h { display: flex; justify-content: space-between; align-items: center; margin-bottom: 3px; }
    #v2-tipbox .v2-pos-tip-h b { font-size: 0.625rem; font-weight: 600; letter-spacing: 0.05em; color: var(--text-muted); }
    #v2-tipbox .v2-pos-tip-h em { font-style: normal; font-size: 0.625rem; font-weight: 600; padding: 1px 7px; }
    #v2-tipbox.is-up .v2-pos-tip-h em { color: var(--positive); background: rgba(94, 221, 156, .15); }
    #v2-tipbox.is-dn .v2-pos-tip-h em { color: var(--negative); background: rgba(232, 106, 98, .15); }
    #v2-tipbox .v2-pos-tip-s { display: block; color: var(--text-muted); font-size: 0.625rem; line-height: 1.45; }

    /* ---- 13 · square tables and tabs (trade page; the pages follow) ---- */
    body.v2 .v2-pos-cols,
    body.v2 .v2-pos-row,
    body.v2 .v2-pos-empty,
    body.v2 .trade-strip-tab,
    body.v2 .trade-strip-tab.active { border-radius: 0 !important; }

    /* ---- 17 · strip text is white; only the % and the time words yield ---- */
    body.v2 .v2-pos-row { color: var(--text-primary); }
    body.v2 .v2-pos-size,
    body.v2 .v2-pos-cv,
    body.v2 .v2-pos-cv span { color: var(--text-primary); }
    body.v2 .v2-pos-pnl i { color: var(--text-muted); }
    body.v2 .v2-pos-exp em { color: var(--text-muted); }

    /* ---- 18 · one green: app.css paints BUY translucent with !important ---- */
    body.v2 .trade-preview-card #trade-now-btn.btn-primary.call  { background: var(--positive) !important; color: var(--v2-on-green) !important; }
    body.v2 .trade-preview-card #trade-now-btn.btn-primary.put   { background: var(--negative) !important; color: var(--v2-on-negative) !important; }
    body.v2 .trade-preview-card #trade-now-btn.btn-primary.range { background: var(--v2-sky) !important; color: var(--v2-on-sky) !important; }
    body.v2 .trade-preview-card #trade-now-btn.btn-primary:hover:not(:disabled) { filter: brightness(1.06); }
    /* the FUND face stays white whatever side class the app leaves on the button */
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face.btn-primary.call,
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face.btn-primary.put,
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face.btn-primary.range,
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face.call,
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face.put,
    body.v2 .trade-preview-card #trade-now-btn.v2-fund-face.range { background: var(--v2-primary-bg) !important; color: var(--v2-ink) !important; }

    /* ---- 20 · the balance is a reading, held in the dark chip ---- */
    body.v2 .v2-balance-chip,
    body.v2 #v2-balance-chip {
        background: var(--v2-chip, #232C42);
        box-shadow: none;
        padding: 0 12px;
        border-radius: 6px !important;
        cursor: default;
    }
    body.v2 .v2-balance-num { font-weight: 700; }

    /* ---- 4 · the bell is a chip like its neighbours; one 8px gap ---- */
    body.v2 .hdr-tools { gap: 8px; }
    body.v2 .hdr-tools .wallet-cta.ms-2 { margin-left: 8px !important; }
    body.v2 #nav-alert-btn {
        width: var(--v2-ctl-h, 30px);
        justify-content: center;
        padding: 0;
        background: var(--v2-chip);
        box-shadow: var(--v2-chip-lift);
        border: 0;
        color: var(--text-secondary);
    }
    body.v2 #nav-alert-btn:hover { background: var(--v2-chip-hover); color: var(--text-primary); }
}

/* short windows: four rows in the strip, the chart keeps more of the frame */
@media (min-width: 992px) and (max-height: 909.98px) {
    body.v2 { --v2-strip-block-h: 216px; }
}

/* round 11 · chain view: the corner label duplicated the ticket's own head and
   collided with the toolbar's pays line on a 240px strip — retired */
@media (min-width: 992px) {
    body.v2 #v2-strip-corner { display: none !important; }
}

/* round 11 · one cap style for every column head (the strip is the reference) */
@media (min-width: 992px) {
    body.v2 .v2-pos-cols { font-weight: 600; }
}

/* ==========================================================================
   ROUND 11 · issue 15 — the position drawer in the app's own language:
   identity row with a status chip, the P&L hero with two cards, a plain
   terms list, the mini payoff, the scenarios as the strip, SHARE + TRADE.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 #position-detail-modal .modal-content { background: var(--background); }
    body.v2 #position-detail-modal .position-detail-modal-header {
        background: transparent;
        border: 0;
        padding: 12px 16px 0;
        min-height: 0;
    }
    body.v2 #position-detail-modal .position-detail-modal-title { display: none; }
    body.v2 #position-detail-modal .btn-close {
        margin: 0 0 0 auto;
        opacity: .6;
        background-size: 10px;
    }
    body.v2 #position-detail-modal .position-detail-modal-body { padding: 4px 16px 16px; }

    body.v2 #position-detail-modal .pd-identity {
        display: flex;
        align-items: center;
        gap: 10px;
        margin: 0 0 14px;
        padding: 0;
        border: 0;
    }
    body.v2 #position-detail-modal .pd-logo { width: 22px; height: 22px; }
    body.v2 #position-detail-modal #position-modal-title {
        margin: 0;
        font-family: var(--v2-display);
        font-size: 1.125rem;
        font-weight: 600;
        letter-spacing: -0.02em;
        color: var(--text-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        min-width: 0;
    }
    body.v2 #v2-pd-status {
        margin-left: auto;
        flex: 0 0 auto;
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        padding: 3px 8px;
        border-radius: var(--v2-r-ctl);
        background: var(--v2-chip);
        color: var(--text-secondary);
    }
    body.v2 #v2-pd-status.is-open { background: rgba(125, 211, 252, .14); color: var(--v2-sky); }
    body.v2 #v2-pd-status.is-paid { background: rgba(94, 221, 156, .14); color: var(--positive); }

    /* the legacy summary cards stand down (their facts sit in the list) */
    body.v2 #position-detail-modal .modal-trade-summary { display: none !important; }

    /* hero + cards */
    body.v2 #v2-pd-tiles {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 170px;
        gap: 10px;
        align-items: stretch;
        margin-bottom: 14px;
    }
    body.v2 #v2-pd-tiles .v2-pd-tile {
        flex: 1 1 0;
        background: var(--card-bg);
        border: 1px solid var(--v2-hair-strong);
        border-radius: var(--v2-r-card-sm, 12px);
        padding: 9px 12px;
    }
    body.v2 #v2-pd-tiles .v2-pd-tile em { font-size: 0.875rem; color: var(--text-primary); }

    /* the terms: a plain list, no dividers */
    body.v2 #v2-pd-terms { margin: 10px 0 4px; }
    body.v2 #v2-pd-terms .v2-pd-row { border-top: 0; padding: 4px 0; font-size: 0.75rem; }
    body.v2 #v2-pd-terms .v2-pd-row em { font-weight: 600; }

    /* the mini payoff */
    body.v2 #v2-pd-payoff {
        border-color: var(--v2-hair-strong);
        border-radius: var(--v2-r-card-sm, 12px);
        background: var(--card-bg);
    }

    /* the two legacy tables become the strip: caps head, hairlines, one line */
    body.v2 #position-detail-modal .profit-scenarios { margin-top: 12px !important; background: transparent !important; border: 0 !important; padding: 0 !important; border-radius: 0 !important; }
    body.v2 #position-detail-modal .profit-scenarios h6 {
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--text-muted);
        margin: 0 0 4px;
    }
    body.v2 #position-detail-modal .profit-scenarios table {
        margin: 0;
        background: transparent;
        border: 0;
    }
    body.v2 #position-detail-modal .profit-scenarios td {
        padding: 6px 0;
        border: 0;
        border-bottom: 1px solid var(--v2-hair);
        background: transparent;
        font-size: 0.75rem;
        color: var(--text-primary);
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        vertical-align: middle;
    }
    body.v2 #position-detail-modal .profit-scenarios td:first-child { color: var(--text-muted); }
    body.v2 #position-detail-modal .profit-scenarios td + td { text-align: right; }
    body.v2 #position-detail-modal .profit-scenarios tr:last-child td { border-bottom: 0; }
    /* the legacy details table's facts live in the terms list now; it stays
       in the DOM as the data source and is not drawn */
    body.v2 #position-detail-modal .profit-scenarios:not(#position-scenarios-block) { display: none !important; }
    body.v2 #v2-pd-terms { margin-top: 0; }
    body.v2 #v2-pd-terms .v2-pd-row em { max-width: 62%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }

    /* footer: SHARE chip + TRADE THIS STRIKE white */
    body.v2 #position-detail-modal .modal-footer:has(#v2-pd-share) {
        background: transparent;
        border-top: 1px solid var(--v2-hair);
        padding: 12px 16px 14px;
    }
    body.v2 .v2-pd-btn { border-radius: var(--v2-r-ctl); text-transform: uppercase; }
    body.v2 .v2-pd-btn.is-pri { background: var(--v2-primary-bg); box-shadow: none; color: var(--v2-ink); }
    body.v2 .v2-pd-btn.is-pri:hover { background: #FFFFFF; }
}

/* ==========================================================================
   ROUND 12 · switchers are not buttons. Choosing between views — the fund
   modal's lanes, the bell's panes — is the segmented control the view links
   and the ticket tabs already use: sunken track, 2px pad, chosen segment
   solid sky, the rest bare and muted. The chip fill stays for buttons.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 .v2-fund-tabs,
    body.v2 .v2-bell-tabs {
        gap: 2px;
        padding: 2px;
        background: var(--panel-sunken);
        border-radius: var(--v2-r-ctl);
    }
    body.v2 .v2-bell-tabs { margin: 10px 14px 0; align-items: stretch; }
    body.v2 .v2-fund-tab,
    body.v2 .v2-bell-tab {
        background: transparent;
        box-shadow: none;
        border: 0;
        border-radius: 7px;
        color: var(--text-muted);
        font-size: 0.625rem;
        font-weight: 600;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        line-height: 1;
        padding: 7px 11px;
    }
    body.v2 .v2-bell-tab { flex: 1 1 0; text-align: center; }
    body.v2 .v2-fund-tab:hover,
    body.v2 .v2-bell-tab:hover { color: var(--text-secondary); background: transparent; }
    body.v2 .v2-fund-tab.is-active,
    body.v2 .v2-bell-tab.is-active {
        background: var(--v2-sky);
        box-shadow: none;
        color: var(--v2-on-sky);
    }
    /* Mark all read is an action, not a pane, so it sits on the header
       line beside Close rather than inside the switcher track. */
    body.v2 .alp-head .v2-bell-read {
        flex: 0 0 auto;
        margin-left: auto;
        background: transparent;
        box-shadow: none;
        border: 0;
        color: var(--text-muted);
        font-size: 0.625rem;
        padding: 0 8px;
    }
    body.v2 .alp-head .v2-bell-read:hover { color: var(--text-primary); }
}


/* ==========================================================================
   ROUND 13 · THE QUIET SYSTEM (Odette Pages canvas, "The quiet system").
   One ground, one panel tone, no borders. Type: Geist for the page title
   only; every caption outside a table head is Inter 12px sentence case,
   muted; figures 22/600 tabular. Controls: ONE button family (30px, r6,
   12px/500 sentence case — dark #232C42, white primary, green for money
   only) and ONE switcher (sunken track, 2px pad, chosen segment = the dark
   chip, never sky). Colour: green/red on P&L only, sky for links and the
   selected asset chip, amber only in bars. Later-in-file, so these rules
   are the terminal word over every earlier round.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 {
        --v2-r-btn: 6px;
        --v2-btn-h: 30px;
        --v2-ink: #0F1520;
    }

    /* ---- 1 · captions outside the table head ------------------------- */
    body.v2 .v2-payoff-label,
    body.v2 .v2-amt-label,
    body.v2 #v2-pos-head,
    body.v2 .v2-payoff-hint {
        font-family: var(--sans);
        font-size: 0.75rem;
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text-muted);
    }
    body.v2 .v2-pos-count { color: var(--text-secondary); }

    /* ---- 2 · the topbar: nav is text, no pills ------------------------ */
    body.v2 .navbar-nav { gap: 36px; } /* after Hyperliquid: ~40px text to text */
    body.v2 .navbar-nav .nav-link {
        font-size: 0.8125rem;
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
        padding: 0;
        height: auto;
        background: transparent !important;
        box-shadow: none !important;
        color: var(--text-muted);
    }
    body.v2 .navbar-nav .nav-link:hover { color: var(--text-secondary); }
    body.v2 .navbar-nav .nav-link.active { color: var(--text-primary); font-weight: 600; }

    /* ---- 3 · the button family ---------------------------------------- */
    body.v2 .v2-btn,
    body.v2 .v2-pd-btn,
    body.v2 .wp-cta,
    body.v2 .v2-pos-empty-act,
    body.v2 .v2-blank-act,
    body.v2 .v2-blank-alt,
    body.v2 .v2-toast-act,
    body.v2 .v2-need-fund,
    body.v2 .v2-connect-alt,
    body.v2 .v2-connect-main,
    body.v2 #v2-connect-btn,
    body.v2 .header-wallet-pill,
    body.v2 #connect-web3modal-btn,
    body.v2 [id^="connect-base-account-btn"],
    body.v2 #use-in-browser-wallet-btn,
    body.v2 #portfolio-section .pf-btn,
    body.v2 #portfolio-section .pf-tool,
    body.v2 #portfolio-section .pf-filter-btn,
    body.v2 #scoreboard-cards .sbc-stage-btn,
    body.v2 #scoreboard-cards .sbc-btn,
    body.v2 #scoreboard-cards .sbc-you-connect,
    body.v2 #scoreboard-cards #sbc-me-pin,
    body.v2 #referral-section .ref-btn,
    body.v2 #referral-section #referral-connect-btn,
    body.v2 #referral-section #referral-load-more,
    body.v2 .pgr button,
    body.v2 .alp-create,
    body.v2 .odette-btn-primary,
    body.v2 .odette-btn-secondary {
        box-sizing: border-box !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        gap: 6px;
        height: var(--v2-btn-h, 30px) !important;
        min-height: 0 !important;
        padding: 0 12px !important;
        border: 0 !important;
        border-radius: var(--v2-r-btn, 6px) !important;
        box-shadow: none !important;
        background: var(--v2-chip, #232C42) !important;
        color: var(--text-primary, #F5F7FA) !important;
        font-family: var(--sans) !important;
        font-size: 0.75rem !important;
        font-weight: 500 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
        line-height: 1 !important;
        white-space: nowrap;
        text-decoration: none !important;
        transform: none !important;
        cursor: pointer;
        transition: background-color 120ms ease, color 120ms ease;
    }

    /* The filter chips are ALSO .form-select-dropdown, which carries its caret
       as an absolute ::after at right:8px (app.css). app.css reserved the room
       for it with padding-right:2rem; the one-button-family rule above collapses
       that to 12px, so the label runs under the caret — measured 3px of overlap
       on "All Assets" at 1470px. The caret occupies 8..15px from the right edge,
       so the gutter has to clear 15px; 22px leaves the same 7px of air the chip
       has elsewhere. Only the caret-bearing members of the family need this. */
    body.v2 #portfolio-section .pf-filter-btn.form-select-dropdown {
        padding-right: 22px !important;
    }

    body.v2 .v2-btn:hover,
    body.v2 .v2-pd-btn:hover,
    body.v2 .wp-cta:hover,
    body.v2 .v2-pos-empty-act:hover,
    body.v2 .v2-blank-alt:hover,
    body.v2 .v2-toast-act:hover,
    body.v2 .v2-connect-alt:hover,
    body.v2 [id^="connect-base-account-btn"]:hover,
    body.v2 #use-in-browser-wallet-btn:hover,
    body.v2 #portfolio-section .pf-btn:hover,
    body.v2 #portfolio-section .pf-tool:hover,
    body.v2 #portfolio-section .pf-filter-btn:hover,
    body.v2 #scoreboard-cards .sbc-stage-btn:hover,
    body.v2 #scoreboard-cards .sbc-btn:hover,
    body.v2 #scoreboard-cards #sbc-me-pin:hover,
    body.v2 #referral-section .ref-btn:hover,
    body.v2 #referral-section #referral-load-more:hover,
    body.v2 .pgr button:hover,
    body.v2 .odette-btn-secondary:hover {
        background: var(--v2-chip-hover, #2C3752) !important;
        color: var(--text-primary) !important;
        filter: none;
    }


    /* hidden wins: the family's !important display must never beat the [hidden]
       attribute or the inline display:none the app's own code hides with
       (wallet.js hides the connect buttons that way; the swap / import /
       position footers too) */
    body.v2 .v2-btn[hidden],
    body.v2 .v2-btn[style*="display: none"],
    body.v2 .v2-btn[style*="display:none"],
    body.v2 .v2-pd-btn[hidden],
    body.v2 .v2-pd-btn[style*="display: none"],
    body.v2 .v2-pd-btn[style*="display:none"],
    body.v2 .wp-cta[hidden],
    body.v2 .wp-cta[style*="display: none"],
    body.v2 .wp-cta[style*="display:none"],
    body.v2 .v2-pos-empty-act[hidden],
    body.v2 .v2-pos-empty-act[style*="display: none"],
    body.v2 .v2-pos-empty-act[style*="display:none"],
    body.v2 .v2-blank-act[hidden],
    body.v2 .v2-blank-act[style*="display: none"],
    body.v2 .v2-blank-act[style*="display:none"],
    body.v2 .v2-blank-alt[hidden],
    body.v2 .v2-blank-alt[style*="display: none"],
    body.v2 .v2-blank-alt[style*="display:none"],
    body.v2 .v2-toast-act[hidden],
    body.v2 .v2-toast-act[style*="display: none"],
    body.v2 .v2-toast-act[style*="display:none"],
    body.v2 .v2-need-fund[hidden],
    body.v2 .v2-need-fund[style*="display: none"],
    body.v2 .v2-need-fund[style*="display:none"],
    body.v2 .v2-connect-alt[hidden],
    body.v2 .v2-connect-alt[style*="display: none"],
    body.v2 .v2-connect-alt[style*="display:none"],
    body.v2 .v2-connect-main[hidden],
    body.v2 .v2-connect-main[style*="display: none"],
    body.v2 .v2-connect-main[style*="display:none"],
    body.v2 #v2-connect-btn[hidden],
    body.v2 #v2-connect-btn[style*="display: none"],
    body.v2 #v2-connect-btn[style*="display:none"],
    body.v2 .header-wallet-pill[hidden],
    body.v2 .header-wallet-pill[style*="display: none"],
    body.v2 .header-wallet-pill[style*="display:none"],
    body.v2 #connect-web3modal-btn[hidden],
    body.v2 #connect-web3modal-btn[style*="display: none"],
    body.v2 #connect-web3modal-btn[style*="display:none"],
    body.v2 [id^="connect-base-account-btn"][hidden],
    body.v2 [id^="connect-base-account-btn"][style*="display: none"],
    body.v2 [id^="connect-base-account-btn"][style*="display:none"],
    body.v2 #use-in-browser-wallet-btn[hidden],
    body.v2 #use-in-browser-wallet-btn[style*="display: none"],
    body.v2 #use-in-browser-wallet-btn[style*="display:none"],
    body.v2 #portfolio-section .pf-btn[hidden],
    body.v2 #portfolio-section .pf-btn[style*="display: none"],
    body.v2 #portfolio-section .pf-btn[style*="display:none"],
    body.v2 #portfolio-section .pf-tool[hidden],
    body.v2 #portfolio-section .pf-tool[style*="display: none"],
    body.v2 #portfolio-section .pf-tool[style*="display:none"],
    body.v2 #portfolio-section .pf-filter-btn[hidden],
    body.v2 #portfolio-section .pf-filter-btn[style*="display: none"],
    body.v2 #portfolio-section .pf-filter-btn[style*="display:none"],
    body.v2 #scoreboard-cards .sbc-stage-btn[hidden],
    body.v2 #scoreboard-cards .sbc-stage-btn[style*="display: none"],
    body.v2 #scoreboard-cards .sbc-stage-btn[style*="display:none"],
    body.v2 #scoreboard-cards .sbc-btn[hidden],
    body.v2 #scoreboard-cards .sbc-btn[style*="display: none"],
    body.v2 #scoreboard-cards .sbc-btn[style*="display:none"],
    body.v2 #scoreboard-cards .sbc-you-connect[hidden],
    body.v2 #scoreboard-cards .sbc-you-connect[style*="display: none"],
    body.v2 #scoreboard-cards .sbc-you-connect[style*="display:none"],
    body.v2 #scoreboard-cards #sbc-me-pin[hidden],
    body.v2 #scoreboard-cards #sbc-me-pin[style*="display: none"],
    body.v2 #scoreboard-cards #sbc-me-pin[style*="display:none"],
    body.v2 #referral-section .ref-btn[hidden],
    body.v2 #referral-section .ref-btn[style*="display: none"],
    body.v2 #referral-section .ref-btn[style*="display:none"],
    body.v2 #referral-section #referral-connect-btn[hidden],
    body.v2 #referral-section #referral-connect-btn[style*="display: none"],
    body.v2 #referral-section #referral-connect-btn[style*="display:none"],
    body.v2 #referral-section #referral-load-more[hidden],
    body.v2 #referral-section #referral-load-more[style*="display: none"],
    body.v2 #referral-section #referral-load-more[style*="display:none"],
    body.v2 .pgr button[hidden],
    body.v2 .pgr button[style*="display: none"],
    body.v2 .pgr button[style*="display:none"],
    body.v2 .alp-create[hidden],
    body.v2 .alp-create[style*="display: none"],
    body.v2 .alp-create[style*="display:none"],
    body.v2 .odette-btn-primary[hidden],
    body.v2 .odette-btn-primary[style*="display: none"],
    body.v2 .odette-btn-primary[style*="display:none"],
    body.v2 .odette-btn-secondary[hidden],
    body.v2 .odette-btn-secondary[style*="display: none"],
    body.v2 .odette-btn-secondary[style*="display:none"] { display: none !important; }

    /* the white primary — one per surface */
    body.v2 .v2-btn.is-pri,
    body.v2 .v2-pd-btn.is-pri,
    body.v2 .wp-cta-pri,
    body.v2 .v2-pos-empty-act.is-pri,
    body.v2 .v2-blank-act,
    body.v2 .v2-need-fund,
    body.v2 .v2-connect-main,
    body.v2 #v2-connect-btn,
    body.v2 #referral-section #referral-tile-create,
    body.v2 #referral-section #referral-head-create,
    body.v2 #connect-web3modal-btn,
    body.v2 #portfolio-section .pf-btn-pri,
    body.v2 #scoreboard-cards .sbc-stage-btn-pri,
    body.v2 #referral-section #referral-connect-btn,
    body.v2 .alp-create,
    body.v2 .odette-btn-primary {
        background: var(--v2-primary-bg) !important;
        color: var(--v2-ink, #0F1520) !important;
    }
    body.v2 .v2-btn.is-pri:hover,
    body.v2 .v2-pd-btn.is-pri:hover,
    body.v2 .wp-cta-pri:hover,
    body.v2 .v2-pos-empty-act.is-pri:hover,
    body.v2 .v2-blank-act:hover,
    body.v2 .v2-need-fund:hover,
    body.v2 .v2-connect-main:hover,
    body.v2 #connect-web3modal-btn:hover,
    body.v2 #portfolio-section .pf-btn-pri:hover,
    body.v2 #scoreboard-cards .sbc-stage-btn-pri:hover,
    body.v2 #referral-section #referral-connect-btn:hover,
    body.v2 .alp-create:hover,
    body.v2 .odette-btn-primary:hover {
        background: #FFFFFF !important;
        color: var(--v2-ink, #0F1520) !important;
        filter: none;
    }
    body.v2 .v2-btn.is-ghost {
        background: transparent !important;
        box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14) !important;
        color: var(--text-secondary) !important;
    }
    body.v2 .v2-btn.is-danger { background: var(--negative, #E86A62) !important; color: var(--v2-on-negative) !important; }
    body.v2 .v2-btn.is-money { background: var(--positive, #5EDD9C) !important; color: var(--v2-on-green) !important; }
    body.v2 .v2-btn:disabled,
    body.v2 .odette-btn-primary:disabled { opacity: .45; cursor: default; }

    /* topbar fix: hidden means hidden — the Bootstrap display utilities on
       the balance chip and the Deposit button beat the UA [hidden] rule */
    body.v2 #v2-balance-chip[hidden],
    body.v2 #v2-connect-btn[hidden] { display: none !important; }
    /* disconnected: ONE Connect wallet button; the three ways in live in the
       wallet popover it opens (the originals stay as click proxies) */
    body.v2 #wallet-status #connect-web3modal-btn,
    body.v2 #wallet-status #connect-base-account-btn,
    body.v2 #wallet-status #use-in-browser-wallet-btn { display: none !important; }
    body.v2 #wallet-status:not(.not-connected) #v2-connect-btn,
    body.v2 #wallet-status.connected #v2-connect-btn { display: none !important; }
    body.v2 .header-wallet-pill .connection-dot { width: 7px; height: 7px; border-radius: 50% !important; }
    body.v2 .header-wallet-pill .header-wallet-chevron { font-size: 11px; color: var(--text-secondary); opacity: 1; margin-left: 2px; }
    body.v2 .hdr-pill-count { background: var(--v2-sky, #7DD3FC) !important; color: #07131C !important; border: 0; }

    /* the connect stack in the ticket keeps its full-width column */
    body.v2 .v2-connect-main { width: 100%; height: 36px !important; }
    body.v2 .v2-connect-alt { flex: 1 1 0; }
    body.v2 .wp-cta { flex: 1; }

    /* the need row: the number is a plain sentence, the button is the family */
    body.v2 .v2-need {
        background: transparent;
        color: var(--text-secondary);
        font-size: 0.75rem;
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
    }

    /* ---- 4 · the switcher --------------------------------------------- */
    body.v2 .view-text-links,
    body.v2 .v2-ticket-tabs,
    body.v2 .v2-fund-tabs,
    body.v2 .v2-bell-tabs,
    body.v2 #v2-day-chips,
    body.v2 #portfolio-section .pf-chips:not([hidden]),
    body.v2 #portfolio-section .pf-views,
    body.v2 #scoreboard-cards .sbc-sorts {
        display: inline-flex;
        align-items: stretch;
        gap: 2px !important;
        padding: 2px !important;
        background: var(--panel-sunken, #070A11) !important;
        border: 0 !important;
        border-radius: 7px;
        box-shadow: none !important;
    }
    body.v2 #v2-day-chips { margin-right: 10px; }
    body.v2 .v2-ticket-tabs { display: flex; margin: 14px 0 12px; }
    body.v2 .v2-bell-tabs { display: flex; }
    body.v2 .v2-fund-tabs { display: flex; }
    body.v2 #basic-view-container:has(#v2-view-region[data-v2-view="advanced"]) #v2-day-chips,
    body.v2 #basic-view-container:has(#v2-view-region[data-v2-view="basic"]) #v2-day-chips { display: inline-flex; }

    body.v2 .view-text-links .view-link,
    body.v2 .v2-ticket-tab,
    body.v2 .v2-fund-tab,
    body.v2 .v2-bell-tab,
    body.v2 .v2-chain-tab,
    body.v2 #portfolio-section .pf-chip,
    body.v2 #portfolio-section .pf-view,
    body.v2 #scoreboard-cards .sbc-sort {
        box-sizing: border-box !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        height: 24px !important;
        min-height: 0 !important;
        padding: 0 10px !important;
        border: 0 !important;
        border-radius: 5px !important;
        background: transparent !important;
        box-shadow: none !important;
        color: var(--text-muted) !important;
        font-family: var(--sans) !important;
        font-variant-numeric: tabular-nums;
        font-size: 0.75rem !important;
        font-weight: 500 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
        line-height: 1 !important;
        text-decoration: none !important;
        white-space: nowrap;
        cursor: pointer;
        transition: background-color 120ms ease, color 120ms ease;
    }
    body.v2 .v2-ticket-tab,
    body.v2 .v2-bell-tab { flex: 1 1 0; }
    body.v2 .view-text-links .view-link:hover,
    body.v2 .v2-ticket-tab:hover,
    body.v2 .v2-fund-tab:hover,
    body.v2 .v2-bell-tab:hover,
    body.v2 .v2-chain-tab:hover,
    body.v2 #portfolio-section .pf-chip:hover,
    body.v2 #portfolio-section .pf-view:hover,
    body.v2 #scoreboard-cards .sbc-sort:hover { color: var(--text-secondary) !important; background: transparent !important; }
    body.v2 .view-text-links .view-link.active,
    body.v2 .v2-ticket-tab.is-active,
    body.v2 .v2-fund-tab.is-active,
    body.v2 .v2-bell-tab.is-active,
    body.v2 .v2-chain-tab.is-active,
    body.v2 #portfolio-section .pf-chip.active,
    body.v2 #portfolio-section .pf-view.active,
    body.v2 #scoreboard-cards .sbc-sort.active {
        background: var(--v2-chip, #232C42) !important;
        color: var(--text-primary, #F5F7FA) !important;
        font-weight: 500 !important;
    }
    /* Mark all read on the header line: bare text, subordinate to the
       title, spaced by .alp-head's own gap rather than its own padding. */
    body.v2 .alp-head .v2-bell-read {
        flex: 0 0 auto;
        height: 24px;
        display: inline-flex;
        align-items: center;
        padding: 0;
        font-size: 0.75rem;
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text-muted);
    }

    /* ---- 5 · colour: status is a word, never a chip ------------------- */
    body.v2 .v2-pos-status { color: var(--text-muted); }
    body.v2 .v2-pos-status.is-paid,
    body.v2 .v2-pos-status.is-open { color: var(--text-primary); }
    body.v2 .v2-pos-status.is-warn { color: var(--text-secondary); }
    body.v2 .wp-badge-warn {
        background: var(--v2-chip, #232C42);
        color: var(--text-secondary);
        border: 0;
    }

    /* ---- 6 · the empty face: one muted sentence + at most one button --- */
    body.v2 .v2-pos-empty {
        gap: 4px;
        padding: 22px 16px 20px;
    }
    body.v2 .v2-pos-empty > svg { display: none; }
    body.v2 .v2-pos-empty b {
        font-size: 0.75rem;
        font-weight: 500;
        color: var(--text-secondary);
    }
    body.v2 .v2-pos-empty > span {
        font-size: 0.75rem;
        color: var(--text-muted);
    }
    body.v2 .v2-pos-empty-act { margin-top: 8px; }

    /* ---- 7 · the payoff ghost: one sentence, no drawing ---------------- */
    body.v2 .v2-payoff-ghost > svg { opacity: .55; }
}


/* ==========================================================================
   ROUND 13 · MODALS AND POPOVERS ON THE QUIET SHELL (Odette Pages canvas,
   "Modals, quiet" + the Odette Modals canvas). One shell: the panel tone,
   radius 12, no border, a 16px title alone with ✕, the content, one
   full-width primary (or two halves). Fields on the sunken surface (r6).
   Notices are a muted sentence. Lanes are the segmented switcher. Green
   only for money (the confirm button). Later-in-file: terminal.
   ========================================================================== */
@media (min-width: 992px) {
    /* ---- the shell ---- */
    body.v2 #depositModal .modal-content,
    body.v2 #swapModal .modal-content,
    body.v2 #funding-options-modal .modal-content,
    body.v2 #trade-confirm-modal .modal-content,
    body.v2 #position-detail-modal .modal-content,
    body.v2 #quick-wallet-explanation .modal-content,
    body.v2 #import-private-key-modal .modal-content {
        background: var(--card-bg, #0E1322) !important;
        border: 0 !important;
        border-radius: 12px !important;
        box-shadow: 0 24px 60px rgba(0, 0, 0, .55) !important;
        height: auto;
        overflow: hidden;
    }
    body.v2 #depositModal .modal-dialog,
    body.v2 #swapModal .modal-dialog,
    body.v2 #funding-options-modal .modal-dialog { max-width: 440px; }
    body.v2 #trade-confirm-modal .modal-dialog { max-width: 420px; }
    body.v2 #quick-wallet-explanation .modal-dialog,
    body.v2 #import-private-key-modal .modal-dialog { max-width: 460px; }

    body.v2 .odette-modal-header,
    body.v2 #trade-confirm-modal .modal-header,
    body.v2 #position-detail-modal .modal-header,
    body.v2 #quick-wallet-explanation .modal-header,
    body.v2 #import-private-key-modal .modal-header {
        display: flex;
        align-items: center;
        gap: 10px;
        min-height: 0;
        padding: 16px 20px 0 !important;
        border: 0 !important;
        background: transparent !important;
        box-shadow: none !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
    }
    body.v2 .odette-modal-header-icon { display: none !important; }
    body.v2 .odette-modal-title,
    body.v2 #trade-confirm-modal .modal-title,
    body.v2 #position-detail-modal .modal-title,
    body.v2 #quick-wallet-explanation .modal-title,
    body.v2 #import-private-key-modal .modal-title {
        display: block;
        margin: 0;
        font-family: var(--sans);
        font-size: 16px;
        font-weight: 600;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text-primary);
        line-height: 1.2;
    }
    body.v2 #import-private-key-modal .modal-title i { display: none; }
    body.v2 #quick-wallet-explanation .quick-wallet-modal-title { font-size: 16px !important; letter-spacing: 0 !important; text-transform: none !important; }
    body.v2 .odette-modal-close,
    body.v2 .modal-header .btn-close {
        margin: 0 0 0 auto !important;
        width: 24px;
        height: 24px;
        padding: 0;
        border: 0;
        background-color: transparent !important;
        box-shadow: none !important;
        opacity: .6;
        color: var(--text-secondary);
        font-size: 14px;
    }
    body.v2 .modal-header .btn-close { background-size: 11px; }
    body.v2 .odette-modal-close:hover,
    body.v2 .modal-header .btn-close:hover { opacity: 1; }

    body.v2 .odette-modal-body,
    body.v2 #trade-confirm-modal .modal-body,
    body.v2 #position-detail-modal .modal-body,
    body.v2 #quick-wallet-explanation .modal-body,
    body.v2 #import-private-key-modal .modal-body {
        padding: 16px 20px 20px !important;
        background: transparent !important;
        font-size: 12px;
        color: var(--text-secondary);
    }

    body.v2 .odette-modal-footer,
    body.v2 #trade-confirm-modal .modal-footer,
    body.v2 #position-detail-modal .modal-footer,
    body.v2 #quick-wallet-explanation .modal-footer,
    body.v2 #import-private-key-modal .modal-footer {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        gap: 8px;
        padding: 0 20px 20px !important;
        margin: 0;
        border: 0 !important;
        background: transparent !important;
    }
    /* footer buttons: the family, at 38px, sharing the width */
    body.v2 .odette-modal-footer > button,
    body.v2 .odette-modal-footer > a,
    body.v2 #trade-confirm-modal .modal-footer .btn,
    body.v2 #position-detail-modal .modal-footer .v2-pd-btn,
    body.v2 #quick-wallet-explanation .modal-footer .btn,
    body.v2 #import-private-key-modal .modal-footer .btn {
        flex: 1 1 0;
        height: 38px !important;
        font-size: 13px !important;
        font-weight: 600 !important;
        padding: 0 14px !important;
    }
    body.v2 .odette-modal-footer i,
    body.v2 #quick-wallet-explanation .modal-footer i,
    body.v2 #import-private-key-modal .modal-footer i { display: none; }

    /* the Bootstrap buttons inside these dialogs take the family */
    body.v2 #quick-wallet-explanation .btn,
    body.v2 #import-private-key-modal .btn,
    body.v2 #trade-confirm-modal .modal-footer .btn {
        box-sizing: border-box !important;
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        gap: 6px;
        height: 30px;
        padding: 0 12px;
        border: 0 !important;
        border-radius: 6px !important;
        box-shadow: none !important;
        background: var(--v2-chip, #232C42) !important;
        color: var(--text-primary) !important;
        font-family: var(--sans) !important;
        font-size: 12px;
        font-weight: 500;
        letter-spacing: 0 !important;
        text-transform: none !important;
        line-height: 1 !important;
        white-space: nowrap;
        cursor: pointer;
    }
    body.v2 #quick-wallet-explanation .btn[hidden], body.v2 #quick-wallet-explanation .btn[style*="display: none"],
    body.v2 #import-private-key-modal .btn[hidden], body.v2 #import-private-key-modal .btn[style*="display: none"],
    body.v2 #trade-confirm-modal .modal-footer .btn[style*="display: none"] { display: none !important; }
    body.v2 #quick-wallet-explanation .btn-primary,
    body.v2 #import-private-key-modal .btn-primary { background: var(--v2-primary-bg) !important; color: var(--v2-ink, #0F1520) !important; }
    body.v2 #import-private-key-modal .btn-danger { background: var(--negative, #E86A62) !important; color: var(--v2-on-negative) !important; }
    body.v2 #import-private-key-modal .btn:disabled { opacity: .45; }
    body.v2 #quick-wallet-explanation .btn i { display: none; }

    /* ---- shared pieces: the key/value list, the note ---- */
    body.v2 .v2-kv {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 12px;
        min-height: 26px;
        font-size: 12px;
    }
    body.v2 .v2-kv > span { color: var(--text-muted); white-space: nowrap; }
    body.v2 .v2-kv > em {
        font-style: normal;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-weight: 500;
        color: var(--text-primary);
        text-align: right;
        min-width: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    body.v2 .v2-kv > em.is-pos { color: var(--positive); }
    body.v2 .v2-fund-note {
        margin: 14px 0 0;
        font-size: 12px;
        line-height: 1.5;
        color: var(--text-muted);
    }

    /* ---- fund your wallet ---- */
    body.v2 #depositModal .v2-fund-tabs { margin: 0 0 16px; }
    body.v2 #depositModal .v2-fund-tab { flex: 1 1 0; }
    body.v2 #depositModal .deposit-panel { display: block; padding: 0; background: transparent; border: 0; }
    body.v2 #depositModal .deposit-network-badge,
    body.v2 #depositModal .deposit-desc,
    body.v2 #depositModal .deposit-warning { display: none !important; }
    body.v2 #depositModal .deposit-addr-card {
        display: flex;
        flex-direction: row;
        align-items: center;
        text-align: left;
        gap: 14px;
        padding: 0;
        margin: 0;
        border: 0 !important;
        background: transparent !important;
        border-radius: 0 !important;
    }
    body.v2 .v2-qr {
        flex: none;
        width: 96px;
        height: 96px;
        padding: 6px;
        background: #F5F7FA;
        border-radius: 6px;
    }
    body.v2 .v2-qr[hidden] { display: none; }
    body.v2 .v2-qr svg { display: block; width: 100%; height: 100%; }
    body.v2 .v2-fund-addr-col { min-width: 0; flex: 1 1 auto; }
    body.v2 .v2-fund-k { font-size: 12px; color: var(--text-muted); margin-bottom: 4px; }
    body.v2 #depositModal .deposit-addr-text {
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 12px;
        line-height: 1.45;
        color: var(--text-primary);
        word-break: break-all;
        white-space: normal;
        text-align: left;
        padding: 0;
        margin: 0;
        background: transparent;
        border: 0;
    }
    body.v2 #v2-fund-card { display: block; }
    body.v2 #v2-fund-card[hidden] { display: none !important; }
    body.v2 #v2-fund-foot .odette-btn-secondary[data-bs-dismiss] { display: none !important; }
    body.v2 #v2-fund-foot .v2-fund-copy { display: inline-flex !important; width: 100%; }
    body.v2 #v2-fund-foot .v2-fund-copy[hidden] { display: none !important; }
    body.v2 #v2-fund-foot .v2-fund-copy i { display: none; }
    body.v2 #v2-fund-foot #v2-fund-card-go[hidden] { display: none !important; }

    /* ---- from wallet (the swap modal as the third lane) ---- */
    body.v2 #swapModal .v2-fund-tabs { margin: 0 0 16px; }
    body.v2 #swapModal .v2-fund-tab { flex: 1 1 0; }
    body.v2 #swapModal .swap-panel { padding: 0; background: transparent; border: 0; border-radius: 0; }
    body.v2 #swapModal .swap-card {
        background: var(--panel-sunken, #070A11) !important;
        border: 0 !important;
        border-radius: 6px !important;
        padding: 10px 14px;
    }
    body.v2 #swapModal .swap-card-header {
        display: flex;
        justify-content: space-between;
        padding: 0;
        margin: 0;
        background: transparent !important;
        border: 0;
        font-size: 11px;
        color: var(--text-muted);
    }
    body.v2 #swapModal .swap-card-label { font-size: 11px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-muted); }
    body.v2 #swapModal .swap-card-balance { font-size: 11px; color: var(--text-muted); }
    body.v2 #swapModal .swap-max-link { color: var(--v2-sky); font-size: 11px; font-weight: 500; letter-spacing: 0; text-transform: none; background: none; border: 0; padding: 0 0 0 4px; }
    body.v2 #swapModal .swap-card-row { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
    body.v2 #swapModal .swap-amount-input {
        flex: 1;
        min-width: 0;
        background: transparent;
        border: 0;
        padding: 0;
        font-family: var(--num);
        font-variant-numeric: tabular-nums;
        font-size: 22px;
        font-weight: 600;
        color: var(--text-primary);
        box-shadow: none;
    }
    body.v2 #swapModal .swap-token-btn,
    body.v2 #swapModal .swap-token-display {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        height: 24px;
        padding: 0 9px;
        border: 0;
        border-radius: 5px !important;
        background: var(--v2-chip, #232C42);
        color: var(--text-primary);
        font-size: 11px;
        font-weight: 500;
    }
    body.v2 #swapModal .swap-token-btn img,
    body.v2 #swapModal .swap-token-display img { width: 14px; height: 14px; }
    body.v2 #swapModal .swap-arrow-divider { margin: 4px 0; display: flex; justify-content: center; }
    body.v2 #swapModal .swap-arrow-circle { width: 22px; height: 22px; background: var(--v2-chip); border: 0; color: var(--text-muted); font-size: 11px; }
    body.v2 #swapModal .swap-quick-amounts { display: flex; gap: 6px; margin-top: 10px; }
    body.v2 #swapModal .swap-quick-chip {
        flex: 1 1 0;
        height: 24px;
        padding: 0;
        border: 0;
        border-radius: 5px !important;
        background: var(--v2-chip, #232C42);
        color: var(--text-primary);
        font-family: var(--num);
        font-size: 11px;
        font-weight: 500;
    }
    body.v2 #swapModal .v2-swap-facts { margin-top: 12px; }
    body.v2 #swapModal .odette-modal-footer i { display: none; }

    /* The token menu was hostage to its trigger. app.css gives
       .odette-dropdown-menu `width: 100%; min-width: auto`, so Popper sized it
       to the 76px chip — and its items are styled for a roomier list (18px
       icon + 12px side padding), leaving ~26px for the label. Measured: the
       item box is 67.6px while "CBBTC" needs 80px and "WETH" 75px, so the
       labels physically overflowed the row and WETH touched the menu edge.
       A 76px menu reads as a widened chip, not a list.

       Scoped to #swapModal on purpose: .odette-dropdown-menu is also used by
       the funding modal's amount and asset menus (app.js), which have not been
       measured — a global min-width would move those too. Aligned to the
       trigger's RIGHT edge because the trigger sits at x≈845 in a card whose
       right edge is ≈930: growing rightward from the left edge would overrun
       the card by ~47px. */
    body.v2 #swapModal .odette-dropdown-menu {
        width: auto !important;
        min-width: 132px !important;
        padding: 4px !important;
        border-radius: 6px !important;
        margin-top: 4px !important;
        left: auto !important;
        right: 0 !important;
    }

    /* round 13: 32px rows, 12px/500 sentence case, 14px coin marks (the same
       size the asset chips use) — the menu was 36px rows at 12.48px with 18px
       icons, none of which are system values. */
    body.v2 #swapModal .odette-dropdown-menu .dropdown-item {
        height: 32px;
        padding: 0 12px !important;
        margin: 0 !important;
        gap: 6px;
        display: flex;
        align-items: center;
        font-size: 12px !important;
        font-weight: 500;
        line-height: 1;
        border-radius: 5px !important;
        color: var(--text-primary) !important;
    }

    body.v2 #swapModal .odette-dropdown-menu .dropdown-item img {
        width: 14px;
        height: 14px;
        flex: none;
    }

    /* ---- confirm trade ---- */
    body.v2 #trade-confirm-modal .bottom-sheet-handle,
    body.v2 #trade-confirm-modal .order-countdown-text,
    body.v2 #trade-confirm-modal .modal-trade-summary,
    body.v2 #trade-confirm-modal .profit-scenarios { display: none !important; }
    body.v2 #trade-confirm-modal .trade-confirm-header-left { display: flex; align-items: center; min-width: 0; }
    body.v2 #trade-confirm-modal #trade-error-alert {
        margin: 0 0 12px;
        padding: 0;
        border: 0;
        background: transparent;
        font-size: 12px;
        color: var(--text-secondary);
    }
    body.v2 .v2-cf-id { display: flex; align-items: center; gap: 8px; }
    body.v2 .v2-cf-id b { font-size: 15px; font-weight: 600; color: var(--text-primary); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    body.v2 .v2-cf-quote {
        margin-left: auto;
        flex: none;
        display: inline-flex;
        align-items: center;
        gap: 4px;
        height: 24px;
        padding: 0 9px;
        border-radius: 5px;
        background: var(--v2-chip, #232C42);
        font-size: 11px;
        color: var(--text-primary);
    }
    body.v2 .v2-cf-quote em { font-style: normal; font-variant-numeric: tabular-nums; }
    body.v2 .v2-cf-list { margin: 12px 0 0; }
    body.v2 .v2-cf-payoff,
    body.v2 #v2-pd-payoff {
        position: relative;
        height: 96px;
        margin: 12px 0 0;
        background: var(--panel-sunken, #070A11);
        border: 0 !important;
        border-radius: 6px;
        overflow: hidden;
    }
    body.v2 .v2-cf-payoff svg,
    body.v2 #v2-pd-payoff svg { display: block; width: 100%; height: 100%; }
    body.v2 .v2-cf-payoff i,
    body.v2 #v2-pd-payoff i {
        position: absolute;
        top: 6px;
        font-style: normal;
        font-size: 10px;
        color: var(--text-muted);
        white-space: nowrap;
    }
    body.v2 .v2-cf-cap-l { left: 10px; }
    body.v2 .v2-cf-cap-r { right: 10px; }
    body.v2 #trade-confirm-modal .form-check {
        display: flex;
        align-items: center;
        gap: 8px;
        margin: 14px 0 0 !important;
        padding: 0 !important;
        border: 0 !important;
        background: transparent !important;
        font-size: 12px;
        color: var(--text-muted);
    }
    body.v2 #trade-confirm-modal .form-check-input {
        margin: 0;
        width: 14px;
        height: 14px;
        border-radius: 4px !important;
        border: 0;
        background-color: var(--v2-chip, #232C42);
        box-shadow: none;
    }
    body.v2 #trade-confirm-modal .form-check-input:checked { background-color: var(--v2-sky, #7DD3FC); }
    body.v2 #trade-confirm-modal .form-check-label { color: var(--text-muted); }
    body.v2 #trade-confirm-modal .modal-footer .btn[data-bs-dismiss] { display: none !important; }
    body.v2 #confirm-trade-btn,
    body.v2 #trade-confirm-modal .modal-footer #confirm-trade-btn.btn {
        width: 100%;
        height: 38px !important;
        border: 0 !important;
        border-radius: 6px !important;
        background: var(--positive, #5EDD9C) !important;
        background-image: none !important;
        box-shadow: none !important;
        animation: none !important;
        color: var(--v2-on-green) !important;
        font-size: 13px !important;
        font-weight: 600 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
    }
    body.v2 #trade-confirm-modal .modal-footer #confirm-trade-btn.btn::before,
    body.v2 #trade-confirm-modal .modal-footer #confirm-trade-btn.btn::after { display: none !important; }
    body.v2 #trade-confirm-modal .modal-footer #confirm-trade-btn.btn:disabled { opacity: .5; }
    /* the app paints a wave <canvas> INSIDE its buy buttons; on the v2 flex
       button it is a 380px flex child that shoves the label off centre
       (user, 2026-09-07: "the text is not aligned") — the quiet system has
       no wave */
    body.v2 #confirm-trade-btn .wave-canvas, body.v2 #inline-confirm-trade-btn .wave-canvas, body.v2 #trade-now-btn .wave-canvas { display: none !important; }

    /* ---- position: centred, 460px ---- */
    body.v2 #position-detail-modal .modal-dialog,
    body.v2 #position-detail-modal.show .modal-dialog {
        position: relative;
        top: auto;
        right: auto;
        bottom: auto;
        margin: 1.75rem auto;
        width: auto !important;
        max-width: 460px !important;
        display: flex;
        transform: none;
        transition: none;
    }
    body.v2 #position-detail-modal .modal-content { height: auto; overflow: visible; border-left: 0; }
    body.v2 #position-detail-modal .position-detail-modal-header { padding: 16px 20px 0 !important; }
    body.v2 #position-detail-modal .position-detail-modal-title { display: block; font-size: 16px !important; font-weight: 600 !important; letter-spacing: 0 !important; text-transform: none !important; color: var(--text-primary) !important; }
    body.v2 #position-detail-modal .position-detail-modal-body { padding: 14px 20px 20px !important; }
    body.v2 #position-detail-modal .pd-identity { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; }
    body.v2 #position-detail-modal .pd-logo { display: none; }
    body.v2 #position-detail-modal #position-modal-title {
        font-family: var(--sans) !important;
        font-size: 15px !important;
        font-weight: 600 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
        color: var(--text-primary) !important;
        margin: 0;
    }
    body.v2 .v2-pd-fig em .countdown { color: inherit !important; font: inherit; }
    body.v2 #v2-pd-status,
    body.v2 #v2-pd-status.is-open,
    body.v2 #v2-pd-status.is-paid,
    body.v2 #v2-pd-status.is-exp {
        margin-left: auto;
        display: inline-flex;
        align-items: center;
        height: 24px;
        padding: 0 9px;
        border-radius: 5px;
        background: var(--v2-chip, #232C42);
        color: var(--text-primary);
        font-size: 11px;
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
    }
    body.v2 #v2-pd-tiles { display: flex; gap: 28px; margin: 0 0 14px; }
    body.v2 .v2-pd-fig { min-width: 0; }
    body.v2 .v2-pd-fig b { display: block; font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--text-muted); margin-bottom: 4px; }
    body.v2 .v2-pd-fig em {
        display: block;
        font-style: normal;
        font-family: var(--sans);
        font-variant-numeric: tabular-nums;
        font-size: 22px;
        font-weight: 600;
        letter-spacing: -0.01em;
        line-height: 1.15;
        color: var(--text-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    body.v2 .v2-pd-fig em.is-up { color: var(--positive); }
    body.v2 .v2-pd-fig em.is-dn { color: var(--negative); }
    body.v2 .v2-pd-fig i { display: block; font-style: normal; font-size: 11px; color: var(--text-muted); margin-top: 4px; white-space: nowrap; }
    body.v2 #v2-pd-payoff { margin: 0 0 12px; }
    body.v2 #v2-pd-terms { margin: 0; }
    body.v2 #v2-pd-terms .v2-pd-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; min-height: 26px; padding: 0; border: 0; font-size: 12px; }
    body.v2 #v2-pd-terms .v2-pd-row span { color: var(--text-muted); }
    body.v2 #v2-pd-terms .v2-pd-row em { font-weight: 500; color: var(--text-primary); max-width: 62%; }
    body.v2 #position-detail-modal #position-scenarios-block { display: none !important; }
    body.v2 #position-detail-modal .modal-footer:has(#v2-pd-share) { padding: 0 20px 20px !important; border: 0 !important; }
    body.v2 #position-detail-modal .v2-pd-btn { text-transform: none; }

    /* ---- quick wallet: intro sentence, three numbered steps, a quiet import link ---- */
    body.v2 #quick-wallet-explanation .quick-wallet-warning {
        margin: 0 0 14px !important;
        padding: 0;
        border: 0;
        background: transparent;
        font-size: 12px;
        line-height: 1.5;
        color: var(--text-secondary);
    }
    body.v2 #quick-wallet-explanation .modal-body { counter-reset: qw; }
    body.v2 #quick-wallet-explanation .quick-wallet-address-section {
        position: relative;
        margin: 0 !important;
        padding: 0 0 16px 34px !important;
        border: 0 !important;
        counter-increment: qw;
    }
    body.v2 #quick-wallet-explanation .quick-wallet-address-section::before {
        content: counter(qw);
        position: absolute;
        left: 0;
        top: 0;
        width: 22px;
        height: 22px;
        border-radius: 50% !important;
        background: var(--v2-chip, #232C42);
        color: var(--text-primary);
        font-size: 10.5px;
        font-weight: 700;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    body.v2 #quick-wallet-explanation .quick-wallet-address-section:first-of-type::before { background: var(--positive); color: #07120B; }
    body.v2 #quick-wallet-explanation .quick-wallet-address-section::after {
        content: '';
        position: absolute;
        left: 11px;
        top: 26px;
        bottom: 4px;
        width: 1px;
        background: var(--v2-hair-strong, rgba(255, 255, 255, .13));
    }
    body.v2 #quick-wallet-explanation .quick-wallet-address-section:last-of-type::after { display: none; }
    body.v2 #quick-wallet-explanation .quick-wallet-address-section:last-of-type { padding-bottom: 0 !important; }
    body.v2 #quick-wallet-explanation .quick-wallet-address-label { display: none; }
    body.v2 #quick-wallet-explanation .qw-step-t { margin: 3px 0 6px !important; font-size: 12.5px; font-weight: 600; color: var(--text-primary); }
    body.v2 #quick-wallet-explanation .qw-step-s { margin: 0 0 8px !important; font-size: 12px; color: var(--text-muted); line-height: 1.5; }
    body.v2 #quick-wallet-explanation .quick-wallet-address-wrapper {
        display: flex;
        align-items: center;
        height: 38px;
        padding: 0 12px;
        background: var(--panel-sunken, #070A11);
        border: 0;
        border-radius: 8px !important;
    }
    body.v2 #quick-wallet-explanation .quick-wallet-address-link,
    body.v2 #quick-wallet-explanation .quick-wallet-address-link:hover {
        display: flex;
        align-items: center;
        gap: 6px;
        min-width: 0;
        color: var(--text-primary);
        text-decoration: none;
    }
    body.v2 #quick-wallet-explanation .quick-wallet-address-text { font-family: var(--num); font-variant-numeric: tabular-nums; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    body.v2 #quick-wallet-explanation .quick-wallet-address-link i { display: inline; font-size: 10px; color: var(--text-muted); }
    body.v2 #quick-wallet-explanation .quick-wallet-copy-btn { height: 26px !important; padding: 0 9px !important; font-size: 11px !important; }
    body.v2 #quick-wallet-explanation .qw-step-acts { display: flex; gap: 6px; }
    body.v2 #quick-wallet-explanation .qw-step-acts .btn { height: 32px !important; }
    body.v2 #quick-wallet-explanation #modal-save-key { height: 32px !important; }
    body.v2 #quick-wallet-explanation .modal-footer { justify-content: space-between; }
    body.v2 #quick-wallet-explanation #import-private-key-trigger,
    body.v2 #quick-wallet-explanation #import-private-key-trigger:hover {
        flex: 0 1 auto;
        height: auto !important;
        padding: 0 !important;
        background: transparent !important;
        color: var(--text-muted) !important;
        font-size: 11px !important;
        font-weight: 500 !important;
    }
    body.v2 #quick-wallet-explanation #import-private-key-trigger:hover { color: var(--v2-sky) !important; }
    body.v2 #quick-wallet-explanation #qw-done-btn { flex: 0 0 auto; width: 96px; }

    /* ---- import private key: stepper, plain sentences, the one red commit ---- */
    body.v2 #import-private-key-modal .modal-content.border-danger { border: 0 !important; }
    body.v2 #import-private-key-modal .modal-header.bg-danger { background: transparent !important; color: var(--text-primary) !important; }
    body.v2 #v2-import-steps { display: flex; align-items: center; gap: 6px; margin: 0 0 16px; }
    body.v2 #v2-import-steps .v2-step {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-family: var(--num);
        font-size: 10.5px;
        font-weight: 600;
        color: var(--text-muted);
    }
    body.v2 #v2-import-steps .v2-step + .v2-step::before { content: ''; width: 24px; height: 1px; background: var(--v2-hair-strong, rgba(255, 255, 255, .13)); margin-right: 6px; }
    body.v2 #v2-import-steps .v2-step i {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-style: normal;
        font-size: 0.625rem;
        background: var(--v2-chip, #232C42);
        color: var(--text-secondary);
    }
    body.v2 #v2-import-steps .v2-step,
    body.v2 #v2-import-steps .v2-step i {
        height: auto;
        padding: 0;
        border: 0;
        box-shadow: none;
        background: transparent;
        flex: none;
    }
    body.v2 #v2-import-steps .v2-step i { width: 18px; height: 18px; background: var(--v2-chip, #232C42); }
    body.v2 #import-private-key-modal .alert { display: block !important; }
    body.v2 #import-private-key-modal .form-check { border: 0 !important; background: transparent !important; }
    body.v2 #v2-import-steps .v2-step.is-on { color: var(--text-primary); }
    body.v2 #v2-import-steps .v2-step.is-on i { background: var(--v2-sky); color: #07131C; }
    body.v2 #v2-import-steps .v2-step.is-done i { background: var(--positive); color: #07120B; }
    body.v2 #import-private-key-modal .alert {
        margin: 0 0 12px;
        padding: 0;
        border: 0;
        background: transparent !important;
        font-size: 12px;
        line-height: 1.5;
        color: var(--text-secondary);
    }
    body.v2 #import-private-key-modal .alert-danger { color: var(--negative); }
    body.v2 #import-private-key-modal .alert-danger strong { color: var(--negative); }
    body.v2 #import-private-key-modal .alert-heading { font-size: 12px; font-weight: 600; margin: 0 0 4px; }
    body.v2 #import-private-key-modal .alert-heading i { display: none; }
    body.v2 #import-private-key-modal .alert hr { display: none; }
    body.v2 #import-private-key-modal .alert p { margin: 0; }
    body.v2 #import-private-key-modal .alert .small { font-size: 12px; margin-top: 4px; }
    body.v2 #import-private-key-modal code { font-family: var(--num); font-size: 12px; color: var(--text-primary); background: transparent; }
    body.v2 #import-private-key-modal .modal-body p,
    body.v2 #import-private-key-modal .modal-body ul { font-size: 12px; color: var(--text-secondary); line-height: 1.6; }
    body.v2 #import-private-key-modal .modal-body ul { padding-left: 16px; margin: 0 0 12px; }
    body.v2 #import-private-key-modal .form-check { display: flex; align-items: flex-start; gap: 8px; padding: 0; margin: 10px 0 0 !important; font-size: 12px; color: var(--text-primary); }
    body.v2 #import-private-key-modal .form-check-input { margin: 1px 0 0; width: 14px; height: 14px; border: 0; border-radius: 4px; background-color: var(--v2-chip, #232C42); box-shadow: none; flex: none; }
    body.v2 #import-private-key-modal .form-check-input:checked { background-color: var(--v2-sky, #7DD3FC); }
    body.v2 #import-private-key-modal .form-check-label strong { font-weight: 500; }
    body.v2 #import-private-key-modal .form-label { font-size: 12px; color: var(--text-muted); }
    body.v2 #import-private-key-modal .form-control {
        height: 38px;
        padding: 0 12px;
        background: var(--panel-sunken, #070A11);
        border: 0;
        border-radius: 6px;
        color: var(--text-primary);
        font-size: 12px;
        box-shadow: none;
    }
    body.v2 #import-private-key-modal .form-text { font-size: 11px; color: var(--text-muted); }
    body.v2 #import-private-key-modal .modal-footer .btn { flex: 1 1 0; }
    body.v2 #import-private-key-modal .modal-footer .btn[style*="display: none"] { display: none !important; }

    /* ---- the wallet popover ---- */
    body.v2 #wallet-pop {
        width: 300px;
        padding: 0;
        border: 0 !important;
        border-radius: 12px !important;
        background: var(--card-bg, #0E1322);
        box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
    }
    body.v2 #wallet-pop .wp-header { padding: 12px 12px 10px; }
    body.v2 #wallet-pop .wp-avatar-gradient { border-radius: 50% !important; }
    body.v2 #wallet-pop .wp-balance-card {
        margin: 0 10px;
        padding: 12px !important;
        background: var(--panel-sunken, #070A11) !important;
        border: 0 !important;
        border-radius: 10px !important;
    }
    body.v2 #wallet-pop .wp-balance-label { font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--text-muted); margin-bottom: 4px; }
    body.v2 #wallet-pop .wp-balance-value { font-family: var(--sans); font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
    body.v2 #wallet-pop .wp-cta { height: 32px !important; }
    body.v2 #wallet-pop .wp-menu { padding: 8px 4px 6px; }
    body.v2 #wallet-pop .wp-row { height: 34px; padding: 0 8px; border-radius: 8px !important; font-size: 12px; color: var(--text-primary); }
    body.v2 #wallet-pop .wp-row:hover { background: rgba(255, 255, 255, .03); }
    body.v2 #wallet-pop .wp-row-end { font-size: 11px; }
    body.v2 #wallet-pop .wp-badge-warn { display: inline-flex; align-items: center; height: 20px; padding: 0 7px; border-radius: 5px !important; font-size: 10px; font-weight: 500; letter-spacing: 0; text-transform: none; }
    body.v2 #wallet-pop .wp-row-danger, body.v2 #wallet-pop .wp-row-danger:hover { color: var(--negative); }
    body.v2 #wallet-pop .wp-disconnected-state { padding: 20px 16px 16px; text-align: left; }
    body.v2 #wallet-pop .wp-disconnected-icon { display: none; }
    body.v2 #wallet-pop .wp-disconnected-title { font-family: var(--sans); font-size: 13px; font-weight: 600; letter-spacing: 0; color: var(--text-primary); margin: 0 0 4px; }
    body.v2 #wallet-pop .wp-disconnected-desc { font-size: 12px; color: var(--text-muted); margin: 0 0 12px; }
    body.v2 #wallet-pop .wp-connect-btn,
    body.v2 #wallet-pop .wp-connect-btn-alt {
        display: flex !important;
        width: 100%;
        height: 32px !important;
        margin: 0 0 6px !important;
        border: 0 !important;
        border-radius: 6px !important;
        background: var(--v2-primary-bg) !important;
        color: var(--v2-ink, #0F1520) !important;
        font-size: 12px !important;
        font-weight: 600 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
        transform: none !important;
        justify-content: center;
    }
    body.v2 #wallet-pop .wp-connect-btn-alt { background: var(--v2-chip, #232C42) !important; color: var(--text-primary) !important; font-weight: 500 !important; }
    body.v2 #wallet-pop .wp-connect-btn i { display: none; }

    /* ---- the bell popover ---- */
    body.v2 #alert-pop {
        width: 340px;
        border: 0 !important;
        border-radius: 12px !important;
        background: var(--card-bg, #0E1322);
        box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
    }
    body.v2 #alert-pop .alp-title { font-family: var(--sans); font-size: 13px; font-weight: 600; letter-spacing: 0; }
    body.v2 #alert-pop .alp-notif {
        margin: 12px 0 0;
        padding: 0;
        border: 0 !important;
        background: transparent !important;
        font-size: 12px;
        color: var(--text-muted);
    }
    body.v2 #alert-pop .alp-notif i { display: none; }
    /* border: 0 — app.css gives .alp-notif-btn `1px solid currentColor` plus
       0.15rem/0.5rem of padding to sit inside it. This rule zeroed the padding
       to make it a bare sky text action (transparent, 12px, sentence case) but
       left the border behind, so "Enable" sat with its glyphs touching the
       ring on all four sides. The border is the leftover, not the padding:
       bare text is what the rest of this popover uses (see Mark all read). */
    body.v2 #alert-pop .alp-notif-btn { height: auto !important; padding: 0 !important; border: 0 !important; background: transparent !important; color: var(--v2-sky) !important; font-size: 12px !important; text-transform: none !important; letter-spacing: 0 !important; }
    body.v2 #alert-pop .alp-form { gap: 8px; margin-top: 10px; }
    body.v2 #alert-pop .alp-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
    body.v2 #alert-pop .alp-field {
        gap: 2px;
        padding: 8px 12px;
        background: var(--panel-sunken, #070A11);
        border-radius: 6px;
    }
    body.v2 #alert-pop .alp-label { font-size: 11px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-muted); }
    body.v2 #alert-pop .alp-sel,
    body.v2 #alert-pop .alp-input,
    body.v2 #alert-pop .alp-price-field {
        height: 24px;
        padding: 0;
        border: 0 !important;
        border-radius: 0 !important;
        background: transparent !important;
        box-shadow: none !important;
        font-family: var(--num);
        font-size: 13px;
        font-weight: 600;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text-primary);
    }
    body.v2 #alert-pop .alp-price-field { display: flex; align-items: center; gap: 4px; }
    body.v2 #alert-pop .alp-price-unit { color: var(--text-muted); font-size: 12px; }
    body.v2 #alert-pop .alp-now { font-size: 11px; color: var(--text-muted); }
    body.v2 #alert-pop .alp-create { width: 100%; height: 32px !important; }
    body.v2 #alert-pop .alp-create i { display: none; }
    body.v2 #alert-pop .alp-divider { display: none; }
    body.v2 #alert-pop .alp-list-head { margin-top: 14px; padding: 0; }
    body.v2 #alert-pop .alp-list-head .t-label { font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--text-muted); }
    body.v2 #alert-pop .alp-list-n { font-size: 12px; }
    body.v2 #alert-pop .alp-item {
        min-height: 32px;
        padding: 6px 0;
        border: 0 !important;
        border-bottom: 1px solid var(--v2-hair) !important;
        border-radius: 0 !important;
        background: transparent !important;
        font-size: 12px;
    }
    body.v2 #alert-pop .alp-empty { font-size: 12px; color: var(--text-muted); padding: 8px 0; }
    body.v2 #alert-pop .alp-test { margin-top: 10px; padding: 0; border: 0; background: transparent; color: var(--v2-sky); font-size: 12px; }
    body.v2 #alert-pop .alp-test i { display: none; }

    /* ---- maker liquidity (public beta) ---- */
    body.v2 .beta-modal-content {
        width: 420px !important;
        max-width: 420px;
        padding: 0 !important;
        background: var(--card-bg, #0E1322) !important;
        border: 0 !important;
        border-radius: 12px !important;
        box-shadow: 0 24px 60px rgba(0, 0, 0, .55) !important;
    }
    body.v2 .beta-modal-header { padding: 16px 20px 0 !important; border: 0 !important; background: transparent !important; display: flex; align-items: center; }
    body.v2 .beta-label { font-size: 16px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text-primary); background: transparent; padding: 0; border: 0; }
    body.v2 .beta-modal-close { margin-left: auto; border: 0; background: transparent; color: var(--text-secondary); opacity: .6; font-size: 14px; }
    body.v2 .beta-modal-body { padding: 16px 20px 20px !important; }
    body.v2 .beta-info-item { display: none !important; }
    body.v2 #v2-liq { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
    body.v2 .v2-liq-fig { padding: 12px; background: var(--panel-sunken, #070A11); border-radius: 10px; }
    body.v2 .v2-liq-fig b { display: block; font-size: 12px; font-weight: 500; color: var(--text-muted); margin-bottom: 4px; }
    body.v2 .v2-liq-fig em { display: block; font-style: normal; font-family: var(--sans); font-variant-numeric: tabular-nums; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; color: var(--text-primary); white-space: nowrap; }
    body.v2 .v2-liq-fig i { display: block; font-style: normal; font-size: 11px; color: var(--text-muted); margin-top: 3px; }
    body.v2 #v2-beta-close { display: inline-flex !important; width: 100%; height: 38px !important; margin-top: 16px; font-size: 13px !important; font-weight: 600 !important; }

    /* ---- the share sheet in the shell ---- */
    body.v2 .v2-share-box {
        width: 480px;
        gap: 0;
        padding: 0 20px 20px;
        background: var(--card-bg, #0E1322);
        border-radius: 12px;
        box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
    }
    body.v2 .v2-share-head { display: flex; align-items: center; height: 48px; }
    body.v2 .v2-share-head b { font-size: 16px; font-weight: 600; color: var(--text-primary); }
    body.v2 .v2-share-x { margin-left: auto; border: 0; background: transparent; color: var(--text-secondary); opacity: .6; font-size: 13px; cursor: pointer; }
    body.v2 .v2-share-x:hover { opacity: 1; }
    body.v2 .v2-share-card { width: 440px; height: 231px; border-radius: 10px; border-color: var(--v2-hair); }
    body.v2 .v2-share-opts { display: flex; gap: 16px; margin: 12px 0 14px; }
    body.v2 .v2-share-ref, body.v2 .v2-share-addr { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: 12px; color: var(--text-primary); }
    body.v2 .v2-share-ref input, body.v2 .v2-share-addr input { margin: 0; width: 14px; height: 14px; accent-color: var(--v2-sky); }
    body.v2 .v2-share-actions { gap: 8px; }
    body.v2 .v2-share-actions button,
    body.v2 .v2-share-actions button:first-child {
        flex: 1 1 0;
        height: 38px;
        padding: 0 14px;
        border: 0;
        border-radius: 6px;
        box-shadow: none;
        background: var(--v2-chip, #232C42);
        color: var(--text-primary);
        font-size: 13px;
        font-weight: 500;
        letter-spacing: 0;
        text-transform: none;
    }
    body.v2 .v2-share-actions button.is-pri { background: var(--v2-primary-bg); color: var(--v2-ink, #0F1520); font-weight: 600; }

    /* the funding-options dialog (Coinbase step) on the shell */
    body.v2 #funding-options-modal .funding-subtitle { font-size: 12px; color: var(--text-muted); margin: 0 0 12px; }
    body.v2 #funding-options-modal .funding-field { margin-bottom: 8px; padding: 8px 12px; background: var(--panel-sunken, #070A11); border: 0; border-radius: 6px !important; }
    body.v2 #funding-options-modal .funding-field-label { font-size: 11px; color: var(--text-muted); }
    body.v2 #funding-options-modal .funding-select-btn { height: 24px; padding: 0; border: 0; background: transparent; color: var(--text-primary); font-size: 13px; font-weight: 600; }
}

/* the trollbox Fills tab reads "Fills" alone — the running sum stays written, not shown */
@media (min-width: 992px) {
    body.v2 #v2-fills-sum { display: none !important; }
}

/* chart view: one rule above the three expiry wells (they abut, so the top
   hairline reads as one line across the wells area); one line between the
   views and the positions strip — the strip block's top hairline; the view
   region's own bottom border sat one device pixel above it */
@media (min-width: 992px) {
    body.v2 #v2-wells { position: relative; }
    body.v2 #v2-wells::before {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: var(--v2-wells-top, 6px);
        height: 1px;
        background: var(--v2-hair);
        pointer-events: none;
    }
    body.v2 #v2-view-region { border-bottom: 0 !important; }
}

/* one 8px gap between siblings in every control cluster (buttons, chips,
   presets, popover CTAs, footer buttons, header actions); 2px inside a
   segmented track; 10px between a switcher and its neighbour on a line */
@media (min-width: 992px) {
    body.v2 .hdr-tools { gap: 8px !important; }
    body.v2 .hdr-tools .wallet-section { margin: 0 !important; }
    body.v2 #asset-selection-container,
    body.v2 #v2-presets,
    body.v2 .v2-connect-alts,
    body.v2 .wp-cta-row,
    body.v2 #swapModal .swap-quick-amounts,
    body.v2 #quick-wallet-explanation .qw-step-acts,
    body.v2 .v2-share-actions,
    body.v2 .v2-page-actions,
    body.v2 #portfolio-section .pf-filters { gap: 8px !important; }
    body.v2 #v2-day-chips { margin-right: 0 !important; }
    body.v2 .filter-label-right { gap: 10px !important; } /* day chips → view switcher */
}

/* ==========================================================================
   HARDEN · keyboard focus, reduced motion. One focus ring for every v2
   control (the family, the switchers, the ladder tiles, the strip rows,
   the nav); motion that carries no information stands down under
   prefers-reduced-motion while the state change stays visible.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 button:focus-visible,
    body.v2 a:focus-visible,
    body.v2 [role="button"]:focus-visible,
    body.v2 [tabindex]:focus-visible,
    body.v2 input:focus-visible,
    body.v2 select:focus-visible,
    body.v2 summary:focus-visible {
        outline: 2px solid var(--v2-sky) !important;
        outline-offset: 2px !important;
        box-shadow: none;
    }
    body.v2 .v2-pos-row:focus-visible,
    body.v2 .sbc-lrow:focus-visible { outline-offset: -2px !important; }
    /* the sky ring on a sky-filled control would vanish: the selected asset chip rings in white */
    body.v2 #asset-selection-container .asset-selection-btn.selected:focus-visible { outline-color: var(--text-primary) !important; }
}

@media (min-width: 992px) and (prefers-reduced-motion: reduce) {
    body.v2 .v2-toast { animation: none; }                       /* it appears; nothing slides */
    body.v2 .v2-toast-progress { animation: none; width: 100%; } /* the timer stays as a bar, not a drain */
    body.v2 #trade-positions-block tr.v2-row-glow { animation: none; background: rgba(94, 221, 156, .12); }
    body.v2 .v2-expiry-bar > i, body.v2 .v2-pos-bar > span { transition: none; }
    body.v2 * { transition-duration: 0.01ms !important; }       /* switcher / hover tints: instant, not gone */
    body.v2 .v2-spin, body.v2 .spinner-border { animation-duration: 1.2s; } /* the one motion that IS the state */
}

/* the footer's unit word was the last text under the 10px floor (app.css .6rem) */
@media (min-width: 992px) {
    body.v2 .status-bar-unit { font-size: 0.625rem; }
}

/* app.css's square sweep no longer reaches body.v2: the frame's own cells say
   their corner themselves (the news column card had inherited a 16px card radius) */
@media (min-width: 992px) {
    body.v2 #v2-news, body.v2 #v2-news.v2-panel-card,
    body.v2 #v2-col3 > *,
    body.v2 #v2-col1 > *,
    body.v2 .trade-preview-card,
    body.v2 #v2-view-region,
    body.v2 #trade-positions-block { border-radius: 0 !important; }
    body.v2 #v2-news { border-radius: 0; }
}

/* the footer's PUBLIC BETA badge was the last text under the 10px floor */
@media (min-width: 992px) {
    body.v2 .status-bar-tag, body.v2 .status-bar-tag span { font-size: 0.625rem; }
    /* the footer's PUBLIC BETA tag was app.css's blue at .7 alpha (3.66:1); the quiet system keeps colour for P&L */
    body.v2 .status-bar-tag, body.v2 .status-bar-tag span { color: var(--text-muted) !important; }
}

/* the view container is a frame cell: square (app.css gives it a card corner
   now that the sweep is scoped) */
@media (min-width: 992px) {
    body.v2 #basic-view-container { border-radius: 0 !important; }
}

/* ==========================================================================
   ADAPT · the narrow desktop band (992–1279): the two-column frame is ~724px
   wide for column 1, so the headline drops its spot chip and one step of
   size, and the positions strip's tracks tighten — measured at 1024: the
   headline wrapped to two lines and the strip overflowed its pane by 15px.
   ========================================================================== */
@media (min-width: 992px) and (max-width: 1279.98px) {
    /* three wells need ~100px each; the 22vw clamp gave them 77 at 1024 */
    body.v2 { --v2-wells-w: 336px; }
    /* CALL / PUT · RANGE fit a 102px well: tighter tracking, the range
       head sized to its word, the CALL / PUT head taking the remainder. */
    body.v2 .v2-well-cols { gap: 2px; padding: 4px 2px 2px; }
    body.v2 .v2-well-col { letter-spacing: 0.03em; }
    body.v2 .v2-well-col.is-range { flex: 0 0 auto; }
    body.v2 #v2-head-line { font-size: 22px; white-space: nowrap; }
    body.v2 #v2-head-line .v2-head-spot { display: none; }
    body.v2 #v2-pos-strip .v2-pos-cols,
    body.v2 #v2-pos-strip .v2-pos-row { grid-template-columns: 130px 100px 160px 110px minmax(0, 1fr) 24px 24px !important; }
}

/* ==========================================================================
   Contrast floor, the identity line (2026-09-04): app.css fades the address
   under a named chat identity to .6 (2.7:1). Colour carries the hierarchy.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 .tb-ident-named .tb-ident-addr { opacity: 1; color: var(--text-muted); }
}

/* ==========================================================================
   CRITIQUE PASS (2026-09-04): clarify / layout / quieter / harden.
   ========================================================================== */
@media (min-width: 992px) {
    /* clarify: the commit speaks in sentences (app.css sets uppercase) */
    body.v2 .trade-preview-card #trade-now-btn { text-transform: none; letter-spacing: 0; }
    /* the retry face is a white way-out, not money: outranks the app's
       .btn-secondary paint (the readiness pass keeps re-adding that class) */
    body.v2 .trade-preview-card #trade-now-btn.btn.v2-retry-face,
    body.v2 .trade-preview-card #trade-now-btn.btn.btn-secondary.v2-retry-face { background: var(--v2-primary-bg) !important; color: var(--v2-ink) !important; opacity: 1 !important; cursor: pointer; }
    body.v2 .v2-pd-btn { text-transform: none; }
    body.v2 .v2-param-v.is-muted { color: var(--text-muted); font-weight: 400; }
    body.v2 #trade-confirm-modal .form-check-label .v2-approve-sub { display: block; font-size: 11px; line-height: 1.3; color: var(--text-muted); margin-top: 2px; }
    body.v2 #wallet-pop .wp-disconnected-desc { white-space: normal; max-width: none; }

    /* layout: the chart draws the payoff; the ticket keeps the figures */
    body.v2 .trade-preview-card .ticket-analysis { display: none !important; }

    /* quieter: colour only on money — the chain heads, the next news time,
       the mention rule and the strip's empty-state action step back */
    body.v2 .v2-chain-head .v2-chain-call,
    body.v2 .v2-chain-head .v2-chain-put { color: var(--text-muted); }
    body.v2 .v2-news-item.is-next .v2-news-when { color: var(--text-primary); }
    body.v2 .message.is-mention { border-left-color: rgba(245, 247, 250, .25); }
    body.v2 #trade-positions-block .v2-pos-empty-act.is-pri,
    body.v2 .v2-pos-empty-act.is-pri { background: var(--v2-chip) !important; color: var(--text-primary) !important; }

    /* harden: the slider caption clears the zone buttons; the scroll hint is
       a fade band, so rows pass under a fade instead of under text */
    body.v2 #v2-slider-caption { position: relative; z-index: 2; margin-top: 18px; }
    body.v2 .v2-scroll-pill {
        left: 0; right: 0; bottom: 0; transform: none;
        justify-content: center;
        border-radius: 0;
        background: linear-gradient(to top, var(--card-bg) 45%, rgba(14, 19, 34, 0));
        padding: 16px 0 6px;
    }
}

/* ==========================================================================
   CRITIQUE PASS 2 (2026-09-06): price honesty, keyboard, presets, slider,
   and the quiet system's own rules on its home page.
   ========================================================================== */
@media (min-width: 992px) {
    /* a settled well shows its renewal face, never stale tiles */
    body.v2 .v2-well.is-expired .v2-well-strikes,
    body.v2 .v2-well.is-expired .v2-well-ranges { display: none; }
    body.v2 .v2-well-empty { background: var(--card-bg); }
    body.v2 .v2-well-clock.is-urgent { color: var(--text-primary) !important; } /* words carry urgency; amber lives in bars */

    /* presets: the cap greys out what it cannot fill; the note holds its line */
    body.v2 .v2-preset.is-over { opacity: .45; cursor: not-allowed; }
    /* the app's own amount note is retired on v2: the cap line under the presets says it */
    body.v2 #ticket-amount-note { display: none !important; }

    /* the ticket speaks (aria-live) without painting */
    body.v2 .v2-visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

    /* slider: the sentence leads the track; the range buttons say Stays */
    body.v2 #v2-slider-caption { margin: 0 0 10px; position: static; }
    body.v2 .ranger-btn-label { text-transform: none; letter-spacing: 0; }
    body.v2 .strike-slider-track .slider-label { text-transform: none; letter-spacing: 0; }

    /* caps only in table heads; Geist only on the page title */
    body.v2 .v2-scen-head { text-transform: none; letter-spacing: 0; font-size: 11px; }
    body.v2 #v2-chart-row .tc-tv-fit,
    body.v2 .status-bar-tag, body.v2 .status-bar-tag span { text-transform: none; letter-spacing: 0; }
    body.v2 .v2-comp-title, body.v2 .v2-question { font-family: var(--sans); letter-spacing: 0; }

    /* the chosen chart range is a dark segment, not a sky outline */
    body.v2 #v2-chart-row .tc-tv-tool[aria-pressed="true"] { background: var(--v2-chip) !important; color: var(--text-primary) !important; box-shadow: none !important; border-color: transparent !important; outline: 0; }

    /* the chart caption keeps its whole sentence */
    body.v2 #v2-pays-line { flex: 1 1 auto; min-width: 0; white-space: normal; line-height: 1.25; max-height: 2.5em; }

    /* on a tile the strike leads (green, 600); the premium is secondary text */
    body.v2 .v2-tile .v2-prem { color: var(--text-secondary); font-weight: 400; opacity: 1; }

    /* chat status words are words */
    body.v2 .message .admin-badge { color: var(--text-secondary); letter-spacing: 0; }
}
@media (min-width: 992px) {
    /* the cap line under the presets: 11px muted, kept until the strike changes */
    body.v2 .v2-cap-note { margin: 6px 0 0; font-family: var(--sans); font-size: 11px; line-height: 1.3; color: var(--text-muted); }
    body.v2 .v2-cap-note[hidden] { display: none; }
}

/* ==========================================================================
   CRITIQUE PASS 3 (2026-09-06): the ticket keeps its own rules, one payoff,
   the lattice by rail, a skip link, the chain head, the popover.
   ========================================================================== */
@media (min-width: 992px) {
    /* chosen preset is the chip tone; the chosen SIDE is its colour (user,
       2026-09-07: "when YES/NO selected the button itself should be
       green/red") — a solid green YES, a solid red NO, dark ink on both */
    /* !important: the button family paints these with !important */
    body.v2 .v2-preset.is-active { background: var(--v2-chip-hover) !important; color: var(--text-primary) !important; box-shadow: none !important; font-weight: 600; }
    body.v2 .v2-side-btn.is-call.is-active { background: var(--positive) !important; border-color: transparent !important; box-shadow: none !important; color: var(--v2-on-green) !important; font-weight: 600; }
    body.v2 .v2-side-btn.is-put.is-active  { background: var(--negative) !important; border-color: transparent !important; box-shadow: none !important; color: var(--v2-on-negative) !important; font-weight: 600; }
    body.v2 .v2-adv-badge { border: 0 !important; background: var(--v2-chip); }

    /* one payoff: the scenarios table is Advanced's, above the commit */
    body.v2:not(.v2-adv) #v2-scenarios { display: none !important; }
    body.v2.v2-adv #v2-scenarios { margin: 0 0 12px; }

    /* the lattice by rail: tone fills, a 2px side rail, colour on the premium only */
    body.v2 .v2-tile.is-call { background: rgba(94, 221, 156, .07); color: var(--text-primary); box-shadow: inset 2px 0 0 var(--positive); }
    body.v2 .v2-tile.is-put  { background: rgba(232, 106, 98, .07); color: var(--text-primary); box-shadow: inset 2px 0 0 var(--negative); }
    body.v2 .v2-tile.is-call:hover { background: rgba(94, 221, 156, .16); }
    body.v2 .v2-tile.is-put:hover  { background: rgba(232, 106, 98, .16); }
    body.v2 .v2-tile.is-call .v2-prem { color: var(--positive); }
    body.v2 .v2-tile.is-put .v2-prem  { color: #F4CBC8; }
    body.v2 .v2-tile.is-selected, body.v2 .v2-tile.is-selected .v2-prem { color: var(--v2-on-green); }
    body.v2 .v2-tile.is-put.is-selected, body.v2 .v2-tile.is-put.is-selected .v2-prem { color: var(--v2-on-negative); }

    /* skip link: hidden until focused, then the first thing on the page */
    body.v2 .v2-skip { position: absolute; left: 8px; top: -48px; z-index: 60; padding: 6px 10px; border-radius: 6px; background: var(--v2-primary-bg); color: var(--v2-ink); font: 500 12px/1 var(--sans); text-decoration: none; }
}
/* Below the breakpoint the ladder it targets is not rendered, and the only
   rule that moved this anchor off screen sat inside the desktop block — so
   phones showed a bare "Skip to strikes" as the first thing on the page. */
@media (max-width: 991.98px) {
    body.v2 .v2-skip { display: none; }
}
@media (min-width: 992px) {
    body.v2 .v2-skip:focus-visible { top: 8px; outline: 2px solid var(--v2-sky); outline-offset: 2px; }

    /* the chain head sits on the panel and the rows are the strip's rows */
    body.v2 .v2-chain-head { background: var(--card-bg); }
    body.v2 .v2-chain-row { min-height: 32px; }
}

/* ==========================================================================
   CRITIQUE PASS 4 (2026-09-06): dollars first, the commit's causes, views
   decoupled, the rules sweep, the lattice at a hand's size.
   ========================================================================== */
@media (min-width: 992px) {
    /* the commit's cause line and its faces */
    body.v2 .v2-commit-cause { margin: 6px 2px 0; font-family: var(--sans); font-size: 11px; line-height: 1.35; color: var(--text-muted); text-align: center; }
    body.v2 .v2-commit-cause[hidden] { display: none; }
    body.v2 .trade-preview-card #trade-now-btn.btn.v2-refresh-face,
    body.v2 .trade-preview-card #trade-now-btn.btn.btn-secondary.v2-refresh-face { background: var(--v2-primary-bg) !important; color: var(--v2-ink) !important; opacity: 1 !important; cursor: pointer; }

    /* the ticket's void: a hidden balance line takes no room */
    body.v2 .v2-balance-line[style*="visibility:hidden"],
    body.v2 .v2-balance-line[style*="visibility: hidden"],
    body.v2.v2-no-wallet .v2-balance-line { display: none !important; }

    /* status is a word */
    body.v2 .v2-adv-badge, body.v2 .v2-adv-badge.is-put, body.v2 .v2-adv-badge.is-range { border: 0 !important; background: transparent !important; padding: 0; color: var(--text-primary); }
    body.v2 #v2-chat .online-count { text-transform: none; letter-spacing: 0; }
    body.v2 .v2-pos-foot { text-transform: none; letter-spacing: 0; }

    /* range cells by rail, like the tiles; the multiple carries the sky */
    body.v2 .v2-range { background: rgba(125, 211, 252, .07); box-shadow: inset 2px 0 0 var(--v2-sky); }
    body.v2 .v2-range:hover { background: rgba(125, 211, 252, .16); }
    body.v2 .v2-range .v2-range-bounds { text-transform: none; letter-spacing: 0; font-weight: 600; color: var(--text-primary); }
    body.v2 .v2-range .v2-range-max { color: var(--v2-sky); }
    body.v2 .v2-range.is-selected { background: var(--v2-sky); box-shadow: none; }
    body.v2 .v2-range.is-selected .v2-range-bounds, body.v2 .v2-range.is-selected .v2-range-max { color: var(--v2-on-sky); }

    /* the chain's quotes rest on the tone with a rail; only the selected one fills */
    body.v2 .v2-chain-quote.is-call:not(.is-selected) { background: rgba(94, 221, 156, .07) !important; box-shadow: inset 2px 0 0 var(--positive); color: var(--text-primary); }
    body.v2 .v2-chain-quote.is-put:not(.is-selected)  { background: rgba(232, 106, 98, .07) !important; box-shadow: inset 2px 0 0 var(--negative); color: var(--text-primary); }

    /* the slider: strikes white, labels at the floor, zones clear of the table */
    body.v2 .v2-tbl-strike.is-call, body.v2 .v2-tbl-strike.is-put { color: var(--text-primary); }
    body.v2 .ranger-btn-label, body.v2 .ranger-btn-range, body.v2 .ranger-btn-multiplier { font-size: 10px !important; }
    body.v2 .ranger-zones-container { min-height: 56px; margin-bottom: 8px; }


    /* the chain is the view: it takes the region, the chart row steps aside */
    body.v2 #v2-view-region[data-v2-view="advanced"] #v2-chart-row { display: none !important; }
    body.v2 #v2-view-region[data-v2-view="advanced"] #v2-chain { max-height: none; height: 100%; flex: 1 1 auto; }

    /* the popover on the modal scale: 16px title, 30px buttons */
    body.v2 #wallet-pop .wp-disconnected-title { font-size: 16px !important; }
    body.v2 #wallet-pop .wp-connect-btn { height: 30px !important; min-height: 30px !important; }
}
@media (min-width: 992px) {
    /* the wells' overflow chip and the slider's own labels read at the floor */
    body.v2 .v2-well-overflow { color: var(--text-secondary); }
    body.v2 .slider-tick-label, body.v2 .slider-tick.tick-put .slider-tick-label, body.v2 .slider-tick.tick-call .slider-tick-label { color: var(--text-muted) !important; opacity: 1 !important; font-size: 10px !important; }
    body.v2 .slider-tick.active .slider-tick-label, body.v2 .slider-tick.active.tick-put .slider-tick-label { color: var(--text-primary) !important; }
    body.v2 .strike-slider-track .slider-label { opacity: 1 !important; }
}

/* ==========================================================================
   CRITIQUE PASS 5 (2026-09-07): keyboard, the chain at the top, one width
   rule, quiet slider and rail, the pays figure in white.
   ========================================================================== */
@media (min-width: 992px) {
    /* the chain is the view: it starts where the region starts */
    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chain { top: 0 !important; inset: 0 !important; height: 100% !important; max-height: none !important; }

    /* the page measures 1160 below the wide break (1440 above 1680) */
    body.v2 #portfolio-section .pf-wrap,
    body.v2 #scoreboard-cards .sbc-wrap,
    body.v2 #referral-section .ref-wrap { max-width: 1160px; margin-left: auto; margin-right: auto; }

    /* the slider's track is a track, not a red-to-green banner */
    /* the slider's track keeps its sides (user): puts red on the left, calls green on the right */
    body.v2 .strike-slider { background: linear-gradient(to right, rgba(232, 106, 98, .38) 0%, rgba(232, 106, 98, .38) 50%, rgba(94, 221, 156, .38) 50%, rgba(94, 221, 156, .38) 100%) !important; }
    body.v2 .strike-slider-track .puts-label { color: var(--negative) !important; }
    body.v2 .strike-slider-track .calls-label { color: var(--positive) !important; }

    /* unchosen range cells sit on the tone; the rail says the product */
    body.v2 .v2-range:not(.is-selected) { background: rgba(255, 255, 255, .03); }
    body.v2 .v2-range:not(.is-selected):hover { background: rgba(125, 211, 252, .12); }

    /* pays is a promise, not P&L: white until money moves */
    body.v2 .v2-param-v.is-pos { color: var(--text-primary); }

    /* the chart's source label keeps its whole text */
    body.v2 #v2-chart-source { width: auto !important; max-width: none !important; overflow: visible !important; text-overflow: clip; }

    /* the referral head's action */
    body.v2 #referral-section .ref-head-actions { margin-left: auto; }
    body.v2 #referral-section #referral-head-link[hidden] { display: none !important; }
}
@media (min-width: 992px) {
    /* trollbox: an admin post is a post — tone, hairline rail, chip reactions */
    body.v2 #v2-chat .message.admin-message { background: rgba(255, 255, 255, .03) !important; border-left-color: var(--v2-hair-strong) !important; box-shadow: none !important; }
    body.v2 #v2-chat .message-reactions > * { background: var(--v2-chip) !important; color: var(--text-secondary) !important; border: 0 !important; box-shadow: none !important; }
}

/* ==========================================================================
   CRITIQUE PASS 6 (2026-09-07): the band on the panel tone, one control
   family outside the ticket too, the chart toolbar as the switcher, the
   lattice filling a tall window, periphery colours by the rules.
   ========================================================================== */
@media (min-width: 992px) {
    /* the competition band is a panel line, not a paper strip */
    body.v2 #v2-banner { background: var(--card-bg) !important; }
    body.v2 .v2-comp-line { background: var(--card-bg) !important; color: var(--text-primary) !important; }
    body.v2 .v2-comp-title { font-family: var(--sans) !important; font-size: 12px !important; font-weight: 600 !important; letter-spacing: 0 !important; color: var(--text-primary) !important; }
    body.v2 .v2-comp-tag, body.v2 .v2-comp-item { font-size: 12px !important; color: var(--text-muted) !important; }
    body.v2 .v2-comp-item b, body.v2 .v2-comp-item .v2-comp-pool { color: var(--text-primary) !important; font-size: 12px !important; }
    body.v2 .v2-comp-cta { background: var(--v2-chip) !important; color: var(--text-primary) !important; height: 24px; padding: 0 10px !important; font-size: 12px !important; font-weight: 500 !important; letter-spacing: 0 !important; line-height: 24px !important; border-radius: 6px !important; }
    body.v2 .v2-comp-cta:hover { background: var(--v2-chip-hover) !important; }

    /* one family: 30px controls, r6 — the strike arrows, the chat's send and field, the bell */
    body.v2 .v2-step { width: 30px !important; height: 30px !important; border-radius: 6px !important; }
    body.v2 #trollbox-send { width: 30px !important; height: 30px !important; min-height: 30px !important; border-radius: 6px !important; background: var(--v2-chip) !important; color: var(--text-primary) !important; box-shadow: none !important; }
    body.v2 #trollbox-send:hover { background: var(--v2-chip-hover) !important; }
    body.v2 #trollbox-input { height: 30px !important; min-height: 30px !important; }
    body.v2 #nav-alert-btn { border-radius: 6px !important; }

    /* the chart's range buttons are the switcher: a sunken track, 24px segments, sentence case */
    body.v2 #v2-chart-row .tc-tv-tools > .tc-tv-segment:not(.tc-tv-zoom) { background: var(--panel-sunken); border-radius: 7px; padding: 2px; gap: 2px; }
    body.v2 #v2-chart-row .tc-tv-tool { min-height: 24px !important; line-height: 24px !important; height: 24px; font-size: 12px !important; font-weight: 500 !important; letter-spacing: 0 !important; text-transform: none !important; padding: 0 10px !important; border-radius: 5px !important; }

    /* colour by the rules: the admin's name is a name, spot is a hairline, the breakeven tag is a chip */
    body.v2 #v2-chat .message-author.admin-author { color: var(--text-primary) !important; font-weight: 600; }
    body.v2 .v2-chain-spot span { background: transparent !important; color: var(--text-muted) !important; font-weight: 500 !important; }
    body.v2 .v2-chain-spot::before, body.v2 .v2-chain-spot::after { border-top-color: var(--v2-hair-strong) !important; }
    body.v2 .tc-be-t { fill: #F5F7FA !important; }
    body.v2 .tc-be-box { fill: #232C42 !important; stroke: none !important; }

    /* a tall window earns 12px tile type */
    body.v2 #v2-wells.is-roomy .v2-tile { font-size: 12px; }
    body.v2 #v2-wells.is-roomy .v2-tile .v2-prem { font-size: 11px; }
    body.v2 #v2-wells.is-roomy .v2-cell-empty { font-size: 11px; }

    /* Advanced: the sub-line sits with its line */
    body.v2.v2-adv #v2-step-sub { text-align: left; }

    /* referrals: one Get my link, in the page head */
    body.v2 #referral-disconnected #referral-connect-btn { display: none !important; }
}
@media (min-width: 992px) {
    /* the strip's Portfolio link is a 12px sentence-case link, not a tracked cap */
    body.v2 #v2-strip-portfolio { text-transform: none !important; letter-spacing: 0 !important; font-size: 12px !important; font-weight: 500; color: var(--text-secondary); }
    body.v2 #v2-strip-portfolio:hover { color: var(--text-primary); }
}

/* ==========================================================================
   CRITIQUE PASS 7 (2026-09-07): the right column on the quiet system, the
   range cell at reading size, the alternate views filling a tall region.
   ========================================================================== */
@media (min-width: 992px) {
    /* the trollbox is a panel: no card, no border, a 36px head, rows not bubbles */
    body.v2 #v2-chat > .trollbox-widget { border: 0 !important; border-radius: 0 !important; background: transparent !important; }
    body.v2 #v2-chat #trollbox-header { height: 36px !important; min-height: 36px !important; padding: 0 14px !important; display: flex !important; align-items: center !important; background: transparent !important; }
    body.v2 #v2-chat .trollbox-title { font-family: var(--sans); font-size: 12px !important; font-weight: 600 !important; letter-spacing: 0 !important; color: var(--text-primary) !important; }
    body.v2 .v2-mod-head { height: 36px; padding: 0 14px; align-items: center; }
    body.v2 .v2-mod-title { font-size: 12px; }
    body.v2 #v2-chat .message { background: transparent !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important; margin: 0 !important; padding: 8px 14px !important; border-bottom: 1px solid var(--v2-hair) !important; }
    body.v2 #v2-chat .message.admin-message, body.v2 #v2-chat .message.is-mention { background: rgba(255, 255, 255, .03) !important; border-left: 0 !important; margin-left: 0 !important; }
    body.v2 #v2-chat .message-header { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
    body.v2 #v2-chat .message-author { font-family: var(--sans); font-size: 12px !important; font-weight: 500 !important; }
    body.v2 #v2-chat .message-time { font-size: 11px !important; color: var(--text-muted) !important; margin-left: auto; }
    body.v2 #v2-chat .message-text, body.v2 #v2-chat .message-content { font-size: 12px !important; line-height: 1.45 !important; }
    body.v2 .message .admin-badge { background: transparent !important; color: var(--text-muted) !important; padding: 0 !important; font-size: 11px !important; font-weight: 500 !important; letter-spacing: 0 !important; }
    body.v2 #v2-chat .message-reactions { gap: 4px; margin-top: 4px; }
    body.v2 #v2-chat .message-reactions > * { font-size: 11px !important; padding: 2px 8px !important; border-radius: 999px !important; }
    body.v2 .v2-fill-row { border-left: 0 !important; background: transparent !important; border-radius: 0 !important; border-bottom: 1px solid var(--v2-hair); }
    body.v2 .v2-fill-row::before { display: none; }

    /* the range cell reads: a wider column, two-line figures, the multiple in sky */
    body.v2 .v2-well-ranges { flex: 0 0 42% !important; }
    body.v2 .v2-well-strikes { flex: 1 1 0 !important; }
    body.v2 .v2-range-bounds { font-size: 11px !important; font-weight: 600 !important; line-height: 1.2 !important; letter-spacing: 0; }
    body.v2 .v2-range-max { font-size: 12px !important; font-weight: 600 !important; line-height: 1.15 !important; margin-top: 2px; }
    body.v2 .v2-well-col.is-range { color: var(--text-muted); }
    body.v2 #v2-wells.is-roomy .v2-tile { font-size: 11px; }

    /* sky marks the selected asset; the well's day is a word */
    body.v2 .v2-well.is-primary .v2-well-day { color: var(--text-primary) !important; }
    body.v2 .v2-well-clock { font-size: 11px !important; }

    /* the status bar sits on the 11px sub size, not a scaled 10.8 */
    body.v2 #desktop-status-bar, body.v2 #desktop-status-bar .status-bar-item, body.v2 #desktop-status-bar .status-bar-label, body.v2 #desktop-status-bar span { font-size: 11px !important; }
    body.v2 .status-bar-unit, body.v2 .status-bar-tag, body.v2 .status-bar-tag span { font-size: 11px !important; }

    /* the alternate views' rows are the Strip's 32px on every window (user,
       2026-09-07: "the rows in slider and chain view are too big") — a tall
       window shows more of the book, not taller rows */
    body.v2 .v2-chain-row, body.v2 .v2-tbl-row { min-height: 32px; }

    /* the skip link lands in its own row under the topbar */
    body.v2 .v2-skip:focus-visible { top: 62px; }

    /* Everyone's open: the big tab carries the count; the panel head says the name */
    body.v2 #pf-all-n { display: none !important; }
}

/* ==========================================================================
   CRITIQUE PASS 8 (2026-09-07): the premium is never hidden at the design
   width, one instrument in three views, two control shapes, colour only on
   money on the chart and slider.
   ========================================================================== */
@media (min-width: 992px) {
    /* the slider's selected row wears its side */
    body.v2 .v2-tbl-row.is-selected:has(.v2-tbl-strike.is-put) { background: rgba(232, 106, 98, .07) !important; }
    body.v2 .v2-tbl-row.is-selected:has(.v2-tbl-strike.is-call) { background: rgba(94, 221, 156, .07) !important; }
    body.v2 .market-price-label { background: transparent !important; border: 0 !important; color: var(--text-primary) !important; font-weight: 600; }
    body.v2 #v2-slider-caption b.v2-cap-pay { color: var(--text-primary) !important; }

    /* the chart's pays tag and breakeven figure are chips with a rail, not filled colour */
    body.v2 #v2-pays-tag.is-call, body.v2 #v2-pays-tag.is-put, body.v2 #v2-pays-tag.is-range { background: var(--v2-chip) !important; color: var(--text-primary) !important; text-transform: none !important; letter-spacing: 0 !important; font-weight: 600; }
    body.v2 #v2-pays-tag.is-call { box-shadow: inset 2px 0 0 var(--positive) !important; }
    body.v2 #v2-pays-tag.is-put { box-shadow: inset 2px 0 0 var(--negative) !important; }
    body.v2 #v2-pays-tag.is-range { box-shadow: inset 2px 0 0 var(--v2-sky) !important; }
    body.v2 .tc-tv-be-value { color: var(--text-primary) !important; }
    body.v2 .tc-tv-be-label { color: var(--text-muted) !important; }

    /* two control shapes: the presets are segments in a sunken track; the field is r6 on the sunken tone */
    body.v2 #v2-presets { background: var(--panel-sunken) !important; border-radius: 7px !important; padding: 2px !important; gap: 2px !important; }
    body.v2 .v2-preset { height: 24px !important; min-height: 24px !important; padding: 0 !important; border-radius: 5px !important; background: transparent !important; box-shadow: none !important; font-size: 12px !important; font-weight: 500 !important; color: var(--text-secondary) !important; }
    body.v2 .v2-preset:hover { background: var(--v2-chip) !important; color: var(--text-primary) !important; }
    body.v2 .v2-preset.is-active { background: var(--v2-chip) !important; color: var(--text-primary) !important; font-weight: 600 !important; }
    body.v2 .v2-preset.is-over { opacity: .45; }
    body.v2 #ticket-amount-field { border-radius: 6px !important; background: var(--panel-sunken) !important; }

    /* the cap line sits under the field it explains, at the caption size */
    body.v2 .v2-cap-note { font-size: 12px !important; color: var(--text-secondary) !important; margin: 6px 0 8px !important; }

    /* the display size is the page title's, on the trade page too — scaled
       with the window so the sentence with its live clock ("Where does BTC
       close in 1 day 2 hr 10 min 10 sec?") stays ONE line on a smaller
       screen (user, 2026-09-07): 26px from 1680px down to ~19px at 1280 */
    body.v2 #v2-head-line { font-size: clamp(15px, 1.35vw, 26px); white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    body.v2 #v2-head-line .v2-head-spot { flex: 0 0 auto; }

    /* an admin post is a post */
    body.v2 #v2-chat .message.admin-message { background: transparent !important; }

    /* referrals: the tagline lives in the head, not again in the band */
    body.v2 #referral-tile-link-sub { display: none !important; }
}
@media (min-width: 992px) and (max-width: 1279.98px) {
    body.v2 #v2-head-line { font-size: clamp(14px, 1.45vw, 18px); }
}
@media (min-width: 1440px) {
    /* the wells take 440px so the strike column keeps its premium (≥66px) beside a 42% range column */
    body.v2 { --v2-wells-w: 440px; }
}
@media (min-width: 992px) {
    body.v2 .trade-preview-card #ticket-amount-field, body.v2 #ticket-amount-field.ticket-amount-field { border-radius: 6px !important; }
}

/* ==========================================================================
   CRITIQUE PASS 9 (2026-09-07): no layout motion in the ticket, the chart
   says the payoff once, the status bar's craft, P&L colour on scenarios,
   the header stays on peripheral pages.
   ========================================================================== */
@media (min-width: 992px) {
    /* the cap line is reserved under the presets */
    body.v2 .v2-cap-note { min-height: 16px; margin: 6px 0 0 !important; }
    body.v2 .v2-cap-note[hidden] { display: block; }

    /* the chart's tag and the ticket's Settles line already say this */
    body.v2 #v2-pays-line { display: none !important; }
    body.v2 #v2-chart-source { opacity: 1 !important; mask: none !important; -webkit-mask: none !important; }

    /* the status bar: no orphan separators, the delay word without an amber dot */
    body.v2 #desktop-status-bar .status-bar-sep + .status-bar-sep,
    body.v2 #desktop-status-bar .status-bar-feedback + .status-bar-sep,
    body.v2 #desktop-status-bar .status-bar-sep:has(+ .status-bar-feedback) { display: none !important; }
    body.v2 #desktop-status-bar .status-dot-degraded { background: var(--text-muted) !important; box-shadow: none !important; }

    /* scenarios are P&L: colour on the money */
    body.v2 #v2-scenarios .scenario-positive { color: var(--positive); }
    body.v2 #v2-scenarios .scenario-negative { color: var(--negative); }

    /* the well head is one size */
    body.v2 .v2-well-day { font-size: 11px !important; }

    /* referrals: the page's one action is the white primary */
    body.v2 #referral-section #referral-head-link { background: var(--v2-primary-bg) !important; color: var(--v2-ink) !important; }

    /* the header stays while a peripheral page scrolls */
    body.v2 > header, body.v2 header.navbar-header, body.v2 .app-container > header { position: sticky; top: 0; z-index: 30; }
}

/* ==========================================================================
   CRITIQUE PASS 10 (2026-09-07): the chosen range is the chip tone with its
   sky rail; a focused preset is not a chosen preset.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 .v2-range.is-selected { background: var(--v2-chip-hover) !important; box-shadow: inset 2px 0 0 var(--v2-sky) !important; }
    body.v2 .v2-range.is-selected .v2-range-bounds { color: var(--text-primary) !important; }
    body.v2 .v2-range.is-selected .v2-range-max { color: var(--v2-sky) !important; }
    body.v2 .v2-preset:focus:not(:focus-visible):not(.is-active) { background: transparent !important; color: var(--text-secondary) !important; }
}

/* ==========================================================================
   FIELD + PRESETS (2026-09-07, user): the amount field is a darker well than
   the sunken tone, and the dollar presets are buttons of the family, not
   segments of a track.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 { --v2-field: #04060B; }
    body.v2 .trade-preview-card #ticket-amount-field, body.v2 #ticket-amount-field.ticket-amount-field { background: var(--v2-field) !important; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .04) !important; }
    body.v2 #trollbox-input, body.v2 #v2-chat .trollbox-input { background: var(--v2-field) !important; }

    body.v2 #v2-presets { background: transparent !important; border-radius: 0 !important; padding: 0 !important; gap: 8px !important; }
    body.v2 .v2-preset { height: 30px !important; min-height: 30px !important; border-radius: 6px !important; background: var(--v2-chip) !important; color: var(--text-primary) !important; font-size: 12px !important; font-weight: 500 !important; box-shadow: none !important; }
    body.v2 .v2-preset:hover, body.v2 .v2-preset:focus-visible { background: var(--v2-chip-hover) !important; }
    body.v2 .v2-preset.is-active { background: var(--v2-chip-hover) !important; color: var(--text-primary) !important; font-weight: 600 !important; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .10) !important; }
    body.v2 .v2-preset.is-over { opacity: .45; }
    body.v2 .v2-preset:focus:not(:focus-visible):not(.is-active) { background: var(--v2-chip) !important; color: var(--text-primary) !important; }
}

/* ==========================================================================
   RAISED SURFACES (2026-09-07, user): anything that floats — popovers, menus,
   tooltips, toasts, the range picker — sits on a raised tone one step above
   the panel, with a hairline ring and a real shadow, so it reads as a layer
   over the page rather than a patch of the same tone.
   ========================================================================== */
@media (min-width: 992px) {
    body.v2 { --v2-raised: #182036; --v2-raised-ring: rgba(255, 255, 255, .10); --v2-raised-shadow: 0 16px 40px rgba(0, 0, 0, .6), 0 2px 8px rgba(0, 0, 0, .35); }
    body.v2 #wallet-pop, body.v2 #alert-pop, body.v2 .hdr-pop, body.v2 .asset-picker-pop,
    body.v2 .v2-pos-tip, body.v2 #v2-range-pick, body.v2 .v2-toast,
    body.v2 .dropdown-menu, body.v2 #portfolio-section .pf-filter .dropdown-menu,
    body.v2 .v2-menu, body.v2 .sbc-menu, body.v2 .pf-menu {
        background: var(--v2-raised) !important;
        border: 0 !important;
        box-shadow: var(--v2-raised-shadow), 0 0 0 1px var(--v2-raised-ring) !important;
    }
    /* the raised tone's own sunken wells stay one step below it */
    body.v2 #wallet-pop .wp-balance-card, body.v2 #alert-pop .alp-field, body.v2 #alert-pop .alp-menu { background: var(--card-bg) !important; }
    body.v2 #wallet-pop .wp-connect-btn-alt, body.v2 .v2-toast .v2-toast-close { background: var(--v2-chip-hover) !important; }
    /* modals: the shell rides the overlay, so a ring is enough */
    body.v2 .modal-content, body.v2 .odette-modal-content, body.v2 .beta-modal-content { box-shadow: 0 24px 60px rgba(0, 0, 0, .6), 0 0 0 1px var(--v2-raised-ring) !important; }
    /* hover tint on raised rows */
    body.v2 .dropdown-menu .dropdown-item:hover, body.v2 #alert-pop .v2-bell-item:hover { background: rgba(255, 255, 255, .05) !important; }
}
@media (min-width: 992px) {
    /* ONE book width for every asset (user, 2026-09-07: "make every asset the
       same size as the BTC strike buttons"): the wells take the width the
       widest tile needs, so ETH's ladder sits as loosely as BTC's */
    body.v2 #v2-wells { --v2-wells-w: 640px; }
    body.v2 #v2-wells .v2-well-ranges { flex: 0 0 96px !important; }
    body.v2 .v2-range-bounds { white-space: normal; }
    body.v2 .v2-range-nums { white-space: nowrap; display: inline-block; }   /* the column holds the bounds on one line */
}
@media (min-width: 992px) and (max-width: 1439.98px) {
    body.v2 #v2-wells { --v2-wells-w: 580px; }
    body.v2 #v2-wells .v2-well-ranges { flex: 0 0 90px !important; }
}
@media (min-width: 992px) {
    /* the headline carries a live clock: tabular digits so it does not jitter */
    body.v2 #v2-head-line { font-variant-numeric: tabular-nums; }
    body.v2 #v2-expiry-left { font-variant-numeric: tabular-nums; min-width: 12ch; text-align: right; }
}


/* ── SHORT RANGE CELLS ─────────────────────────────────────────────────
   A zone two rows tall cannot hold three lines. The word goes, the
   numbers and the cap stay on two lines; the aria-label keeps the word.

   The leading is the whole fix (2026-09-09). On BTC a 1,000-wide band is two
   rows: the cell is 27.8px, 26px inside its two 1px sky borders, while the
   content wanted 11x1.2 + 3px gap + 12x1.15 = 30px. "up to 2.3x" hung ~4px
   past the bottom and overflow:hidden clipped its descenders, so the pair
   read as two tiles colliding. At line-height 1 the same two lines are 23px
   and fit. NOT a width problem: "78,000-79,000" measures 83px in an 86-92px
   column, so abbreviating or widening would have missed it.

   Wrapped in the desktop query, which it never was: `body class="v2"` is
   STATIC in app.html, so these rules were reaching mobile, where the strike
   ladder is a different component. */
@media (min-width: 992px) {
    body.v2 .v2-range.is-short { padding-top: 0; padding-bottom: 0; gap: 0; justify-content: center; }
    body.v2 .v2-range.is-short .v2-range-bounds { font-size: 0 !important; line-height: 0 !important; }
    body.v2 .v2-range.is-short .v2-range-nums { font-size: 11px; line-height: 1; display: inline-block; white-space: nowrap; }
    /* beats the 1.15/2px set earlier in this file on specificity */
    body.v2 .v2-range.is-short .v2-range-max { line-height: 1 !important; margin-top: 0; }
    /* Spread bands share Ranger's coordinates; their arrows show the side
       that keeps paying beyond the second strike. */
    body.v2 #v2-wells .v2-spread { --spread-ink: var(--positive); box-shadow: inset 2px 0 0 var(--spread-ink) !important; }
    body.v2 #v2-wells .v2-spread.is-put { --spread-ink: var(--negative); }
    body.v2 #v2-wells .v2-spread .v2-range-max { color: var(--spread-ink) !important; }
    /* the box's top and bottom edges are its own colour, not the range sky */
    body.v2 #v2-wells .v2-spread { border-top-color: color-mix(in srgb, var(--spread-ink) 40%, transparent) !important; border-bottom-color: color-mix(in srgb, var(--spread-ink) 40%, transparent) !important; }
    body.v2 #v2-wells .v2-spread.v2-range-bracket { border-color: var(--spread-ink); }
    body.v2 #v2-wells .v2-spread.is-selected { outline: 1px solid var(--spread-ink); outline-offset: -1px; }
}

/* ── NO RANGES ───────────────────────────────────────────────────────────
   No range quoted on any expiry (BNB, XRP): the RANGE column leaves and the
   call/put tiles take the whole well; the wells give the chart the width a
   single column does not need. */
@media (min-width: 992px) {
    body.v2 #v2-wells.no-ranges .v2-well-ranges,
    body.v2 #v2-wells.no-ranges .v2-well-col.is-range { display: none !important; }
    body.v2 #v2-wells.no-ranges .v2-well-strikes { flex: 1 1 100% !important; }
    body.v2 #v2-wells.no-ranges { --v2-wells-w: 480px; }
}
@media (min-width: 992px) and (max-width: 1439.98px) {
    body.v2 #v2-wells.no-ranges { --v2-wells-w: 440px; }
}

/* ── CHAIN FLUSH ───────────────────────────────────────────────────────────
   The chain's column head sits on the region's top edge, not 14px under it
   (user, 2026-09-07: "a gap in the column header row and the edge at top"). */
@media (min-width: 992px) {
    body.v2 #v2-view-region[data-v2-view="advanced"] > #v2-chain { padding-top: 0 !important; }
    body.v2 #v2-view-region[data-v2-view="advanced"] .v2-chain-head { padding-top: 6px; padding-bottom: 6px; }
}

/* ── RAIL PANELS ───────────────────────────────────────────────────────────
   The news and the trollbox are the ONE panel tone (radius 8, no border),
   like every other panel: the trollbox had been left transparent and
   borderless beside a bordered news card, so it read as bare ground with
   too much space around it (user, 2026-09-07). */
@media (min-width: 992px) {
    body.v2 #v2-news, body.v2 #v2-chat > .trollbox-widget {
        background: var(--card-bg) !important;
        border: 0 !important;
        border-radius: 8px !important;
    }
    body.v2 #v2-chat #trollbox-header { border-bottom: 1px solid var(--v2-hair); }
}

/* ── EVERYONE'S OPEN (the trollbox's second pane) ─────────────────────────
   trader · position · P&L · cost, best P&L first; P&L is the one coloured
   figure (Colour only on P&L). */
@media (min-width: 992px) {
    body.v2 .v2-fill-row { grid-template-areas: 'who pnl' 'what prem' !important; gap: 2px 8px; padding: 7px 12px !important; }
    body.v2 .v2-fill-row b { grid-area: who; font-size: 11px; color: var(--text-secondary); }
    body.v2 .v2-fill-row b u { text-decoration: none; margin-left: 6px; font-size: 10px; color: var(--v2-sky); }
    body.v2 .v2-fill-row span { grid-area: what; font-size: 11px; }
    body.v2 .v2-fill-row em { grid-area: pnl; justify-self: end; font-size: 11px; font-weight: 600; color: var(--text-secondary); white-space: nowrap; }
    body.v2 .v2-fill-row em.is-up { color: var(--positive); }
    body.v2 .v2-fill-row em.is-dn { color: var(--negative); }
    body.v2 .v2-fill-row i { grid-area: prem; justify-self: end; font-size: 10px; color: var(--text-muted); }
    body.v2 .v2-fill-row.is-me { box-shadow: inset 2px 0 0 var(--v2-sky); }
}

/* the trader's name and address on ONE line in the Everyone pane (the ident
   markup stacks them; a 60px row is two rows' worth) */
@media (min-width: 992px) {
    body.v2 .v2-fill-row b .tb-ident, body.v2 .v2-fill-row b [class^="tb-ident"] { display: inline !important; }
    body.v2 .v2-fill-row b .tb-ident-addr { margin-left: 6px; font-size: 10px; color: var(--text-muted); }
    body.v2 .v2-fill-row b .tb-ident-name { font-weight: 600; }
    body.v2 .v2-fill-row b br { display: none; }
}

/* ── GHOST TILES ───────────────────────────────────────────────────────────
   An un-quoted level is a greyed-out tile, not a hairline row: same shape,
   same height, the chip tone at a whisper, the price muted (user,
   2026-09-07: "a missing strike should look like a greyed-out button; the
   empty rows were crowding the other strike buttons" — BNB). */
@media (min-width: 992px) {
    body.v2 .v2-cell-empty {
        border: 0 !important;
        border-radius: var(--v2-r-tile, 3px);
        background: rgba(255, 255, 255, .035);
        color: rgba(126, 138, 156, .68);   /* the rung floor: never under ~3:1 */
        justify-content: flex-start;
        padding: 0 6px;
        font-size: 0.625rem;
    }
    body.v2 #v2-wells.is-roomy .v2-cell-empty { font-size: 11px; }
    body.v2 .v2-cell-empty.is-last { border-bottom: 0 !important; }
}

/* a close ladder (tiles under 13px on a short window): smaller type, tighter pad */
@media (min-width: 992px) {
    body.v2 #v2-wells.is-close .v2-tile, body.v2 #v2-wells.is-close .v2-cell-empty { font-size: 10px; padding: 0 4px; }
}

/* ── THE STRIP SPANS THE CHART AND THE TICKET ─────────────────────────────
   Positions/History is a second grid row under columns 1 and 2, up to the
   rail's divider; the rail keeps its full height beside both rows. */
@media (min-width: 1440px) {
    body.v2 .trade-unified-layout { grid-template-rows: minmax(0, 1fr) auto !important; }
    body.v2 #v2-col1, body.v2 #v2-col2 { grid-row: 1 !important; }
    body.v2 #v2-col3 { grid-row: 1 / span 2 !important; }
    body.v2 .trade-unified-layout > #trade-positions-block { grid-column: 1 / 3; grid-row: 2; }
}
@media (min-width: 992px) and (max-width: 1439.98px) {
    body.v2 .trade-unified-layout { grid-template-rows: auto auto auto !important; }
    body.v2 #v2-col1 { grid-row: 1 / span 2 !important; }
    body.v2 #v2-col2 { grid-row: 1 !important; }
    body.v2 #v2-col3 { grid-row: 2 !important; }
    body.v2 .trade-unified-layout > #trade-positions-block { grid-column: 1 / -1; grid-row: 3; }
}
@media (min-width: 992px) {
    body.v2 .trade-unified-layout > #trade-positions-block { margin: 0 !important; width: auto !important; border-top: 1px solid var(--v2-hair); border-right: 1px solid var(--v2-hair); min-width: 0; }
    body.v2 .trade-unified-layout > #trade-positions-block > .col-12 { padding: 0; }
}

/* a short window: the strip row gives the ticket its buy button back
   (the ticket's card needs ~530px; at 854px tall the 216px strip clipped it) */
@media (min-width: 992px) and (max-height: 920px) {
    body.v2 { --v2-strip-block-h: 168px; }
}

/* ── THE HEADLINE ROW ON A NARROWER SCREEN ──────────────────────────────────
   The sentence carries a seconds clock; beside it the day chips and the view
   switcher must never wrap or spill (user, 2026-09-07). Under 1500px the spot
   figure leaves the headline (the ticket shows it) and the right cluster
   refuses to shrink. */
@media (min-width: 992px) and (max-width: 1499.98px) {
    body.v2 #v2-head-line .v2-head-spot { display: none !important; }
}
@media (min-width: 992px) {
    body.v2 .filter-label-section { flex-wrap: nowrap !important; }
    body.v2 .filter-label-section > .filter-label-right { flex: 0 0 auto !important; }
    body.v2 #desktop-prediction-prompt { flex: 1 1 auto; min-width: 0; }
}

@media (min-width: 992px) {
    /* the cap line and the balance share ONE row under the presets — cap
       left, balance right (user, 2026-09-08: the balance sat on top of
       "The maker can fill up to…"); five presets now, $1 first */
    body.v2 #v2-cap-note { max-width: calc(100% - 96px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    body.v2 #v2-cap-note + .v2-balance-line { margin-top: -16px !important; line-height: 16px; min-height: 16px; }
}

@media (min-width: 992px) {
    /* the position modal's payoff is the real curve and hoverable: the
       leader follows the pointer, the right caption reads the P&L there */
    body.v2 #v2-pd-payoff.is-live { cursor: crosshair; }
    body.v2 #v2-pd-payoff .v2-cf-cap-r.is-pos { color: #5EDD9C; }
    body.v2 #v2-pd-payoff .v2-cf-cap-r.is-neg { color: #E86A62; }
    /* the confirm modal draws the same live curve (2026-09-10) */
    body.v2 #v2-cf-payoff.is-live { cursor: crosshair; }
    body.v2 #v2-cf-payoff .v2-cf-cap-r.is-pos { color: #5EDD9C; }
    body.v2 #v2-cf-payoff .v2-cf-cap-r.is-neg { color: #E86A62; }
}

@media (min-width: 992px) {
    /* the confirm button is the ticket's buy button: green call, red put, sky range */
    body.v2 #trade-confirm-modal.v2-kind-put .modal-footer #confirm-trade-btn.btn { background: var(--negative) !important; color: var(--v2-on-negative) !important; }
    body.v2 #trade-confirm-modal.v2-kind-range .modal-footer #confirm-trade-btn.btn { background: var(--v2-sky) !important; color: var(--v2-on-sky) !important; }
}

@media (min-width: 992px) {
    /* rows compacted around a stray off-grid strike: the type steps down with them */
    body.v2 .v2-tile.is-tight, body.v2 .v2-cell-empty.is-tight { font-size: 10px; padding: 0 4px; line-height: 1; }
}

@media (min-width: 992px) {
    /* the day chips belong to the slider and the chain; the wells ARE the days in chart view (user, 2026-09-08) */
    body.v2 #basic-view-container:has(#v2-view-region[data-v2-view="chart"]) #v2-day-chips { display: none !important; }
    /* the spot price beside the live head on the chart */
    body.v2 .tc-tv-spot-tag {
        position: absolute; left: 0; top: 0; z-index: 6; pointer-events: none;
        font-family: var(--sans); font-size: 11px; font-weight: 600; line-height: 14px;
        padding: 3px 6px; border-radius: 4px; white-space: nowrap;
        color: var(--text-primary); background: var(--panel-sunken, #070A11);
        box-shadow: 0 0 0 1px rgba(255, 255, 255, .14);
        font-variant-numeric: tabular-nums;
    }
    body.v2 .tc-tv-spot-tag[hidden] { display: none; }
}

@media (min-width: 992px) {
    /* TradingView's own attribution mark (LightweightCharts paints
       `a#tv-attr-logo` into the price pane's <td>, bottom-left by default).
       Keep the genuine logo and its link — only move it out of the price
       action to the pane's TOP-RIGHT and take it to 75%.
       Geometry, MEASURED in Chrome at 1470px (not estimated). The logo's
       offsetParent is the pane <td> [0,224 → 264,534], so both insets are
       pane-relative, and the painted box lands at [231.8,230 → 258,244.2]
       (35x19 SVG at .75, anchored to the top-right corner):
         · `.tc-tv-tools` is [0,182 → 265,224] — it sits ABOVE the pane and
           ends exactly at the pane's top edge;
         · its zoom segment overflows RIGHT to [216,190.5 → 340.2,214.5]
           (`overflow: visible`), which is what a naive top:6px/right:8px on
           a toolbar-parented mark collides with. Anchored to the <td>
           instead, the mark starts at y=230 — 15.5px below the lowest
           toolbar child (max bottom 214.5, stable across timeframe/mode
           switches and while hovering the zoom group);
         · `#v2-wells` (the strike ladder) starts at x=265, and the mark's
           right edge is 258.
       Verified: box intersects none of the three. */
    body.v2 #v2-chart-row #tv-attr-logo {
        /* TOP-LEFT, at the library's own size (user, 2026-09-09). Left rather
           than right because the right edge of this pane is where
           #v2-chart-row::after paints its dissolve — that pseudo-element sits
           at z-index 2 in the ROW's context while #tc-tv-frame is a stacking
           context at z-index 1, so anything placed top-right is painted OVER
           by the scrim: the mark's "V" dissolved into the background and read
           as a clipped glyph. The left edge carries no scrim, so the mark
           keeps its natural size and full opacity there. */
        left: 6px !important;
        right: auto !important;
        top: 6px !important;
        bottom: auto !important;
    }

    /* The chart toolbar wanted 403px inside a 265px pane (.tc-tv-wrap is
       overflow:hidden), so everything past x=265 was simply invisible:
       measured, zoom-in showed 13px of itself, and "Fit all" and the feed
       caption were gone entirely. .tc-tv-tool carries min-width:42px from
       target-chart.css, which is why trimming padding alone changed nothing.

       Nothing is removed: the labels give back 4px each and the two zoom
       buttons drop to 26px, which is enough to bring BOTH inside the pane on
       the narrowest asset. "Fit all" and the feed caption keep their place in
       the row and are visible wherever the pane can hold them (XRP's 425px
       pane fits everything); on ETH's 265px pane they still fall past the
       edge, which is a pane-width problem — the ladder takes 640px of 905 —
       and not something this rule can honestly solve. */
    body.v2 #v2-chart-row .tc-tv-tool { min-width: 38px !important; padding: 0 8px !important; }
    body.v2 #v2-chart-row .tc-tv-zoom .tc-tv-tool { min-width: 26px !important; padding: 0 6px !important; }

    /* target-chart.css gives .tc-tv-zoom `margin-left: auto`, which pins the
       group to the FAR right of the toolbar whenever the pane has room —
       174px of dead space after "3d" on a no-ranges asset like XRP, whose
       ladder is 480px instead of 640 and so leaves a 425px pane. On ETH the
       pane is 265px, the toolbar overflows, and the auto margin collapses to
       zero, which is why the gap only shows on some assets. The zoom controls
       belong beside the timeframes they act on. */
    body.v2 #v2-chart-row .tc-tv-zoom { margin-left: 0 !important; }
}

/* the loading face over the chart row is static markup (app.html): never
   rendered on phones, and on the desktop shown by DEFAULT until V2Wells
   marks the row `is-settled` */
.v2-lattice-veil { display: none; }
@media (min-width: 992px) {
    /* the loading face over the chart row: the ground, one muted caption;
       up from the very first paint, on every hide/show of the row, on an
       asset switch and while a fit is being remade — down only once the
       ladder has settled (tiles on screen, the fit done, rows on their
       prices). It also takes the pointer: a tile under an untrustworthy
       ladder is not clickable. */
    body.v2 #v2-chart-row { position: relative; }
    body.v2 .v2-lattice-veil {
        position: absolute; inset: 0; z-index: 30;
        display: flex; align-items: center; justify-content: center;
        background: var(--background, #0B0F19);
        font-family: var(--sans); font-size: 12px; color: var(--text-muted);
        pointer-events: auto;
    }
    /* settled: the face fades out once (it comes back at once, no fade) */
    body.v2 #v2-chart-row.is-settled > .v2-lattice-veil {
        opacity: 0; visibility: hidden; pointer-events: none;
        transition: opacity 160ms ease, visibility 0s linear 160ms;
    }
}

@media (min-width: 992px) {
    /* a ghost rung is the tile's own shape: square, like a quoted tile (user, 2026-09-15) */
    body.v2 .v2-cell-empty { border-radius: 0 !important; }
}

/* ── RANGE PICKER (2026-09-27) ───────────────────────────────────────────
   The "+N MORE" list reads like the ladder: sorted by strike, highest first,
   one 32px row per zone, "> / <" for spreads, the multiple in the colour of
   its box (range sky, call spread green, put spread red). */
@media (min-width: 992px) {
    body.v2 #v2-range-pick { width: 220px; padding: 8px 0 4px; border-radius: 12px; background: var(--v2-panel, #0E1322); }
    body.v2 #v2-range-pick .v2-rp-head {
        padding: 0 12px 6px; margin: 0; font-size: 12px; font-weight: 500;
        letter-spacing: 0; text-transform: none; color: var(--text-muted);
        border-bottom: 1px solid var(--v2-hair);
    }
    body.v2 #v2-range-pick .v2-rp-row {
        grid-template-columns: 4px 1fr auto; gap: 10px; height: 32px; padding: 0 12px;
        margin: 0; border-radius: 0; background: transparent; box-shadow: none;
        border-bottom: 1px solid var(--v2-hair);
    }
    body.v2 #v2-range-pick .v2-rp-row:last-child { border-bottom: 0; }
    body.v2 #v2-range-pick .v2-rp-row:hover { background: rgba(255, 255, 255, .04); }
    body.v2 #v2-range-pick .v2-rp-row.is-selected { background: rgba(125, 211, 252, .08); box-shadow: inset 2px 0 0 var(--rp-ink); }
    body.v2 #v2-range-pick .v2-rp-span { height: 20px; }
    body.v2 #v2-range-pick .v2-rp-span i { background: var(--rp-ink); }
    body.v2 #v2-range-pick .v2-rp-b { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
    body.v2 #v2-range-pick .v2-rp-m { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--rp-ink); }
    body.v2 #v2-range-pick .is-range { --rp-ink: var(--v2-sky); }
    body.v2 #v2-range-pick .is-call  { --rp-ink: var(--positive); }
    body.v2 #v2-range-pick .is-put   { --rp-ink: var(--negative); }
}


/* ── LOADING FACE (2026-09-27) ───────────────────────────────────────────
   The page loads into its own shape: the chart row's loading face is a
   quiet skeleton of the chart and the three wells (no words, no spinner),
   one shimmer sweeps the whole face, and every late value holds its place
   with a bar of the same tone. The face lifts once, with a short fade.
   Only the error face speaks (veilFace), and then the skeleton steps aside. */
@media (min-width: 992px) {
    body.v2 { --v2-skel: rgba(255, 255, 255, .035); --v2-skel-hi: rgba(255, 255, 255, .06); }

    /* the one line is for screen readers until it has something to say */
    body.v2 .v2-lattice-veil .v2-veil-msg {
        position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
    }
    body.v2 .v2-lattice-veil.is-error .v2-veil-msg { position: static; width: auto; height: auto; clip: auto; white-space: normal; z-index: 1; }
    body.v2 .v2-lattice-veil.is-error .v2-veil-skel { display: none; }

    body.v2 .v2-veil-skel { position: absolute; inset: 0; display: flex; overflow: hidden; }
    body.v2 .v2-veil-skel i { display: block; border-radius: 4px; background: var(--v2-skel); }

    /* the chart: its toolbar, then an empty plot on the page's hairlines */
    body.v2 .v2-veil-chart { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; padding: 12px 0 0 16px; }
    body.v2 .v2-veil-tools { display: flex; gap: 8px; height: 26px; align-items: center; }
    body.v2 .v2-veil-tools i { width: 34px; height: 22px; }
    body.v2 .v2-veil-tools i:nth-child(4) { width: 52px; margin-left: 16px; }
    body.v2 .v2-veil-plot {
        flex: 1 1 auto; margin: 16px 72px 34px 0;
        background: repeating-linear-gradient(to bottom, transparent 0 63px, var(--v2-hair) 63px 64px);
        border-bottom: 1px solid var(--v2-hair);
    }

    /* the wells: head, then rungs of the tile's own height, a range column */
    body.v2 .v2-veil-wells { flex: 0 0 640px; display: flex; gap: 8px; padding: 6px 10px 0 4px; }
    body.v2 .v2-veil-well { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; border-left: 1px solid var(--v2-hair); }
    body.v2 .v2-veil-head { height: 62px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; }
    body.v2 .v2-veil-head i { width: 42px; height: 9px; }
    body.v2 .v2-veil-head i + i { width: 88px; }
    body.v2 .v2-veil-body { flex: 1 1 auto; display: flex; gap: 4px; padding: 16px 4px 28px; }
    body.v2 .v2-veil-rungs {
        flex: 1 1 0;
        background: repeating-linear-gradient(to bottom, var(--v2-skel) 0 22px, transparent 22px 26px);
        -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
                mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
    }
    body.v2 .v2-veil-ranges { flex: 0 0 90px; position: relative; }
    body.v2 .v2-veil-ranges i { position: absolute; left: 0; right: 0; top: 24%; height: 16%; border-radius: 3px; }
    body.v2 .v2-veil-ranges i + i { top: 44%; height: 14%; }

    /* ONE shimmer over the whole face, not one per shape */
    body.v2 .v2-veil-skel::after {
        content: ''; position: absolute; inset: 0; pointer-events: none;
        background: linear-gradient(100deg, transparent 35%, rgba(255, 255, 255, .025) 50%, transparent 65%);
        background-size: 250% 100%;
        animation: v2-veil-sweep 1.8s ease-in-out infinite;
    }
    @keyframes v2-veil-sweep { from { background-position: 150% 0; } to { background-position: -100% 0; } }

    /* boot: the chart tab is the landing view — the slider and the chain are
       never painted before the first switchView */
    html.v2-boot body.v2 .strike-slider-track,
    html.v2-boot body.v2 .strike-slider-container,
    html.v2-boot body.v2 .option-type-groups,
    html.v2-boot body.v2 .options-table-container { display: none !important; }

    /* late values hold their place with a bar, not a dash */
    body.v2 #v2-col1 .asset-selection-btn .v2-asset-price:empty::before {
        content: ''; display: inline-block; width: 44px; height: 9px; border-radius: 3px;
        background: var(--v2-skel-hi); vertical-align: middle;
    }
    body.v2 .v2-step-value.is-pending {
        color: transparent !important; position: relative; display: inline-block; min-width: 140px;
    }
    body.v2 .v2-step-value.is-pending::after {
        content: ''; position: absolute; left: 10%; right: 10%; top: 50%; height: 26px; margin-top: -13px;
        border-radius: 6px; background: var(--v2-skel);
    }

    /* the positions strip loads as its own rows */
    body.v2 .v2-pos-row.is-skel { cursor: default; height: 32px; padding-top: 0; padding-bottom: 0; }
    body.v2 .v2-pos-row.is-skel:hover { background: transparent; }
    body.v2 .v2-pos-row.is-skel i { display: block; height: 9px; width: 64%; border-radius: 3px; background: var(--v2-skel); }
    body.v2 .v2-pos-row.is-skel i:first-child { width: 80%; }
    body.v2 .v2-pos-skel .v2-pos-row.is-skel:nth-child(2) { opacity: .7; }
    body.v2 .v2-pos-skel .v2-pos-row.is-skel:nth-child(3) { opacity: .45; }
}
@media (min-width: 992px) and (max-width: 1439.98px) {
    body.v2 .v2-veil-wells { flex-basis: 580px; }
}
@media (min-width: 992px) and (prefers-reduced-motion: reduce) {
    body.v2 .v2-veil-skel::after { animation: none; }
    body.v2 #v2-chart-row.is-settled > .v2-lattice-veil { transition: none; }
}
@media (min-width: 992px) {
    /* a hovered spread previews its cap as ONE dashed line in its own colour */
    body.v2 .v2-zone-band.is-line { background: none; border-bottom: 0; }
    body.v2 .v2-zone-band.is-line.is-call { border-top-color: rgba(94, 221, 156, .6); }
    body.v2 .v2-zone-band.is-line.is-put { border-top-color: rgba(232, 106, 98, .6); }
}

/* ── THE TRADE PAGE LOADING SCREEN (2026-09-27) ──────────────────────────
   Until the chart and ladder first settle, the trade workspace shows its own
   shape and nothing else: asset strip, title, chart + three wells, ticket,
   positions — every late value a bar of one tone, one shimmer, one fade.
   Underneath, the page builds (hidden sections, staggered fades, the legacy
   positions table) out of sight. html.v2-loading is set in <head> and lifted
   by the first V2Wells.veil(false), or after 15s. */
#v2-boot { display: none; }
@media (min-width: 992px) {
    html.v2-loading body.v2 #trade-section { position: relative; }
    html.v2-loading body.v2 #v2-boot {
        display: grid;
        position: absolute; z-index: 40; top: 0; left: 0; right: var(--v2-rail-w);
        height: calc(100vh - 116px - var(--v2-notice-h, 0px));
        grid-template-columns: minmax(0, 1fr) var(--v2-ticket-w);
        grid-template-rows: calc(var(--v2-view-h) + 145px) minmax(0, 1fr);
        background: var(--background, #0B0F19);
        border-top: 1px solid var(--v2-hair);
        overflow: hidden;
        pointer-events: auto;
    }
    body.v2 #v2-boot i, body.v2 #v2-boot b { display: block; border-radius: 4px; background: var(--v2-skel); }
    body.v2 #v2-boot b { background: var(--v2-skel-hi); border-radius: 6px; }

    /* column 1: assets, title, the chart row (the veil's own skeleton parts) */
    body.v2 .v2-boot-main { display: flex; flex-direction: column; min-width: 0; }
    body.v2 .v2-boot-assets { display: flex; gap: 8px; height: 48px; align-items: center; padding: 0 16px; border-bottom: 1px solid var(--v2-hair); }
    body.v2 .v2-boot-assets i { width: 104px; height: 26px; border-radius: 6px; }
    body.v2 .v2-boot-assets i:first-child { background: var(--v2-skel-hi); }
    body.v2 .v2-boot-title { display: flex; align-items: center; justify-content: space-between; height: 47px; padding: 0 16px; border-bottom: 1px solid var(--v2-hair); }
    body.v2 .v2-boot-title i { width: 340px; height: 20px; }
    body.v2 .v2-boot-title b { width: 150px; height: 28px; }
    body.v2 .v2-boot-view { flex: 1 1 auto; display: flex; min-height: 0; }

    /* column 2: the ticket */
    body.v2 .v2-boot-ticket { display: flex; flex-direction: column; gap: 14px; padding: 18px 16px; border-left: 1px solid var(--v2-hair); min-width: 0; }
    body.v2 .v2-boot-ticket .is-seg { height: 30px; }
    body.v2 .v2-boot-ticket .is-h { width: 70%; height: 20px; margin-top: 4px; }
    body.v2 .v2-boot-ticket .is-spot { width: 46%; height: 34px; margin: 6px auto 4px; }
    body.v2 .v2-boot-pair, body.v2 .v2-boot-presets { display: flex; gap: 6px; }
    body.v2 .v2-boot-pair b { flex: 1; height: 30px; }
    body.v2 .v2-boot-ticket .is-field { height: 44px; background: var(--v2-skel); }
    body.v2 .v2-boot-presets b { flex: 1; height: 30px; }
    body.v2 .v2-boot-rows { display: flex; flex-direction: column; gap: 14px; padding: 14px 0 4px; }
    body.v2 .v2-boot-rows i { height: 10px; width: 100%; background: linear-gradient(90deg, var(--v2-skel) 0 28%, transparent 28% 84%, var(--v2-skel) 84%); border-radius: 0; }
    body.v2 .v2-boot-ticket .is-cta { height: 40px; }

    /* row 2: the positions strip */
    body.v2 .v2-boot-pos { grid-column: 1 / -1; border-top: 1px solid var(--v2-hair); padding: 8px 12px 0; }
    body.v2 .v2-boot-tabs { display: flex; gap: 12px; align-items: center; height: 32px; padding: 0 4px; }
    body.v2 .v2-boot-tabs b { width: 84px; height: 24px; }
    body.v2 .v2-boot-tabs i { width: 52px; height: 10px; }
    body.v2 .v2-boot-row { display: grid; grid-template-columns: 130px 100px 160px 110px minmax(0, 1fr); gap: 10px; align-items: center; height: 32px; padding: 0 16px; border-bottom: 1px solid var(--v2-hair); }
    body.v2 .v2-boot-row i { height: 9px; width: 60%; }
    body.v2 .v2-boot-row.is-head i { height: 7px; width: 44%; }
    body.v2 .v2-boot-row:last-child { opacity: .5; }

    /* one shimmer over the whole screen */
    html.v2-loading body.v2 #v2-boot::after {
        content: ''; position: absolute; inset: 0; pointer-events: none;
        background: linear-gradient(100deg, transparent 35%, rgba(255, 255, 255, .025) 50%, transparent 65%);
        background-size: 250% 100%;
        animation: v2-veil-sweep 1.8s ease-in-out infinite;
    }
}
@media (min-width: 992px) and (max-width: 1439.98px) {
    html.v2-loading body.v2 #v2-boot { right: 0; }
}
@media (min-width: 992px) and (prefers-reduced-motion: reduce) {
    html.v2-loading body.v2 #v2-boot::after { animation: none; }
}
@media (min-width: 992px) {
    html.v2-loading-out body.v2 #v2-boot { opacity: 0; transition: opacity 200ms ease; pointer-events: none; }
}
@media (min-width: 992px) {
    /* the header's wallet side waits for the loading screen: no "Connect
       wallet" flash while a remembered wallet reconnects */
    html.v2-loading body.v2 header .hdr-tools,
    html.v2-loading body.v2 header .wallet-section { visibility: hidden; }
    /* before the wallet script decides, the markup holds BOTH faces (the
       connect button and the connected pill) stacked — a 60px header that
       jumps to 30px. While loading, only one line is laid out. */
    html.v2-loading body.v2 header .wallet-section .connected-details { display: none !important; }
    /* the retired Positions link leaves no slot in the nav (the link was
       hidden, its <li> kept a gap until script removed it) */
    body.v2 .navbar-nav .nav-item:has(> #nav-positions) { display: none; }
}

/* ── SLIDER: SPREADS ON THE ZONE TRACK (2026-09-27) ──────────────────────
   Under the slider, the ranges' rows are followed by the spreads' lanes on
   the same price axis: a call spread green, a put spread red, "> cap" /
   "< cap" and its multiple — the wells' dialect. Square like the range
   boxes; each runs from its strike to the axis end on its paying side,
   because a spread keeps paying past its cap. */
@media (min-width: 992px) {
    body.v2 .ranger-zone-button.is-spread,
    body.v2 .ranger-zones-container.dimmed .ranger-zone-button.is-spread {
        height: 34px !important; min-height: 0 !important;
        display: flex; flex-direction: row; align-items: center; justify-content: flex-start; gap: 8px;
        padding: 0 10px;
        background: color-mix(in srgb, var(--sp-ink) 8%, transparent);
        border: 0; border-radius: 0;
        border-left: 2px solid color-mix(in srgb, var(--sp-ink) 70%, transparent);
        opacity: 1;
    }
    /* the side is the colour, whatever state the track is in; the strike
       edge carries the line — a call's left, a put's right */
    body.v2 #ranger-zones .ranger-zone-button.is-spread.is-call { --sp-ink: var(--positive); }
    body.v2 #ranger-zones .ranger-zone-button.is-spread.is-put {
        --sp-ink: var(--negative);
        justify-content: flex-end;
        border-left: 0; border-right: 2px solid color-mix(in srgb, var(--sp-ink) 70%, transparent);
    }
    body.v2 .ranger-zone-button.is-spread:hover { background: color-mix(in srgb, var(--sp-ink) 16%, transparent); }
    /* selected: the range box's own treatment in the spread's colour — a
       full fill step, the edge at full strength */
    body.v2 #ranger-zones .ranger-zone-button.is-spread.selected {
        background: color-mix(in srgb, var(--sp-ink) 30%, transparent);
        border-left-color: var(--sp-ink); border-right-color: var(--sp-ink);
        box-shadow: none;
    }
    body.v2 .ranger-zone-button.is-spread .ranger-btn-range { color: var(--text-primary); font-weight: 600; white-space: nowrap; }
    body.v2 .ranger-zone-button.is-spread .ranger-btn-multiplier { color: var(--sp-ink) !important; font-weight: 600; white-space: nowrap; }
}

/* ── SLIDER: GUIDES FROM THE BOXES TO THE AXIS (2026-09-28) ──────────────
   Every edge that means a price — a range's two bounds, a spread's strike —
   hangs from the slider's labels by a faint dotted line, so each box reads
   against the axis. Hover (or the selection) lights that box's lines in its
   colour and shades the stretch of the slider it pays on. */
@media (min-width: 992px) {
    body.v2 #ranger-zones { overflow: visible; }
    body.v2 #ranger-zones .ranger-zone-button { z-index: 1; }
    body.v2 #ranger-zones .v2-zg {
        --zg-ink: rgba(125, 211, 252, .28);
        position: absolute; z-index: 0; width: 0; margin-left: -0.5px;
        border-left: 1px dotted var(--zg-ink);
        pointer-events: none;
        transition: border-color 120ms ease;
    }
    body.v2 #ranger-zones .v2-zg.is-call { --zg-ink: rgba(94, 221, 156, .28); }
    body.v2 #ranger-zones .v2-zg.is-put { --zg-ink: rgba(232, 106, 98, .28); }
    body.v2 #ranger-zones .v2-zg[data-hot="is-range"] { border-left: 1px solid rgba(125, 211, 252, .85); }
    body.v2 #ranger-zones .v2-zg[data-hot="is-call"] { border-left: 1px solid rgba(94, 221, 156, .85); }
    body.v2 #ranger-zones .v2-zg[data-hot="is-put"] { border-left: 1px solid rgba(232, 106, 98, .85); }
    body.v2 #ranger-zones .v2-zband {
        position: absolute; z-index: 0; pointer-events: none; border-radius: 4px;
        background: rgba(125, 211, 252, .35);
        box-shadow: 0 0 0 3px rgba(125, 211, 252, .12);
    }
    body.v2 #ranger-zones .v2-zband.is-call { background: rgba(94, 221, 156, .38); box-shadow: 0 0 0 3px rgba(94, 221, 156, .12); }
    body.v2 #ranger-zones .v2-zband.is-put { background: rgba(232, 106, 98, .38); box-shadow: 0 0 0 3px rgba(232, 106, 98, .12); }
    body.v2 #ranger-zones .v2-zband[hidden] { display: none; }
}

/* ── DAY TABS ≠ VIEW SWITCHER (2026-09-28) ───────────────────────────────
   The expiry days are a different question from the view, so they stop
   wearing the segmented switcher: bare words on the ground, the chosen day
   in full ink over a 2px underline, the others muted. The view switcher
   keeps the sunken track beside them. */
@media (min-width: 992px) {
    body.v2 #v2-day-chips {
        gap: 14px !important;
        padding: 0 !important;
        background: transparent !important;
        border-radius: 0 !important;
        margin-right: 18px !important;
        align-items: stretch;
    }
    body.v2 #v2-day-chips .v2-chain-tab {
        height: 28px !important;
        padding: 0 1px !important;
        border-radius: 0 !important;
        background: transparent !important;
        border-bottom: 2px solid transparent !important;
        color: var(--text-muted) !important;
    }
    body.v2 #v2-day-chips .v2-chain-tab:hover { color: var(--text-secondary) !important; background: transparent !important; }
    body.v2 #v2-day-chips .v2-chain-tab.is-active {
        background: transparent !important;
        color: var(--text-primary, #F5F7FA) !important;
        font-weight: 600 !important;
        border-bottom-color: var(--text-primary, #F5F7FA) !important;
    }
}

/* ── WRONG-NETWORK BANNER (2026-09-28) ───────────────────────────────────
   A strip, not a floating yellow box: full width under the competition band,
   a faint amber ground with an amber hairline beneath, one amber dot, one
   short line, and the page's white primary button — the close mark muted. */
@media (min-width: 992px) {
    body.v2 #connection-alert {
        margin: 0 !important;
        padding: 0 44px 0 20px !important;
        border: 0 !important;
        border-bottom: 1px solid rgba(217, 168, 60, .22) !important;
        border-radius: 0 !important;
        background: rgba(217, 168, 60, .06) !important;
        color: var(--text-secondary) !important;
        box-shadow: none !important;
    }
    body.v2 #connection-alert .network-alert-box {
        display: flex; align-items: center; gap: 14px; min-height: 44px;
    }
    body.v2 #connection-alert-text {
        display: inline-flex; align-items: center; gap: 10px;
        font-size: 12.5px; font-weight: 500; color: var(--text-primary);
    }
    body.v2 #connection-alert-text::before {
        content: ''; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%;
        background: #D9A83C; box-shadow: 0 0 0 3px rgba(217, 168, 60, .18);
    }
    body.v2 #switch-network-btn {
        margin-left: 0 !important;
        height: 28px; padding: 0 12px !important;
        border: 0 !important; border-radius: 6px !important;
        background: var(--v2-primary-bg, #F5F7FA) !important;
        color: var(--v2-ink, #0B0F19) !important;
        font-size: 12px !important; font-weight: 600 !important; line-height: 28px !important;
        box-shadow: none !important;
    }
    body.v2 #switch-network-btn:hover { filter: brightness(.92); }
    body.v2 #connection-alert .btn-close {
        top: 50% !important; right: 14px !important; transform: translateY(-50%);
        padding: 0 !important; width: 10px; height: 10px;
        opacity: .45; filter: invert(1) grayscale(1); background-size: 10px;
    }
    body.v2 #connection-alert .btn-close:hover { opacity: .8; }
}
@media (min-width: 992px) {
    /* the ticket's switch reads like its other primary buttons: sentence case */
    body.v2 .v2-switch-base { letter-spacing: 0; font-size: 13px; text-transform: none; }
}

/* ── TICKET: ONE-LINE PAIRS, NEVER A SCROLL (2026-09-28) ─────────────────
   Two strikes (a spread's "2,720 / 2,700", a range's "2,600–2,700") sit on
   one line at a smaller figure. When the ticket is taller than its column,
   fitTicket() tightens the spacing in two steps instead of scrolling. */
@media (min-width: 992px) {
    body.v2 .v2-step-value.is-pair { font-size: 26px !important; white-space: nowrap; letter-spacing: -0.01em; line-height: 1.15 !important; }

    body.v2 .trade-preview-card.is-tight { padding-top: 8px !important; padding-bottom: 8px !important; }
    body.v2 .trade-preview-card.is-tight .v2-ticket-tabs { margin: 6px 0 8px !important; }
    body.v2 .trade-preview-card.is-tight .v2-question { margin-bottom: 8px !important; }
    body.v2 .trade-preview-card.is-tight .v2-step-sub { margin: 4px 0 6px !important; }
    body.v2 .trade-preview-card.is-tight .v2-expiry-line { margin-bottom: 6px !important; }
    body.v2 .trade-preview-card.is-tight .v2-side { margin-bottom: 8px !important; }
    body.v2 .trade-preview-card.is-tight .v2-presets { margin-bottom: 8px !important; }
    body.v2 .trade-preview-card.is-tight .ticket-decision { row-gap: 6px !important; gap: 6px !important; }

    body.v2 .trade-preview-card.is-tighter .v2-param { padding-top: 1px !important; padding-bottom: 1px !important; margin-bottom: 2px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-step-value:not(.is-pair) { font-size: 28px !important; }
    body.v2 .trade-preview-card.is-tighter .ticket-amount-field { padding-top: 6px !important; padding-bottom: 6px !important; margin-bottom: 6px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-switch-base { padding: 9px 0 !important; }
    body.v2 .trade-preview-card.is-tighter .v2-ticket-tabs { margin: 2px 0 6px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-question { margin-bottom: 4px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-expiry-line { padding-bottom: 3px !important; margin-bottom: 4px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-side { margin-bottom: 6px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-presets { margin-bottom: 6px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-balance-line { margin-bottom: 2px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-commit-cause { margin-top: 2px !important; }
}
@media (min-width: 992px) {
    /* a spread cell runs from its strike to the column's end: its multiple
       sits at the strike end, the edge that means a price */
    body.v2 #v2-wells .v2-range.v2-spread.is-call { justify-content: flex-end; padding-bottom: 5px; }
    body.v2 #v2-wells .v2-range.v2-spread.is-put { justify-content: flex-start; padding-top: 5px; }
    body.v2 #v2-wells .v2-range.v2-spread.is-call { border-top-color: transparent !important; }
    body.v2 #v2-wells .v2-range.v2-spread.is-put { border-bottom-color: transparent !important; }
}

/* ── LADDER TILES: STRIKE + SIDE ONLY; COST IN THE TICKET (2026-09-28) ───
   The tile says the level and the side ("> 2,800" call, "< 2,660" put); the
   premium moved to the ticket's Cost row, so the strike column — and the
   ladder — narrow and the chart takes the width back. The ticket's rows sit
   flush, one after another. */
@media (min-width: 992px) {
    body.v2 #v2-wells .v2-tile .v2-prem { display: none !important; }
    body.v2 #v2-wells .v2-tile { justify-content: flex-start; }
    body.v2 #v2-wells .v2-tile .v2-tile-sign {
        font-style: normal; display: inline-block; width: 1.1em; margin-right: 2px;
        color: var(--positive); opacity: .85;
    }
    body.v2 #v2-wells .v2-tile.is-put .v2-tile-sign { color: var(--negative); }
    body.v2 #v2-wells .v2-tile.is-selected .v2-tile-sign { color: inherit; opacity: 1; }
    body.v2 #v2-wells { --v2-wells-w: 560px; }

    body.v2 #v2-params .v2-param { margin: 0 !important; padding-top: 1px !important; padding-bottom: 1px !important; line-height: 16px !important; min-height: 0 !important; }
    body.v2 #v2-params .v2-param > * { line-height: 16px !important; }
    body.v2 #v2-params { gap: 0 !important; row-gap: 0 !important; }
}
@media (min-width: 992px) and (max-width: 1439.98px) {
    body.v2 #v2-wells { --v2-wells-w: 520px; }
}
@media (min-width: 992px) {
    /* the spread label: one line; when the box is too narrow for it (a strike
       near the axis end) it sits OUTSIDE the box, beyond the strike, so the
       box's edge stays on the true strike (codex, PR #77) */
    body.v2 #ranger-zones .ranger-zone-button.is-spread .v2-sp-lab { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
    body.v2 #ranger-zones .ranger-zone-button.is-spread.is-label-out { overflow: visible; }
    body.v2 #ranger-zones .ranger-zone-button.is-spread.is-label-out .v2-sp-lab { position: absolute; top: 50%; transform: translateY(-50%); }
    body.v2 #ranger-zones .ranger-zone-button.is-spread.is-call.is-label-out .v2-sp-lab { right: calc(100% + 8px); }
    body.v2 #ranger-zones .ranger-zone-button.is-spread.is-put.is-label-out .v2-sp-lab { left: calc(100% + 8px); }
}

/* ==========================================================================
   Round 14 · trade cleanup (2026-09-29). Less grey text, one clear clock on
   the ticket. Nothing is removed: hidden copy moves to a tooltip, the live
   region or the Advanced switch. Colours are the existing tokens only.
   ========================================================================== */
@media (min-width: 992px) {
    /* the ticket's clock: when it settles on one line, the time left set
       large beneath it, the day bar under both */
    body.v2 .v2-expiry-line {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        row-gap: 2px;
        align-items: baseline;
        margin: 4px 0 10px;
        padding: 8px 12px 12px;
        border-radius: 6px;
        background: var(--v2-chip-inset);
        white-space: normal;
    }
    body.v2 .v2-expiry-line b {
        font-family: var(--sans);
        font-size: 12px;
        font-weight: 500;
        letter-spacing: 0;
        color: var(--text-primary);
    }
    body.v2 .v2-expiry-line span,
    body.v2 #v2-expiry-left {
        font-family: var(--num);
        font-size: 26px;
        font-weight: 600;
        line-height: 1.1;
        letter-spacing: -0.02em;
        color: var(--text-primary);
        font-variant-numeric: tabular-nums;
        text-align: left;
        min-width: 0;
    }
    body.v2 .v2-expiry-bar { left: 12px; right: 12px; bottom: 6px; }
    body.v2 .trade-preview-card.is-tight .v2-expiry-line { padding-top: 6px !important; padding-bottom: 10px !important; }
    body.v2 .trade-preview-card.is-tighter .v2-expiry-line { padding-top: 5px !important; padding-bottom: 9px !important; }
    body.v2 .trade-preview-card.is-tighter #v2-expiry-left { font-size: 22px; }

    /* the slider's sentence repeats the ticket's Pays row: kept for screen
       readers, off the page */
    body.v2 #v2-slider-caption {
        position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden;
        clip: rect(0 0 0 0); white-space: nowrap;
    }

    /* Delta and IV live under Advanced; Basic shows strike, premium, break-even */
    body.v2:not(.v2-adv) .v2-tbl-head,
    body.v2:not(.v2-adv) .v2-tbl-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    body.v2:not(.v2-adv) .v2-tbl-head span:nth-child(n+4),
    body.v2:not(.v2-adv) .v2-tbl-row span:nth-child(n+4) { display: none; }
    body.v2:not(.v2-adv) .v2-chain-head,
    body.v2:not(.v2-adv) .v2-chain-row { grid-template-columns: minmax(0, 1fr) 96px minmax(0, 1fr); }
    body.v2:not(.v2-adv) .v2-chain-head > .v2-chain-greeks,
    body.v2:not(.v2-adv) .v2-chain-row > .v2-chain-greeks { display: none !important; }

    /* news folds to the next event; the head opens the list */
    body.v2 #v2-news .v2-mod-head { cursor: pointer; user-select: none; }
    body.v2 #v2-news .v2-news-chev { margin-left: auto; font-size: 11px; color: var(--text-muted); transition: transform 160ms ease; }
    body.v2 #v2-news:not(.is-folded) .v2-news-chev { transform: rotate(180deg); }
    body.v2 #v2-news .v2-mod-head:focus-visible { outline: 2px solid var(--v2-sky); outline-offset: -2px; }
    body.v2 #v2-news.is-folded .v2-news-item:not(.is-next),
    body.v2 #v2-news.is-folded .v2-news-all { display: none; }
    body.v2 #v2-news.is-folded .v2-news-list { padding-bottom: 6px; }
    body.v2 #v2-news.is-folded .v2-news-item.is-next { border-bottom: 0; min-width: 0; }
    body.v2 #v2-news.is-folded .v2-news-item.is-next .v2-news-name {
        min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }

    /* the payoff at expiry in the ticket: the confirm modal's curve, shorter;
       a short window shrinks it, then lets it step aside before the Buy button would */
    /* the captions get their own strip above the plot: laid over it, they ran
       through the curve wherever the profit line sat at the top (2026-09-29) */
    body.v2 .v2-tk-payoff { height: auto; padding-top: 24px; margin: 8px 0 2px; cursor: crosshair; }
    /* the curve is drawn at 340×96: the plot keeps that shape so the marker
       stays round and the strokes even (a fixed height squashed it) */
    body.v2 .v2-tk-payoff svg { height: auto; aspect-ratio: 340 / 96; }
    body.v2 .v2-tk-payoff i { top: 5px; line-height: 14px; }
    body.v2 .v2-tk-payoff[hidden] { display: none; }
    body.v2 .v2-tk-payoff .v2-cf-cap-r.is-pos { color: #5EDD9C; }
    body.v2 .v2-tk-payoff .v2-cf-cap-r.is-neg { color: #E86A62; }
    body.v2 .trade-preview-card.is-tighter .v2-tk-payoff { margin-top: 4px; }
    body.v2 .trade-preview-card.is-tightest .v2-tk-payoff { display: none; }

    /* the room's notices: an info mark beside the tabs, not the list's head */
    body.v2 #trollbox-messages > .system-message.v2-room-rule { display: none; }
    body.v2 #v2-chat .trollbox-title > #v2-chat-rules { display: inline-block; font-size: 12px; line-height: 1; color: var(--text-muted); cursor: help; margin-left: 2px; }
    body.v2 #v2-chat-rules:hover,
    body.v2 #v2-chat-rules:focus-visible { color: var(--text-primary); outline: none; }
}
