/**
 * shell.css — new dashboard shell layout (step 1 of overhaul).
 *
 * Adds the two-pane workspace + agent shell, the sticky topbar
 * with KPI strip and markets cluster, the resize splitter,
 * collapsible sections, the new strategy detail modal, the
 * markets/broker/monitor detail modals, and the mobile bottom
 * sheet. Sits *on top of* dashboard.css and chat.css; does not
 * redefine theme variables.
 *
 * Why a new file: dashboard.css is already ~3,000 lines and the
 * shell layout is a layered concern. Keeping the shell rules
 * isolated lets us revert by removing one stylesheet link.
 */

/* ── Body reset ─────────────────────────────────────────────
   The legacy layout used `body { padding: 1rem 2rem }` and let
   the page scroll. The new shell takes the full viewport, with
   the workspace pane handling its own scroll. */
body {
    padding: 0 !important;
    overflow: hidden;
    height: 100vh;
}

/* Background blobs were anchored to the body's scroll context;
   in the new shell they'd land behind the topbar and look odd.
   Disabled here, theme palettes stay untouched. */
body::before,
body::after {
    display: none !important;
}

/* ── Topbar ─────────────────────────────────────────────────
   56px sticky strip. Contains the brand, the KPI cluster, the
   markets cluster, and the theme/notification controls. Always
   visible regardless of workspace scroll position. */
.topbar {
    height: 56px;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    border-bottom: 1px solid var(--card-border);
    background: var(--card-bg);
    backdrop-filter: blur(24px) saturate(1.2);
    -webkit-backdrop-filter: blur(24px) saturate(1.2);
    flex-shrink: 0;
    z-index: 10;
    position: relative;
}

.topbar h1 {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -.01em;
    margin: 0;
    flex-shrink: 0;
}

.topbar #last-updated {
    font-size: .65rem;
    color: var(--muted2);
    flex-shrink: 0;
}

/* KPI cluster: balance, P&L, win rate, position counts. Scrolls
   horizontally if the viewport is too narrow to fit everything;
   the scrollbar is hidden so it looks like one row that simply
   trims off-screen. */
.topbar .kpis {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.topbar .kpis::-webkit-scrollbar {
    display: none;
}

.kpi {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    flex-shrink: 0;
}

.kpi .label {
    font-size: .65rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.kpi .value {
    font-size: .9rem;
    font-weight: 600;
    color: var(--muted4);
}

.kpi .value.pos {
    color: #4ade80;
}

.kpi .value.neg {
    color: #f87171;
}

.kpi-divider {
    width: 1px;
    height: 28px;
    background: var(--card-border);
    flex-shrink: 0;
}

/* Clickable KPIs — visual affordance for the ones that open
   detail modals (Balance, Available, Win rate, P&L, Strats/Pos).
   The label and value get a subtle hover so it's clear they're
   interactive without being noisy. */
.kpi.clickable {
    cursor: pointer;
    border-radius: 6px;
    padding: .15rem .4rem;
    margin: 0 -.4rem;
    transition: background .15s;
}

.kpi.clickable:hover {
    background: var(--btn-bg);
}

.kpi.clickable:hover .label {
    color: var(--muted3);
}

/* Status pills (broker, monitor) — clickable, open detail modals */
.topbar .status-pill {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem;
    border-radius: 999px;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    font-size: .75rem;
    color: var(--muted4);
    flex-shrink: 0;
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

.topbar .status-pill:hover {
    border-color: var(--btn-border-hover);
    background: var(--btn-bg);
}

.topbar .status-pill .dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--muted2);
}

.topbar .status-pill .dot.green {
    background: #4ade80;
    box-shadow: 0 0 6px rgba(74, 222, 128, .5);
}

.topbar .status-pill .dot.amber {
    background: #fbbf24;
}

.topbar .status-pill .dot.red {
    background: #f87171;
}

.topbar .right {
    display: flex;
    align-items: center;
    gap: .35rem;
    flex-shrink: 0;
}

/* ── Markets cluster ────────────────────────────────────────
   Summary chip + one pill per market we trade. Single source of
   truth = the API's market-hours response, transformed into the
   pill list at refreshMarketHours() time. */
.markets-cluster {
    display: flex;
    align-items: center;
    gap: .25rem;
    flex-shrink: 0;
    padding-left: .25rem;
    border-left: 1px solid var(--card-border);
    margin-left: .25rem;
}

.market-summary {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .15rem .55rem;
    border-radius: 6px;
    background: var(--btn-bg);
    border: 1px solid var(--btn-border);
    font-size: .7rem;
    color: var(--color);
    cursor: pointer;
    line-height: 1;
    transition: border-color .15s, background .15s;
    flex-shrink: 0;
    font-weight: 500;
}

.market-summary:hover {
    border-color: var(--btn-border-hover);
    background: var(--btn-bg-hover);
}

.market-summary .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #4ade80;
}

