/* NexusTrading — Dark Trading Terminal Theme */

:root {
    --bg-primary: #0a0a0f;
    --bg-secondary: #111118;
    --bg-tertiary: #1a1a28;
    --bg-hover: #22223a;
    --border: #2a2a3e;
    --text-primary: #e5e5ef;
    --text-secondary: #9ca3af;
    --text-muted: #6b7280;
    --accent: #6366f1;
    --accent-hover: #818cf8;
    --green: #22c55e;
    --green-bg: rgba(34, 197, 94, 0.1);
    --red: #ef4444;
    --red-bg: rgba(239, 68, 68, 0.1);
    --yellow: #eab308;
    --yellow-bg: rgba(234, 179, 8, 0.1);
    --sidebar-width: 220px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: var(--bg-primary);
    color: var(--text-primary);
    font-size: 14px;
    line-height: 1.5;
}

/* Layout */
.app-layout {
    display: flex;
    min-height: 100vh;
}

/* Sidebar */
.sidebar {
    width: var(--sidebar-width);
    background: var(--bg-secondary);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 100;
}

.sidebar-brand {
    padding: 1.5rem 1rem;
    border-bottom: 1px solid var(--border);
}

.sidebar-brand h1 {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: 0.15em;
    color: var(--accent);
}

.brand-sub {
    font-size: 0.7rem;
    color: var(--text-muted);
    letter-spacing: 0.2em;
    text-transform: uppercase;
}

.sidebar-nav {
    list-style: none;
    padding: 0.5rem 0;
    flex: 1;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 1rem;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.85rem;
    transition: all 0.15s;
}

.nav-link:hover { background: var(--bg-hover); color: var(--text-primary); }
.nav-link.active { background: var(--bg-tertiary); color: var(--accent); border-right: 2px solid var(--accent); }
.nav-icon {
    width: 1.15rem;
    height: 1.15rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.nav-icon svg {
    width: 1.05rem;
    height: 1.05rem;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    display: block;
}
.nav-link.active .nav-icon { color: var(--accent); }

.sidebar-footer {
    padding: 1rem;
    border-top: 1px solid var(--border);
}

.engine-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

.status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
}

.status-dot.running { background: var(--green); box-shadow: 0 0 6px var(--green); }
.status-dot.ready { background: var(--yellow); }
.status-dot.error { background: var(--red); }

/* Main Content */
.main-content {
    flex: 1;
    min-width: 0;
    margin-left: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    overflow-x: hidden;
}

/* Gallery chrome — the top-bar is OPEN space, not a boxed bar. No fill, no
   divider: it shares the page background so the eye flows straight from the
   title down into the content. A taller, airy gutter gives the live widgets
   (gauge, bell) room to breathe; motion — not chrome — signals "alive". */
.top-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1.25rem;
    min-height: 68px;
    padding: 0.9rem 1.75rem;
    background: transparent;
    border-bottom: none;
}

.top-bar h2 {
    font-size: 1.2rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--text-primary);
}

.top-bar-left {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}
/* Ghost toggle — reads as chrome, not a button. Borderless until hover. */
.sidebar-toggle {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1.15rem;
    line-height: 1;
    transition: all 0.15s;
}
.sidebar-toggle:hover { color: var(--text-primary); background: var(--bg-hover); }

/* Sidebar collapsed — slide it off-screen and reclaim the gutter. */
.app-layout.sidebar-collapsed .sidebar {
    transform: translateX(-100%);
    transition: transform 0.2s ease;
}
.app-layout.sidebar-collapsed .main-content {
    margin-left: 0;
    transition: margin-left 0.2s ease;
}
.sidebar { transition: transform 0.2s ease; }
.main-content { transition: margin-left 0.2s ease; }
/* Restoring the collapsed state from storage must NOT animate — otherwise the
   content width slides on every page load and the chart rescales mid-slide.
   base.html adds this for the first frame only, then removes it. */
.app-layout.no-sidebar-anim .sidebar,
.app-layout.no-sidebar-anim .main-content { transition: none !important; }

.top-bar-right {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

/* ── Top-bar exchange-status gauge (GLOBAL view) ─────────────────────────
   Self-injects into .top-bar-right on EVERY page (exchange_gauge.js): venue ·
   armed-pair count · open LONG/SHORT · unrealized PnL. Borderless, text-only —
   no box, no hairline dividers; groups parted by an airy middot, colour only on
   the numbers. The numbers run a step LARGER than the chrome but the spacing is
   COMPACT, so several venues can sit side-by-side without crowding the bar. */
.mkt-exstat {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
    white-space: nowrap;
    color: var(--text-secondary);
    transition: opacity 0.18s ease;
}
.mkt-exstat.is-stale { opacity: 0.38; }
.mkt-exstat .mx-venue { font-weight: 600; color: var(--text-secondary); }
.mkt-exstat .mx-grp {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}
/* Airy middot between groups — tight margin keeps multiple venues compact. */
.mkt-exstat .mx-grp::before {
    content: "\00B7";
    margin-right: 0.4rem;
    color: var(--text-muted);
    opacity: 0.45;
}
/* Numbers moved to the LEFT, the venue label anchors the RIGHT (next to the
   bell): drop the leading middot on the first number group, and give the
   trailing venue its own separating middot so the parting stays consistent. */
.mkt-exstat .mx-grp:first-child::before { content: none; }
.mkt-exstat .mx-venue::before {
    content: "\00B7";
    margin-right: 0.4rem;
    color: var(--text-muted);
    opacity: 0.45;
}
/* Live-feed heartbeat — a slow breathing pulse says the gauge is streaming.
   Frozen (no animation) when the feed goes stale. */
.mkt-exstat .mx-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    display: inline-block;
    animation: nx-live-pulse 2.2s ease-in-out infinite;
}
.mkt-exstat.is-stale .mx-dot { animation: none; opacity: 0.5; }
@keyframes nx-live-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.5); opacity: 1; }
    50%      { box-shadow: 0 0 0 5px rgba(99, 102, 241, 0); opacity: 0.6; }
}
/* The live counts run a step LARGER than the chrome (inline-block so the
   .nx-bump pop lands on them), and EACH sits in a fixed-width tabular slot:
   a 2→3→4 digit swing stays inside its slot, so the ticking numbers never
   reflow the gauge — the venue label + bell to their right stay rock-still. */
