/* 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: #06b6d4;
    --accent-hover: #22d3ee;
    --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);

    /* Mode/surface tokens — consolidated here so import order can't leave them
       undefined (were tables.css-only). */
    --live: #3b82f6;  --live-bg: rgba(59, 130, 246, 0.12);
    --dry: #a78bfa;   --dry-bg: rgba(167, 139, 250, 0.12);
    --gold: #d4af37;  --gold-bg: rgba(212, 175, 55, 0.10);
    --panel: #0f1018; --panel-2: #14151f; --border-soft: #1f2030;

    /* One mono stack, one easing — used everywhere. */
    --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Consolas, monospace;
    --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);

    /* System scale — every gap/size/radius snaps to these (8px rhythm). */
    --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem;
    --space-5: 1.5rem;  --space-6: 2rem;   --space-7: 3rem;
    --text-xs: 0.62rem; --text-sm: 0.74rem; --text-base: 0.85rem;
    --text-md: 1rem;    --text-lg: 1.25rem; --text-xl: 1.6rem;
    --radius-sm: 4px;   --radius-md: 6px;   --radius-lg: 10px;
}

* { 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;
}

/* Shell layout (header · main · footer), primary nav, .nav-icon, .engine-status,
   .status-dot and .top-bar-right moved to shell.css when the fixed sidebar was
   replaced by the global header/footer rail. The old .app-layout / .sidebar /
   .main-content / .top-bar / sidebar-toggle / sidebar-collapsed rules were
   removed — no dead CSS for DOM that no longer exists. */

/* ── 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;
    margin-right: 0.85rem;
    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;
}
/* 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(6, 182, 212, 0.5); opacity: 1; }
    50%      { box-shadow: 0 0 0 5px rgba(6, 182, 212, 0); opacity: 0.6; }
}
/* The live counts: a step LARGER than the chrome + inline-block so the .nx-bump
   pop lands on them. */
.mkt-exstat .mx-armed,
.mkt-exstat .mx-long,
.mkt-exstat .mx-short,
.mkt-exstat .mx-pnl {
    display: inline-block;
    font-size: 0.95rem;
}
.mkt-exstat .mx-armed { color: var(--text-primary); font-weight: 600; }
.mkt-exstat .mx-long  { color: var(--green); font-weight: 600; }
.mkt-exstat .mx-short { color: var(--red);   font-weight: 600; }
.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 moved to shell.css (it is part of the header/main/footer shell
   scroll model now). */

/* 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(6, 182, 212, 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. */
.badge-regime { display: inline-flex; align-items: center; gap: 0.3rem; background: none; }
.badge-regime .br-count {
    font-weight: 500;
    opacity: 0.75;
    font-size: 0.65rem;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-muted);
}
.badge-regime .br-last,
.badge-regime .br-action,
.badge-regime .br-cross,
.badge-regime .br-self   { font-weight: 600; }
.badge-regime .br-cross,
.badge-regime .br-self   { opacity: 0.85; }
.badge-regime .br-sep   { opacity: 0.55; margin: 0 0.1rem; color: var(--text-muted); }
/* 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(6, 182, 212, 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(6, 182, 212, 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(6,182,212,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(6,182,212,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(6,182,212,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(6,182,212,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(6,182,212,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: #06b6d4; }
.nou-toast-info    .nou-toast-icon { background: #06b6d4; }

/* 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(6, 182, 212, 0.06);
    border-color: rgba(6, 182, 212, 0.4);
}
.bindable-row.picked {
    background: rgba(6, 182, 212, 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: 150px;
    max-width: 260px;
    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);
}
.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-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;
}

/* ── Avatar uploader (_admin/avatar.js) — DÙNG CHUNG header user-menu + people/
   person-modal. Nạp toàn cục (app.css) nên 2 nơi style nhất quán. Preview tròn +
   nút Đổi/Xoá; input file ẩn (kích bằng nút). ───────────────────────────────── */
.av-edit { display: flex; align-items: center; gap: 14px; }
.av-preview { flex: 0 0 auto; }
.av-pic {
    width: 64px; height: 64px; border-radius: 50%; display: inline-flex;
    align-items: center; justify-content: center; overflow: hidden;
    background: var(--bg-tertiary); border: 1px solid var(--border);
}
.av-pic.av-ini { color: var(--accent); font-size: 1.25rem; font-weight: 700; text-transform: uppercase; }
.av-pic img, img.av-pic { width: 100%; height: 100%; object-fit: cover; display: block; }
.av-file { display: none; }
.av-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