.market-pill {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .15rem .4rem;
    border-radius: 6px;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    font-size: .7rem;
    color: var(--muted4);
    cursor: pointer;
    line-height: 1;
    transition: border-color .15s, background .15s;
    flex-shrink: 0;
}

.market-pill:hover {
    border-color: var(--btn-border-hover);
    background: var(--btn-bg);
}

.market-pill .dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
}

.market-pill .dot.green {
    background: #4ade80;
}

.market-pill .dot.amber {
    background: #fbbf24;
}

.market-pill .dot.red {
    background: #f87171;
}

.market-pill strong {
    font-weight: 600;
    font-size: .7rem;
    letter-spacing: .02em;
    color: var(--muted4);
}

.market-pill .pct {
    font-size: .65rem;
    font-variant-numeric: tabular-nums;
}

.market-pill .pct.pos {
    color: #4ade80;
}

.market-pill .pct.neg {
    color: #f87171;
}

/* On narrow viewports drop the change_pct so all market codes
   still fit. The dot still conveys open/closed status. */
@media (max-width: 1100px) {
    .market-pill .pct {
        display: none;
    }
}

/* Theme & notification buttons inherit from dashboard.css's
   .theme-btn rules; nothing to add here. The bell is rendered
   inline in the topbar markup as a .theme-btn. */

/* ── Two-pane shell ─────────────────────────────────────────
   Workspace (scrollable) | splitter | agent pane (fixed
   height). The grid columns are driven by CSS variables that
   the splitter JS updates. */
.shell {
    display: grid;
    grid-template-columns: var(--workspace-w, 1fr) 6px var(--agent-w, 380px);
    height: calc(100vh - 56px);
    position: relative;
}

.workspace {
    overflow-y: auto;
    padding: 1rem 1.25rem 4rem;
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) transparent;
    position: relative;
    z-index: 1;
}

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

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

/* The legacy stylesheet sets `position: relative; z-index: 1`
   on .grid, .grid-top, .actions etc. so the background blobs
   sit behind cards. With blobs disabled and the workspace
   already z:1, those rules still work fine. We just need to
   make sure the workspace's own scroll context contains them. */

/* ── Splitter ──────────────────────────────────────────────
   6px draggable column. Visual line is centered, hover/drag
   thicken it without changing layout. */
.splitter {
    cursor: col-resize;
    position: relative;
    background: transparent;
}

.splitter::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--card-border);
    transform: translateX(-50%);
    transition: background .15s, width .15s;
}

.splitter:hover::before,
.splitter.dragging::before {
    background: var(--btn-border-hover);
    width: 3px;
}

/* ── Agent pane ────────────────────────────────────────────
   Promoted from a floating drawer to a first-class pane.
   Default 380px, resizable via splitter, collapsible to a
   24px edge strip. The strip exposes a vertical "Agent" rail
   so the pane can be re-opened with one click. */
.agent-pane {
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    backdrop-filter: blur(24px) saturate(1.2);
    -webkit-backdrop-filter: blur(24px) saturate(1.2);
    border-left: 1px solid var(--card-border);
    overflow: hidden;
    position: relative;
}

/* Override the legacy .chat-drawer drawer positioning on
   desktop. The agent-pane node also has class="chat-drawer"
   so chat.js can keep using its existing FAB-toggles-#chat-drawer
   wiring on mobile. On desktop the same node is the right
   column of the shell grid, so it must NOT be position:fixed
   and must NOT be transformed off-screen. The mobile media
   query later in this file restores the drawer behaviour at
   ≤900px. */