.mkt-exstat .mx-armed,
.mkt-exstat .mx-long,
.mkt-exstat .mx-short,
.mkt-exstat .mx-pnl {
    display: inline-block;
    font-size: 0.95rem;
    font-variant-numeric: tabular-nums;
}
.mkt-exstat .mx-armed { color: var(--text-primary); font-weight: 600; min-width: 2.4ch; text-align: right; }
.mkt-exstat .mx-long  { color: var(--green); font-weight: 600; min-width: 3.6ch; }
.mkt-exstat .mx-short { color: var(--red);   font-weight: 600; min-width: 3.6ch; }
.mkt-exstat .mx-pnl      { min-width: 7ch; text-align: right; }
.mkt-exstat .mx-pnl.pos  { color: var(--green); font-weight: 700; }
.mkt-exstat .mx-pnl.neg  { color: var(--red);   font-weight: 700; }
.mkt-exstat .mx-pnl.flat { color: var(--text-muted); font-weight: 600; }
/* Groups that open a popover read as interactive — a quiet cursor + hover lift,
   no button chrome. */
.mkt-exstat .mx-clickable {
    cursor: pointer;
    border-radius: 5px;
    padding: 0.12rem 0.2rem;
    transition: background 0.15s ease;
}
.mkt-exstat .mx-clickable:hover { background: var(--bg-hover); }
.mkt-exstat .mx-clickable:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }

/* ── Gauge popover (armed pairs / open positions) ────────────────────────
   A floating, gallery-quiet panel: soft shadow, hairline border, a scrollable
   list parted by hover only (no boxy cards). Appended to <body>, positioned
   under its anchor by exchange_gauge.js. */