@media (min-width: 901px) {
    .agent-pane.chat-drawer {
        position: relative !important;
        transform: none !important;
        width: auto !important;
        max-width: none !important;
        box-shadow: none !important;
        z-index: auto !important;
        top: auto !important;
        right: auto !important;
        bottom: auto !important;
        left: auto !important;
    }
}

.shell.agent-collapsed {
    grid-template-columns: 1fr 0 24px;
}

.shell.agent-collapsed .splitter {
    pointer-events: none;
}

.shell.agent-collapsed .agent-pane>*:not(.agent-rail) {
    display: none;
}

.agent-rail {
    display: none;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
    padding: .75rem 0;
    width: 100%;
}

.shell.agent-collapsed .agent-rail {
    display: flex;
}

.agent-rail button {
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: 8px;
    font-size: .9rem;
}

.agent-rail-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: .7rem;
    color: var(--muted);
    letter-spacing: .15em;
    text-transform: uppercase;
    margin-top: .5rem;
}

.agent-pane .chat-header {
    /* Reuses the existing .chat-header styles from chat.css with a
     small tweak — the pane is a column header, not a drawer. */
    padding: .75rem 1rem;
}

/* The agent body / footer styles already exist in chat.css; the
   only thing different here is the container is a pane (not a
   drawer transformed off-screen). The chat.js drawer-toggle path
   is replaced by the pane-collapse toggle. */

/* ── Mobile fallback ───────────────────────────────────────
   Below 900px we collapse to a single column. The agent
   becomes a bottom-sheet drawer triggered by an FAB (the same
   pattern as today's chat widget, kept because it works on
   touch). */
@media (max-width: 900px) {
    .shell {
        grid-template-columns: 1fr !important;
    }

    .splitter {
        display: none;
    }

    /* The agent pane stops being a column and becomes a fixed
       full-screen sheet that slides in from the right. Reuses
       the existing chat-drawer transform pattern so chat.js's
       FAB toggle (.open class) keeps working. */
    .agent-pane {
        position: fixed;
        top: 56px;
        bottom: 0;
        right: 0;
        width: 100vw;
        max-width: 100vw;
        z-index: 1001;
        transform: translateX(100%);
        transition: transform .25s ease-out;
        border-left: none;
    }

    .agent-pane.open {
        transform: translateX(0);
    }

    .agent-pane .chat-header {
        border-bottom: 1px solid var(--card-border);
        padding: 1rem 1rem;
    }

    /* The desktop "→|" collapse button is a no-op on mobile —
       there's no grid to collapse. Hide it; show a regular
       close (✕) instead so the user can dismiss the drawer
       without hunting for the FAB. */
    #chat-collapse {
        display: none !important;
    }

    #chat-close {
        display: inline-flex !important;
    }

    /* The collapsed-rail is desktop-only — on mobile the pane
       is either a full-screen drawer (.open) or off-screen. */
    .agent-rail {
        display: none !important;
    }

    /* Topbar density: slightly reduced padding, but tap targets
       (theme buttons, pills) get bigger via separate rules. */
    .topbar {
        padding: 0 .75rem;
        gap: .6rem;
    }

    .topbar h1 {
        font-size: .9rem;
    }

    /* Bigger tap targets — minimum ~36×36 for buttons, 32px
       for pills. Apple/Google guidelines say 44×44; we trade
       a bit of vertical space for that on the topbar's 56px
       fixed height. */
    .theme-btn {
        min-height: 36px;
        min-width: 36px;
        padding: .4rem .55rem;
        font-size: .8rem;
    }

    .topbar .status-pill,
    .market-summary,
    .market-pill {
        padding: .35rem .65rem;
        font-size: .8rem;
        min-height: 32px;
    }

    .market-pill .dot,
    .market-summary .dot,
    .topbar .status-pill .dot {
        width: 8px;
        height: 8px;
    }

    /* Topbar scrollable KPI cluster: a soft right-edge fade
       so the user sees there's more content to scroll to. The
       fade aligns with the right gutter so it doesn't bleed
       under the theme buttons. */
    .topbar .kpis {
        position: relative;
        mask-image: linear-gradient(to right,
                transparent 0,
                #000 16px,
                #000 calc(100% - 24px),
                transparent 100%);
        -webkit-mask-image: linear-gradient(to right,
                transparent 0,
                #000 16px,
                #000 calc(100% - 24px),
                transparent 100%);
        scroll-snap-type: x proximity;
    }

    .topbar .kpi,
    .topbar .status-pill,
    .markets-cluster {
        scroll-snap-align: start;
    }

    /* Section summaries get a touch more vertical padding so
       they're easier to tap accurately. */
    .workspace details.section>summary {
        padding: 1rem 1.1rem;
        min-height: 48px;
    }

    /* Strategy detail modal tabs: allow wrapping if there's
       no room (e.g. with a translation that lengthens labels). */
    .strategy-modal-tabs,
    .market-tabs {
        flex-wrap: wrap;
    }

    /* Modal close buttons: bigger tap target. */
    .modal-close {
        font-size: 1.4rem;
        padding: .4rem .6rem;
        line-height: 1;
    }

    /* Tables inside modals can overflow on phones; let the
       parent scroll horizontally rather than break the layout. */
    .modal-body table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        white-space: nowrap;
    }
}

@media (max-width: 540px) {
    .workspace {
        padding: .75rem;
    }

    /* Hide the brand label below 540px to free up topbar room.
       The "last updated" stamp goes too — it lives inside the
       brand block; the user can pull-to-refresh / wait the 30s. */
    .topbar h1,
    .topbar #last-updated {
        display: none;
    }

    /* Topbar gets even tighter and the divider lines go away
       so each KPI reads as its own chip with a bit of air. */
    .topbar {
        gap: .5rem;
    }

    .kpi-divider {
        display: none;
    }

    /* KPIs become slightly more chip-like with a faint border
       so they're visually delimited without the dividers. */
    .kpi {
        padding: .25rem .5rem;
        background: var(--input-bg);
        border: 1px solid var(--input-border);
        border-radius: 6px;
        line-height: 1.15;
    }

    .kpi.clickable {
        margin: 0;
    }

    /* Modal panels go nearly full-screen on phones. The 16px
       backdrop padding from the .modal-backdrop default leaves
       a small breathing margin so the modal isn't edge-glued. */
    .modal {
        max-width: 100% !important;
        max-height: calc(100vh - 32px) !important;
        border-radius: 12px;
    }

    .modal-header {
        padding: .85rem 1rem;
    }

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

    /* Performance modal stat grid loses its 4-col layout in
       favour of a 2-col chip grid that fits a 360px viewport. */
    .strategy-perf-grid {
        grid-template-columns: 1fr 1fr;
    }

    .strategy-perf-grid .val {
        font-size: .85rem;
    }
}

/* ── Mobile FAB ────────────────────────────────────────────
   Reuses the existing #chat-fab style from chat.css. We only
   need to hide it on desktop (where the agent pane is always
   visible) and surface it on mobile. */
@media (min-width: 901px) {
    .chat-fab {
        display: none !important;
    }
}

/* ── Strategy detail modal: Setup / Performance / Trades ───
   The modal carries the indicator setup matrix, the full
   config block, the latest reasons, and (when present) the
   adaptation context. The Performance and Trades tabs live
   side-by-side as separate panes the user toggles. */

.strategy-modal-tabs {
    display: flex;
    gap: .35rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--card-border);
    padding-bottom: .5rem;
}

.strategy-modal-tab {
    padding: .35rem .75rem;
    font-size: .75rem;
    border-radius: 8px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted3);
    cursor: pointer;
    transition: background .15s, border-color .15s;
}

.strategy-modal-tab:hover {
    color: var(--color);
}

.strategy-modal-tab.active {
    background: var(--btn-bg);
    border-color: var(--btn-border);
    color: var(--color);
}

/* Setup tab top row: 3 stat blocks. */
.strategy-setup-toprow {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .5rem;
    margin-bottom: .5rem;
}