.mx-pop {
    position: fixed;
    z-index: 1200;
    min-width: 244px;
    max-width: 340px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 14px 36px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.35);
    overflow: hidden;
    font-size: 0.8rem;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 0.13s ease, transform 0.13s ease;
}
.mx-pop.open { opacity: 1; transform: translateY(0); }
.mx-pop[hidden] { display: none; }
.mx-pop-head {
    display: flex; align-items: baseline; justify-content: space-between;
    padding: 0.6rem 0.85rem 0.5rem;
    font-size: 0.66rem; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
}
.mx-pop-sub { color: var(--text-secondary); font-weight: 600; letter-spacing: 0; font-size: 0.75rem; }
.mx-pop-list { max-height: 300px; overflow-y: auto; padding: 0.2rem 0; }
.mx-pop-row {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.4rem 0.85rem;
    color: var(--text-secondary); text-decoration: none;
    transition: background 0.12s ease;
}
.mx-pop-row:hover { background: var(--bg-hover); color: var(--text-primary); }
.mx-pop-sym {
    flex: 1 1 auto; min-width: 0;
    color: var(--text-primary); font-weight: 500;
    font-variant-numeric: tabular-nums;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mx-pop-tf   { color: var(--text-muted); font-size: 0.7rem; flex: 0 0 auto; }
.mx-pop-meta { color: var(--accent); font-weight: 600; white-space: nowrap; flex: 0 0 auto; }
.mx-pop-side { flex: 0 0 0.9rem; text-align: center; font-weight: 700; }
.mx-pop-side.long  { color: var(--green); }
.mx-pop-side.short { color: var(--red); }
.mx-pop-dry {
    flex: 0 0 auto;
    font-size: 0.58rem; letter-spacing: 0.06em; color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 3px; padding: 0 0.25rem;
}
.mx-pop-pnl { flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mx-pop-pnl.pos  { color: var(--green); }
.mx-pop-pnl.neg  { color: var(--red); }
.mx-pop-pnl.flat { color: var(--text-muted); }
.mx-pop-empty { padding: 0.85rem; text-align: center; color: var(--text-muted); }
.mx-pop-foot {
    display: block; padding: 0.55rem 0.85rem; text-align: center;
    border-top: 1px solid var(--border);
    color: var(--accent); text-decoration: none; font-weight: 600; font-size: 0.74rem;
    transition: background 0.12s ease;
}
.mx-pop-foot:hover { background: var(--bg-hover); }
.mx-pop-list::-webkit-scrollbar { width: 8px; }
.mx-pop-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.mx-pop-list::-webkit-scrollbar-track { background: transparent; }

/* ── Live-data motion ───────────────────────────────────────────────────
   A terminal should feel alive, not static. A value that JUST changed gets a
   brief, refined cue — never a constant distraction:
     .nx-bump     a colour-agnostic glow + tiny pop for any count (works on
                  inline spans via text-shadow in the element's own colour).
     .tick-up/down a directional green/red wash for the price tape.
   Reused by the market top-bar gauge and the price strip. Subtle by design —
   an advanced AI gallery, not a casino. */
@keyframes nx-val-bump {
    0%   { transform: scale(1);    filter: brightness(1);   text-shadow: none; }
    30%  { transform: scale(1.12); filter: brightness(1.6); text-shadow: 0 0 8px currentColor; }
    100% { transform: scale(1);    filter: brightness(1);   text-shadow: none; }
}
.nx-bump { animation: nx-val-bump 0.55s ease; }

@keyframes nx-tick-up   { 0%, 100% { background: transparent; } 30% { background: var(--green-bg); } }
@keyframes nx-tick-down { 0%, 100% { background: transparent; } 30% { background: var(--red-bg);   } }
.tick-up   { animation: nx-tick-up   0.6s ease; }
.tick-down { animation: nx-tick-down 0.6s ease; }

.content-area {
    padding: 1.5rem;
    flex: 1;
    overflow-y: auto;
}

/* Buttons */
.btn {
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-tertiary);
    color: var(--text-primary);
    cursor: pointer;
    font-size: 0.8rem;
    transition: all 0.15s;
}

.btn:hover { background: var(--bg-hover); }
.btn-sm { padding: 0.25rem 0.6rem; font-size: 0.75rem; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: white; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-danger { background: transparent; border-color: var(--red); color: var(--red); }
.btn-danger:hover { background: var(--red-bg); }

/* Stats Grid */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.stat-card {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 1rem;
}

.stat-label { font-size: 0.75rem; color: var(--text-muted); margin-bottom: 0.25rem; }
.stat-value { font-size: 1.25rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Panels */
.panel {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-bottom: 1rem;
}

.panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border);
}

.panel-header h3 { font-size: 0.9rem; font-weight: 600; }
.panel-body { padding: 0; }

/* Tables */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table th {
    padding: 0.6rem 0.75rem;
    text-align: left;
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 1px solid var(--border);
}

.data-table td {
    padding: 0.6rem 0.75rem;
    font-size: 0.8rem;
    border-bottom: 1px solid rgba(42, 42, 62, 0.5);
}

.data-table tr:hover { background: var(--bg-hover); }
.text-center { text-align: center; }

/* Badges */
.badge {
    display: inline-block;
    padding: 0.15rem 0.4rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.badge-green { background: var(--green-bg); color: var(--green); }
.badge-red { background: var(--red-bg); color: var(--red); }
.badge-yellow { background: var(--yellow-bg); color: var(--yellow); }
.badge-gray { background: rgba(107, 114, 128, 0.15); color: var(--text-muted); }
.badge-accent { background: rgba(99, 102, 241, 0.15); color: var(--accent); }

/* Regime badge (market status bar) — a "last | action | cross" strip.
   EACH segment is text-tinted by ITS OWN regime via a tone class (set in
   market.html::regimeTone), so a regime reads the SAME colour everywhere and
   no segment ever falls back to unstyled white. Minimalist: text-tint only,
   no per-regime box. The tooltip carries the per-path active/total breakdown. */
/* Compact regime strip — Title-case (kills the shouty all-caps inherited from
   .badge). ONE inline row: the dimension segments and the active-slot count
   share a single baseline. When the whole stats bar runs out of width the
   pinned .ms-right group drops to the next line as a unit (flex-wrap on
   .mkt-stats) — so the strip never grows a horizontal scrollbar. */
.badge-regime {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.1rem 0.3rem;
    background: none;
    padding: 0;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.74rem;
}
.badge-regime .br-dims {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.1rem 0.26rem;
}
.badge-regime .br-last,
.badge-regime .br-r2,
.badge-regime .br-macro,
.badge-regime .br-self,
.badge-regime .br-rsi,
.badge-regime .br-swing { font-weight: 600; white-space: nowrap; }
.badge-regime .br-r2,
.badge-regime .br-macro,
.badge-regime .br-self,
.badge-regime .br-rsi,
.badge-regime .br-swing { opacity: 0.85; }
.badge-regime .br-sep { opacity: 0.4; color: var(--border); font-weight: 400; }
/* Active-slot count — trailing chip after the dims, set off by a hairline
   divider so it reads as a separate metric without a heavy box. */
.badge-regime .br-count {
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 0.18rem;
    font-weight: 500;
    font-size: 0.66rem;
    color: var(--text-muted);
    padding-left: 0.4rem;
    border-left: 1px solid var(--border);
}
.badge-regime .br-count .brc-glyph { opacity: 0.65; font-size: 0.58rem; }
/* Mentality (6th dim) — non-directional MAGNITUDE: calm → escalating → danger.
   Distinct from the directional bull/bear tones (Crazy is not "bearish"). */
.badge-regime .rt-ment-neutral { color: var(--text-muted); }
.badge-regime .rt-ment-hyper   { color: #d4a35a; }
.badge-regime .rt-ment-crazy   { color: var(--red); }
/* RSI-zone (7th dim) — 9-state RSI-momentum × price, 3-tier momentum tone: bullish
   (momentum-RISE, incl bullish_div) green, neutral cyan, bearish (momentum-FALL, incl
   bearish_div) red. The state NAME carries the detail. */
.badge-regime .rt-rsi-bull      { color: #5cae87; }
.badge-regime .rt-rsi-neutral   { color: #6cb6c9; }   /* soft cyan — visibly coloured, calm */
.badge-regime .rt-rsi-bear      { color: var(--red); }
/* Speed (deepest dim) — non-directional MAGNITUDE: calm → escalating → danger.
   Crazy/Fast = the rule-breaking tape (crash / crazy-bull), not "bearish". */
.badge-regime .rt-speed-calm    { color: var(--text-muted); }
.badge-regime .rt-speed-normal  { color: #6cb6c9; }   /* soft cyan — rule-abiding band */
.badge-regime .rt-speed-fast    { color: #d4a35a; }   /* amber — volatility building */
.badge-regime .rt-speed-crazy   { color: var(--red); }
/* Semantic regime tones — complete over regime-1 (5) / regime-2 action (9) /
   cross (12) + a muted fallback, using only existing palette tokens. */
.badge-regime .rt-bull        { color: var(--green); }
.badge-regime .rt-bull-strong { color: #f472b6; }
.badge-regime .rt-bear        { color: var(--red); }
.badge-regime .rt-bear-strong { color: #fca5a5; }
.badge-regime .rt-neutral     { color: var(--accent); }
/* noise/choppy + ANY unmapped regime → a visible amber, NOT the washed-out
   grey that read as "white"/unstyled. This class is also regimeTone()'s
   fallback, so a future unmapped label can never render blank again. */
.badge-regime .rt-muted       { color: #d4a35a; }
/* Loading / error placeholder (applied to the container) — text-only muted,
   no box, so it matches the real badge. */
.badge-regime-unknown         { color: var(--text-muted); }

/* P&L Colors */
.pnl-positive { color: var(--green); }
.pnl-negative { color: var(--red); }
.pnl-neutral { color: var(--text-secondary); }

/* Tabs */
.tabs {
    display: flex;
    gap: 0;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--border);
}

.tab {
    padding: 0.5rem 1rem;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.85rem;
    border-bottom: 2px solid transparent;
}

.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.tab:hover { color: var(--text-primary); }

/* Modal */
.modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.modal-content {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    width: 480px;
    max-height: 90vh;
    overflow-y: auto;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    border-bottom: 1px solid var(--border);
}

.modal-header h3 { font-size: 1rem; }
.modal-close { background: none; border: none; color: var(--text-muted); font-size: 1.5rem; cursor: pointer; }

/* Pill toggle switch — used in the pair Edit modal header to flip a
   pair Active/Inactive without scrolling to the bottom of the form.
   Generic enough to reuse anywhere a boolean needs a clear visual. */
.nou-switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 22px;
    flex-shrink: 0;
    cursor: pointer;
}
.nou-switch input { opacity: 0; width: 0; height: 0; }
.nou-switch-slider {
    position: absolute;
    inset: 0;
    background: #3a3a3a;
    border-radius: 22px;
    transition: background 0.2s ease;
}
.nou-switch-slider::before {
    content: "";
    position: absolute;
    height: 16px;
    width: 16px;
    left: 3px;
    bottom: 3px;
    background: #f1f1f1;
    border-radius: 50%;
    transition: transform 0.2s ease;
    box-shadow: 0 1px 3px rgba(0,0,0,0.35);
}
.nou-switch input:checked + .nou-switch-slider { background: #22c55e; }
.nou-switch input:checked + .nou-switch-slider::before { transform: translateX(22px); }
.nou-switch input:focus-visible + .nou-switch-slider {
    box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.35);
}
.nou-switch-group {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-left: auto;
    margin-right: 0.75rem;
    user-select: none;
}
.nou-switch-group .nou-switch-label {
    font-size: 0.82rem;
    color: var(--text-secondary);
    min-width: 4ch;
}
.nou-switch-group.is-on .nou-switch-label { color: #22c55e; }

/* Forms */
.form-group { padding: 0.75rem 1rem; }
.form-group label { display: block; font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 0.3rem; }

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 0.5rem;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-size: 0.85rem;
    box-sizing: border-box;
}

.form-group textarea {
    font-family: 'Consolas', 'Monaco', monospace;
    font-size: 0.78rem;
    line-height: 1.5;
    tab-size: 2;
    resize: vertical;
    white-space: pre-wrap;
    word-break: break-all;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--accent);
}

.form-row { display: flex; gap: 0; }
.form-row .form-group { flex: 1; }
.form-actions { padding: 1rem; display: flex; gap: 0.5rem; justify-content: flex-end; border-top: 1px solid var(--border); }

/* Wide modal — used for forms that need to spread fields across the
   full viewport so dense settings panels stop feeling cramped. */
.modal.modal-wide .modal-content {
    width: 96vw;
    max-width: 1240px;
    max-height: 94vh;
    display: flex;
    flex-direction: column;
}
.modal-wide .modal-body {
    flex: 1;
    overflow-y: auto;
    padding: 0.4rem 0.8rem 0.2rem;
}
.modal-wide .form-actions {
    position: sticky;
    bottom: 0;
    background: var(--bg-secondary);
    z-index: 2;
}

/* Sectioned form: each <details class="form-section"> groups related
   inputs under a clickable header. The chevron rotates with [open]. */
.form-section {
    border: 1px solid var(--border);
    border-radius: 6px;
    margin: 0.5rem 0;
    background: var(--bg-primary);
}
.form-section > summary {
    cursor: pointer;
    padding: 0.55rem 0.85rem;
    font-weight: 600;
    font-size: 0.84rem;
    color: var(--text-primary);
    background: var(--bg-secondary);
    border-radius: 6px;
    list-style: none;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 0.45rem;
}
.form-section > summary::-webkit-details-marker { display: none; }
.form-section > summary::before {
    content: '\25B8';
    color: var(--text-muted);
    transition: transform 0.12s ease;
    display: inline-block;
}
.form-section[open] > summary::before { transform: rotate(90deg); }
.form-section[open] > summary {
    border-bottom: 1px solid var(--border);
    border-radius: 6px 6px 0 0;
}

/* Auto-fitting grid: fields flow into as many columns as the modal
   width allows. Cap each column at ~260px so labels stay readable. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0;
    padding: 0.2rem 0.4rem;
}
.form-grid .form-group { padding: 0.55rem 0.7rem; }

.form-section-hint {
    padding: 0.25rem 0.85rem 0.7rem;
    font-size: 0.76rem;
    color: var(--text-muted);
}

/* Key/value endpoint editor — table-style layout. Rows zebra-stripe to
   keep the eye anchored across long endpoint lists; inputs sit flush
   in the cells (no individual borders) so the row reads as one
   editable line rather than two boxed fields. The raw JSON textarea
   stays mounted but hidden so power users can flip without losing
   work. */
.kv-editor { padding: 0.3rem 0 0.4rem; }
.kv-editor-toolbar {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0 0.85rem 0.5rem;
    flex-wrap: wrap;
    color: var(--text-muted);
    font-size: 0.74rem;
}
.kv-editor-toolbar .kv-spacer { flex: 1; }
.kv-editor-toolbar .btn {
    padding: 0.28rem 0.6rem;
    font-size: 0.74rem;
    line-height: 1.1;
}
.kv-list {
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.kv-row {
    display: grid;
    grid-template-columns: minmax(130px, 200px) 1fr 28px;
    align-items: stretch;
    border-bottom: 1px solid var(--border);
    background: var(--bg-primary);
}
.kv-list .kv-row:last-child { border-bottom: 0; }
.kv-list .kv-row:nth-child(even) { background: var(--bg-secondary); }
.kv-list .kv-row:hover { background: rgba(99, 102, 241, 0.06); }
.kv-row input {
    width: 100%;
    padding: 0.42rem 0.7rem;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    font-size: 0.76rem;
    background: transparent;
    border: 0;
    color: var(--text-primary);
    box-shadow: none;
    border-radius: 0;
}
.kv-row input:focus {
    background: rgba(99, 102, 241, 0.08);
    outline: 0;
}
.kv-row input.kv-key {
    color: var(--accent);
    border-right: 1px solid var(--border);
    font-weight: 500;
    letter-spacing: 0.01em;
}
.kv-row input.kv-val {
    color: var(--text-secondary);
}
.kv-row .kv-remove {
    background: transparent;
    border: 0;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    opacity: 0.5;
    transition: opacity 0.1s, color 0.1s;
}
.kv-row:hover .kv-remove { opacity: 1; }
.kv-row .kv-remove:hover { color: var(--red); }
.kv-empty {
    padding: 1.2rem 0.85rem;
    color: var(--text-muted);
    font-size: 0.78rem;
    font-style: italic;
    text-align: center;
}
.kv-raw-wrap { padding: 0 0.85rem; }
.kv-raw-wrap textarea {
    width: 100%;
    font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
    font-size: 0.76rem;
    padding: 0.55rem 0.7rem;
    background: var(--bg-primary);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-radius: 4px;
}

/* Multi-slot pattern cards used by the pair-config forms.
   Header (enable toggle, name, remove) + 7-input grid; stacked. */
.pattern-slot-list {
    display: flex; flex-direction: column; gap: 0.5rem;
    padding: 0.5rem 0.85rem;
}
.pattern-slot-card {
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-tertiary);
    overflow: hidden;
}
.pattern-slot-head {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.4rem 0.6rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
}
.pattern-slot-head input[type="text"] {
    background: var(--bg-tertiary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.25rem 0.45rem;
    border-radius: 4px;
    font-size: 0.82rem;
}
.btn-xs {
    padding: 0.15rem 0.45rem;
    font-size: 0.72rem;
    line-height: 1;
    border-radius: 3px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-primary);
    cursor: pointer;
}
.btn-xs:hover { background: var(--bg-tertiary); }

/* Per-slot effectiveness badge in the Pattern Filter card header.
   Same color bands shared by /pairs hover popup so the signal stays
   consistent: green = working, amber = noisy, red = drag. */
.pattern-stats-badge {
  display: inline-flex; align-items: center;
  padding: 0.15rem 0.5rem;
  font-size: 0.7rem;
  line-height: 1.2;
  border-radius: 4px;
  border: 1px solid var(--border);
  color: var(--text-primary);
  white-space: nowrap;
  background: var(--bg-secondary);
  font-variant-numeric: tabular-nums;
}
.pattern-stats-badge.stats-empty {
  color: var(--text-muted);
  border-style: dashed;
}
.pattern-stats-badge.stats-ok   { background: rgba(34, 197, 94, 0.12);  border-color: rgba(34, 197, 94, 0.45);  color: #6dd99a; }
.pattern-stats-badge.stats-warn { background: rgba(245, 158, 11, 0.12); border-color: rgba(245, 158, 11, 0.45); color: #f4b860; }
.pattern-stats-badge.stats-bad  { background: rgba(239, 68, 68, 0.12);  border-color: rgba(239, 68, 68, 0.45);  color: #ef7676; }

/* /pairs table — pattern cell + hover/click popup. */
.pattern-cell {
  position: relative;
  display: inline-block;
  cursor: default;
}
.pattern-cell-trigger {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--bg-secondary);
  color: var(--text-primary);
  font-size: 0.72rem;
  cursor: pointer;
  user-select: none;
}
.pattern-cell-trigger:hover { background: var(--bg-tertiary); }
.pattern-stats-popup {
  position: absolute;
  top: 100%; left: 0;
  min-width: 320px;
  margin-top: 4px;
  padding: 0.4rem 0.5rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.55);
  z-index: 200;
  display: none;
}
.pattern-cell.pattern-cell-open .pattern-stats-popup { display: block; }
.pattern-stats-popup-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  border-bottom: 1px dashed var(--border);
}
.pattern-stats-popup-row:last-child { border-bottom: none; }
.pattern-stats-popup-name { color: var(--text-primary); font-size: 0.78rem; }
.pattern-stats-popup-empty {
  color: var(--text-muted); font-size: 0.78rem; padding: 0.3rem;
}

/* Info Grid */
.info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; padding: 1rem; }
.info-item { display: flex; flex-direction: column; gap: 0.25rem; }
.info-label { font-size: 0.7rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; }

/* ---------- Page header — title + lede + actions on every list page. */
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--border);
}
.page-header-text { display: flex; flex-direction: column; gap: 0.25rem; }
.page-header-title {
    font-size: 1.15rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}
.page-header-lede {
    font-size: 0.8rem;
    color: var(--text-muted);
    max-width: 64ch;
    line-height: 1.45;
}
.page-header-actions {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}

/* Stat pills row — compact KPI ribbon above tables. */
.stat-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 1rem;
}
.stat-pill {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.55rem 0.8rem;
    min-width: 130px;
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}
.stat-pill-label {
    font-size: 0.66rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.stat-pill-value {
    font-size: 1rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.stat-pill-sub {
    font-size: 0.7rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.stat-pill.accent { border-color: var(--accent); }
.stat-pill.accent .stat-pill-value { color: var(--accent); }

/* Data card — replacement for the bare .panel. Gives every list page
   a sticky header with title + filter row + actions on one line. */
.data-card {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 1rem;
    overflow: hidden;
}
.data-card-head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border);
    background: linear-gradient(180deg,
        rgba(99,102,241,0.04) 0%, transparent 100%);
}
.data-card-head h3 {
    font-size: 0.92rem;
    font-weight: 600;
    margin: 0;
}
.data-card-head .lede {
    font-size: 0.74rem;
    color: var(--text-muted);
}
.data-card-head .spacer { flex: 1; }
.data-card-body { padding: 0; }
.data-card-body.padded { padding: 0.85rem 1rem; }
.data-card-footer {
    padding: 0.55rem 1rem;
    border-top: 1px solid var(--border);
    font-size: 0.74rem;
    color: var(--text-muted);
    background: var(--bg-primary);
}

/* Toolbar — search + filters above a table. */
.toolbar {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    flex-wrap: wrap;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--border);
    background: var(--bg-primary);
}
.toolbar input[type="search"],
.toolbar input[type="text"],
.toolbar select {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.32rem 0.55rem;
    border-radius: 4px;
    font-size: 0.78rem;
    min-width: 0;
}
.toolbar input[type="search"]:focus,
.toolbar input[type="text"]:focus,
.toolbar select:focus {
    outline: none;
    border-color: var(--accent);
}
.toolbar .toolbar-hint {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-left: auto;
}

/* Tightened table — replaces .data-table for new pages so rows align
   numerically and the header sticks while scrolling. */
.data-table-tight {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}
.data-table-tight thead th {
    position: sticky;
    top: 0;
    background: var(--bg-secondary);
    z-index: 1;
    padding: 0.5rem 0.7rem;
    text-align: right;
    border-bottom: 1px solid var(--border);
    font-size: 0.66rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    white-space: nowrap;
}
.data-table-tight thead th:first-child,
.data-table-tight tbody td:first-child {
    text-align: left;
}
.data-table-tight tbody td {
    padding: 0.45rem 0.7rem;
    text-align: right;
    border-bottom: 1px solid rgba(42, 42, 62, 0.5);
    color: var(--text-primary);
    white-space: nowrap;
}
.data-table-tight tbody td.col-symbol {
    font-weight: 500;
    color: var(--text-primary);
}
.data-table-tight tbody tr:hover { background: rgba(99,102,241,0.05); }
.data-table-tight tbody tr.row-dim { opacity: 0.45; }
.data-table-tight input[type="number"],
.data-table-tight input[type="text"],
.data-table-tight select {
    width: 100%;
    min-width: 60px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.22rem 0.4rem;
    border-radius: 3px;
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.data-table-tight select { text-align: left; }
.data-table-tight input[type="number"]:focus,
.data-table-tight input[type="text"]:focus,
.data-table-tight select:focus {
    outline: none;
    border-color: var(--accent);
}
.data-table-tight input[type="checkbox"] {
    accent-color: var(--accent);
    cursor: pointer;
}
.data-table-tight .col-actions {
    display: inline-flex;
    gap: 0.3rem;
    justify-content: flex-end;
}

/* Section divider rows inside a table — used to group exchanges by
   exchange_type ("Crypto", "Forex", ...). */
.data-table-tight tr.section-divider td {
    padding: 0.45rem 0.75rem;
    background: var(--bg-primary);
    color: var(--text-muted);
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    text-align: left;
}

/* Empty-state block — shown when a list returns 0 rows. */
.empty-state {
    padding: 2.5rem 1.5rem;
    text-align: center;
    color: var(--text-muted);
}
.empty-state-title {
    font-size: 0.95rem;
    color: var(--text-secondary);
    margin-bottom: 0.4rem;
    font-weight: 500;
}
.empty-state-hint { font-size: 0.78rem; }

/* Role / status pills shared by exchange + binding pages. */
.role-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border: 1px solid var(--border);
    color: var(--text-muted);
    background: var(--bg-primary);
    white-space: nowrap;
}
.role-pill.primary { color: var(--accent); border-color: var(--accent); background: rgba(99,102,241,0.10); }
.role-pill.ok { color: var(--green); border-color: var(--green); background: var(--green-bg); }
.role-pill.warn { color: var(--yellow); border-color: var(--yellow); background: var(--yellow-bg); }
.role-pill.muted { color: var(--text-muted); }

/* Inline value pair: "Label: 0.05%" used in card heads. */
.kv {
    display: inline-flex;
    gap: 0.3rem;
    font-size: 0.74rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.kv b { color: var(--text-primary); font-weight: 500; }

/* Inline action row — used inside data-card footer for bulk actions. */
.inline-form {
    display: flex;
    align-items: flex-end;
    gap: 0.55rem;
    flex-wrap: wrap;
}
.inline-form .field {
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
    min-width: 110px;
}
.inline-form .field label {
    font-size: 0.66rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.inline-form .field input,
.inline-form .field select {
    background: var(--bg-primary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.32rem 0.55rem;
    border-radius: 4px;
    font-size: 0.78rem;
}
.inline-form .field input:focus,
.inline-form .field select:focus { outline: none; border-color: var(--accent); }


/* Chart */
.chart-container { background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.chart-toolbar { display: flex; align-items: center; gap: 1rem; padding: 0.75rem 1rem; border-bottom: 1px solid var(--border); }
.chart-price { font-size: 1.25rem; font-weight: 600; }
.chart-change { font-size: 0.85rem; }

/* Server-crash banner */
.server-crash-banner {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.65rem 1rem; margin: 0.5rem 1rem 0;
    background: var(--red-bg); border: 1px solid var(--red); border-radius: 6px;
    color: var(--red); font-size: 0.85rem; font-weight: 500;
}
.server-crash-banner[hidden] { display: none; }
.server-crash-banner .crash-icon { font-size: 1.1rem; }
.server-crash-banner .banner-close {
    margin-left: auto; background: none; border: none; color: var(--red);
    font-size: 1.2rem; cursor: pointer; padding: 0 0.25rem;
}
.server-crash-banner .banner-close:hover { color: var(--text-primary); }

/* Scrollbar */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--bg-primary); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* Auto-tune section inside the pair Edit modal. Three vertical cards:
   acceptance gate (x/y/z), auto-computed ranges (3 path columns), and
   the action bar (Run + Refresh). Visual language mirrors the existing
   .pattern-slot-card so the modal stays consistent. */
.at-wrap { display: flex; flex-direction: column; gap: 0.6rem;
           padding: 0.6rem 0.85rem 0.8rem; }
.at-card {
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-tertiary);
    overflow: hidden;
}
.at-card-head {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.4rem 0.7rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
    font-size: 0.8rem; font-weight: 600;
}
.at-card-head .at-head-meta {
    font-weight: normal; color: var(--text-muted);
    font-size: 0.74rem; margin-left: auto;
}
.at-card-body { padding: 0.55rem 0.7rem; }
.at-card-body.tight { padding: 0.35rem 0.5rem; }

/* Acceptance gate grid: 5 numeric inputs in an auto-fit grid mirroring
   .form-grid sizing, then a separator + enable toggles + Save. */
.at-gate-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.5rem 0.65rem;
}
.at-field { display: flex; flex-direction: column; gap: 0.15rem; }
.at-field > label {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.at-field > label .at-sym {
    color: var(--accent); font-weight: 700; margin-left: 0.2rem;
}
.at-field > input[type="number"] {
    background: var(--bg-primary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.35rem 0.5rem;
    border-radius: 4px;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}
.at-field > input[type="number"]:focus {
    outline: none; border-color: var(--accent);
}
.at-gate-actions {
    display: flex; align-items: center; gap: 0.75rem;
    flex-wrap: wrap;
    padding-top: 0.55rem; margin-top: 0.55rem;
    border-top: 1px dashed var(--border);
}
.at-toggle {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-size: 0.78rem; cursor: pointer;
    padding: 0.18rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-primary);
    user-select: none;
}
.at-toggle input { accent-color: var(--accent); margin: 0; }
.at-toggle.on { background: rgba(99,102,241,0.12);
                border-color: var(--accent); color: var(--accent); }
.at-status { font-size: 0.74rem; color: var(--text-muted); }

/* Ranges card: 3 path columns side-by-side, each lists its axes. */
.at-ranges-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.6rem;
}
.at-range-col {
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--bg-primary);
    overflow: hidden;
}
.at-range-col-head {
    padding: 0.3rem 0.55rem;
    background: var(--bg-secondary);
    border-bottom: 1px solid var(--border);
    font-size: 0.74rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--text-muted);
}
.at-range-col-head.on { color: var(--accent); }
.at-axis-list {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.18rem 0.6rem;
    padding: 0.4rem 0.55rem;
    font-size: 0.77rem;
    font-variant-numeric: tabular-nums;
}
.at-axis-list .ax-name { color: var(--text-muted); }
.at-axis-list .ax-val  { font-family: 'JetBrains Mono', Consolas, monospace; }
.at-ranges-foot {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 0.5rem 0.8rem;
    padding: 0.45rem 0.6rem 0.1rem;
    font-size: 0.74rem; color: var(--text-muted);
    border-top: 1px dashed var(--border);
    margin-top: 0.55rem;
}
.at-ranges-foot .at-stat { font-variant-numeric: tabular-nums; }
.at-ranges-foot .at-stat b { color: var(--text-primary); font-weight: 600; }
.at-ranges-foot .spacer { flex: 1; }

/* Combo preview pill row + Run action bar. */
.at-preview {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem;
    font-size: 0.78rem; color: var(--text-muted);
}
.at-pill {
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
}
.at-pill b { color: var(--text-primary); }
.at-pill.total { background: rgba(99,102,241,0.12);
                 border-color: var(--accent); color: var(--accent); }
.at-actions {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
    padding-top: 0.5rem; margin-top: 0.5rem;
    border-top: 1px dashed var(--border);
}
.at-actions .spacer { flex: 1; }

/* Discovered slot groups inside the same panel. */
.at-slots { margin-top: 0.4rem; }
.at-slots-empty {
    padding: 0.8rem;
    border: 1px dashed var(--border);
    border-radius: 5px;
    color: var(--text-muted);
    font-size: 0.78rem;
    text-align: center;
}
.at-group-head {
    font-weight: 600; font-size: 0.78rem; margin: 0.7rem 0 0.25rem;
}
.at-group-head .at-count { color: var(--text-muted); font-weight: normal; }

/* Toast notifications — stacked top-right above the rest of the UI.
   Kind-coded left border so the operator can spot success vs error
   without reading; click anywhere on the card to dismiss. */
.nou-toast-stack {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    pointer-events: none;
    max-width: 380px;
}
.nou-toast {
    pointer-events: auto;
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    padding: 0.65rem 0.85rem 0.7rem;
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-left-width: 4px;
    border-radius: 6px;
    font-size: 0.82rem;
    line-height: 1.35;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
    cursor: pointer;
    opacity: 0;
    transform: translateX(12px);
    transition: opacity 0.18s ease, transform 0.18s ease;
}
.nou-toast-show { opacity: 1; transform: translateX(0); }
.nou-toast-hide { opacity: 0; transform: translateX(12px); }
.nou-toast-icon {
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    line-height: 1.1rem;
    text-align: center;
    border-radius: 50%;
    font-weight: 700;
    font-size: 0.78rem;
    color: #fff;
}
.nou-toast-text { flex: 1; min-width: 0; }
.nou-toast-title {
    font-weight: 600;
    font-size: 0.78rem;
    margin-bottom: 0.15rem;
}
.nou-toast-body { word-wrap: break-word; white-space: pre-line; }
.nou-toast-success { border-left-color: #16a34a; }
.nou-toast-success .nou-toast-icon { background: #16a34a; }
.nou-toast-error   { border-left-color: #dc2626; }
.nou-toast-error   .nou-toast-icon { background: #dc2626; }
.nou-toast-warn    { border-left-color: #d97706; }
.nou-toast-warn    .nou-toast-icon { background: #d97706; }
.nou-toast-info    { border-left-color: #6366f1; }
.nou-toast-info    .nou-toast-icon { background: #6366f1; }

/* Positions / Orders toolbar — exchange filter + page-size + count
   pill stack inline. The spacer pushes the count + sort hint to the
   right so the layout reads "controls on the left, status on the
   right" same as Smart Funding's data-card pattern. */
.pos-toolbar .toolbar-group {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.pos-toolbar .toolbar-group label {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.pos-toolbar .toolbar-spacer { margin-left: auto; }
.pos-count-pill {
    font-size: 0.74rem;
    color: var(--text-secondary);
    padding: 0.25rem 0.55rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 12px;
    font-variant-numeric: tabular-nums;
}

/* Sortable column headers — click-to-cycle (desc → asc → off). The
   arrow stays dim until the column is the active sort target, then
   flips up/down so the operator can read the direction at a glance. */
.data-table-tight th.th-sort,
.data-table th.th-sort {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.data-table-tight th.th-sort:hover,
.data-table th.th-sort:hover { color: var(--accent); }
.th-arrow {
    display: inline-block;
    margin-left: 0.18rem;
    font-size: 0.72rem;
    line-height: 1;
}
.th-arrow-dim { color: var(--text-muted); opacity: 0.5; }
.th-arrow-on  { color: var(--accent); font-weight: 600; }

/* Pagination bar — same toolbar chrome, but centred buttons and an
   inline gap glyph for skipped page ranges. Disabled / active states
   come from .btn defaults. */
.pos-pager {
    justify-content: center;
    gap: 0.3rem;
    border-top: 1px solid var(--border);
    border-bottom: none;
}
.pos-pager .btn-sm { min-width: 2.1rem; padding: 0.3rem 0.55rem; }
.pos-pager .btn-active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.pager-gap { color: var(--text-muted); padding: 0 0.15rem; }

/* Exchange pill — single-token venue label in the positions table.
   Keeps the column narrow so the symbol/PnL fields don't get pushed. */
.ex-pill {
    display: inline-block;
    padding: 0.1rem 0.45rem;
    border-radius: 10px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    font-size: 0.7rem;
    color: var(--text-secondary);
}

/* Add-binding picker — scrollable checkbox grid for selecting multiple
   pairs at once. Toolbar pins to the top of the card; the list grows
   to a capped height with overflow so a long unbound list doesn't
   push the page chrome around. */
.bindable-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    padding-bottom: 0.55rem;
    margin-bottom: 0.55rem;
    border-bottom: 1px solid var(--border);
}
.bindable-toolbar input[type="search"] {
    flex: 1 1 220px;
    min-width: 200px;
    padding: 0.35rem 0.55rem;
    background: var(--bg-primary);
    color: var(--text-primary);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.82rem;
}
.bindable-count {
    font-size: 0.78rem;
    color: var(--text-muted);
}
.bindable-count b { color: var(--accent); }
.bindable-spacer { flex: 1; }
.bindable-run {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.bindable-run select {
    background: var(--bg-primary);
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 0.3rem 0.5rem;
    border-radius: 4px;
    font-size: 0.82rem;
    text-transform: none;
    letter-spacing: 0;
}
.bindable-list {
    max-height: 420px;
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.3rem;
    padding: 0.15rem;
}
.bindable-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.65rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 5px;
    cursor: pointer;
    font-size: 0.82rem;
    transition: background 0.1s, border-color 0.1s;
}
.bindable-row:hover {
    background: rgba(99, 102, 241, 0.06);
    border-color: rgba(99, 102, 241, 0.4);
}
.bindable-row.picked {
    background: rgba(99, 102, 241, 0.1);
    border-color: var(--accent);
}
.bindable-row input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    flex: 0 0 auto;
    accent-color: var(--accent);
}
.bindable-sym {
    flex: 1;
    font-weight: 600;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bindable-meta {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: 0 0 auto;
}

/* ── Market chart: fire-marker colour legend + click popup ──────────
   The 5 entry-path colours (+ a co-fire swatch) come from a single JS
   map (ENTRY_PATH_COLORS in market.html), shared with the chart markers
   and the entry-stats panel so the three always match. */
.mkt-legend {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.7rem;
    color: var(--text-secondary);
}
.mkt-leg-item {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}
.mkt-leg-dot {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    display: inline-block;
    flex: 0 0 auto;
}

/* Popup shown when a fire marker is clicked — lists which path(s) fired
   that candle (the co-fire case shows all overlapping paths). */
.mkt-fire-popup {
    position: fixed;
    z-index: 1200;
    min-width: 210px;
    max-width: 340px;
    padding: 0.55rem 0.65rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
    font-size: 0.72rem;
    color: var(--text-secondary);
}
/* Hover preview must never steal the cursor (it's offset from it); a click
   PINS the popup, which then accepts pointer events so text can be selected. */
.mkt-fire-popup.hover { pointer-events: none; }
.mkt-fire-popup.pinned { pointer-events: auto; }
.mkt-fire-popup-title {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.4rem;
}
.mkt-fire-popup-title .msc-dir {
    margin-left: auto;
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 0.05rem 0.32rem;
    border-radius: 4px;
}
.mkt-fire-popup-title .msc-dir.long  { color: var(--green); background: rgba(48, 164, 108, 0.14); }
.mkt-fire-popup-title .msc-dir.short { color: var(--red);   background: rgba(229, 72, 77, 0.14); }
.mkt-fire-popup-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.12rem 0;
}
.mkt-fire-chip {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    flex: 0 0 auto;
}
/* Per-slot card: id · path · branch on top, the fire/win/loss/WR tally below. */
.mkt-slot-card { padding: 0.34rem 0; border-top: 1px solid var(--border); }
.mkt-slot-card:first-of-type { border-top: none; padding-top: 0.1rem; }
.mkt-slot-card .msc-head { display: flex; align-items: center; gap: 0.34rem; }
.mkt-slot-card .msc-id {
    font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums;
}
.mkt-slot-card .msc-path { color: var(--text-secondary); }
.mkt-slot-card .msc-branch {
    font-size: 0.6rem; color: var(--text-muted);
    border: 1px solid var(--border); border-radius: 4px; padding: 0 0.26rem;
}
.mkt-slot-card .msc-name {
    margin-left: auto; font-size: 0.62rem; color: var(--text-muted);
    max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mkt-slot-card .msc-stats {
    display: flex; align-items: center; gap: 0.6rem;
    margin-top: 0.2rem; padding-left: 1.05rem;
    font-size: 0.68rem; color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.mkt-slot-card .msc-stats b { color: var(--text-secondary); font-weight: 600; }
.mkt-slot-card .msc-stats .pos b { color: var(--green); }
.mkt-slot-card .msc-stats .neg b { color: var(--red); }
.mkt-slot-card .msc-stats .msc-wr b { color: var(--text-primary); }
/* Two tallies per slot: GLOBAL (all cells) and the CELL GATE (the marginal cell
   whose WR admitted the entry). The tag hangs at the card's left edge; the cell
   row is tinted so the gate's own record reads apart from the global one. */
.mkt-slot-card .msc-stats .msc-tag {
    min-width: 3.4rem; margin-left: -1.05rem;
    font-size: 0.56rem; font-weight: 700; letter-spacing: 0.04em;
    text-transform: uppercase; color: var(--text-muted);
}
.mkt-slot-card .msc-stats.msc-cell { margin-top: 0.1rem; }
.mkt-slot-card .msc-stats.msc-cell .msc-tag { color: #9b82c9; }
.mkt-slot-card .msc-stats.msc-cell .msc-wr b { color: #c3b2ea; }