.strategy-setup-toprow .stat-block,
.strategy-perf-grid .stat-block {
    padding: .55rem .7rem;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: 8px;
}

.strategy-setup-toprow .lbl,
.strategy-perf-grid .lbl {
    font-size: .55rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.strategy-setup-toprow .val,
.strategy-perf-grid .val {
    font-size: .9rem;
    font-weight: 600;
    color: var(--muted4);
}

.strategy-perf-grid .val.pos {
    color: #4ade80;
}

.strategy-perf-grid .val.neg {
    color: #f87171;
}

.strategy-setup-h4 {
    margin: 1.1rem 0 .5rem;
    font-size: .7rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .05em;
    font-weight: 600;
}

/* Modal-sized indicator matrix — bigger than the existing
   card-level .ind-matrix from dashboard.css. Padded card,
   tabular numerics, met/miss colour. */
.modal .strategy-ind-matrix {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .55rem 1.5rem;
    padding: .75rem 1rem;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: 10px;
    font-size: .9rem;
}

.modal .strategy-ind-matrix .ind-label {
    color: var(--muted3);
}

.modal .strategy-ind-matrix .ind-value {
    text-align: right;
    color: var(--muted4);
    font-variant-numeric: tabular-nums;
}

.modal .strategy-ind-matrix .ind-value.met {
    color: #4ade80;
}

.modal .strategy-ind-matrix .ind-value.miss {
    color: #f87171;
}

.strategy-config-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: .4rem .75rem;
    padding: .75rem 1rem;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: 10px;
}

.strategy-config-grid .row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: .82rem;
    padding: 0;
    border-bottom: none;
}

.strategy-config-grid .row .lbl {
    color: var(--muted);
    font-size: .72rem;
}

.strategy-config-grid .row .val {
    color: var(--muted4);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 540px) {

    .strategy-setup-toprow,
    .strategy-config-grid {
        grid-template-columns: 1fr;
    }
}

.strategy-reasons-list {
    margin: 0;
    padding-left: 1.1rem;
    list-style: disc;
    color: var(--muted3);
    font-size: .82rem;
    line-height: 1.55;
}

.strategy-reasons-list li::marker {
    color: var(--muted);
}

/* Performance tab: 4-column metric grid + equity curve. */
.strategy-perf-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: .5rem;
    margin-bottom: 1rem;
}

@media (max-width: 540px) {
    .strategy-perf-grid {
        grid-template-columns: 1fr 1fr;
    }
}

.strategy-equity-curve {
    width: 100%;
    height: 140px;
    background: rgba(0, 0, 0, .15);
    border-radius: 10px;
    margin-bottom: 1rem;
}

.strategy-trade-row {
    display: grid;
    grid-template-columns: 60px 70px 1fr auto auto;
    gap: .5rem;
    padding: .35rem .25rem;
    font-size: .75rem;
    border-bottom: 1px solid var(--td-border);
    align-items: center;
}

.strategy-trade-row:last-child {
    border-bottom: none;
}

/* ── Markets / broker / monitor detail modals ─────────────
   The markets modal has its own tabbed body (one tab per
   market). Broker and monitor modals are simple key-value
   lists rendered into existing ids the dashboard.js refresh
   code writes to. */

.market-tabs {
    display: flex;
    gap: .25rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--card-border);
    padding-bottom: .5rem;
    flex-wrap: wrap;
}

.market-tab {
    padding: .35rem .75rem;
    font-size: .75rem;
    border-radius: 8px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted3);
    cursor: pointer;
}

.market-tab.active {
    background: var(--btn-bg);
    border-color: var(--btn-border);
    color: var(--color);
}

.market-detail {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.market-detail .stat-block {
    padding: .75rem 1rem;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: 10px;
}

.market-detail .stat-block .lbl {
    font-size: .65rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .05em;
}

.market-detail .stat-block .val {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--muted4);
}

.market-detail-timeline {
    grid-column: span 2;
    position: relative;
    height: 24px;
    background: var(--mh-track-bg);
    border-radius: 6px;
    margin-top: .25rem;
    margin-bottom: 1.5rem;
}

.market-detail-timeline .session {
    position: absolute;
    top: 0;
    bottom: 0;
    background: rgba(74, 222, 128, .25);
    border-radius: 4px;
}

.market-detail-timeline .now {
    position: absolute;
    top: -4px;
    bottom: -4px;
    width: 2px;
    background: #fbbf24;
    z-index: 2;
    border-radius: 1px;
}

.market-detail-timeline .hours {
    position: absolute;
    bottom: -16px;
    left: 0;
    right: 0;
    display: flex;
    justify-content: space-between;
    font-size: .55rem;
    color: var(--muted2);
}

.market-symbol-list {
    grid-column: span 2;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: .4rem;
}

.market-symbol-pill {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: .35rem .6rem;
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: 8px;
    font-size: .75rem;
}

@media (max-width: 540px) {
    .market-detail {
        grid-template-columns: 1fr;
    }
}

/* Simple key-value modal body for broker / monitor modals.
   Uses the existing .row class from dashboard.css. */
.kv-modal-body .row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: .4rem 0;
    font-size: .85rem;
    border-bottom: 1px solid var(--td-border);
}

.kv-modal-body .row:last-child {
    border-bottom: none;
}

.kv-modal-body .row span:first-child {
    color: var(--muted3);
}

.kv-modal-body .row span:last-child {
    color: var(--muted4);
    font-weight: 500;
}


/* ── Workspace sections ─────────────────────────────────────
   The workspace is split into 5 collapsible sections:
   Operations, Portfolio, Strategy signals, Diagnostics,
   Backtest & tools. Each is a <details> element so the
   open/closed state is keyboard-accessible and we get free
   tap targets on touch devices. shell.js persists open/closed
   state per section to localStorage. */

.workspace details.section {
    margin-bottom: 1.25rem;
    background: transparent;
    border: 1px solid var(--card-border);
    border-radius: 14px;
    overflow: hidden;
    background: var(--card-bg);
    backdrop-filter: blur(24px) saturate(1.2);
    -webkit-backdrop-filter: blur(24px) saturate(1.2);
}

.workspace details.section>summary {
    list-style: none;
    cursor: pointer;
    padding: .85rem 1.1rem;
    display: flex;
    align-items: center;
    gap: .6rem;
    user-select: none;
    transition: background .15s;
}

.workspace details.section>summary:hover {
    background: var(--btn-bg);
}

.workspace details.section>summary::-webkit-details-marker {
    display: none;
}

.workspace details.section>summary::before {
    content: '▸';
    font-size: .8rem;
    color: var(--muted2);
    transition: transform .15s;
    flex-shrink: 0;
}

.workspace details.section[open]>summary::before {
    transform: rotate(90deg);
}

.section-title-text {
    font-size: .85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--color);
}

.summary-meta {
    margin-left: auto;
    font-size: .72rem;
    color: var(--muted);
    font-weight: 400;
}

.section-body {
    padding: 0 1.1rem 1.1rem;
}

/* ── Lighter card chrome inside sections ─────────────────
   Every .card and .strategy-card inside a workspace section
   gets the nested-panel treatment (subtle --input-bg,
   no backdrop blur, no hover lift) so the section's outer
   border is the dominant frame. Without this override the
   legacy ``.card`` / ``.strategy-card`` rules apply and we
   get a doubled-frame look (card-bg over card-bg).

   Carefully scoped:
     - background → --input-bg (the actual fix)
     - backdrop-filter / box-shadow → none (cosmetic cleanup)
     - border-color is NOT touched on .strategy-card because
       the buy/sell/hold/monitoring variants set
       ``border-left-color`` and a generic border-color
       override would clobber the accent stripe.

   .section-grid cards already get a stricter variant of
   this (fixed height + scroll); their rule wins on selector
   specificity. */

.workspace details.section .card,
.workspace details.section .strategy-card {
    background: var(--input-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
}

/* On non-strategy cards (no left-accent stripe) the
   border can also drop to --input-border for a fully
   matched chip look. */
.workspace details.section .card {
    border-color: var(--input-border);
}

.workspace details.section .card:hover,
.workspace details.section .strategy-card:hover {
    border-color: var(--card-border-hover);
    box-shadow: none;
}

/* When a section is collapsed we don't need the extra padding
   between the summary and (non-existent) body, but the body
   is hidden anyway. The summary keeps its own padding. */

@media (max-width: 540px) {
    .workspace details.section>summary {
        padding: .7rem .85rem;
    }

    .section-body {
        padding: 0 .75rem .75rem;
    }

    .summary-meta {
        display: none;
    }
}


/* ── Section-level card grid ───────────────────────────────
   Used by sections that show 2+ inner cards (Operations,
   Diagnostics, etc). Auto-fits 2 columns when there's room,
   collapses to 1 below 720px or when only one card is
   visible (auto-fit + minmax handles both).

   Cards inside this grid are a lighter-chrome variant of the
   global .card — matched to the mockup. The section already
   provides the outer chrome (border, summary), so the inner
   cards drop the heavy backdrop-blur background and adopt
   the subtler --input-bg + --input-border treatment we use
   on stat-blocks. Result: clear hierarchy without doubled
   frames.

   Equal-height cards: every card claims a fixed height so
   one card with lots of content (a long Notifications list)
   doesn't make the row tall and leave a near-empty Proposals
   card. The body scrolls vertically inside the card. */

.section-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 1rem;
    align-items: stretch;
}

.section-grid .card {
    margin: 0;
    padding: .9rem 1rem;
    border-radius: 10px;
    background: var(--input-bg);
    border-color: var(--input-border);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    /* Equal height across the row, with the card body
       handling its own overflow. The 320px floor matches the
       Operations layout's old behaviour but keeps cards
       short enough to scan a 13" laptop without leaving the
       fold. Tweak via --section-card-height per-section. */
    height: var(--section-card-height, 320px);
    /* !important on display:flex — dashboard.js's existing
       refresh* functions toggle visibility with
       ``card.style.display = 'block'`` on un-hide. Without
       !important that inline write wins and clobbers the
       head/body flex stacking. With !important the card
       always lays out the same way; the JS toggle still
       hides it via display:none (which our rule explicitly
       defers to via a separate selector). */
    display: flex !important;
    flex-direction: column;
    overflow: hidden;
}

/* Honour explicit display:none from dashboard.js when a card
   has nothing to show yet (proposals-card, tier2-card, etc).
   The cards are display:flex by default (rule above) but the
   inline display:none must keep working — separate selector
   so !important on the inline style is preserved. */
.section-grid .card[style*="display:none"],
.section-grid .card[style*="display: none"] {
    display: none !important;
}

.section-grid .card:hover {
    /* Don't lift on hover — the lighter chrome reads as
       "structural panel" not "interactive card". The card
       body's scroll affordance is the real interaction. */
    border-color: var(--input-border);
    box-shadow: none;
}

.section-card-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .5rem;
    margin-bottom: .65rem;
    flex-shrink: 0;
}

.section-card-head h3 {
    margin: 0;
    font-size: .72rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 600;
}

.section-card-actions {
    display: flex;
    gap: .5rem;
    align-items: center;
    flex-shrink: 0;
    flex-wrap: wrap;
}

.section-card-meta {
    font-size: .72rem;
    color: var(--muted3);
}

.section-card-btn {
    font-size: .72rem;
    padding: .2rem .55rem;
}

/* Tab bar inside a section card head — tighter density so
   it fits next to the title without pushing it down. */
.section-card-tab-bar {
    margin: 0 !important;
}

.section-card-tab-bar .tab-btn {
    font-size: .68rem;
    padding: .2rem .5rem;
}

/* Card body — the part that scrolls. Eats the remaining
   vertical space in the card and shows a thin scrollbar. */
.section-card-body {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    margin: 0 -.5rem;
    padding: 0 .5rem;
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb) transparent;
}

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

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

@media (max-width: 720px) {
    .section-grid {
        grid-template-columns: 1fr;
        gap: .75rem;
    }

    /* On phones, fixed heights feel cramped — let cards take
       their natural height (capped) and show a normal scroll
       only if they overflow the cap. */
    .section-grid .card {
        height: auto;
        max-height: 420px;
    }
}