/* ────────────────────────────────────────────────────────────────
   Sinux Signals — design tokens
   Neutral slate base + a single blue accent (light & dark).
   Chrome stays neutral so the semantic colours — green/red P&L, amber
   tickers, action pills — read clearly on top.
   ──────────────────────────────────────────────────────────────── */

:root {
  /* Brand anchors */
  --sinux-emerald: #10B981;
  --sinux-ink:     #0B0C0E;
  --sinux-pale:    #F2F3F5;

  /* Type — display (Conthrax substitute) / body / mono */
  --f-display: "Orbitron", "Conthrax", system-ui, sans-serif;
  --f-sans:    "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono:    "JetBrains Mono", "IBM Plex Mono", ui-monospace, Menlo, monospace;

  /* Density (overridden by tweaks) */
  --row-h: 44px;
  --pad-x: 16px;
  --pad-y: 12px;

  /* Text-size scale (overridden by [data-fontscale]) — multiplies the rem root.
     Default = 1 (today's sizes exactly). Only TEXT scales, not spacing/borders. */
  --fs: 1;

  /* Misc */
  --radius-sm: 4px;
  --radius: 6px;
  --radius-lg: 10px;
}

/* ── DARK theme (default) — neutral slate field, single blue accent */
:root,
[data-theme="dark"] {
  --bg-0: #0A0D0C;
  --bg-1: #131714;
  --bg-2: #191E1A;
  --bg-3: #212823;
  --bg-4: #2A312C;

  --border-1: #1F241F;
  --border-2: #2E342F;
  --border-3: #383F3A;

  --fg-0: #F3F5F1;
  --fg-1: #C7CCD3;
  --fg-2: #888E85;
  --fg-3: #5A5F57;
  --fg-mono: #D8DCD4;

  --accent:      #10B981;
  --accent-dim: #0D9C6D;
  --accent-glow: rgba(18, 196, 137, 0.14);

  /* Semantic trade actions — distinct hues that read on neutral slate */
  --c-open:   #34C281;
  --c-add:    #2DB9C4;
  --c-trim:   #F2B53D;
  --c-cut:    #FF7A45;
  --c-close:  #E06A8B;
  --c-hold:   #8A92A2;
  --c-watch:  #9B7BFF;
  --c-expire: #565C66;
  --c-ticker: #F5B845;   /* ticker symbols — high-contrast amber */

  --c-up:     #34C281;
  --c-down:   #F2585B;

  --conf-high:   #34C281;
  --conf-medium: #F2B53D;
  --conf-low:    #8A92A2;

  /* Analyst color slots — varied hues for chart lines / chips */
  --a-1: #5B8CF5;
  --a-2: #F2585B;
  --a-3: #34C281;
  --a-4: #9B7BFF;
  --a-5: #F5B845;
  --a-6: #2DB9C4;
  --a-7: #E06A8B;

  --shadow-1: 0 1px 2px rgba(0,0,0,0.30);
  --shadow-2: 0 16px 40px rgba(0,0,0,0.46);
  --grid-line: rgba(255,255,255,0.05);

  --body-bg: linear-gradient(180deg, #0F130F 0%, #0A0D0C 340px);
}

/* ── LIGHT theme — neutral light field, blue accent (darker for white bg) */
[data-theme="light"] {
  --bg-0: #F7F8F4;
  --bg-1: #FFFFFF;
  --bg-2: #EDF0EA;
  --bg-3: #E3E5DE;
  --bg-4: #D6DAD1;

  --border-1: #E6E8E1;
  --border-2: #D4D8CE;
  --border-3: #BBC1B6;

  --fg-0: #14171C;
  --fg-1: #3A3F48;
  --fg-2: #686E63;
  --fg-3: #9CA295;
  --fg-mono: #21262E;

  --accent:      #059669;
  --accent-dim:  #047857;
  --accent-glow: rgba(5, 150, 105, 0.12);

  --c-open:   #1A9E63;
  --c-add:    #1496A1;
  --c-trim:   #C2901C;
  --c-cut:    #D9582B;
  --c-close:  #C04E70;
  --c-hold:   #5E6675;
  --c-watch:  #6A52D0;
  --c-expire: #888E99;
  --c-ticker: #B7791F;   /* ticker symbols — dark amber for contrast on light */

  --c-up:     #18A06B;
  --c-down:   #E0414F;

  --conf-high:   #18A06B;
  --conf-medium: #C2901C;
  --conf-low:    #5E6675;

  --a-1: #3D6AE0;
  --a-2: #E0414F;
  --a-3: #18A06B;
  --a-4: #6A52D0;
  --a-5: #C2901C;
  --a-6: #1496A1;
  --a-7: #C04E70;

  --shadow-1: 0 1px 2px rgba(20,23,28,0.06);
  --shadow-2: 0 16px 40px rgba(20,23,28,0.13);
  --grid-line: rgba(20,23,28,0.06);

  --body-bg: linear-gradient(180deg, #FFFFFF 0%, #F7F8F4 340px);
}

/* Branded LIGHT mode — backgrounds, borders and the page field pick up a faint
   wash of the brand accent, so light mode echoes the brand (cyan for Charan,
   gold for Market Magicians, …) instead of being plain neutral grey. Automatic
   for any brand: it derives from --accent, which each brand sets per theme.
   Two attribute selectors → wins over the base light theme; the injected brand
   <style> only sets the accent vars, so these background tints apply on top. */
:root[data-brand][data-theme="light"] {
  --bg-0: color-mix(in oklab, var(--accent) 6%,  #F6F8FA);
  --bg-1: color-mix(in oklab, var(--accent) 3.5%, #FFFFFF);
  --bg-2: color-mix(in oklab, var(--accent) 8%,  #EBEEF1);
  --bg-3: color-mix(in oklab, var(--accent) 11%, #E0E4E8);
  --bg-4: color-mix(in oklab, var(--accent) 14%, #D4D9DF);
  --border-1: color-mix(in oklab, var(--accent) 13%, #E4E7EB);
  --border-2: color-mix(in oklab, var(--accent) 17%, #D3D7DD);
  --border-3: color-mix(in oklab, var(--accent) 24%, #BAC0C8);
  --grid-line: color-mix(in oklab, var(--accent) 18%, transparent);
  --body-bg: linear-gradient(180deg,
    color-mix(in oklab, var(--accent) 8%, #FBFCFD) 0%,
    color-mix(in oklab, var(--accent) 5%, #F6F8FA) 340px);
}

[data-density="compact"] {
  --row-h: 36px;
  --pad-x: 12px;
  --pad-y: 8px;
}
[data-density="comfortable"] {
  --row-h: 52px;
  --pad-x: 20px;
  --pad-y: 16px;
}
/* Accessibility text-size steps (set on <html> via data-fontscale). New users
   default to "md"; "sm" is the original compact size, "lg" the largest. Scales
   every rem-based font platform-wide. */
[data-fontscale="sm"] { --fs: 1; }
[data-fontscale="md"] { --fs: 1.125; }
[data-fontscale="lg"] { --fs: 1.25; }

/* ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg-0);
  color: var(--fg-0);
  font-family: var(--f-sans);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* rem root = 16px × the text-size scale. Every font-size is rem, so the whole
   platform's type scales from this one line; spacing/borders stay px (no overflow). */
html { font-size: calc(16px * var(--fs, 1)); }

body {
  min-height: 100vh;
  background-image: var(--body-bg);
  font-size: 0.875rem;   /* = 14px at the default scale */
}

button { font-family: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
input, select, textarea { font-family: inherit; color: inherit; }
::selection { background: var(--accent-glow); color: var(--fg-0); }

.mono { font-family: var(--f-mono); }
.kbd {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  padding: 2px 5px;
  border-radius: 3px;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  color: var(--fg-1);
}

/* ── scrollbars */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--border-3); background-clip: padding-box; border: 2px solid transparent; }
*::-webkit-scrollbar-track { background: transparent; }

/* ── Shell (sidebar + main) — full width */
.shell {
  display: grid;
  grid-template-columns: 224px minmax(0, 1fr);
  /* Two rows: sidebar+main share the first; the footer spans the full width of
     the second, running under the sidebar instead of stopping at its edge. */
  grid-template-rows: minmax(0, 1fr) auto;
  height: 100vh;          /* lock to the viewport — content scrolls, page doesn't */
  overflow: hidden;
  width: 100%;
}

/* Mobile reading-progress rail — hidden on desktop (the viewport is locked, so
   there is no page-level scroll to track). Made visible + fixed under 900px. */
.scroll-rail { display: none; }

/* ── Sidebar */
.sidebar {
  position: sticky;
  top: 0;
  height: 100%;   /* fill the first grid row — the footer owns the strip below */
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px 14px;
  border-right: 1px solid var(--border-1);
  background: var(--bg-1);
}
/* Brand lockup: [mark | name] vertically centered as a row; the white-label
   "Powered by Sinux Signals" line spans full-width beneath the lockup. */
.sidebar .brand {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 6px 8px 20px;
}
.sidebar .brand .brand-row {
  display: flex;
  align-items: center;   /* mark stays centered against the name, even wrapped */
  gap: 11px;
}
.sidebar .brand .mark {
  width: 30px; height: 30px;
  border-radius: 8px;
  background: var(--accent);
  color: var(--bg-0);
  display: grid; place-items: center;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 1rem;
  flex-shrink: 0;
}
/* Real brand logo in the mark slot — the image brings its own background */
.sidebar .brand .mark.mark-img { background: none; overflow: hidden; }
.sidebar .brand .mark img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }
.sidebar .brand .brand-name {
  font-family: var(--f-display);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--fg-0);
  line-height: 1.18;
  overflow-wrap: anywhere;   /* longer white-label names wrap instead of clipping */
}
/* White-label sub-line — the Sinux Signals reference under a brand lockup.
   Always Sinux emerald (NOT the brand accent): it names Sinux, so it keeps
   Sinux's colour no matter whose brand is active. */
.sidebar .brand .brand-powered {
  font-family: var(--f-mono);
  font-size: 0.5625rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--sinux-emerald);
  white-space: nowrap;
  padding-left: 1px;
}
.sidebar nav { display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 11px;
  border-radius: var(--radius);
  color: var(--fg-2);
  font-size: 0.84375rem;
  font-weight: 500;
  text-align: left;
  transition: background 120ms, color 120ms;
}
.nav-item .icon { flex-shrink: 0; }
.nav-item:hover { background: var(--bg-2); color: var(--fg-0); }
.nav-item.active { background: var(--accent-glow); color: var(--accent); }
.nav-label { flex: 1; }
.nav-badge {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  color: var(--fg-2);
  background: var(--bg-2);
  padding: 1px 7px;
  border-radius: 99px;
}
.nav-item.active .nav-badge { background: color-mix(in oklab, var(--accent) 18%, transparent); color: var(--accent); }
.sidebar-foot {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--border-1);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sidebar-ver { font-size: 0.65625rem; letter-spacing: 0.1em; color: var(--fg-3); padding-left: 2px; }

/* ── Main column + top bar */
.main { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* Reserve the iOS status-bar / notch inset so the header never sits under it
     (we draw full-screen via viewport-fit=cover + black-translucent). env()
     resolves to 0 off-PWA, so this is a no-op on desktop/Android. */
  padding: calc(16px + env(safe-area-inset-top, 0px)) calc(28px + env(safe-area-inset-right, 0px)) 16px calc(28px + env(safe-area-inset-left, 0px));
  border-bottom: 1px solid var(--border-1);
  background: color-mix(in oklab, var(--bg-0) 86%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.nav-toggle { display: none; }      /* hamburger — shown on mobile */
.nav-backdrop { display: none; }    /* drawer backdrop — shown on mobile */
.topbar-title { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.topbar-title h1 {
  margin: 0;
  font-size: 1.1875rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg-0);
}
.topbar-sub {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--f-mono);
  font-size: 0.71875rem;
  color: var(--fg-2);
  flex-wrap: wrap;
}
.topbar-sub .sep { color: var(--fg-3); }
.topbar-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
/* Content fills the space between top bar and footer and is the scroll owner —
   so the footer stays pinned and never needs a page scroll to reach. */
.content { padding: 22px 28px 24px; display: flex; flex-direction: column; gap: 16px; min-width: 0; min-height: 0; flex: 1 1 auto; overflow-y: auto; }
/* Don't let the flex column squeeze a tall child (e.g. the Settings panel) down
   and clip it — keep natural height so the content area scrolls instead. The
   positions split opts back in to filling via its own `flex` below. */
.content > * { flex-shrink: 0; }

/* Positions split fills the viewport; each panel scrolls inside its own box.
   `.solo` is the same geometry without the events rail (rail is owner-only /
   granted), so hiding the rail keeps the pinned header + in-panel scrolling. */
.split.cols, .split.solo { grid-template-rows: minmax(0, 1fr); flex: 1 1 auto; min-height: 0; }
.split.cols > .panel, .split.solo > .panel { min-height: 0; }
.split.cols .scroll-y, .split.solo .scroll-y { flex: 1 1 auto; min-height: 0; }

/* ── App footer — a full-width strip across BOTH grid columns (under the
   sidebar too), so the version/copyright reads once, edge to edge. */
.app-footer {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 28px; border-top: 1px solid var(--border-1);
  background: var(--bg-0);
  font-size: 0.6875rem; letter-spacing: 0.04em; color: var(--fg-3); flex-shrink: 0;
}
.app-footer-mid { text-align: center; flex: 1; }
.app-footer-ver { white-space: nowrap; }
.app-footer a { color: var(--accent); text-decoration: none; font-weight: 600; }
.app-footer a:hover { text-decoration: underline; }

/* ── Status pill */
.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  color: var(--accent);
  text-transform: lowercase;
}
.status .dot {
  width: 8px; height: 8px; border-radius: 99px;
  background: var(--accent);
  box-shadow: 0 0 0 0 var(--accent-glow);
  animation: pulse 1.6s ease-out infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-glow); }
  70%  { box-shadow: 0 0 0 8px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ── Stat tiles */
.statgrid {
  display: grid;
  /* Auto-fit: 4-up on wide screens, wrapping to 2×2 on narrower ones instead
     of crushing the cards. (Mobile pins an explicit 2-col layout.) */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
}
.stat {
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
  overflow: hidden;
}
.stat .lbl {
  font-family: var(--f-sans);
  font-size: 0.75rem;
  letter-spacing: 0.01em;
  color: var(--fg-2);
  display: flex;
  align-items: center;
  gap: 8px;
}
.stat .val {
  font-family: var(--f-mono);
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
}
.stat .delta {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  color: var(--fg-3);
}
.stat .delta.up { color: var(--c-up); }
.stat .delta.down { color: var(--c-down); }
/* Positions summary strip: colored values + green/red inline splits */
.stat .val.up { color: var(--c-up); }
.stat .val.down { color: var(--c-down); }
.stat .val.val-sm { font-size: 1.1875rem; }
.stat .val.val-sm .ticker { font-size: 1rem; }
.stat .delta .up { color: var(--c-up); }
.stat .delta .down { color: var(--c-down); }
.stat .icon {
  width: 14px; height: 14px;
  color: var(--fg-2);
  flex-shrink: 0;
}

/* ── Filter bar */
.filterbar {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  gap: 8px;
}
.input, .select, .btn {
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  color: var(--fg-0);
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 0.8125rem;
  outline: none;
  transition: border-color 120ms, background 120ms;
}
.input:focus, .select:focus { border-color: var(--border-3); }
.input::placeholder { color: var(--fg-3); }
.input.search { padding-left: 38px; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236d7787' stroke-width='2'><circle cx='11' cy='11' r='7'/><path d='m21 21-4.3-4.3'/></svg>"); background-repeat: no-repeat; background-position: 12px 50%; }
.btn { cursor: pointer; display: inline-flex; align-items: center; gap: 8px; }
.btn:hover { background: var(--bg-2); border-color: var(--border-2); }
.btn.primary {
  background: var(--accent-glow);
  border-color: var(--accent-dim);
  color: var(--accent);
}
.btn.primary:hover { background: oklch(from var(--accent) l c h / 0.28); }
.btn.danger { background: var(--c-down); border-color: var(--c-down); color: #fff; }
.btn.danger:hover { background: var(--c-down); border-color: var(--c-down); filter: brightness(1.08); }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; gap: 5px; }
.btn .icon { width: 14px; height: 14px; }
.btn.ghost { background: transparent; border-color: transparent; }
.btn.ghost:hover { background: var(--bg-2); border-color: var(--border-1); }

/* ── Icon-only buttons (delete, options, etc.) */
.icon-btn {
  width: 30px; height: 30px;
  display: inline-grid;
  place-items: center;
  border-radius: var(--radius-sm);
  color: var(--fg-3);
  background: transparent;
  border: 1px solid transparent;
  transition: color 120ms, background 120ms, border-color 120ms;
  flex-shrink: 0;
}
.icon-btn:hover { color: var(--fg-1); background: var(--bg-3); }
/* Button text label — hidden on desktop (icon-only), shown in mobile card footers */
.btn-label { display: none; }
.icon-btn.active { color: var(--accent); background: var(--accent-glow); }
/* Manage (admin manual update) — accent-tinted so it reads as the primary row action */
.icon-btn.manage-btn { color: var(--accent); }
.icon-btn.manage-btn:hover { color: var(--accent); background: var(--accent-glow); }
.icon-btn.danger:hover { color: var(--c-down); background: color-mix(in oklab, var(--c-down) 12%, transparent); border-color: color-mix(in oklab, var(--c-down) 30%, transparent); }
.numinput {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 6px 14px;
  font-family: var(--f-mono);
  font-size: 0.75rem;
}
.numinput label { color: var(--fg-2); font-size: 0.625rem; letter-spacing: 0.14em; text-transform: uppercase; }
.numinput input { width: 50px; background: transparent; border: 0; outline: 0; color: var(--fg-0); font-family: var(--f-mono); font-size: 0.8125rem; padding: 4px 0; text-align: right; }

/* ── Positions filter row: timeframe segment + min-trades stepper + reset */
.pos-filterbar { align-items: stretch; }
.pos-range { flex-shrink: 0; }
.pos-range .seg-btn { padding: 0 13px; display: inline-flex; align-items: center; }
.pos-reset { flex-shrink: 0; color: var(--fg-2); font-size: 0.75rem; }
.pos-reset:hover { color: var(--fg-0); }

/* ── Panels */
.panel {
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.panel-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-1);
}
.panel-title {
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.panel-hdr-tools { display: flex; align-items: center; gap: 12px; }
.panel-meta {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-2);
}

/* ── Tables */
.tbl { width: 100%; border-collapse: collapse; }
/* Fixed layout: columns get defined widths (via <colgroup>), the flex column
   absorbs the rest, and cells clip with ellipsis — so the table always fills
   its container instead of overflowing. */
.tbl-fixed { table-layout: fixed; }
.tbl-fixed th, .tbl-fixed td { overflow: hidden; text-overflow: ellipsis; }
.tbl thead th {
  text-align: left;
  font-family: var(--f-mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  color: var(--fg-2);
  text-transform: uppercase;
  padding: 10px var(--pad-x);
  border-bottom: 1px solid var(--border-1);
  background: var(--bg-1);
  position: sticky;
  top: 0;
  z-index: 1;
  white-space: nowrap;
}
.tbl thead th.sortable { cursor: pointer; user-select: none; }
.tbl thead th.sortable:hover { color: var(--fg-1); }
.tbl thead th .sort-ind {
  display: inline-block;
  margin-left: 4px;
  opacity: 0.5;
}
.tbl thead th.active .sort-ind { color: var(--accent); opacity: 1; }
.tbl tbody td {
  padding: var(--pad-y) var(--pad-x);
  border-bottom: 1px solid var(--border-1);
  font-size: 0.8125rem;
  vertical-align: middle;
  height: var(--row-h);
}
.tbl tbody tr { transition: background 120ms; }
.tbl tbody tr:hover { background: var(--bg-2); }
.tbl tbody tr.expanded { background: var(--bg-2); }
.tbl tbody tr.expanded + tr.expand-row > td { background: var(--bg-2); }

.tbl tbody tr.row-selected,
.tbl tbody tr.row-selected:hover { background: var(--accent-glow); }

/* ── Bulk action bar (multi-select) */
.bulk-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  background: var(--accent-glow);
  border: 1px solid var(--accent-dim);
  border-radius: var(--radius);
  font-size: 0.8125rem; color: var(--fg-0);
}
.bulk-bar strong { color: var(--accent); }

/* ── Recycle bin (Events / Watchlist "Deleted" view) ── */
.trash-wrap { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; }
.trash-note { padding: 24px 14px; font-size: 0.8125rem; }
.trash-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 2px 8px; font-size: 0.78125rem;
  border-bottom: 1px solid var(--border-1); margin-bottom: 4px;
}
.trash-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  background: var(--bg-1); border: 1px solid var(--border-1);
  border-radius: var(--radius);
}
.trash-row-main { min-width: 0; flex: 1; }
.trash-label {
  font-size: 0.84375rem; color: var(--fg-0); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.trash-sub { font-size: 0.71875rem; color: var(--fg-3); margin-top: 5px; }
.trash-row-acts { display: flex; gap: 6px; flex-shrink: 0; }

/* ── To-Do tab (reconciliation + parse-quality queue) ──
   Deliberately the same restrained card-list as the recycle bin: a flat stack of
   rows, one accent-bearing kind pill, actions on the right. No status dashboard. */
.todo-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.todo-wrap { display: flex; flex-direction: column; gap: 14px; padding: 12px 14px; }
.todo-group { display: flex; flex-direction: column; gap: 8px; }
.todo-group-head {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 0.71875rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-3); padding-bottom: 6px; border-bottom: 1px solid var(--border-1);
}
.todo-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 12px;
  background: var(--bg-1); border: 1px solid var(--border-1);
  border-radius: var(--radius);
  box-shadow: inset 3px 0 0 var(--todo-tone, var(--border-3));
}
/* Status reads off the card itself — a left stripe plus a faint wash — so a
   glance down the list separates settled from outstanding without reading a
   word. Open rows take the stripe from their KIND (severity); settled rows
   override it with green/grey and recede. Status rules must stay AFTER the
   tone rules: equal specificity, so source order decides the winner. */
.todo-row.tone-warn { --todo-tone: var(--c-watch); }
.todo-row.tone-bad  { --todo-tone: var(--c-down); }
.todo-row.tone-act  { --todo-tone: var(--c-up); }
.todo-row.td-resolved {
  --todo-tone: var(--c-up);
  background: color-mix(in oklab, var(--c-up) 7%, var(--bg-1));
  border-color: color-mix(in oklab, var(--c-up) 24%, var(--border-1));
}
.todo-row.td-dismissed { --todo-tone: var(--fg-3); opacity: .68; }
.todo-row.td-resolved .todo-detail,
.todo-row.td-dismissed .todo-detail { color: var(--fg-2); }
.todo-row-main { min-width: 0; flex: 1; }
.todo-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.todo-contract { font-size: 0.75rem; color: var(--fg-2); }
.todo-detail { font-size: 0.8125rem; color: var(--fg-1); margin-top: 6px; line-height: 1.45; }
.todo-sub { font-size: 0.71875rem; color: var(--fg-3); margin-top: 6px; }
.todo-row-acts { display: flex; gap: 6px; flex-shrink: 0; }
/* Kind pill — tone carries the meaning, never the brand accent (semantics stay
   readable across white-label brands, same rule as the action pills). */
.todo-kind {
  font-family: var(--f-mono); font-size: 0.65625rem; letter-spacing: .04em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 999px;
  border: 1px solid currentColor; white-space: nowrap;
}
.tk-warn { color: var(--c-watch, #d9a441); }
.tk-bad  { color: var(--c-down, #e2555b); }
.tk-act  { color: var(--c-up, #3fbf7f); }
/* Settled state, spelled out — the stripe says it at a glance, this says it
   exactly (colour alone must never be the only carrier of meaning). */
.todo-status {
  font-family: var(--f-mono); font-size: 0.625rem; letter-spacing: .05em;
  text-transform: uppercase; padding: 1px 6px; border-radius: 999px;
  border: 1px solid currentColor; white-space: nowrap;
}
.ts-resolved  { color: var(--c-up); }
.ts-dismissed { color: var(--fg-3); }
@media (max-width: 640px) {
  .todo-row { flex-direction: column; align-items: stretch; gap: 8px; }
  .todo-row-acts { justify-content: flex-end; }
}

/* Mobile-only "Select all" bar (the table header checkbox is hidden in card mode) */
.cards-selectall { display: none; }

.tbl td.mono { font-family: var(--f-mono); }
.tbl td.muted { color: var(--fg-2); }
.tbl td.dim { color: var(--fg-3); }
.tbl td.num { text-align: right; font-family: var(--f-mono); }

.ticker {
  font-family: var(--f-mono);
  font-weight: 600;
  color: var(--c-ticker);
  font-size: 0.8125rem;
}
.contract {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  color: var(--fg-1);
}

/* ── Instrument (shares vs option) cell */
.inst { display: inline-flex; align-items: center; gap: 8px; font-family: var(--f-mono); font-size: 0.75rem; white-space: nowrap; }
.inst-tag {
  font-size: 0.59375rem; font-weight: 600; letter-spacing: 0.08em;
  padding: 2px 6px; border-radius: 4px;
  border: 1px solid currentColor;
  background: color-mix(in oklab, currentColor 12%, transparent);
}
.inst-tag.call   { color: var(--c-up); }
.inst-tag.put    { color: var(--c-down); }
.inst-tag.opt    { color: var(--accent); }
.inst-tag.shares { color: var(--fg-2); }
.inst-detail { color: var(--fg-1); }

/* ── Segmented control (reusable) */
.seg { display: inline-flex; border: 1px solid var(--border-1); border-radius: var(--radius); overflow: hidden; }
.seg-btn {
  padding: 9px 14px; font-size: 0.75rem; font-family: var(--f-mono);
  color: var(--fg-2); background: var(--bg-1);
  border-right: 1px solid var(--border-1);
  transition: color 120ms, background 120ms;
}
.seg-btn:last-child { border-right: 0; }
.seg-btn:hover { color: var(--fg-0); }
.seg-btn.on { background: var(--accent-glow); color: var(--accent); }

/* ── Analyst filter dropdown (reusable across feeds) */
.analyst-filter { position: relative; display: inline-block; }
.af-btn { padding: 8px 12px; display: inline-flex; align-items: center; gap: 7px; font-family: var(--f-mono); font-size: 0.75rem; color: var(--fg-1); }
.af-label { white-space: nowrap; }
.af-menu {
  /* Desktop: anchor to the button's right (it usually sits right-aligned).
     Mobile overrides to left:0 (the trigger sits on the left there). Width is
     capped so it can never spill off either edge. */
  position: absolute; top: calc(100% + 4px); right: 0; left: auto; z-index: 60;
  min-width: 220px; max-width: min(300px, calc(100vw - 28px)); max-height: 320px; overflow-y: auto;
  background: var(--bg-1); border: 1px solid var(--border-2);
  border-radius: var(--radius); box-shadow: var(--shadow-2); padding: 4px;
}
.af-menu-hd {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 8px 8px; font-family: var(--f-mono); font-size: 0.625rem;
  letter-spacing: .10em; text-transform: uppercase; color: var(--fg-2);
}
.af-menu-hd button { color: var(--accent); font-size: 0.625rem; letter-spacing: .06em; }
.af-opt {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 8px; border-radius: 7px; font-size: 0.8125rem; color: var(--fg-1);
  text-align: left;
}
.af-opt:hover { background: var(--bg-2); }
.af-opt.on { color: var(--fg-0); }
.af-check { width: 14px; display: inline-flex; align-items: center; justify-content: center; color: var(--accent); flex-shrink: 0; }

/* ── Pills / badges */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--f-mono);
  font-size: 0.625rem;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 99px;
  border: 1px solid currentColor;
  background: color-mix(in oklab, currentColor 12%, transparent);
}
.pill.open    { color: var(--c-open); }
.pill.add     { color: var(--c-add); }
.pill.trim    { color: var(--c-trim); }
.pill.cut     { color: var(--c-cut); }
.pill.close   { color: var(--c-close); }
.pill.hold    { color: var(--c-hold); }
.pill.watch   { color: var(--c-watch); }
.pill.expire  { color: var(--c-expire); }
.pill.high    { color: var(--conf-high); }
.pill.medium  { color: var(--conf-medium); }
.pill.low     { color: var(--conf-low); }

.dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 99px;
  background: currentColor;
  margin-right: 6px;
  vertical-align: middle;
}

/* ── Analyst chip */
.analyst {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--f-mono);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--fg-0);
}
.analyst .swatch {
  width: 8px; height: 8px;
  border-radius: 99px;
  background: var(--col, var(--accent));
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--col, var(--accent)) 18%, transparent);
}
/* Analyst avatar — ringed in that analyst's colour so the colour-coding that
   ties rows together survives, and the face reads as identity rather than
   decoration. Falls back to the plain swatch when no picture resolves. */
.analyst .analyst-pic {
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--col, var(--accent)) 70%, transparent);
  background: var(--bg-2);
  flex-shrink: 0;
}
/* A picture is a wider object than the 8px dot — tighten the gap so the name
   still reads as one unit with it rather than drifting away. */
.analyst:has(.analyst-pic) { gap: 7px; }

/* ── Splits */
.split { display: grid; gap: 14px; }
.split.cols { grid-template-columns: 1fr 420px; }
.split.cols-narrow { grid-template-columns: 280px 1fr; }

/* Charts page fills the viewport like the positions split; each region scrolls
   inside its own box so the panels extend into the available vertical space. */
.split.cols-charts {
  grid-template-columns: 280px 1fr;
  grid-template-rows: minmax(0, 1fr);
  flex: 1 1 auto; min-height: 0;
}
.split.cols-charts > .panel { min-height: 0; }
.charts-right { display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 14px; min-height: 0; }
/* Focused charts view: ticker list + one big chart that fills its column. */
.charts-side { display: flex; flex-direction: column; }
.charts-tk-search { padding: 10px 12px; border-bottom: 1px solid var(--border-1); }
.charts-tk-search .input.search { width: 100%; padding: 8px 14px 8px 38px; }
.charts-right-solo { grid-template-rows: minmax(0, 1fr); }
.chart-wrap-fill { height: 100%; min-height: 0; box-sizing: border-box; }
/* In fill mode the rendered svg height must track the (responsive) viewBox
   height, else preserveAspectRatio letterboxes + centers the chart. */
.chart-wrap-fill .chart-svg { height: auto; }
.charts-subgrid > .panel { min-height: 0; }
.charts-sources { max-height: 280px; }
.charts-fill { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.charts-fill-cap { flex: 1 1 auto; min-height: 140px; overflow-y: auto; }

/* ── Event rail card */
.event {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-1);
  cursor: pointer;
  transition: background 120ms;
}
.event:hover { background: var(--bg-2); }
.event .e-analyst { font-family: var(--f-mono); font-size: 0.6875rem; letter-spacing: 0.10em; color: var(--fg-1); }
.event .e-time   { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-2); justify-self: end; }
.event .e-ticker { font-family: var(--f-mono); font-weight: 600; color: var(--accent); font-size: 0.875rem; }
.event .e-pill   { justify-self: end; }
.event .e-note   { grid-column: 1 / -1; color: var(--fg-1); font-size: 0.75rem; margin-top: 4px; }
.event.slide-in { animation: slideIn 380ms cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes slideIn {
  from { opacity: 0; transform: translateY(-8px); background: var(--accent-glow); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Fresh event in the rail — a quiet left accent so "new" reads without shouting. */
.event.event-fresh { box-shadow: inset 2px 0 0 var(--accent); }

/* ── Recency cues — the at-a-glance "new vs old" language, shared by the
   Positions, Events and rail feeds. Subtle on purpose: a "NEW" tag for the
   last ~2h, a softly tinted relative time, and a quiet left accent on the row. */
.rcy-new {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 0.53125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-glow);
  border: 1px solid var(--accent-dim);
  border-radius: 4px;
  padding: 1px 4px;
  margin-right: 6px;
  vertical-align: middle;
  line-height: 1.35;
}
.rcy-live  { color: var(--accent); }
.rcy-today { color: var(--fg-1); }
.tbl tbody tr.row-fresh > td { background: color-mix(in oklab, var(--accent) 5%, transparent); }
.tbl tbody tr.row-fresh > td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.tbl tbody tr.row-fresh:hover > td { background: color-mix(in oklab, var(--accent) 9%, transparent); }
.mpos.row-fresh { box-shadow: inset 2px 0 0 var(--accent); }

/* ── Positions: P&L as the visual anchor ─────────────────────────────────── */
.pos-pnl { line-height: 1.3; }
.pnl-big { font-family: var(--f-mono); font-size: 0.875rem; font-weight: 600; display: block; }
.pnl-big.up { color: var(--c-up); }
.pnl-big.down { color: var(--c-down); }
/* fg-2, not fg-3: these are the two dollar figures the big percentage derives
   from — they measured 2.9:1 on the panel background, below the AA floor,
   while the derived number above them shouted at full strength. */
.pnl-sub { display: block; font-size: 0.6875rem; color: var(--fg-2); margin-top: 4px; }
.pnl-arr { color: var(--fg-3); }
.pnl-avg { font-size: 0.65625rem; color: var(--fg-2); margin-left: 4px; text-transform: uppercase; letter-spacing: .04em; }
/* Green/red left accent bar by current P&L */
.tbl tbody tr.pnl-up > td:first-child { box-shadow: inset 3px 0 0 var(--c-up); }
.tbl tbody tr.pnl-down > td:first-child { box-shadow: inset 3px 0 0 var(--c-down); }
.mpos.pnl-up { box-shadow: inset 3px 0 0 var(--c-up); }
.mpos.pnl-down { box-shadow: inset 3px 0 0 var(--c-down); }
/* Details moved out of the row, surfaced in the expand panel */
/* Cap the tracks — 1fr let 5-8 fields sprawl the full table width (the panel is
   a colSpan cell), so Entry/Stop/Mark sat hundreds of px apart on a wide
   monitor. 160px absorbs the longest "Last stated" value without wrapping. */
.pos-detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 160px)); justify-content: start; gap: 10px 20px; padding: 14px 16px 6px; margin: 0; }
.pos-detail-grid dt { font-size: 0.59375rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-3); margin-bottom: 5px; }
.pos-detail-grid dd { margin: 0; font-size: 0.8125rem; color: var(--fg-0); }
.pos-seg { flex-shrink: 0; }

/* ── Parser detail */
.parser-detail {
  padding: 18px 24px;
  background: var(--bg-2);
  border-top: 1px dashed var(--border-2);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
.parser-detail h4 {
  font-family: var(--f-mono);
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-2);
  margin: 0 0 10px;
  font-weight: 500;
}
.parser-detail .raw-msg {
  background: var(--bg-0);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 12px 14px;
  font-size: 0.8125rem;
  color: var(--fg-1);
  line-height: 1.55;
}
.parser-detail .reasoning {
  font-size: 0.75rem;
  color: var(--fg-1);
  line-height: 1.55;
}
.parser-detail .reasoning .highlight {
  background: var(--accent-glow);
  color: var(--accent);
  padding: 1px 4px;
  border-radius: 2px;
}
.parser-detail pre {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  color: var(--fg-mono);
  background: var(--bg-0);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin: 0;
  overflow-x: auto;
  line-height: 1.6;
}
.parser-detail pre .k { color: oklch(0.78 0.12 290); }
.parser-detail pre .s { color: var(--accent); }
.parser-detail pre .n { color: var(--c-trim); }
.parser-detail .meta-row {
  display: flex;
  gap: 16px;
  margin-top: 12px;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  color: var(--fg-2);
  flex-wrap: wrap;
}
.parser-detail .meta-row span strong { color: var(--fg-0); font-weight: 500; }

/* ── Trade interaction timeline (position expand + recaps) */
.position-detail { padding: 16px 24px; background: var(--bg-2); border-top: 1px dashed var(--border-2); }
.pd-title {
  font-family: var(--f-mono); font-size: 0.625rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--fg-2); margin: 0 0 10px; font-weight: 500;
}
.trade-timeline { display: flex; flex-direction: column; }
.tl-row {
  display: flex; align-items: center; gap: 10px;
  /* Staircase indent: each step nests the follow-up under the entry (--tl-level
     0..2, set per row). Easier to read; capped so it never runs off-screen. */
  padding: 9px 0 9px calc(var(--tl-level, 0) * 20px);
  border-bottom: 1px solid var(--border-1);
  font-size: 0.75rem;
}
.tl-row:last-child { border-bottom: 0; }
/* Leading anchor dot — accent on the entry, muted on the nested follow-ups. */
.tl-mark { width: 5px; height: 5px; border-radius: 50%; background: var(--fg-3); opacity: .55; flex-shrink: 0; }
.tl-entry .tl-mark { width: 7px; height: 7px; background: var(--accent); opacity: 1; }
.tl-row > .pill, .tl-row > .icon { flex-shrink: 0; }
.tl-time { color: var(--fg-3); font-size: 0.6875rem; white-space: nowrap; flex-shrink: 0; }
.tl-detail { color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 0; }
.tl-note { color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1 1 auto; min-width: 40px; }
/* Per-interaction override affordance — appears on row hover (always on touch). */
.tl-edit { flex-shrink: 0; background: none; border: 0; color: var(--fg-3); cursor: pointer; padding: 2px 5px; border-radius: 4px; display: inline-flex; align-items: center; opacity: 0; transition: opacity 120ms, color 120ms, background 120ms; }
.tl-row:hover .tl-edit { opacity: 1; }
.tl-edit:hover { color: var(--accent); background: var(--bg-2); }
@media (hover: none) { .tl-edit { opacity: 1; } }
.recap .trade-timeline { max-height: 188px; overflow-y: auto; margin: 2px 0; }
.recap .tl-row .tl-note { display: none; }

/* ── Mobile Open Positions accordion (rendered only < 900px by MobilePositionList).
   Collapsed = ticker · instrument · analyst · entry→now; tap to reveal details. */
.mpos-list { display: flex; flex-direction: column; gap: 10px; }
.mpos { background: var(--bg-1); border: 1px solid var(--border-2); border-radius: var(--radius); box-shadow: var(--shadow-1); overflow: hidden; }
.mpos.open { border-color: var(--accent-dim); }
.mpos-head { display: block; width: 100%; text-align: left; padding: 14px 15px; background: none; cursor: pointer; }
.mpos-head:active { background: var(--bg-2); }
/* Top row — identity left, status + chevron right. */
.mpos-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mpos-id { display: inline-flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; row-gap: 6px; }
.mpos-id .ticker { font-size: 1rem; }
.mpos-top-r { display: inline-flex; align-items: center; gap: 9px; flex-shrink: 0; }
.mpos-chev { color: var(--fg-3); display: inline-flex; }
/* Contract on its own line under the identity — strike · expiry, unpinched. */
.mpos-cx { margin-top: 7px; font-size: 0.71875rem; line-height: 1.3; color: var(--fg-2); letter-spacing: 0.01em; }
.mpos-cx .ic-strike { color: var(--fg-1); font-weight: 600; }
.mpos-cx .ic-sep { color: var(--fg-3); }
/* Body — analyst left (grows/wraps freely), numbers right-aligned in a fixed
   stack so a two-line analyst name can never shove them around. */
.mpos-bd { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-top: 12px; }
.mpos-bd > .analyst { flex: 1 1 auto; min-width: 0; align-items: flex-start; }
.mpos-nums { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; text-align: right; }
.mpos-pct { font-family: var(--f-mono); font-size: 1rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.mpos-pct.up { color: var(--c-up); }
.mpos-pct.down { color: var(--c-down); }
.mpos-flow { font-size: 0.78125rem; color: var(--fg-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mpos-flow .mpos-arrow { color: var(--fg-3); margin: 0 2px; }
.mpos-entry-lbl { color: var(--fg-3); font-size: 0.65625rem; letter-spacing: .04em; text-transform: uppercase; margin-left: 4px; }
.mpos-metaline { font-size: 0.6875rem; color: var(--fg-3); white-space: nowrap; display: inline-flex; align-items: center; }
.mpos-metaline .mpos-dot { color: var(--fg-3); margin: 0 5px; }
.mpos-metaline .mark-age { margin: 0; }
.mpos-nums .mpos-spark { margin-top: 2px; }
.mpos-body { padding: 2px 14px 14px; border-top: 1px solid var(--border-1); }
.mpos-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 11px 16px; margin: 13px 0 4px; }
.mpos-grid > div { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.mpos-grid dt { font-family: var(--f-mono); font-size: 0.5625rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
.mpos-grid dd { margin: 0; font-size: 0.84375rem; color: var(--fg-1); font-family: var(--f-mono); }
.mpos-dn { color: var(--c-down); }
.mpos-sec { margin-top: 14px; }
.mpos-lbl { display: block; font-family: var(--f-mono); font-size: 0.5625rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 6px; }
.mpos-note { margin: 0; font-size: 0.8125rem; line-height: 1.5; color: var(--fg-1); word-break: break-word; }
.mpos-btns { display: flex; gap: 8px; margin-top: 16px; }
.mpos-btns .btn { flex: 1; justify-content: center; height: 38px; }
.mpos-body .parser-detail { margin: 14px -14px 0; border-radius: 0 0 var(--radius) var(--radius); }
.mpos-body .position-detail { display: none; }
/* Shared by the Events / Watchlist accordions (selection, day groups, etc.) */
.mpos-r2r { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; }
.mpos-meta { font-family: var(--f-mono); font-size: 0.71875rem; color: var(--fg-2); display: inline-flex; align-items: center; white-space: nowrap; }
.mpos-cb { width: 16px; height: 16px; flex-shrink: 0; margin: 0 2px 0 0; }
.mpos.msel { border-color: var(--accent-dim); background: var(--accent-glow); }
.mpos-day { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding: 16px 2px 4px; }
.mpos-day-t { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); }
.mpos-day-m { font-size: 0.6875rem; color: var(--fg-3); }
.mpos-tickrow { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.mpos-note-title { font-weight: 600; color: var(--fg-0); margin-bottom: 7px; }

/* ── Analyst-first Open Positions overview (per-server `positions_by_analyst`).
   An editorial ROSTER, not a card grid: one full-bleed league-table row per
   analyst on hairline rules, ranked by open count. Fills the width by
   construction (a 3-analyst book never reads as a sparse grid) and reflows to a
   clean single-column stack on mobile. Boutique, asymmetric, restrained — no
   rounded-card grid. */
.an-roster { padding: 0; }
/* Head + row share ONE identical grid template — keep them in step (no subgrid
   available) or the columns drift out of alignment. */
.an-roster-head,
.an-roster-row {
  display: grid;
  /* Fixed flags column (not auto) so a row WITH an expiring pill keeps the exact
     same tracks as one without — otherwise the flexible columns absorb the pill's
     width and rows drift out of vertical alignment with each other + the header. */
  grid-template-columns: 44px minmax(160px, 1.25fr) 132px 84px minmax(0, 1.6fr) 72px 22px;
  align-items: center;
  column-gap: 18px;
  padding-left: 20px;
  padding-right: 18px;
}
.an-roster-head {
  position: sticky; top: 0; z-index: 1;
  height: 34px;
  background: var(--bg-1);          /* opaque — rows must not bleed through on scroll */
  border-bottom: 1px solid var(--border-1);
  font: 600 0.65625rem/1 var(--f-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--fg-3);
}
.an-roster-head .r { text-align: right; }

.an-roster-row {
  position: relative;
  min-height: 66px;
  padding-top: 13px; padding-bottom: 13px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border-1);
  cursor: pointer;
  transition: background 130ms ease;
}
/* Colour spine carried over from the old card — reads as an evolution. */
.an-roster-row::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--col); opacity: 0.5;
  transition: opacity 130ms ease;
}
.an-roster-row:hover { background: color-mix(in oklab, var(--col) 7%, var(--bg-1)); }
.an-roster-row:hover::before { opacity: 1; }

.an-r-rank {
  justify-self: end;
  font: 700 1.375rem/1 var(--f-mono);
  font-variant-numeric: tabular-nums;
  color: color-mix(in oklab, var(--fg-3) 52%, transparent);
  transition: color 130ms ease;
}
.an-roster-row:hover .an-r-rank { color: color-mix(in oklab, var(--col) 70%, var(--fg-3)); }
/* Lead row (sparse view): the ghost numeral takes the analyst's own colour. */
.an-roster-row.lead .an-r-rank { color: color-mix(in oklab, var(--col) 55%, transparent); }

.an-r-id { display: flex; align-items: center; gap: 11px; min-width: 0; }
.an-ov-pic {
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--col) 65%, transparent);
  background: var(--bg-2);
  flex-shrink: 0;
}
.an-r-id .swatch.lg {
  width: 40px; height: 40px; border-radius: 99px;
  background: color-mix(in oklab, var(--col) 22%, var(--bg-3));
  box-shadow: 0 0 0 1.5px color-mix(in oklab, var(--col) 60%, transparent);
  flex-shrink: 0;
}
.an-r-idtext { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.an-r-eyebrow {
  font: 600 0.625rem/1 var(--f-mono);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: color-mix(in oklab, var(--col) 55%, var(--fg-2));
}
.an-r-name {
  font: 600 0.875rem/1 var(--f-mono);
  letter-spacing: 0.05em;
  color: var(--fg-0);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.an-r-sub {
  font-size: 0.71875rem; color: var(--fg-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.an-r-sub .up { color: var(--c-up); }
.an-r-sub .down { color: var(--c-down); }
.an-r-sub .muted { color: var(--fg-3); }

.an-r-book { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.an-r-open { display: flex; align-items: baseline; gap: 5px; }
.an-r-open strong {
  font: 700 1.375rem/1 var(--f-mono);
  font-variant-numeric: tabular-nums;
  color: var(--fg-0);
}
.an-r-open-l {
  font: 0.65625rem/1 var(--f-mono);
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--fg-3);
}

/* Signature motif: the segmented book-health meter — up / down / still-unmarked,
   proportioned by count. Semantic colours only; unmarked is neutral grey. */
.bmeter {
  display: flex; height: 5px; width: 108px; gap: 2px;
  border-radius: 3px; overflow: hidden;
  background: var(--bg-3);
}
.bmeter i { display: block; min-width: 3px; }   /* keep a lopsided sliver visible */
.bm-up { background: var(--c-up); }
.bm-down { background: var(--c-down); }
.bm-un { background: color-mix(in oklab, var(--fg-3) 45%, var(--bg-3)); }

.an-r-pnl { justify-self: end; text-align: right; font-variant-numeric: tabular-nums; }
.an-r-pnl .fig { font: 700 1.1875rem/1 var(--f-mono); }
.an-r-pnl .fig.up { color: var(--c-up); }
.an-r-pnl .fig.down { color: var(--c-down); }
.an-r-pnl .fig.none { color: var(--fg-3); }
.an-r-pnl .lbl { display: block; font-size: 0.625rem; letter-spacing: 0.08em; color: var(--fg-3); margin-top: 3px; }

.an-r-watch {
  min-width: 0; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
  font: 0.75rem/1.3 var(--f-mono); letter-spacing: 0.02em;
  color: var(--fg-2);
}
.an-r-watch .dot { color: var(--fg-3); margin: 0 6px; }
.an-r-watch .more { color: var(--fg-3); }

.an-r-flags { justify-self: end; }
/* Expiring pill — amber, matching the app's DTE / "expiring" convention
   (--c-trim), never the analyst identity accent. */
.an-r-exp {
  font: 600 0.65625rem/1 var(--f-mono);
  letter-spacing: 0.04em;
  color: var(--c-trim);
  padding: 3px 7px; border-radius: 5px; white-space: nowrap;
  border: 1px solid color-mix(in oklab, var(--c-trim) 40%, transparent);
  background: color-mix(in oklab, var(--c-trim) 12%, transparent);
}
.an-r-chev { color: var(--fg-3); display: inline-flex; transition: color 130ms ease, transform 130ms ease; }
.an-roster-row:hover .an-r-chev { color: var(--col); transform: translateX(2px); }

.an-roster-foot {
  display: flex; flex-wrap: wrap; gap: 14px;
  padding: 12px 20px;
  font: 0.75rem/1 var(--f-mono); letter-spacing: 0.02em;
  color: var(--fg-2);
}
.an-roster-foot .up { color: var(--c-up); }
.an-roster-foot .down { color: var(--c-down); }

/* Low count: spend the extra height on a bigger masthead figure + the best/worst
   subline (earned by data), never on padding. Desktop-only — gated at min-width
   901px so these high-specificity boosts don't leak past the mobile reflow. */
@media (min-width: 901px) {
  .an-roster.sparse .an-roster-row { min-height: 88px; padding-top: 20px; padding-bottom: 20px; }
  .an-roster.sparse .an-r-rank { font-size: 1.875rem; }
  .an-roster.sparse .an-r-name { font-size: 0.9375rem; }
  .an-roster.sparse .an-r-open strong { font-size: 1.5625rem; }
}

/* Mobile: drop the table columns for the known-good vertical stack — now also
   carrying the meter, avg and best/worst. Pure CSS reflow; the JS never branches.
   Reflows at 900px to match the app's mobile boundary (useIsMobile / sidebar
   drawer / the rail stacking) — so there's no cramped desktop-table band. */
@media (max-width: 900px) {
  .an-roster-head { display: none; }
  .an-roster-row,
  .an-roster.sparse .an-roster-row {
    grid-template-columns: 34px 1fr auto;
    grid-template-areas:
      "rank id    chev"
      ".    book  pnl"
      ".    watch watch";
    column-gap: 12px; row-gap: 10px;
    min-height: 0;
    padding: 16px 16px 16px 18px;
  }
  .an-r-rank { grid-area: rank; justify-self: start; align-self: start; font-size: 0.9375rem; }
  .an-r-id { grid-area: id; }
  .an-r-chev { grid-area: chev; align-self: start; }
  .an-r-book { grid-area: book; flex-direction: row; align-items: center; gap: 12px; }
  .an-r-pnl { grid-area: pnl; }
  .an-r-watch { grid-area: watch; }
  .an-r-flags { display: none; }   /* expiring is already summarised in the footer */
  .bmeter { width: 88px; height: 4px; }
}

/* Drill-in header: back to the analyst grid + whose positions you're viewing. */
.pos-drill-hdr { display: inline-flex; align-items: center; gap: 12px; min-width: 0; }
.pos-back {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: none; cursor: pointer;
  font-size: 0.78125rem; color: var(--fg-2);
  padding: 4px 7px; margin-left: -7px; border-radius: 6px;
  transition: color 120ms ease, background 120ms ease;
}
.pos-back:hover { color: var(--fg-0); background: var(--bg-2); }
.pos-back-arrow { font-size: 0.9375rem; line-height: 1; }
.pos-drill-name {
  font-family: var(--f-mono);
  font-weight: 600;
  letter-spacing: 0.05em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.pos-drill-name::before {
  content: ""; display: inline-block;
  width: 1px; height: 12px;
  background: var(--border-2);
  margin-right: 12px;
  vertical-align: -1px;
}

/* Contextual empty state for the quick-filter segments — so All+Today over a
   quiet weekend reads as "nothing today", never a broken/blank page. */
.pos-empty {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 60px 24px;
  text-align: center;
}
.pos-empty p { margin: 0; color: var(--fg-2); font-size: 0.875rem; max-width: 34ch; }

/* ── Sources tab */
.source-card {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-1);
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  transition: background 120ms;
}
.source-card:hover { background: var(--bg-2); }
.source-card .check {
  width: 18px; height: 18px;
  border-radius: 4px;
  border: 1.5px solid var(--border-3);
  display: grid;
  place-items: center;
  background: var(--bg-2);
  flex-shrink: 0;
}
.source-card .check.on {
  background: var(--accent);
  border-color: var(--accent);
}
.source-card .check.on::after {
  content: ""; width: 9px; height: 6px;
  border-left: 1.5px solid var(--bg-0);
  border-bottom: 1.5px solid var(--bg-0);
  transform: rotate(-45deg) translate(1px, -1px);
}
.source-card .count {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  color: var(--fg-2);
}
.source-card .eye {
  width: 16px; height: 16px;
  color: var(--fg-3);
}
.source-card .eye:hover { color: var(--fg-0); }

.ticker-row {
  padding: 10px 18px;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--border-1);
  cursor: pointer;
  transition: background 120ms;
}
.ticker-row:hover { background: var(--bg-2); }
.ticker-row.active { background: var(--bg-3); }
.ticker-row .name { font-family: var(--f-mono); font-weight: 600; font-size: 0.8125rem; color: var(--accent); }
.ticker-row .meta { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-2); }

/* ── Chart */
.chart-wrap {
  position: relative;
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 18px;
  min-height: 460px;
}
.chart-hdr {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
  gap: 16px;
}
.chart-hdr .ticker-big {
  font-family: var(--f-mono);
  font-weight: 600;
  font-size: 1.375rem;
  color: var(--accent);
}
.chart-hdr .sub {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--fg-2);
  margin-left: 14px;
}
/* Right column of the chart header: timeframe switcher above the source line */
.chart-hdr-right { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; flex-shrink: 0; }
.chart-int .seg-btn { padding: 5px 9px; font-size: 0.6875rem; }

.chart-hdr .source-attr {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.10em;
  color: var(--fg-2);
}

.chart-legend {
  display: flex; flex-wrap: wrap; gap: 7px 14px;
  margin: 2px 0 10px;
}
.chart-legend .leg-item {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-1);
}
.chart-legend .leg-dot {
  width: 10px; height: 10px; border-radius: 2px;
  border: 1.5px solid rgba(0, 0, 0, 0.85);
  box-shadow: 0 0 0 1px var(--border-2);
  flex-shrink: 0;
}
.chart-svg { width: 100%; height: 460px; display: block; }
.chart-tooltip {
  position: absolute;
  z-index: 5;
  background: var(--bg-0);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 12px 14px;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  color: var(--fg-1);
  pointer-events: none;
  max-width: 280px;
  box-shadow: var(--shadow-2);
}
.chart-tooltip .t-hdr {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 6px;
  font-weight: 600;
  color: var(--fg-0);
}
.chart-tooltip .t-note { color: var(--fg-1); white-space: normal; line-height: 1.5; }
.chart-tooltip .t-meta { color: var(--fg-2); margin-top: 6px; }

/* ── Signal flyout */
.flyout-back {
  position: fixed; inset: 0;
  background: rgba(2, 4, 8, 0.55);
  backdrop-filter: blur(2px);
  z-index: 50;
  animation: fadeIn 180ms ease-out;
}
.flyout {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 440px;
  background: var(--bg-1);
  border-left: 1px solid var(--border-2);
  box-shadow: var(--shadow-2);
  z-index: 51;
  display: flex;
  flex-direction: column;
  animation: slideRight 260ms cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideRight { from { transform: translateX(100%); } to { transform: translateX(0); } }
.flyout-hdr {
  padding: 18px 22px;
  border-bottom: 1px solid var(--border-1);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.flyout-body { padding: 18px 22px; overflow-y: auto; flex: 1; }
.flyout-body .field { margin-bottom: 18px; }
.flyout-body .field h5 {
  margin: 0 0 9px;
  font-family: var(--f-mono);
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-2);
  font-weight: 500;
}

/* ── Watchlist (column table, grouped by day) */
/* Day separator row inside the table body */
.tbl tbody tr.day-sep > td {
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-2);
  padding: 8px var(--pad-x);
  position: sticky; top: 0; z-index: 1;
}
.tbl tbody tr.day-sep:hover > td { background: var(--bg-2); }
.day-sep-title {
  font-size: 0.75rem; font-weight: 600; color: var(--fg-0);
  letter-spacing: .01em;
}
.day-sep-meta { font-size: 0.6875rem; color: var(--fg-3); margin-left: 10px; }

/* Category pill (analysis / watchlist) */
.wl-kind {
  display: inline-block;
  font-family: var(--f-mono); font-size: 0.59375rem; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 99px;
  border: 1px solid currentColor;
  background: color-mix(in oklab, currentColor 12%, transparent);
  color: var(--c-watch);
}
.wl-kind.analysis { color: var(--c-open); }

/* Ticker chips inside the cell — wrap within the column */
.wl-tickcell { display: flex; flex-wrap: wrap; gap: 5px; }
.wl-tick {
  font-family: var(--f-mono); font-weight: 600; font-size: 0.71875rem;
  color: var(--accent);
  padding: 1px 7px; border-radius: 99px;
  border: 1px solid var(--accent-dim);
  background: var(--accent-glow);
  white-space: nowrap;
}

/* Expanded raw-note row */
.tbl tbody tr.wl-raw-row > td {
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-2);
  padding: 12px var(--pad-x) 14px;
}
.tbl tbody tr.wl-raw-row:hover > td { background: var(--bg-2); }
.wl-raw-title { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); margin: 12px 0 6px; }
.wl-raw {
  font-size: 0.78125rem; color: var(--fg-1); line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
}

/* ── Recap card */
/* ── Recaps overview: prominent win/loss/avg summary + win-loss chart */
.recap-overview { padding: 18px 20px; margin-bottom: 14px; display: flex; flex-direction: column; gap: 16px; }
.recap-summary { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.recap-hero { display: flex; align-items: baseline; gap: 12px; flex-shrink: 0; }
.recap-winrate { font-family: var(--f-display); font-size: 2.625rem; font-weight: 700; line-height: 1; letter-spacing: -0.01em; }
.recap-hero-lbl { display: flex; flex-direction: column; font-size: 0.75rem; color: var(--fg-1); text-transform: uppercase; letter-spacing: .08em; }
.recap-hero-lbl span { font-family: var(--f-mono); font-size: 0.625rem; color: var(--fg-3); text-transform: none; letter-spacing: .04em; margin-top: 6px; }
.recap-mid { display: flex; flex-direction: column; gap: 12px; flex: 1; min-width: 240px; }
.recap-wlbar { display: flex; height: 9px; border-radius: 99px; overflow: hidden; background: var(--bg-3); }
.recap-wlbar .wl-win { background: var(--c-up); }
.recap-wlbar .wl-loss { background: var(--c-down); }
.recap-statset { display: flex; gap: 26px; flex-wrap: wrap; }
.recap-stat { display: flex; flex-direction: column; gap: 4px; }
.recap-stat .rs-val { font-family: var(--f-mono); font-size: 1.1875rem; font-weight: 600; color: var(--fg-0); }
.recap-stat .rs-val.up { color: var(--c-up); }
.recap-stat .rs-val.down { color: var(--c-down); }
.recap-stat .rs-lbl { font-size: 0.625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-3); }
.recap-chartwrap { border-top: 1px solid var(--border-1); padding-top: 14px; }
.recap-chart-svg { width: 100%; height: 168px; display: block; }
.recap-chart-meta { padding: 8px 2px 0; font-size: 0.71875rem; color: var(--fg-2); min-height: 22px; }
.recap-chart-meta strong { font-weight: 600; }

/* Performance-by-period bars. DOM/flex rather than SVG so every bar can carry a
   real, legible % label — the previous cumulative line pushed all the values onto
   a cramped axis where they couldn't be read. */
.recap-chart-hd { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.rc-title { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); display: flex; flex-direction: column; gap: 5px; }
.rc-title .rc-sub { font-family: var(--f-mono); font-size: 0.65625rem; font-weight: 400; color: var(--fg-3); letter-spacing: .02em; }
.rc-bars { position: relative; display: flex; align-items: stretch; gap: 4px; padding: 0 2px; }
.rc-zero { position: absolute; left: 0; right: 0; height: 1px; background: var(--border-2); pointer-events: none; }
.rc-bar {
  position: relative; flex: 1 1 0; min-width: 0;
  background: none; border: 0; padding: 0; cursor: pointer;
  border-radius: var(--radius);
  transition: background 120ms;
}
.rc-bar:hover, .rc-bar.on { background: color-mix(in oklab, var(--fg-0) 5%, transparent); }
.rc-bar-fill {
  position: absolute; left: 18%; right: 18%;
  border-radius: 2px;
  background: var(--c-up);
  transition: opacity 120ms;
  opacity: .82;
}
.rc-bar.down .rc-bar-fill { background: var(--c-down); }
.rc-bar:hover .rc-bar-fill, .rc-bar.on .rc-bar-fill { opacity: 1; }
.rc-bar.peak .rc-bar-fill { box-shadow: 0 0 0 1px color-mix(in oklab, var(--fg-0) 22%, transparent); }
/* The number IS the point — always visible, never only on hover. */
.rc-bar-val {
  position: absolute; left: 0; right: 0; text-align: center;
  font-family: var(--f-mono); font-size: 0.65625rem; font-weight: 600;
  color: var(--c-up); white-space: nowrap; pointer-events: none;
}
.rc-bar.down .rc-bar-val { color: var(--c-down); }
.rc-bar-x {
  position: absolute; left: 0; right: 0; bottom: 0; text-align: center;
  font-family: var(--f-mono); font-size: 0.59375rem; color: var(--fg-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
}
/* Many bars → drop the per-bar % (they'd collide); hover still reports exactly. */
.rc-bars:has(.rc-bar:nth-child(15)) .rc-bar-val { display: none; }
.rc-bars:has(.rc-bar:nth-child(26)) .rc-bar-x { display: none; }
@media (max-width: 760px) {
  .rc-bars:has(.rc-bar:nth-child(8)) .rc-bar-val { display: none; }
  .rc-bars:has(.rc-bar:nth-child(13)) .rc-bar-x { display: none; }
}
.recap-daypanel { margin-top: 12px; border: 1px solid var(--border-2); border-radius: var(--radius); background: var(--bg-1); }
.recap-daypanel-hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px 0; font-size: 0.65625rem; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-2);
}
.recap-daypanel .recap-period { border: none; margin: 0; }

/* Trims taken — partial exits listed as part of the period's recap. */
.recap-trims { margin-top: 10px; padding-top: 8px; border-top: 1px dashed var(--border-1); }
.recap-trims-hd { display: flex; align-items: center; gap: 8px; font-size: 0.71875rem; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-2); margin-bottom: 8px; }
.recap-trims-hd .rt-note { text-transform: none; letter-spacing: 0; font-size: 0.6875rem; color: var(--fg-3); }
.rl-sq.trim { background: var(--c-trim); }
.recap-trim-line { cursor: default; }

/* ── Period recaps (Daily / Weekly / Monthly / 3M / 6M / 12M buckets) ─────── */
.recap-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.recap-periods { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.recap-period {
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  overflow: hidden;
}
.recap-period-hdr {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 18px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-1);
  flex-wrap: wrap;
}
.rp-label { font-weight: 600; font-size: 0.875rem; color: var(--fg-0); letter-spacing: -0.01em; }
.rp-stats { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; font-size: 0.75rem; color: var(--fg-2); }
.rp-stat b { font-family: var(--f-mono); font-weight: 600; }
.rp-stat b.up { color: var(--c-up); }
.rp-stat b.down { color: var(--c-down); }
.rp-stat.rp-n { color: var(--fg-3); }
.recap-period-body { padding: 6px 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.recap-an-group { padding: 4px 0; }
.recap-an-hd { display: flex; align-items: center; gap: 8px; padding: 12px 8px 6px; }
.recap-an-hd .an-name, .recap-an-hd .analyst-name { font-size: 0.8125rem; letter-spacing: .06em; }
.recap-an-n { font-family: var(--f-mono); font-size: 0.71875rem; color: var(--fg-3); }

/* One closed trade per row. CAPPED WIDTH on purpose: the contract column used to
   be `1fr`, so on a wide monitor it stretched to ~1700px and marooned the prices
   at the far edge — you couldn't tell which numbers belonged to which trade. The
   row now stops at a readable measure and the columns sit next to each other. */
.recap-line {
  display: grid;
  grid-template-columns: 12px minmax(72px, max-content) minmax(0, 1fr) max-content minmax(74px, max-content);
  align-items: center; gap: 18px;
  padding: 9px 10px; border-radius: 8px; cursor: pointer;
  max-width: 940px;
}
.recap-line + .recap-line { border-top: 1px solid var(--border-1); border-radius: 0; }
.recap-line:hover, .recap-line.open { background: var(--bg-2); border-radius: 8px; }
.rl-sq { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.rl-sq.win { background: var(--c-up); }
.rl-sq.loss { background: var(--c-down); }
.rl-tkr { font-family: var(--f-mono); font-weight: 600; color: var(--accent); font-size: 0.90625rem; letter-spacing: -0.01em; }
/* The contract identifies the trade — it was dimmer than the numbers beside it. */
.rl-con { font-size: 0.8125rem; color: var(--fg-1); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rl-mv { font-size: 0.84375rem; color: var(--fg-1); white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; }
.rl-arr { color: var(--fg-3); padding: 0 2px; }
.rl-pct { font-family: var(--f-mono); font-weight: 600; font-size: 0.90625rem; text-align: right; min-width: 74px; font-variant-numeric: tabular-nums; }
.rl-pct.up { color: var(--c-up); }
.rl-pct.down { color: var(--c-down); }
/* ── Recaps: best/worst callouts + analyst leaderboard ───────────────────── */
.recap-highlights { display: flex; flex-wrap: wrap; gap: 14px; }
.recap-bestworst { display: flex; flex-direction: column; gap: 8px; flex: 1 1 260px; min-width: 0; }
.rbw { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--radius); }
.rbw-lbl { font-family: var(--f-mono); font-size: 0.625rem; text-transform: uppercase; letter-spacing: .07em; min-width: 56px; flex-shrink: 0; }
.rbw-lbl.up { color: var(--c-up); }
.rbw-lbl.down { color: var(--c-down); }
.rbw .ticker { font-size: 0.875rem; }
.rbw .rl-pct { margin-left: auto; }
.recap-board { flex: 1 1 300px; min-width: 0; background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--radius); padding: 11px 14px; }
.recap-board-hd { font-family: var(--f-mono); font-size: 0.625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-2); margin-bottom: 9px; }
.recap-board-row { display: grid; grid-template-columns: minmax(0,1fr) auto auto auto; gap: 14px; align-items: center; padding: 7px 0; font-size: 0.75rem; border-top: 1px solid var(--border-1); }
.recap-board-row:first-of-type { border-top: 0; }
.recap-board-row .rb-wr { color: var(--fg-2); }
.recap-board-row .rb-rec .up { color: var(--c-up); }
.recap-board-row .rb-rec .down { color: var(--c-down); }
.recap-board-row .rb-net { font-weight: 600; min-width: 58px; text-align: right; }
.recap-board-row .rb-net.up { color: var(--c-up); }
.recap-board-row .rb-net.down { color: var(--c-down); }
.recap-line-detail { padding: 6px 4px 12px; }
.recap-line-detail .recap { background: var(--bg-2); }

/* Published-recap overlay (shown for servers with show_recap on, Daily view) */
.pub-recap { margin: 4px 10px 8px; border: 1px solid var(--border-2); border-radius: 10px; background: var(--bg-2); overflow: hidden; }
.pub-recap-hdr { display: flex; align-items: center; gap: 10px; padding: 9px 12px; cursor: pointer; flex-wrap: wrap; }
.pub-tag { display: inline-flex; align-items: center; gap: 6px; font-size: 0.6875rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--c-up); }
.pub-stats { font-size: 0.75rem; color: var(--fg-2); }
.pub-badge { font-size: 0.6875rem; font-weight: 600; padding: 2px 8px; border-radius: 999px; margin-left: auto; }
.pub-badge.ok { color: var(--c-up); background: color-mix(in srgb, var(--c-up) 14%, transparent); }
.pub-badge.warn { color: var(--c-watch); background: color-mix(in srgb, var(--c-watch) 16%, transparent); }
.pub-caret { color: var(--fg-3); font-size: 0.6875rem; }
.pub-recap-body { padding: 4px 12px 12px; border-top: 1px solid var(--border-1); display: flex; flex-direction: column; gap: 3px; }
.pub-line { display: flex; align-items: center; gap: 9px; padding: 5px 2px; font-size: 0.75rem; flex-wrap: wrap; }
.pub-an { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-2); min-width: 60px; }
.pub-flag { font-size: 0.625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--c-watch); background: color-mix(in srgb, var(--c-watch) 15%, transparent); padding: 1px 6px; border-radius: 5px; }
.pub-fix { font-size: 0.625rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--c-up); background: color-mix(in srgb, var(--c-up) 14%, transparent); padding: 1px 6px; border-radius: 5px; }
.pub-pod { margin-top: 6px; font-size: 0.75rem; color: var(--fg-1); }

/* Owner-only reconciliation flags */
.recap-flags { margin-bottom: 14px; padding: 0; overflow: hidden; }
.recap-flags-hdr { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; cursor: pointer; font-size: 0.8125rem; color: var(--fg-1); }
.recap-flags-hdr b { color: var(--c-watch); }
.recap-flags-body { border-top: 1px solid var(--border-1); display: flex; flex-direction: column; }
.recap-flag { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 16px; border-bottom: 1px solid var(--border-1); flex-wrap: wrap; }
.recap-flag:last-child { border-bottom: 0; }
.rf-main { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rf-kind { font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--c-watch); }
.rf-tkr { font-family: var(--f-mono); font-size: 0.8125rem; color: var(--fg-0); }
.rf-detail { font-size: 0.6875rem; color: var(--fg-3); }
.rf-actions { display: flex; gap: 8px; }
.rf-actions .btn { padding: 6px 12px; font-size: 0.75rem; }

.recap-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-top: 16px;
}
.recap {
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.recap .top { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.recap .ticker-big {
  font-family: var(--f-mono);
  font-weight: 600;
  font-size: 1.375rem;
  color: var(--accent);
  letter-spacing: -0.01em;
}
.recap .contract { font-size: 0.75rem; color: var(--fg-2); margin-top: 2px; }
.recap .pnl {
  font-family: var(--f-mono);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.recap .pnl.win { color: var(--c-up); }
.recap .pnl.loss { color: var(--c-down); }
.recap .pnl-sub { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-2); }
.recap .timeline {
  display: grid;
  grid-template-columns: repeat(var(--steps, 3), 1fr);
  gap: 1px;
  background: var(--border-1);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.recap .timeline .step {
  background: var(--bg-2);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
}
.recap .timeline .step .when { color: var(--fg-2); font-size: 0.625rem; }
.recap .footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  color: var(--fg-2);
  padding-top: 6px;
  border-top: 1px solid var(--border-1);
}

/* ── Forms (add channel / analyst) */
.form-card {
  background: var(--bg-2);
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 18px;
}
.form-card-hdr {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 14px;
}
.form-card-hdr h3 { margin: 0; font-size: 0.875rem; font-weight: 600; }
.form-card-hdr .server-tag { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-3); }
.form-grid { display: grid; gap: 12px; }
.field { display: flex; flex-direction: column; min-width: 0; }
.field-label {
  font-size: 0.6875rem; color: var(--fg-2); font-weight: 500;
  margin-bottom: 6px; letter-spacing: 0.01em;
}
.field-hint { font-size: 0.71875rem; color: var(--fg-3); }
/* Live "id → Discord name" resolver shown under an id input in the add forms. */
.id-resolve { font-size: 0.6875rem; margin-top: 5px; min-height: 14px; display: flex; align-items: center; gap: 4px; }
.id-resolve-wait { color: var(--fg-3); }
.id-resolve-ok { color: var(--c-open); display: inline-flex; align-items: center; gap: 4px; }
.id-resolve-err { color: var(--c-trim); }
/* Analyst linked-accounts (bot/alt merged into one analyst) */
.linked-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; min-height: 20px; align-items: center; }
.linked-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 0.71875rem; padding: 3px 6px 3px 10px; border-radius: 99px; background: var(--bg-2); border: 1px solid var(--border-2); color: var(--fg-1); }
.linked-chip-x { display: grid; place-items: center; width: 16px; height: 16px; border-radius: 99px; border: none; background: transparent; color: var(--fg-3); cursor: pointer; }
.linked-chip-x:hover { color: var(--c-down); background: color-mix(in oklab, var(--c-down) 12%, transparent); }
.linked-add { display: flex; gap: 8px; align-items: center; }
.linked-add .input { flex: 1; min-width: 0; }
.form-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-top: 16px; flex-wrap: wrap;
}
.form-err {
  margin-top: 12px; padding: 8px 11px;
  background: color-mix(in oklab, var(--c-down) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--c-down) 35%, transparent);
  border-radius: var(--radius-sm);
  font-family: var(--f-mono); font-size: 0.71875rem; color: var(--c-down);
  display: flex; align-items: center; gap: 6px;
}
.form-scope {
  display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
  margin-top: 14px; font-size: 0.78125rem; color: var(--fg-1);
}
.form-scope { align-items: flex-start; }
.form-scope label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.form-scope .scope-title { font-size: 0.6875rem; color: var(--fg-2); font-weight: 500; padding-top: 8px; }

/* Server scope as selectable chips (nicer than raw checkboxes) */
.scope-chips { display: flex; flex-wrap: wrap; gap: 8px; }

/* ── Evidence ledger (Positions): provenance + urgency cues (LEDGER_UI) ──
   Every price on this page is a mark an analyst stated in Discord, so age and
   staleness are shown rather than implied. Stale = amber, never red. */
.mark-age { margin-left: 6px; font-size: 0.65625rem; color: var(--fg-3); letter-spacing: .02em; }
.mark-age.aging { color: var(--fg-2); }
.mark-age.stale { color: var(--c-trim); }
.mark-age.none  { color: var(--fg-3); font-style: italic; }
.upd-stale { color: var(--c-trim) !important; }

/* Days-to-expiry — computed from the contract spec (no market feed). */
.dte-chip {
  margin-left: 6px; padding: 1px 5px; border-radius: 3px;
  font-family: var(--f-mono); font-size: 0.59375rem; letter-spacing: .04em;
  color: var(--fg-2); background: var(--bg-3); border: 1px solid var(--border-1);
  white-space: nowrap; vertical-align: middle;
}
.dte-chip.soon    { color: var(--c-trim); border-color: color-mix(in oklab, var(--c-trim) 45%, transparent); background: color-mix(in oklab, var(--c-trim) 10%, transparent); }
.dte-chip.today   { color: var(--c-down); border-color: color-mix(in oklab, var(--c-down) 50%, transparent); background: color-mix(in oklab, var(--c-down) 12%, transparent); }
.dte-chip.expired { color: var(--fg-3); text-decoration: line-through; }

/* Analyst colour edge — categorical reinforcement; the chip stays the signal. */
.pos-row-led > td:first-child { box-shadow: inset 2px 0 0 var(--an-col, var(--accent)); }
/* Expansion scent: hints there's a timeline inside without opening the row. */
.pos-scent { margin-left: 7px; font-family: var(--f-mono); font-size: 0.625rem; color: var(--fg-3); }
.pd-provenance { margin: 2px 0 10px; font-size: 0.71875rem; color: var(--fg-3); font-style: italic; }
.statgrid .val.val-warn { color: var(--c-trim); }
/* Numerals line up column-to-column even at different digit counts. */
.tbl td.num, .tbl td.mono, .pnl-sub, .pnl-big, .mpos-pct, .mpos-flow { font-variant-numeric: tabular-nums; }

/* Roles & capabilities matrix (Guide → Access & roles) */
.guide-matrix { overflow-x: auto; margin-top: 10px; border: 1px solid var(--border-1); border-radius: var(--radius); }
.guide-matrix table { border-collapse: collapse; width: 100%; min-width: 640px; font-size: 0.75rem; }
.guide-matrix th, .guide-matrix td { padding: 7px 10px; border-bottom: 1px solid var(--border-1); text-align: center; white-space: nowrap; }
.guide-matrix th:first-child, .guide-matrix td:first-child { text-align: left; white-space: normal; min-width: 220px; color: var(--fg-1); }
.guide-matrix thead th { font-family: var(--f-mono); font-size: 0.625rem; letter-spacing: .07em; text-transform: uppercase; color: var(--fg-2); background: var(--bg-2); }
.guide-matrix tr:last-child td { border-bottom: none; }
.guide-matrix td.mx { font-family: var(--f-mono); }
.guide-matrix td.mx-yes { color: var(--c-up); }
.guide-matrix td.mx-no { color: var(--fg-3); }
.mx-own, .mx-tog { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-1); }

/* Per-server role assignment (Access editor): one row per server, its role
   select appearing when the server is toggled on. */
.scope-role-list { display: flex; flex-direction: column; gap: 8px; }
.scope-role-row { display: flex; align-items: center; gap: 10px; }
.scope-role-row .scope-chip { min-width: 180px; justify-content: flex-start; }
.scope-role-row .select { width: auto; min-width: 150px; padding-top: 6px; padding-bottom: 6px; }
@media (max-width: 760px) {
  .scope-role-row { flex-wrap: wrap; }
  .scope-role-row .scope-chip { min-width: 0; flex: 1 1 100%; }
}
.scope-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 13px 6px 8px; border-radius: 99px;
  border: 1px solid var(--border-2); background: var(--bg-2);
  color: var(--fg-1); font-size: 0.78125rem; line-height: 1; cursor: pointer;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.scope-chip:hover { border-color: var(--border-3); color: var(--fg-0); }
.scope-chip.on { background: var(--accent-glow); border-color: var(--accent-dim); color: var(--accent); }
.scope-chip-box {
  width: 16px; height: 16px; border-radius: 5px; flex-shrink: 0;
  display: grid; place-items: center;
  border: 1.5px solid var(--border-3); color: var(--bg-0); background: transparent;
}
.scope-chip.on .scope-chip-box { background: var(--accent); border-color: var(--accent); }

/* Analyst editor toggles — name + description with a switch on the right */
.toggle-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 14px; }
.toggle-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 13px; border: 1px solid var(--border-1); border-radius: var(--radius);
  background: var(--bg-2); cursor: pointer; transition: border-color 120ms;
}
.toggle-card:hover { border-color: var(--border-3); }
.toggle-card .switch { flex-shrink: 0; }
.toggle-meta { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.toggle-name { font-size: 0.8125rem; font-weight: 500; color: var(--fg-0); }
.toggle-desc { font-size: 0.6875rem; color: var(--fg-3); line-height: 1.3; }

/* Access toolbar: role filter on the left, Add-user on the right.
   When the add form opens it breaks to its own full-width line below. */
.access-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; margin-bottom: 16px; padding-right: 8px; }
.access-toolbar .seg-filter { margin: 0; }
.access-toolbar .form-card { flex-basis: 100%; margin-right: -8px; }

/* Right-aligned "Add X" bar (servers, channels, analysts, roles). The add form
   breaks to its own full-width line below when opened. */
.add-bar { display: flex; justify-content: flex-end; flex-wrap: wrap; margin-bottom: 16px; padding-right: 8px; }
.add-bar .form-card { flex-basis: 100%; margin-right: -8px; }

/* Size the primary "Add" buttons to cap the row's action column, centered. */
.add-bar > .btn.primary,
.access-toolbar > .btn.primary { min-width: 118px; justify-content: center; }

/* Segmented role filter (Access) */
.seg-filter {
  display: inline-flex; gap: 3px; margin: 2px 0 16px;
  background: var(--bg-2); border: 1px solid var(--border-1);
  border-radius: var(--radius); padding: 3px;
}
.seg-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 13px; border-radius: 5px;
  font-family: var(--f-mono); font-size: 0.71875rem; letter-spacing: 0.04em;
  text-transform: capitalize; color: var(--fg-2);
}
.seg-btn:hover { color: var(--fg-0); }
.seg-btn.on { background: var(--bg-0); color: var(--accent); box-shadow: var(--shadow-1); }
.seg-count {
  font-size: 0.625rem; min-width: 16px; text-align: center;
  padding: 1px 5px; border-radius: 99px;
  background: var(--bg-3); color: var(--fg-3);
}
.seg-btn.on .seg-count { background: var(--accent-glow); color: var(--accent); }

/* Bounded, scrollable list region — Access users + role grants each ~half */
.access-list { max-height: 38vh; overflow-y: auto; }

/* Toggle switch — the ONE on/off control across the app: off reads red, on reads
   green, so state is unmistakable at a glance (the muted red is a tint, not an
   alarm). `.rg` is kept as a no-op alias for existing markup. */
.switch { display: inline-flex; align-items: center; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  position: relative; width: 38px; height: 21px; border-radius: 99px;
  background: color-mix(in oklab, var(--c-down) 24%, var(--bg-3));
  border: 1px solid color-mix(in oklab, var(--c-down) 42%, var(--border-2));
  transition: background 140ms, border-color 140ms;
}
.switch-thumb {
  position: absolute; top: 2px; left: 2px; width: 15px; height: 15px;
  border-radius: 50%; background: color-mix(in oklab, var(--c-down) 66%, #fff);
  transition: transform 140ms, background 140ms;
}
.switch input:checked + .switch-track { background: var(--c-up); border-color: var(--c-up); }
.switch input:checked + .switch-track .switch-thumb { transform: translateX(17px); background: #fff; }
.switch input:focus-visible + .switch-track { box-shadow: 0 0 0 2px color-mix(in oklab, var(--c-up) 30%, transparent); }
/* Label sat beside the switch (the "enabled / disabled" style rows). */
.switch.toggle-row { gap: 10px; align-items: center; }
.switch .toggle-txt { font-size: 0.8125rem; color: var(--fg-1); }
.switch input:not(:checked) ~ .toggle-txt { color: var(--fg-2); }

/* ── Audit log */
.audit-row {
  display: grid;
  grid-template-columns: 150px 140px auto minmax(0, 1fr);
  align-items: center; gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-1);
  font-size: 0.78125rem;
}
.audit-row:hover { background: var(--bg-2); }
.audit-row:last-child { border-bottom: 0; }
.audit-row .audit-time { color: var(--fg-3); font-size: 0.6875rem; white-space: nowrap; }
.audit-row .audit-actor { color: var(--fg-1); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.audit-row .audit-target { color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Settings */
.settings-tabs {
  display: flex;
  gap: 2px;
  padding: 0 10px;
  border-bottom: 1px solid var(--border-1);
}
.settings-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 16px;
  color: var(--fg-2);
  font-size: 0.84375rem;
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 120ms;
}
.settings-tab:hover { color: var(--fg-0); }
.settings-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.settings-content { padding: 24px 28px; }
.settings-content h2 { font-size: 1.125rem; margin: 0 0 7px; }
.settings-content p.sub { color: var(--fg-2); margin: 0 0 18px; font-size: 0.8125rem; }

.channel-row {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 10px 8px 10px 14px;
  border-bottom: 1px solid var(--border-1);
}
.row-actions { display: flex; align-items: center; gap: 2px; }
.row-editor {
  padding: 16px 18px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border-1);
  border-top: 1px dashed var(--border-2);
}
.row-editor:last-child { border-bottom: 0; }
.toggle-line {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.8125rem; color: var(--fg-1); cursor: pointer;
  min-height: 38px;
}
.channel-row:hover { background: var(--bg-2); }
.channel-row:last-child { border-bottom: 0; }
.channel-row .hash { color: var(--fg-3); font-family: var(--f-mono); font-size: 0.9375rem; }
.channel-row .name { font-family: var(--f-sans); font-size: 0.8125rem; font-weight: 500; color: var(--fg-0); }
.channel-row .id { font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-3); margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Category pills — used in the channel row AND the add-channel form, so these
   base styles are NOT scoped to .channel-row (the row-specific responsive
   overrides below still are). */
.cat-select {
  display: flex; gap: 0;
  border: 1px solid var(--border-1);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.cat-select button {
  padding: 5px 11px;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  color: var(--fg-2);
  background: var(--bg-1);
  letter-spacing: 0.04em;
  transition: all 120ms;
}
.cat-select button:not(:last-child) { border-right: 1px solid var(--border-1); }
.cat-select button:hover { color: var(--fg-0); background: var(--bg-2); }
.cat-select button.on {
  background: var(--accent-glow);
  color: var(--accent);
}
/* Multi-author picker (channel add form + row editor) */
.owner-multi { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.owner-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.owner-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--f-mono); font-size: 0.6875rem;
  color: var(--fg-1); background: var(--bg-2);
  border: 1px solid var(--border-1); border-radius: var(--radius-sm);
  padding: 2px 3px 2px 8px;
}
.owner-chip button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 4px;
  color: var(--fg-3); font-size: 0.875rem; line-height: 1;
}
.owner-chip button:hover { color: var(--c-down); background: var(--bg-3); }
.channel-row .live-dot {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--f-mono); font-size: 0.6875rem;
}
.channel-row .live-dot .d { width: 6px; height: 6px; border-radius: 99px; background: currentColor; }

/* Category group header in the channels screen */
.cat-group { margin-bottom: 8px; }
.cat-group:last-child { margin-bottom: 0; }
.cat-group-hdr {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 4px;
  margin-top: 18px;
}
.cat-group-hdr .cat-name {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.8125rem; font-weight: 600; color: var(--fg-0);
}
.cat-group-hdr .cat-count {
  font-family: var(--f-mono); font-size: 0.6875rem; color: var(--fg-3);
}
.cat-group-hdr .cat-desc { font-size: 0.75rem; color: var(--fg-2); max-width: 380px; text-align: right; }
.cat-group .rows {
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-1);
}

/* ── Whitelist */
.user-row {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  padding: 12px 8px 12px 16px;
  border-bottom: 1px solid var(--border-1);
}
.user-row:hover { background: var(--bg-2); }
.user-row:last-child { border-bottom: 0; }
.user-row .avatar {
  width: 30px; height: 30px;
  border-radius: 99px;
  background: var(--bg-3);
  display: grid; place-items: center;
  font-family: var(--f-mono);
  font-size: 0.8125rem;
  font-weight: 600;
}
.user-row .uname { font-family: var(--f-sans); font-size: 0.8125rem; font-weight: 500; color: var(--fg-0); }
.user-row .priority {
  font-family: var(--f-mono); font-size: 0.6875rem;
  padding: 3px 8px;
  border-radius: 99px;
  border: 1px solid var(--border-2);
  color: var(--fg-1);
}
.user-row .priority.high { color: var(--accent); border-color: var(--accent-dim); background: var(--accent-glow); }
.user-row .priority.muted { color: var(--fg-3); }
.tier-legend { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }

/* Server group header in the analyst list — disambiguates the same analyst
   registered across multiple servers. */
.setting-grp { display: flex; align-items: center; gap: 8px; padding: 13px 16px 9px; border-bottom: 1px solid var(--border-1); }
.setting-grp svg { color: var(--fg-3); flex-shrink: 0; }
.setting-grp-name { font-size: 0.78125rem; font-weight: 600; color: var(--fg-0); }
.setting-grp-n { margin-left: auto; font-size: 0.6875rem; color: var(--fg-3); }

/* ── Misc */
.empty {
  padding: 60px 20px;
  text-align: center;
  color: var(--fg-2);
  font-size: 0.8125rem;
}
.scroll-y { overflow-y: auto; }
.flex { display: flex; }
.gap-6 { gap: 6px; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }

/* ── Focus ring */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── Toasts */
.toast-host {
  position: fixed;
  bottom: 20px; right: 20px;
  z-index: 300;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: 10px;
  min-width: 230px; max-width: 380px;
  padding: 11px 14px;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  font-size: 0.8125rem; color: var(--fg-0);
  cursor: pointer;
  animation: toastIn 220ms cubic-bezier(.22, 1, .36, 1);
}
.toast .toast-icon { display: grid; place-items: center; color: var(--accent); flex-shrink: 0; }
.toast .toast-msg { line-height: 1.4; }
.toast.success { border-left-color: var(--c-up); }
.toast.success .toast-icon { color: var(--c-up); }
.toast.error { border-left-color: var(--c-down); }
.toast.error .toast-icon { color: var(--c-down); }
@keyframes toastIn { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }

/* ── Confirmation modal */
.modal-back {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(2, 4, 8, 0.55);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: grid; place-items: center; padding: 24px;
  animation: fadeIn 150ms ease-out;
}
.modal {
  width: 100%; max-width: 420px;
  background: var(--bg-1);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  animation: modalIn 180ms cubic-bezier(.22, 1, .36, 1);
}
.modal-icon {
  width: 40px; height: 40px; border-radius: 10px;
  margin: 20px 20px 0;
  display: grid; place-items: center;
  background: var(--accent-glow); color: var(--accent);
}
.modal-icon.danger { background: color-mix(in oklab, var(--c-down) 14%, transparent); color: var(--c-down); }
.modal-title { padding: 14px 20px 0; font-size: 1rem; font-weight: 600; color: var(--fg-0); }
.modal-body { padding: 8px 20px 20px; color: var(--fg-1); font-size: 0.84375rem; line-height: 1.55; white-space: pre-line; }
.modal-actions {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 14px 20px; border-top: 1px solid var(--border-1);
  background: var(--bg-2);
}
@keyframes modalIn { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }

/* User-access editor modal — reuses the calc modal frame, a touch wider for the
   two-column form + per-server role controls. */
.user-modal { max-width: 560px; width: 100%; max-height: calc(100vh - 48px); display: flex; flex-direction: column; }

/* ── Position cost calculator */
.calc-modal { max-width: 480px; width: 100%; max-height: calc(100vh - 48px); display: flex; flex-direction: column; }
.calc-hdr { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 18px 20px 14px; border-bottom: 1px solid var(--border-1); flex-shrink: 0; }
.calc-title { font-size: 1rem; font-weight: 600; color: var(--fg-0); display: flex; align-items: center; gap: 8px; }
.calc-contract { font-size: 0.75rem; color: var(--fg-2); }
.calc-sub { font-size: 0.65625rem; color: var(--fg-3); margin-top: 6px; letter-spacing: 0.06em; text-transform: uppercase; }
.calc-body { padding: 16px 20px 20px; display: flex; flex-direction: column; gap: 14px; overflow-y: auto; }
.calc-field { display: flex; flex-direction: column; gap: 6px; }
.calc-field > span { font-size: 0.6875rem; color: var(--fg-2); letter-spacing: 0.04em; }
.calc-input { display: flex; align-items: center; gap: 6px; background: var(--bg-2); border: 1px solid var(--border-2); border-radius: var(--radius); padding: 0 10px; }
.calc-input:focus-within { border-color: var(--accent-dim); }
.calc-input input { flex: 1; min-width: 0; background: transparent; border: 0; outline: none; color: var(--fg-0); font-family: var(--f-mono); font-size: 0.9375rem; padding: 9px 0; }
.calc-pre, .calc-suf { color: var(--fg-3); font-family: var(--f-mono); font-size: 0.8125rem; }
/* "Posted at" — two on-brand fields (date + ET time) replacing the native
   datetime-local picker, which ignored every design token. */
.postedat { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.postedat .postedat-date { flex: 1 1 120px; min-width: 108px; }
.postedat .postedat-time { flex: 1 1 100px; min-width: 92px; }
.postedat .postedat-date input, .postedat .postedat-time input { font-size: 0.875rem; }
.postedat .btn { flex: 0 0 auto; }
.calc-note { font-size: 0.75rem; color: var(--fg-1); margin-top: -4px; }
.calc-note strong { color: var(--fg-0); }
/* $ vs % input-mode toggle (manual update modal) */
.calc-field-hdr { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; }
.mode-toggle { display: inline-flex; border: 1px solid var(--border-2); border-radius: var(--radius-sm); overflow: hidden; flex-shrink: 0; }
.mode-toggle button { font-family: var(--f-mono); font-size: 0.6875rem; line-height: 1; padding: 3px 9px; color: var(--fg-2); background: var(--bg-1); white-space: nowrap; transition: all 120ms; }
.mode-toggle button:not(:last-child) { border-right: 1px solid var(--border-2); }
.mode-toggle button.on { background: var(--accent-glow); color: var(--accent); }

/* ── Recap-publish preview (Settings → Servers) — a Discord-embed-style card */
.recap-preview { margin-top: 10px; background: var(--bg-1); border: 1px solid var(--border-1); border-left: 3px solid var(--accent); border-radius: var(--radius); padding: 12px 14px; font-size: 0.8125rem; }
.rcp-hd { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.rcp-logo { width: 22px; height: 22px; border-radius: 5px; object-fit: cover; flex-shrink: 0; }
.rcp-title { font-family: var(--f-display); font-weight: 700; letter-spacing: .02em; }
.rcp-stats { color: var(--fg-1); }
.rcp-play { margin-top: 3px; color: var(--fg-1); }
.rcp-block { margin-top: 9px; }
.rcp-sec { font-family: var(--f-mono); font-size: 0.65625rem; letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 3px; }
.rcp-an { font-weight: 600; color: var(--fg-0); margin-top: 4px; }
.rcp-row { display: flex; align-items: center; gap: 7px; padding: 1px 0 1px 8px; }
.rcp-sq { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.rcp-sq.up { background: var(--c-up); } .rcp-sq.down { background: var(--c-down); } .rcp-sq.trim { background: var(--c-trim); }
.rcp-mv { font-size: 0.75rem; color: var(--fg-1); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rcp-pct { font-family: var(--f-mono); font-weight: 700; margin-left: auto; flex-shrink: 0; }
.rcp-pct.up { color: var(--c-up); } .rcp-pct.down { color: var(--c-down); }
.rcp-link { margin-top: 9px; color: var(--accent); font-weight: 600; word-break: break-word; }
.rcp-note { margin-top: 9px; color: var(--fg-2); white-space: pre-wrap; font-size: 0.75rem; line-height: 1.5; }
.rcp-footer { display: flex; align-items: center; gap: 6px; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border-1); color: var(--fg-3); font-size: 0.65625rem; }
.rcp-flogo { width: 15px; height: 15px; border-radius: 4px; }
.rcp-empty { color: var(--fg-2); font-style: italic; }
.calc-warn { font-size: 0.75rem; color: var(--c-trim); }
.calc-split { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.calc-card { min-width: 0; background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--radius); padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.calc-card .calc-input { background: var(--bg-0); }
.calc-card-hdr { font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-2); font-family: var(--f-mono); }
.calc-out { display: flex; flex-direction: column; gap: 2px; min-height: 42px; }
.calc-out > span { font-size: 0.71875rem; color: var(--fg-2); }
.calc-out strong { font-size: 1.125rem; color: var(--accent); font-family: var(--f-mono); }
.calc-left { font-size: 0.65625rem; color: var(--fg-3); }
@media (max-width: 480px) { .calc-split { grid-template-columns: 1fr; } }

/* ── Manage position (admin manual update) */
.manage-modal { max-width: 480px; width: 100%; max-height: calc(100vh - 48px); display: flex; flex-direction: column; }
.manage-body { padding: 16px 20px 18px; display: flex; flex-direction: column; gap: 14px; overflow-y: auto; }
.manage-ctx { display: flex; gap: 16px; flex-wrap: wrap; font-family: var(--f-mono); font-size: 0.71875rem; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--radius); padding: 9px 12px; }
.manage-ctx strong { color: var(--fg-0); margin-left: 4px; }
.manage-actions.seg { display: flex; flex-wrap: wrap; }
.manage-actions.seg .seg-btn { flex: 1 1 0; min-width: 56px; display: flex; align-items: center; justify-content: center; text-align: center; }
.manage-hint { font-size: 0.75rem; color: var(--fg-2); margin-top: -6px; }
/* Numeric fields: at most two per row, with labels that reserve a consistent
   height so the inputs always line up (no ragged "up and down" boxes). */
.manage-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px 14px; align-items: end; }
.manage-fields .calc-field > span { min-height: 28px; display: flex; align-items: flex-end; line-height: 1.25; }
.manage-fields .calc-field .calc-input,
.manage-fields .calc-field .select { height: 38px; }
.manage-twoseg { display: flex; gap: 10px; flex-wrap: wrap; }
.manage-twoseg .seg { flex: 1 1 0; min-width: 130px; display: flex; }
.manage-twoseg .seg .seg-btn { flex: 1 1 0; justify-content: center; text-align: center; }
.manage-note { width: 100%; resize: vertical; background: var(--bg-2); border: 1px solid var(--border-2); border-radius: var(--radius); padding: 9px 10px; color: var(--fg-0); font-family: inherit; font-size: 0.8125rem; line-height: 1.5; outline: none; }
.manage-note:focus { border-color: var(--accent-dim); }
.manage-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
.manage-foot .btn { min-width: 96px; justify-content: center; }
.manage-disclaimer { font-size: 0.65625rem; color: var(--fg-3); line-height: 1.5; }
.manual-tag { display: inline-block; margin-left: 6px; padding: 0 5px; border-radius: 4px; font-family: var(--f-mono); font-size: 0.59375rem; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border-2); vertical-align: middle; }

/* Per-admin "can manage positions" toggle (in the user editor) + row chip */
.perm-list { display: flex; flex-direction: column; gap: 0; margin-top: 14px; }
.perm-list .perm-row { margin-top: 8px; }
.perm-row { display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 12px 14px; background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--radius); }
.perm-txt { flex: 1; min-width: 0; }
.perm-title { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); }
.perm-sub { font-size: 0.71875rem; color: var(--fg-2); margin-top: 4px; }
.perm-chip { margin-left: 8px; padding: 0 6px; border-radius: 4px; font-family: var(--f-mono); font-size: 0.59375rem; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); background: var(--accent-glow); border: 1px solid var(--accent-dim); vertical-align: middle; }

/* ── Login gate */
.login-gate { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.login-card {
  width: 100%; max-width: 380px;
  background: var(--bg-1);
  border: 1px solid var(--border-1);
  border-radius: var(--radius-lg);
  padding: 36px 32px;
  text-align: center;
  box-shadow: var(--shadow-2);
}
.login-card .brand { display: inline-flex; align-items: center; gap: 11px; margin-bottom: 18px; }
.login-card .brand .mark {
  width: 34px; height: 34px; border-radius: 9px;
  background: var(--accent); color: var(--bg-0);
  display: grid; place-items: center;
  font-family: var(--f-display); font-weight: 700; font-size: 1.125rem;
}
.login-card .brand .brand-name {
  font-family: var(--f-display); font-size: 1.0625rem; font-weight: 600;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--fg-0);
}
.login-card p { color: var(--fg-2); font-size: 0.84375rem; margin: 0 0 24px; }
.discord-btn {
  width: 100%; justify-content: center; text-decoration: none;
  background: #5865F2; border-color: #5865F2; color: #fff;
  padding: 12px 16px; font-size: 0.875rem; font-weight: 500;
}
.discord-btn:hover { background: #4752c4; border-color: #4752c4; }

/* ── Access denied wall */
.denied-card .brand { margin-bottom: 22px; }
.denied-badge {
  width: 52px; height: 52px; margin: 0 auto 16px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--c-down);
  background: color-mix(in srgb, var(--c-down) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--c-down) 35%, transparent);
}
.denied-title {
  font-family: var(--f-display); font-size: 1.1875rem; font-weight: 600;
  color: var(--fg-0); margin: 0 0 10px; letter-spacing: 0.01em;
}
.denied-reason { color: var(--fg-1); font-size: 0.84375rem; line-height: 1.55; margin: 0 0 12px; }
.denied-sub { color: var(--fg-3); font-size: 0.75rem; line-height: 1.5; margin: 0 0 24px; }
.denied-card .discord-btn { background: transparent; border-color: var(--border-2); color: var(--fg-1); }
.denied-card .discord-btn:hover { background: var(--bg-2); border-color: var(--border-1); color: var(--fg-0); }

/* ── Sidebar user chip */
.user-chip {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 8px;
  border: 1px solid var(--border-1);
  border-radius: var(--radius);
  background: var(--bg-2);
}
.user-chip .user-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.user-chip .user-name {
  font-size: 0.78125rem; font-weight: 500; color: var(--fg-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-chip .user-role {
  font-family: var(--f-mono); font-size: 0.59375rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent);
}

/* Charts: the two mini-tables sit side by side on desktop. */
.charts-subgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; min-height: 0; }

/* ── Guide (in-app tutorial) — TOC rail + content filling the full width */
.guide {
  display: grid; grid-template-columns: 230px minmax(0, 1fr); gap: 26px; align-items: start;
  width: 100%;
}
.guide-toc {
  position: sticky; top: 0;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--bg-1); border: 1px solid var(--border-1); border-radius: var(--radius-lg);
  padding: 12px 10px;
}
.guide-toc-hdr { font-size: 0.625rem; text-transform: uppercase; letter-spacing: .12em; color: var(--fg-3); padding: 2px 8px 8px; }
.guide-toc-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 6px 8px; border-radius: var(--radius-sm);
  font-size: 0.78125rem; color: var(--fg-2); text-align: left;
}
.guide-toc-item:hover { background: var(--bg-2); color: var(--fg-0); }
.guide-toc-foot { font-size: 0.625rem; color: var(--fg-3); padding: 10px 8px 2px; border-top: 1px solid var(--border-1); margin-top: 8px; }
.guide-toc-foot strong { color: var(--accent); text-transform: uppercase; }
.guide-body { min-width: 0; display: flex; flex-direction: column; gap: 26px; padding-bottom: 30px; }
.guide-sec { background: var(--bg-1); border: 1px solid var(--border-1); border-radius: var(--radius-lg); padding: 20px 22px; }
.guide-sec-title { margin: 0 0 12px; font-size: 1rem; font-weight: 600; color: var(--fg-0); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.guide-sec p { margin: 0 0 12px; font-size: 0.84375rem; line-height: 1.65; color: var(--fg-1); }
.guide-sec p:last-child { margin-bottom: 0; }
.guide-note { font-size: 0.78125rem; color: var(--fg-2); border-left: 2px solid var(--accent-dim); padding-left: 12px; }
.guide-list { margin: 0 0 12px; padding-left: 18px; display: flex; flex-direction: column; gap: 7px; font-size: 0.84375rem; line-height: 1.6; color: var(--fg-1); }
.guide-list:last-child { margin-bottom: 0; }
.guide-list strong { color: var(--fg-0); }
.guide-role {
  font-family: var(--f-mono); font-size: 0.59375rem; letter-spacing: .08em; text-transform: uppercase;
  padding: 1px 7px; border-radius: 99px; border: 1px solid var(--border-2); color: var(--fg-2); background: var(--bg-2);
}
.guide-role.r-analyst { color: var(--c-open); border-color: color-mix(in oklab, var(--c-open) 35%, transparent); background: color-mix(in oklab, var(--c-open) 9%, transparent); }
.guide-role.r-editor { color: var(--c-watch); border-color: color-mix(in oklab, var(--c-watch) 35%, transparent); background: color-mix(in oklab, var(--c-watch) 9%, transparent); }
.guide-role.r-admin { color: var(--accent); border-color: var(--accent-dim); background: var(--accent-glow); }
.guide-role.r-server_owner { color: var(--a-1); border-color: color-mix(in oklab, var(--a-1) 35%, transparent); background: color-mix(in oklab, var(--a-1) 9%, transparent); }
.guide-role.r-owner { color: var(--c-close); border-color: color-mix(in oklab, var(--c-close) 35%, transparent); background: color-mix(in oklab, var(--c-close) 9%, transparent); }
/* "Snapshot" frame around live mock components */
.guide-shot { margin: 14px 0; border: 1px solid var(--border-2); border-radius: var(--radius); overflow: hidden; background: var(--bg-0); }
.guide-shot-bar { display: flex; gap: 5px; padding: 8px 10px; border-bottom: 1px solid var(--border-1); background: var(--bg-2); }
.guide-shot-bar span { width: 8px; height: 8px; border-radius: 50%; background: var(--border-3); }
.guide-shot-body { padding: 14px 16px; }
.guide-shot-cap { padding: 8px 16px; border-top: 1px solid var(--border-1); font-size: 0.6875rem; color: var(--fg-3); font-family: var(--f-mono); letter-spacing: .03em; }
.guide-rows { display: flex; flex-direction: column; gap: 9px; }
.guide-row { display: flex; align-items: center; gap: 12px; }
.guide-row .pill, .guide-row .inst-tag { flex-shrink: 0; }
.guide-row-txt { font-size: 0.78125rem; color: var(--fg-1); }
.guide-dim { color: var(--fg-2); font-size: 0.71875rem; }
.guide-up { color: var(--c-up); }
.guide-posrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.guide-posrow-l, .guide-posrow-r { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.guide-flow { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.guide-discord { display: flex; flex-direction: column; gap: 3px; background: #2b2d31; border-radius: 8px; padding: 10px 14px; min-width: 200px; }
.guide-discord-author { color: #949cf7; font-weight: 600; font-size: 0.75rem; }
.guide-discord-msg { color: #dbdee1; font-size: 0.78125rem; }
.guide-flow-arrow { color: var(--fg-3); font-size: 0.6875rem; }
.guide-parsed { display: flex; flex-direction: column; gap: 4px; font-size: 0.71875rem; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--radius); padding: 10px 14px; }
.guide-parsed strong { color: var(--accent); }
.guide-foot { font-size: 0.65625rem; color: var(--fg-3); text-align: center; padding: 4px 0 10px; letter-spacing: .06em; }

/* ── Usage (owner-only consumption dashboard) */
.usage { display: flex; flex-direction: column; gap: 16px; }
.usage-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.usage-head .sub { flex: 1 1 320px; }
.usage-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.usage-srv { padding: 8px 12px; font-size: 0.78125rem; cursor: pointer; max-width: 220px; }
/* "platform-wide" scope caveat on the user-activity panels — amber note tint */
.usage-pw { color: var(--c-watch); }
.usage-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 14px; }
.usage-panel { min-width: 0; }
.usage-chart { padding: 14px 16px 10px; }
.usage-svg { width: 100%; height: 150px; display: block; }
.usage-chart-meta { padding: 6px 2px 4px; font-size: 0.6875rem; color: var(--fg-2); min-height: 22px; }
.usage-chart-meta strong { color: var(--fg-0); }
.usage-dim { color: var(--fg-3); }
.usage-empty { padding: 26px 18px; font-size: 0.78125rem; color: var(--fg-3); text-align: center; }
.usage-rank { display: flex; flex-direction: column; gap: 9px; padding: 14px 16px; }
.usage-rank-row { display: grid; grid-template-columns: minmax(90px, 170px) 1fr auto; align-items: center; gap: 10px; }
.usage-rank-name { font-size: 0.75rem; color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.usage-rank-track { height: 8px; border-radius: 99px; background: var(--bg-2); overflow: hidden; }
.usage-rank-fill { display: block; height: 100%; border-radius: 99px; }
.usage-rank-val { font-size: 0.6875rem; color: var(--fg-2); white-space: nowrap; }
.usage-tbl th, .usage-tbl td { padding: 9px 16px; }
.usage-user { display: inline-flex; align-items: center; gap: 8px; }
.usage-role { font-size: 0.625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--accent); }

/* ── Report a bug (sidebar entry, every user) */
.bug-report-btn {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 11px;
  border: 1px dashed var(--border-2);
  border-radius: var(--radius);
  color: var(--fg-2);
  font-size: 0.75rem;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.bug-report-btn:hover { color: var(--c-trim); border-color: color-mix(in oklab, var(--c-trim) 45%, transparent); background: color-mix(in oklab, var(--c-trim) 7%, transparent); }

/* Sidebar footer appearance controls — theme switch + text-size stepper. Stacked
   as two full-width segmented bars so they line up with the Report-a-bug button
   above (a compact side-by-side pair looked cramped on the narrow sidebar). */
.sidebar-appearance { display: flex; flex-direction: column; gap: 8px; }
.sidebar-appearance > div { width: 100%; }
/* Centre each segment's content — the theme buttons have no inline justify, so
   at full width their icons would otherwise hug the left and break column
   alignment with the A A A row below. */
.sidebar-appearance > div > button { flex: 1; justify-content: center; }

/* ── Bugs tab (owner triage) */
.bugs { display: flex; flex-direction: column; gap: 12px; }
.bug-card { padding: 0; }
.bug-card-hdr {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px 0;
}
.bug-status { font-size: 0.59375rem; letter-spacing: .08em; text-transform: uppercase; border: 1px solid; border-radius: 99px; padding: 1px 8px; }
.bug-cat { font-size: 0.625rem; color: var(--fg-3); text-transform: uppercase; letter-spacing: .08em; }
.bug-time { margin-left: auto; font-size: 0.6875rem; color: var(--fg-3); }
.bug-actions { display: flex; gap: 2px; }
.bug-msg { padding: 10px 16px 4px; font-size: 0.84375rem; line-height: 1.6; color: var(--fg-0); white-space: pre-wrap; overflow-wrap: anywhere; }
.bug-ctx { padding: 0 16px 12px; font-size: 0.65625rem; color: var(--fg-3); letter-spacing: .04em; }
.bug-msg:last-child { padding-bottom: 14px; }

/* ── Ratings: star meter + picker (gold is a semantic colour, never rebranded) */
.star-meter { position: relative; display: inline-block; line-height: 0; vertical-align: middle; }
.sm-track { display: flex; }
.sm-row { display: flex; gap: 2px; flex-wrap: nowrap; }
.sm-star { flex: none; line-height: 0; }
.sm-empty { color: var(--border-3); }
.sm-full { position: absolute; inset: 0; width: 0; overflow: hidden; color: #F6C244; }
.star-picker { display: flex; gap: 6px; justify-content: center; padding: 2px 0; }
.star-btn { background: none; border: none; padding: 2px; cursor: pointer; color: var(--border-3); line-height: 0; transition: transform 80ms ease, color 120ms ease; }
.star-btn:hover { transform: scale(1.12); }
.star-btn.on { color: #F6C244; }

/* ── The bottom-corner rating prompt */
.rating-prompt {
  position: fixed; z-index: 150; right: 20px; bottom: 20px;
  width: 322px; max-width: calc(100vw - 24px);
  background: var(--bg-1); border: 1px solid var(--border-2); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2); padding: 14px 15px;
  display: flex; flex-direction: column; gap: 10px;
  animation: rpIn 220ms cubic-bezier(.22, 1, .36, 1);
}
@keyframes rpIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.rp-hdr { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.rp-title { font-size: 0.84375rem; font-weight: 600; color: var(--fg-0); line-height: 1.4; }
.rp-sub { font-size: 0.6875rem; color: var(--fg-3); }
.rp-note { width: 100%; resize: vertical; border: 1px solid var(--border-1); border-radius: 8px; background: var(--bg-2); color: var(--fg-0); padding: 8px 10px; font: inherit; font-size: 0.78125rem; }
.rp-foot { display: flex; justify-content: flex-end; gap: 8px; }
.rp-done { display: flex; align-items: center; gap: 12px; padding: 6px 4px; }
.rp-done-star { color: #F6C244; line-height: 0; }

/* ── Ratings tab */
.ratings { display: flex; flex-direction: column; gap: 14px; }
.rating-controls { display: flex; align-items: center; gap: 8px; }
.rating-select { background: var(--bg-2); border: 1px solid var(--border-1); border-radius: 8px; color: var(--fg-0); font: inherit; font-size: 0.75rem; padding: 5px 8px; }
.rating-overview { display: grid; grid-template-columns: 200px 1fr 1.2fr; gap: 12px; }
.rating-avg { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 18px; text-align: center; }
.ra-num { font-size: 2.875rem; font-weight: 700; line-height: 1; color: var(--fg-0); font-family: var(--f-mono); }
.ra-den { font-size: 1.125rem; color: var(--fg-3); font-weight: 500; }
.ra-meta { font-size: 0.6875rem; color: var(--fg-3); }
.rating-dist, .rating-trend-panel { padding: 16px 18px; }
.rd-title { font-size: 0.65625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-3); margin-bottom: 10px; }
.rating-dist-row { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.rdr-label { display: inline-flex; align-items: center; gap: 2px; width: 30px; color: var(--fg-2); font-size: 0.6875rem; }
.rdr-track { flex: 1; height: 8px; background: var(--bg-3); border-radius: 99px; overflow: hidden; }
.rdr-fill { height: 100%; border-radius: 99px; transition: width 400ms cubic-bezier(.22, 1, .36, 1); }
.rdr-count { width: 30px; text-align: right; color: var(--fg-2); font-size: 0.6875rem; }
.rating-trend { display: flex; align-items: flex-end; gap: 3px; height: 92px; padding-top: 6px; }
.rt-col { flex: 1; height: 100%; display: flex; align-items: flex-end; min-width: 2px; }
.rt-bar { width: 100%; border-radius: 3px 3px 0 0; transition: height 400ms ease; }
.rt-axis { display: flex; justify-content: space-between; margin-top: 6px; font-size: 0.625rem; color: var(--fg-3); }
.rating-list-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.rlh-title { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); }
.rating-card { padding: 0; }
.rating-card-hdr { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 16px 10px; }
.rating-srv { font-size: 0.65625rem; color: var(--fg-3); border: 1px solid var(--border-1); border-radius: 99px; padding: 1px 8px; }
.rating-comment { padding: 0 16px 14px; font-size: 0.8125rem; line-height: 1.6; color: var(--fg-1); white-space: pre-wrap; overflow-wrap: anywhere; }

/* ── Ratings owner config */
.rating-config { padding: 0; overflow: hidden; }
.rc-summary { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px; background: none; border: none; color: var(--fg-0); padding: 14px 16px; cursor: pointer; text-align: left; font: inherit; }
.rc-sum-l { display: flex; align-items: center; gap: 10px; font-size: 0.8125rem; }
.rc-dim { color: var(--fg-3); font-size: 0.6875rem; }
.rc-body { padding: 6px 16px 16px; display: flex; flex-direction: column; gap: 14px; border-top: 1px solid var(--border-1); }
.rc-toggle { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.rc-toggle > span:not(.switch-track) { display: flex; flex-direction: column; }
.rc-hint { font-size: 0.6875rem; color: var(--fg-3); font-weight: 400; }
.rc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.rc-field { display: flex; flex-direction: column; gap: 5px; }
.rc-field > span:first-child { font-size: 0.6875rem; font-weight: 600; color: var(--fg-2); }
.rc-field input[type="number"], .rc-field input[type="text"] { background: var(--bg-2); border: 1px solid var(--border-1); border-radius: 8px; color: var(--fg-0); font: inherit; font-size: 0.78125rem; padding: 7px 9px; }
.rc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.rc-chip { background: var(--bg-2); border: 1px solid var(--border-1); border-radius: 99px; color: var(--fg-2); font: inherit; font-size: 0.71875rem; padding: 4px 11px; cursor: pointer; }
.rc-chip.on { background: var(--accent-glow); border-color: var(--accent-dim); color: var(--accent); }
.rc-grant-group { display: flex; flex-direction: column; gap: 5px; margin-bottom: 8px; }
.rc-grant-srv { font-size: 0.625rem; color: var(--fg-3); text-transform: uppercase; letter-spacing: .06em; }
.rc-foot { display: flex; justify-content: flex-end; }
.rc-err { color: var(--c-down); font-size: 0.6875rem; }

@media (max-width: 760px) {
  .rating-overview { grid-template-columns: 1fr; }
  .rc-grid { grid-template-columns: 1fr; }
  .rating-prompt { right: 12px; left: 12px; bottom: 12px; width: auto; }
}

/* ── Guide: tour CTA banner + numbered steps */
.guide-tour-cta {
  display: flex; align-items: center; gap: 16px; justify-content: space-between;
  padding: 16px 18px; border-radius: var(--radius-lg);
  border: 1px solid var(--accent-dim); background: var(--accent-glow);
}
.guide-tour-cta .gtc-txt { min-width: 0; }
.gtc-title { display: inline-flex; align-items: center; gap: 7px; font-size: 0.875rem; font-weight: 600; color: var(--fg-0); }
.gtc-sub { font-size: 0.78125rem; color: var(--fg-2); margin-top: 3px; }
.guide-tour-cta .btn { flex-shrink: 0; }
.guide-list.guide-steps { list-style: decimal; }
.guide-list.guide-steps li { padding-left: 2px; }

/* ── Onboarding tour (spotlight + tooltip) */
.tour-catch { position: fixed; inset: 0; z-index: 300; }
/* NO-SPOTLIGHT dim. A step whose target isn't on screen (the sidebar nav is
   off-canvas on a phone, so most steps land here at ~360px) used to dim 64% AND
   blur — obscuring the very tab the step had just navigated to and was narrating.
   Reported as "darkens and blurs the entire background so it's hard to see what
   it's talking about". The blur is gone and the dim is light: with nothing to
   point at, the content behind IS the subject, so it has to stay readable. */
.tour-catch.dim { background: rgba(4, 6, 12, 0.34); }
.tour-highlight {
  position: fixed; z-index: 301; border-radius: 12px; pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(4, 6, 12, 0.64), 0 0 0 2px var(--accent), 0 0 22px 2px var(--accent-glow);
  transition: top .28s cubic-bezier(.22,1,.36,1), left .28s cubic-bezier(.22,1,.36,1), width .28s cubic-bezier(.22,1,.36,1), height .28s cubic-bezier(.22,1,.36,1);
}
.tour-pop {
  position: fixed; z-index: 302; max-width: calc(100vw - 24px);
  background: var(--bg-1); border: 1px solid var(--border-2); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2); padding: 18px 20px 16px;
  display: flex; flex-direction: column; gap: 11px;
  animation: rpIn 200ms cubic-bezier(.22, 1, .36, 1);
}
.tour-pop-hd { display: flex; align-items: center; justify-content: space-between; }
.tour-step-n { font-size: 0.6875rem; color: var(--fg-3); letter-spacing: .06em; }
.tour-pop-title { font-size: 1.0625rem; font-weight: 600; color: var(--fg-0); line-height: 1.3; }
.tour-pop-body { font-size: 0.875rem; line-height: 1.6; color: var(--fg-1); }
.tour-dots { display: flex; align-items: center; gap: 5px; padding: 2px 0; }
.tour-dot { width: 6px; height: 6px; border-radius: 99px; background: var(--border-3); transition: all .2s ease; }
.tour-dot.on { width: 17px; background: var(--accent); }
.tour-pop-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; }
.tour-nav { display: flex; gap: 8px; }
.tour-skip { color: var(--fg-3); }

@media (max-width: 640px) {
  .guide-tour-cta { flex-direction: column; align-items: stretch; }
  .guide-tour-cta .btn { width: 100%; justify-content: center; }
  /* Centered cards sit near the bottom on mobile so tab content stays visible above. */
  .tour-pop[data-place="center"] { left: 12px !important; right: 12px; top: auto !important; bottom: 16px; width: auto !important; transform: none !important; }
}

/* ── Notifications (bell + dropdown) */
.notif-backdrop { display: none; }            /* only shown on mobile (see responsive) */
.notif-wrap { position: relative; flex-shrink: 0; }
.notif-bell { position: relative; }
.notif-bell.has-unread { color: var(--fg-0); }
.notif-dot {
  position: absolute; top: -3px; right: -3px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: 99px;
  background: var(--c-down); color: #fff;
  font-family: var(--f-mono); font-size: 0.59375rem; font-weight: 700; line-height: 1;
  border: 2px solid var(--bg-0);
}
.notif-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 80;
  width: 348px; max-width: calc(100vw - 24px);
  background: var(--bg-1); border: 1px solid var(--border-2); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2); overflow: hidden;
  animation: modalIn 150ms cubic-bezier(.22,1,.36,1);
}
.notif-hdr { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--border-1); }
.notif-title { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); }
.notif-list { max-height: min(420px, 60vh); overflow-y: auto; }
.notif-empty { padding: 28px 20px; text-align: center; font-size: 0.78125rem; color: var(--fg-3); line-height: 1.5; }
.notif-item {
  display: flex; align-items: flex-start; gap: 10px;
  width: 100%; text-align: left;
  padding: 11px 14px; border-bottom: 1px solid var(--border-1);
  transition: background 110ms;
}
.notif-item:hover { background: var(--bg-2); }
.notif-item.fresh { background: color-mix(in oklab, var(--accent) 7%, transparent); }
.notif-item.fresh:hover { background: color-mix(in oklab, var(--accent) 11%, transparent); }
.notif-item-dot { width: 7px; height: 7px; border-radius: 50%; margin-top: 6px; flex-shrink: 0; }
.notif-item-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.notif-item-r1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.notif-item-r1 .ticker { font-size: 0.8125rem; }
.notif-item-ct { font-size: 0.6875rem; color: var(--fg-2); }
.notif-item-kind { font-size: 0.78125rem; font-weight: 600; color: var(--fg-1); }
.notif-item-more { font-size: 0.65625rem; color: var(--fg-3); }
.notif-item-recap { display: inline-flex; align-items: center; gap: 6px; font-size: 0.78125rem; font-weight: 600; color: var(--accent); }
.notif-item-r2 { font-size: 0.6875rem; color: var(--fg-3); }
/* Settings view */
.notif-settings { padding: 4px 0 8px; max-height: min(440px, 64vh); overflow-y: auto; }
.notif-set-sec { padding: 12px 14px; border-bottom: 1px solid var(--border-1); }
.notif-set-sec:last-of-type { border-bottom: 0; }
.notif-set-row { display: flex; align-items: center; gap: 12px; }
.notif-set-txt { flex: 1; min-width: 0; }
.notif-set-name { font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); }
.notif-set-sub { font-size: 0.6875rem; color: var(--fg-2); margin-top: 2px; }
.notif-set-warn { font-size: 0.6875rem; color: var(--c-down); margin-top: 8px; line-height: 1.4; }
.notif-set-lbl { font-size: 0.625rem; text-transform: uppercase; letter-spacing: .08em; color: var(--fg-3); margin-bottom: 8px; }
.notif-trig { display: flex; align-items: center; gap: 11px; padding: 6px 0; cursor: pointer; }
.notif-trig-txt { display: flex; flex-direction: column; }
.notif-trig-txt strong { font-size: 0.78125rem; font-weight: 600; color: var(--fg-0); }
.notif-trig-txt span { font-size: 0.6875rem; color: var(--fg-3); }
.notif-set-foot { padding: 12px 14px 4px; font-size: 0.6875rem; color: var(--fg-3); line-height: 1.5; }

/* ════════════════════════════════════════════════════════════════════════
   RESPONSIVE — kept at the very end so these overrides win the cascade.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Medium screens (laptops, scaled-up 1080p): the zone between the phone
   layout (≤900px) and full desktop, where fixed side rails starve the data
   tables and percent-width columns crush their content. Two principles:
   1. A data table never shrinks below readable — the panel scrolls sideways
      instead of clipping values.
   2. Side rails stack below/above their main panel once they'd steal too much
      width. */
/* Dense tables (positions 12-col, events 14-col) don't truncate on smaller
   screens — instead the type + padding shrink so every column FITS, the events
   rail slims, and it only drops below the table once even that isn't enough.
   Goal: "Jun 11, 12:30" stays readable instead of becoming "Jun 11, …". */
@media (max-width: 1950px) and (min-width: 901px) {
  .split.cols { grid-template-columns: minmax(0, 1fr) 380px; }   /* slimmer events rail */
  .feed-scroll { overflow-x: auto; }
  .tbl-fixed thead th { font-size: 0.5625rem; letter-spacing: .05em; padding-left: 7px; padding-right: 7px; }
  .tbl-fixed tbody td { font-size: 0.71875rem; padding-left: 7px; padding-right: 7px; }
  .tbl-fixed .ticker { font-size: 0.75rem; }
}
@media (max-width: 1620px) and (min-width: 901px) {
  /* Not enough room for table + rail side-by-side even scaled → stack the rail
     below; the table takes the full content width. */
  .split.cols, .split.solo { grid-template-columns: 1fr; grid-template-rows: none; flex: none; }
  .split.cols > .panel:last-child .scroll-y { max-height: 380px; }
}
@media (max-width: 1180px) and (min-width: 901px) {
  /* Narrow desktops / split windows: squeeze a little more so 12–14 columns
     still fit the full-width table. */
  .tbl-fixed thead th { font-size: 0.53125rem; letter-spacing: .02em; padding-left: 5px; padding-right: 5px; }
  .tbl-fixed tbody td { font-size: 0.65625rem; padding-left: 5px; padding-right: 5px; }
}
@media (max-width: 1200px) and (min-width: 901px) {
  /* Charts: the sources column stacks above the chart instead of pinching it. */
  .split.cols-charts { grid-template-columns: 1fr; grid-template-rows: none; flex: none; }
  .charts-sources { max-height: 220px; }
}
@media (max-width: 1080px) and (min-width: 901px) {
  /* Guide: the side TOC would pinch the prose — switch to the chip nav early. */
  .guide { grid-template-columns: 1fr; gap: 16px; }
  .guide-toc { position: static; flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .guide-toc-hdr, .guide-toc-foot { flex-basis: 100%; border: 0; padding: 2px 4px; }
  .guide-toc-item { border: 1px solid var(--border-1); border-radius: 99px; padding: 5px 11px; font-size: 0.71875rem; }
  .guide-toc-item .guide-role { display: none; }
}

@media (max-width: 900px) {
  /* Phones: drop the viewport lock — the page scrolls naturally instead. */
  .shell { grid-template-columns: 1fr; height: auto; overflow: visible; }
  .main { overflow: visible; min-height: 0; }
  .content { overflow: visible; }
  .split.cols, .split.solo { flex: none; min-height: 0; grid-template-rows: none; }

  /* Reading-progress rail: thin accent line pinned to the top edge of the
     viewport; its fill tracks how far down the page you've scrolled, so it's
     obvious there's more below. Fades out on pages that don't overflow. */
  .scroll-rail {
    display: block; position: fixed; top: 0; left: 0; right: 0;
    height: 3px; z-index: 90; pointer-events: none;
    background: var(--border-1);
    opacity: 0; transition: opacity 220ms ease;
  }
  .scroll-rail.on { opacity: 1; }
  .scroll-rail-fill {
    display: block; height: 100%; width: 100%;
    transform-origin: left center; transform: scaleX(0);
    background: var(--accent);
    box-shadow: 0 0 8px color-mix(in oklab, var(--accent) 55%, transparent);
  }
  .split.cols .scroll-y, .split.solo .scroll-y { flex: none; }

  /* Sidebar → slide-in drawer */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: 252px; max-width: 84vw;
    z-index: 120;
    transform: translateX(-100%);
    transition: transform 220ms cubic-bezier(.22, 1, .36, 1);
    box-shadow: var(--shadow-2);
    /* clear the status bar (top) and home indicator (bottom) inside the drawer */
    padding-top: calc(18px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    padding-left: calc(14px + env(safe-area-inset-left, 0px));
  }
  .sidebar.open { transform: translateX(0); }
  .nav-backdrop {
    display: block; position: fixed; inset: 0;
    background: rgba(2, 4, 8, 0.5);
    backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
    z-index: 110; animation: fadeIn 160ms ease-out;
  }
  .nav-toggle {
    display: inline-grid; place-items: center;
    width: 40px; height: 40px; border-radius: var(--radius);
    color: var(--fg-1); background: var(--bg-1);
    border: 1px solid var(--border-1); flex-shrink: 0;
  }
  .nav-toggle:hover { background: var(--bg-2); }

  /* Header: title + meta on top, the server selector drops to its own full-width
     row so the meta has room to breathe instead of wrapping into a tall column. */
  .topbar { padding: calc(12px + env(safe-area-inset-top, 0px)) calc(16px + env(safe-area-inset-right, 0px)) 12px calc(16px + env(safe-area-inset-left, 0px)); gap: 10px 12px; flex-wrap: wrap; }
  .topbar-left { flex: 1 1 100%; }
  .topbar-title { min-width: 0; flex: 1; }
  .topbar-title h1 { font-size: 1.125rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .topbar-sub { font-size: 0.6875rem; gap: 6px; row-gap: 2px; }
  /* Bell + server selector share one full-width row (bell no longer gets
     squeezed onto its own line). */
  .topbar-actions { flex: 1 1 100%; gap: 8px; min-width: 0; align-items: center; }
  .notif-wrap { flex-shrink: 0; }
  .notif-bell { width: 38px; height: 38px; }
  .server-multi { flex: 1; min-width: 0; }
  .server-multi-btn { width: 100%; }
  .server-multi-btn .icon:last-child { margin-left: auto; }
  .content { padding: 16px calc(14px + env(safe-area-inset-right, 0px)) calc(72px + env(safe-area-inset-bottom, 0px)) calc(14px + env(safe-area-inset-left, 0px)); gap: 14px; }

  /* Notifications open as a clean top sheet over a backdrop — never the broken
     off-screen strip the anchored desktop dropdown produced on mobile. */
  .notif-backdrop { display: block; position: fixed; inset: 0; z-index: 124; background: rgba(2, 4, 8, 0.55); animation: fadeIn 150ms ease-out; }
  .notif-panel {
    position: fixed; top: calc(10px + env(safe-area-inset-top, 0px)); left: 10px; right: 10px; z-index: 125;
    width: auto; max-width: none; max-height: 86vh;
    display: flex; flex-direction: column;
  }
  .notif-list, .notif-settings { max-height: none; flex: 1; }

  .app-footer { flex-direction: column; gap: 4px; text-align: center; padding: 14px 16px; }
  .app-footer-mid { flex: none; }

  /* Stack every desktop split */
  .split.cols, .split.cols-narrow, .split.cols-charts { grid-template-columns: 1fr; }
  .charts-subgrid { grid-template-columns: 1fr; }
  /* Charts: drop the viewport-fill machinery so the page scrolls naturally */
  .split.cols-charts { flex: none; min-height: 0; grid-template-rows: none; }
  .charts-right { grid-template-rows: none; }
  /* Current Positions + Chart Events flow with the page — no nested scrollbars */
  .charts-fill { flex: none; min-height: 0; max-height: none; overflow: visible; }
  /* Tickers list stays a contained scroll (it can be long) */
  .charts-fill-cap { flex: none; min-height: 0; max-height: 44vh; }

  .statgrid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .stat { padding: 12px 14px; gap: 5px; }
  .stat .val { font-size: 1.375rem; }
  .stat .lbl { font-size: 0.71875rem; }
  /* Usage filter controls go full-width and the server picker leads */
  .usage-controls { width: 100%; gap: 8px; }
  .usage-srv { flex: 1 1 140px; max-width: none; }
  .usage-controls .seg { flex: 1 1 auto; display: flex; }
  .usage-controls .seg-btn { flex: 1; text-align: center; justify-content: center; }
  .recap-grid { grid-template-columns: 1fr; }
  .recap-line { grid-template-columns: 14px auto minmax(0, 1fr) auto; row-gap: 2px; gap: 10px; max-width: none; }
  .recap-line .rl-con { grid-column: 3 / 5; font-size: 0.6875rem; }
  .recap-line .rl-mv { grid-column: 2 / 4; }
  .recap-period-hdr { gap: 8px; }
  .rp-stats { gap: 10px; }

  /* Main feed panels grow naturally so the PAGE scrolls — no nested scrollbars. */
  .feed-scroll { max-height: none !important; min-height: 0 !important; overflow: visible !important; }

  /* Guide: TOC becomes a wrap-chip block above the content. */
  .guide { grid-template-columns: 1fr; gap: 16px; }
  .guide-toc { position: static; flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .guide-toc-hdr, .guide-toc-foot { flex-basis: 100%; border: 0; padding: 2px 4px; }
  .guide-toc-item { border: 1px solid var(--border-1); border-radius: 99px; padding: 5px 11px; font-size: 0.71875rem; }
  .guide-toc-item .guide-role { display: none; }
  .guide-sec { padding: 16px 14px; }
  .guide-flow-arrow { flex-basis: 100%; text-align: center; }

  /* Panel header: a header that carries tools (e.g. Open Positions' instrument
     filter) drops them onto their own full-width row below the title. */
  .panel-hdr { flex-wrap: wrap; gap: 8px 10px; padding: 14px 14px; }
  .panel-hdr-tools { flex: 1 1 100%; gap: 8px 10px; flex-wrap: wrap; }
  /* Three rows, so nothing crams: (1) the action button, (2) the analyst filter
     + the count, (3) the instrument seg full-width (All / Options / Shares get
     even, readable space instead of being squished against the count). */
  .panel-hdr-tools > .btn { order: 1; flex: 1 1 100%; justify-content: center; }
  .panel-hdr-tools .analyst-filter { order: 2; }
  .panel-hdr-tools .panel-meta { order: 3; margin-left: auto; white-space: nowrap; flex-shrink: 0; }
  .panel-hdr-tools .seg { order: 4; flex: 1 1 100%; display: flex; min-width: 0; }
  .panel-hdr-tools .seg-btn { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; text-align: center; padding-left: 8px; padding-right: 8px; }
  /* Analyst dropdown opens from the LEFT on mobile (the trigger sits left), so
     it never spills off the left edge and clips the names. */
  .af-menu { left: 0; right: auto; min-width: 240px; max-width: calc(100vw - 28px); }

  .chart-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; padding: 14px; }

  /* ── Tables → stacked cards ──────────────────────────────────────────────
     Dense tables become one card per row: each cell shows its column name as a
     label and its value beside it, so nothing is truncated or off-screen. */
  .tbl-cards { min-width: 0 !important; }
  .tbl-cards, .tbl-cards tbody { display: block; width: 100%; }
  .tbl-cards colgroup, .tbl-cards thead { display: none; }
  .tbl-cards tr { display: block; }

  .tbl-cards tbody tr:not(.day-sep):not(.wl-raw-row):not(.expand-row):not(.is-empty) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 14px;
    align-items: start;
    background: var(--bg-1);
    border: 1px solid var(--border-2);
    border-radius: var(--radius);
    padding: 11px 14px 12px;
    margin-bottom: 14px;
    box-shadow: var(--shadow-1);
  }
  .tbl-cards tbody tr:hover { background: var(--bg-1); }
  .tbl-cards tbody tr.row-selected,
  .tbl-cards tbody tr.row-selected:hover {
    background: var(--accent-glow); border-color: var(--accent-dim);
  }
  .tbl-cards tbody tr.expanded { background: var(--bg-1); }

  /* Each cell is a plain block: a tiny label on its own line, then the value
     flowing normally below it (so inline pieces like "0.49 → 0.35 (-28%)" stay
     on one wrapping line, NOT stacked). Two cells per row via the grid above. */
  .tbl-cards td {
    display: block;
    height: auto; min-height: 0; min-width: 0;
    padding: 6px 0; border: none;
    overflow: visible; white-space: normal; text-overflow: clip;
    font-size: 0.84375rem; text-align: left; line-height: 1.4;
  }
  .tbl-cards td::before {
    content: attr(data-label); display: block; margin-bottom: 3px;
    font-family: var(--f-mono); font-size: 0.5625rem; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--fg-3); line-height: 1.2;
  }
  .tbl-cards td:not([data-label])::before { content: none; }
  /* long values (P&L, timestamps) wrap instead of overflowing their half-cell */
  .tbl-cards td.num, .tbl-cards td.mono { white-space: normal !important; }
  .tbl-cards td .inst-detail { white-space: normal; }

  /* Checkbox row */
  .tbl-cards td.cell-check { grid-column: 1 / -1; display: flex; flex-direction: row; align-items: center; gap: 8px; }
  .tbl-cards td.cell-check::before { content: "Select"; display: inline; order: 2; margin: 0; }
  .tbl-cards td.cell-check input { order: 1; }

  /* Ticker chips → label left, chips wrap on the right (aligned with the other
     values for a consistent left-label / right-value rhythm). */
  .tbl-cards td.cell-chips {
    grid-column: 1 / -1; display: block;
    white-space: normal !important; overflow: visible !important;
  }
  .tbl-cards td.cell-chips .wl-tickcell { justify-content: flex-start; flex-wrap: wrap; gap: 6px; min-width: 0; }

  /* Long note → label on its own line (left), text wraps below, clamped to 3
     lines. Overrides the base card cell's right-align + the desktop inline
     ellipsis styles so the label sits left and the text never clips mid-word. */
  .tbl-cards td.cell-note {
    grid-column: 1 / -1;
    display: block; padding: 8px 0 4px; text-align: left;
    white-space: normal !important; overflow: visible !important; text-overflow: clip !important;
  }
  .tbl-cards td.cell-note::before {
    display: block; margin: 0 0 5px; margin-right: 0;
  }
  .tbl-cards td.cell-note .cell-text {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden; white-space: normal; word-break: break-word;
    color: var(--fg-1); font-size: 0.78125rem; line-height: 1.5;
  }

  /* Action buttons → a prominent split footer: equal-width buttons with icon +
     label spanning the bottom of the card (e.g. left = Parser, right = Delete). */
  .tbl-cards td.cell-actions {
    grid-column: 1 / -1;
    display: flex; gap: 8px; padding: 10px 0 2px; margin-top: 4px;
    border-top: 1px solid var(--border-1);
  }
  .tbl-cards td.cell-actions::before { content: none; }
  .tbl-cards td.cell-actions:empty { display: none; }
  .tbl-cards td.cell-actions .icon-btn {
    flex: 1; width: auto; height: 34px;
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
    border: 1px solid var(--border-1); border-radius: var(--radius-sm);
    background: var(--bg-2); color: var(--fg-1);
    font-size: 0.75rem; font-weight: 500;
  }
  .tbl-cards td.cell-actions .icon-btn svg { width: 14px; height: 14px; }
  .tbl-cards td.cell-actions .icon-btn:active { background: var(--bg-3); }
  .tbl-cards td.cell-actions .icon-btn .btn-label { display: inline; }
  .tbl-cards td.cell-actions .icon-btn.danger {
    color: var(--c-down);
    border-color: color-mix(in oklab, var(--c-down) 32%, transparent);
    background: color-mix(in oklab, var(--c-down) 9%, transparent);
  }

  /* Day separator → plain section heading, aligned with the card content */
  .tbl-cards tr.day-sep > td {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
    position: static; padding: 18px 14px 8px;
    background: transparent; border: none;
  }
  .tbl-cards tr.day-sep > td::before { content: none; }
  .tbl-cards tr.day-sep .day-sep-meta { margin-left: 0; }

  /* Expanded note + empty state → plain full-width block */
  .tbl-cards tr.wl-raw-row > td,
  .tbl-cards tr.expand-row > td,
  .tbl-cards tr.is-empty > td {
    display: block; padding: 4px 0 12px; border: none;
  }
  .tbl-cards tr.wl-raw-row > td::before,
  .tbl-cards tr.expand-row > td::before,
  .tbl-cards tr.is-empty > td::before { content: none; }
  /* Parser/timeline detail can be wide — let it scroll inside the card */
  .tbl-cards tr.expand-row > td { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tbl-cards tr.expand-row .parser-detail { grid-template-columns: 1fr; }

  /* Expansion (interaction timeline + parser JSON) → readable on a phone:
     tighter padding, rows wrap instead of truncating, JSON wraps (no h-scroll). */
  .position-detail, .parser-detail { padding: 12px 14px; gap: 14px; }
  .position-detail { border-top: none; }
  .tl-row { flex-wrap: wrap; gap: 3px 8px; padding: 9px 0 9px calc(var(--tl-level, 0) * 14px); }
  .tl-detail, .tl-note {
    white-space: normal; overflow: visible; text-overflow: clip;
    flex: 1 1 100%; min-width: 0;
  }
  .parser-detail pre { font-size: 0.6875rem; white-space: pre-wrap; word-break: break-word; }
  .parser-detail .raw-msg { font-size: 0.78125rem; }
  /* Pull the expansion up so it reads as part of the card above it */
  .tbl-cards tbody tr.expanded { margin-bottom: 0; box-shadow: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
  .tbl-cards tr.wl-raw-row, .tbl-cards tr.expand-row {
    background: var(--bg-1); border: 1px solid var(--border-2); border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    padding: 0 14px 6px; margin-bottom: 16px; box-shadow: var(--shadow-1);
  }

  /* Filter bars: every control gets its own full-width row, segmented toggles
     spread their buttons evenly so all options are visible and tappable. */
  .filterbar { display: flex; flex-wrap: wrap; gap: 8px; }
  .filterbar > * { flex: 1 1 100%; min-width: 0; }
  .filterbar .seg, .filterbar .select { width: 100%; }
  .filterbar .seg { display: flex; }
  /* Timeframe / type segments get a bigger, comfortably-tappable size on mobile. */
  .filterbar .seg-btn { flex: 1; text-align: center; justify-content: center; padding: 10px 8px; font-size: 0.8125rem; }

  /* Mobile select-all bar */
  .cards-selectall {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 14px; border-bottom: 1px solid var(--border-1);
    font-size: 0.8125rem; color: var(--fg-1); cursor: pointer;
  }
  .cards-selectall input { width: 16px; height: 16px; }
  .cards-selectall-n { margin-left: auto; font-size: 0.6875rem; color: var(--accent); }

  /* Forms → one column, full-width actions */
  .form-grid { grid-template-columns: 1fr !important; }
  .form-card { padding: 14px; }
  .form-actions { flex-direction: column-reverse; align-items: stretch; gap: 10px; }
  .form-actions .btn { width: 100%; justify-content: center; }
  .form-actions .field-hint { text-align: center; }

  /* ── Settings (mobile) ─────────────────────────────────────────────────── */
  .settings-content { padding: 18px 16px; }
  .toggle-grid { grid-template-columns: 1fr; }

  /* Sub-nav: pan horizontally without the ugly native scrollbar; momentum +
     snap make it obvious the strip scrolls and keep every tab tappable.
     Lock the vertical axis explicitly — otherwise `overflow-x: auto` makes the
     browser compute `overflow-y: auto` too, and iOS lets the strip rubber-band
     up/down inside its frame. overflow-y: hidden keeps vertical drags scrolling
     the page instead. */
  .settings-tabs {
    overflow-x: auto; overflow-y: hidden; flex-wrap: nowrap; gap: 0;
    -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity;
    scrollbar-width: none; touch-action: pan-x;
  }
  .settings-tabs::-webkit-scrollbar { display: none; }
  .settings-tab { white-space: nowrap; flex: 0 0 auto; padding: 12px 14px; font-size: 0.8125rem; scroll-snap-align: start; }

  /* Config rows (channels / analysts / servers / access / role grants) become
     standalone cards — the icon + name block (.row-main) fills the first line and
     pushes the controls to the right; bulky controls wrap below. */
  .channel-row, .user-row {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 8px 12px; grid-template-columns: none;
    padding: 12px 14px;
    background: var(--bg-1); border: 1px solid var(--border-2);
    border-radius: var(--radius); box-shadow: var(--shadow-1);
    margin-bottom: 10px;
  }
  .channel-row:hover, .user-row:hover { background: var(--bg-1); }
  .channel-row .name, .user-row .uname { font-size: 0.8125rem; }
  .channel-row .row-main, .user-row .row-main { flex: 1 1 auto; min-width: 0; }
  .row-actions { margin-left: 0; }
  /* strip the wrapping container so each row stands alone as a card */
  .cat-group .rows, .access-list, .setting-list, .servers .rows {
    border: none; border-radius: 0; overflow: visible; background: none;
  }
  /* the inline editor reads as a connected continuation of the card it edits */
  .channel-row:has(+ .row-editor), .user-row:has(+ .row-editor) {
    margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0;
  }
  .row-editor {
    border: 1px solid var(--border-2); border-top: none;
    border-radius: 0 0 var(--radius) var(--radius); margin-bottom: 10px;
  }

  /* Channels: category picker spans its own row, each option evenly tappable. */
  .channel-row .cat-select { flex: 1 1 100%; order: 5; }
  .channel-row .cat-select button { flex: 1; text-align: center; }
  .channel-row .live-dot { order: 4; }
  /* Category-group header → name on top, description full-width below (was squished right) */
  .cat-group-hdr { flex-wrap: wrap; gap: 4px 10px; margin-top: 16px; padding: 6px 2px; }
  .cat-group-hdr .cat-desc { flex: 1 1 100%; text-align: left; max-width: none; font-size: 0.71875rem; }

  /* Analysts: legend pills wrap; per-row tier buttons become a full-width
     segmented control on their own line so you can actually pick a tier. */
  .tier-legend .pill { font-size: 0.625rem; }
  .user-row .avatar { order: 1; }
  .user-row .row-main { order: 2; }
  .user-row .mono { order: 3; }
  .user-row .row-actions { order: 4; }
  .user-row .tier-btns { order: 5; flex: 1 1 100%; }
  .user-row .tier-btns .btn { flex: 1; justify-content: center; }
  /* server group header reads as a plain section label between the cards */
  .setting-grp { border: none; padding: 16px 2px 4px; }

  /* Access toolbar: role filter spreads full-width (so the roles are togglable),
     Add-user button stacks full-width beneath it. */
  .access-toolbar { flex-direction: column; align-items: stretch; gap: 10px; padding-right: 0; }
  /* Role filter: with 6 roles, scroll horizontally instead of squishing each
     chip until "Server Owner" is unreadable. */
  .access-toolbar .seg-filter { width: 100%; margin: 0; display: flex; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .access-toolbar .seg-filter::-webkit-scrollbar { display: none; }
  .access-toolbar .seg-filter .seg-btn { flex: 0 0 auto; justify-content: center; padding: 8px 12px; white-space: nowrap; }
  .access-toolbar > .btn.primary { width: 100%; min-width: 0; }
  .add-bar { padding-right: 0; }
  .add-bar > .btn.primary { width: 100%; min-width: 0; }
  /* open Add-forms span full width without the desktop -8px pull (avoids overflow) */
  .access-toolbar .form-card, .add-bar .form-card { margin-right: 0; }

  /* Access + role-grant rows: name fills line 1 with the toggle + actions; the
     role-grant level <select> drops to its own full-width line. Release the
     bounded inner scroll so the whole page scrolls as one. */
  .access-list { max-height: none; overflow: visible; }
  .access-list .channel-row > .select { flex: 1 1 100%; order: 5; }

  /* Audit log → clean stacked card: time + action pill on line 1, actor and
     target on their own lines; long IDs wrap instead of clipping. */
  .audit-row {
    display: flex; flex-wrap: wrap; align-items: baseline;
    gap: 3px 10px; padding: 11px 14px 12px;
  }
  .audit-row .audit-time { order: 1; }
  .audit-row .pill { order: 2; margin-left: auto; }
  .audit-row .audit-actor { order: 3; flex-basis: 100%; white-space: normal; overflow: visible; }
  .audit-row .audit-target { order: 4; flex-basis: 100%; white-space: normal; overflow: visible; word-break: break-word; }

  /* Integrations: pipeline cards 2×2 (no more vertical word-piles); run-log
     rows stack the time over the message and break the long stored-as ID. */
  .pipeline-stats { grid-template-columns: 1fr 1fr !important; }
  .runlog-row { grid-template-columns: 1fr !important; gap: 3px !important; overflow-wrap: anywhere; }

  .flyout { width: 100%; }
  /* Full-height sheet on mobile: the header (with its close ✕) must clear the
     status bar / notch, or it lands under it and can't be tapped. Pad past the
     safe-area inset, with a hard minimum for devices that report a 0 inset but
     still draw the page under the status bar. */
  .flyout-hdr { padding-top: max(calc(16px + env(safe-area-inset-top, 0px)), 44px); }
  .flyout-body { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
  .toast-host { left: 12px; right: 12px; align-items: stretch; }
  .toast { max-width: none; min-width: 0; }

  /* Recap card: keep ticker (left) and P&L (right) on one row — it fits at
     full width and reads far cleaner than stacking them. */
  .recap { padding: 16px; }
  .recap .top { gap: 12px; }
  .recap .top > div:first-child { min-width: 0; }
  .recap .ticker-big { font-size: 1.25rem; }
  .recap .pnl { font-size: 1.375rem; }
}

@media (max-width: 460px) {
  .statgrid { grid-template-columns: 1fr 1fr; }
  .topbar-actions { flex-wrap: wrap; }
  .settings-content h2 { font-size: 1rem; }
  /* Compact stat tiles so the four KPIs don't dominate the phone screen. */
  .stat { padding: 10px 12px; gap: 3px; }
  .stat .val { font-size: 1.1875rem; }
  .stat .lbl { font-size: 0.6875rem; gap: 6px; }
  .stat .delta { font-size: 0.625rem; }
}

/* The originating post on a parse-quality to-do — enough to recognise the trade
   without leaving the tab. Clamped: some forwards are very long. */
.todo-src {
  display: flex; gap: 8px; align-items: baseline;
  margin-top: 6px; padding: 6px 8px;
  background: var(--bg-0); border: 1px solid var(--border-1);
  border-radius: calc(var(--radius) - 2px);
}
.todo-src-ch { font-size: 0.65625rem; color: var(--fg-3); flex-shrink: 0; }
.todo-src-txt {
  font-size: 0.75rem; color: var(--fg-2); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}

/* Recap approval — the recap's own numbers as evidence, then the choice. Laid
   out as a block so it never squeezes the row's other actions. */
.todo-approve { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.todo-approve-ev { display: flex; gap: 10px; font-size: 0.6875rem; color: var(--fg-3); }
.todo-approve-px {
  display: flex; align-items: center; gap: 6px;
  font-size: 0.71875rem; color: var(--fg-2);
}
.todo-approve-acts { display: flex; gap: 6px; }
@media (max-width: 640px) {
  .todo-approve { align-items: stretch; }
  .todo-approve-acts { justify-content: flex-end; }
}

/* Position-level edit affordance above a timeline. The warning only appears when
   the events genuinely disagree about the contract — i.e. the aggregator is
   already treating them as more than one position. */
.tl-poshead {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 0 0 6px; margin-bottom: 4px; border-bottom: 1px solid var(--border-1);
}
.tl-warn {
  font-family: var(--f-mono); font-size: 0.65625rem; letter-spacing: .03em;
  color: var(--c-down); border: 1px solid currentColor;
  padding: 1px 6px; border-radius: 999px;
}
.tl-posedit { font-size: 0.71875rem; padding: 3px 8px; }
.manage-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }

/* Subsection heading inside a period block ("Positions closed" / "Trims taken").
   Both lists now carry one, so the day reads as labelled sections rather than a
   run of rows whose grouping you have to infer. */
.recap-sub-hd {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 0.71875rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-2); margin: 14px 0 2px; padding: 0 8px 6px;
  border-bottom: 1px solid var(--border-1);
}
.recap-sub-hd:first-child { margin-top: 4px; }
.recap-sub-hd .rt-note { text-transform: none; letter-spacing: 0; font-size: 0.71875rem; color: var(--fg-3); }
/* The trims block keeps its own top rule only when it follows closed trades. */
.recap-trims { margin-top: 0; padding-top: 0; border-top: 0; }

/* Inline qualifier inside a field label ("market time (ET)"). */
.calc-hint { color: var(--fg-3); font-weight: 400; text-transform: none; letter-spacing: 0; }

/* "Trims in stats" — a real toggle switch (reuses the shared .switch), so its
   on/off state is unmistakable at a glance rather than a mystery checkbox. */
.recap-trim-toggle { gap: 8px; font-size: 0.75rem; color: var(--fg-2); user-select: none; }
.recap-trim-toggle .recap-trim-lbl { white-space: nowrap; }
.recap-trim-toggle input:checked ~ .recap-trim-lbl { color: var(--fg-1); }

/* ── Live market data — flash, chips, sparkline ─────────────────────────────
   Terminal idiom (TWS/Bloomberg): flash the changed NUMBER's text colour, never
   a background wash — reads on both themes, survives white-label --bg overrides,
   and keeps WCAG 2.3.1 headroom. Attack ~150ms hold, decay to steady over
   ~800ms (IBM Carbon productive easing); 950ms total sits under the 1Hz paint
   gate so flashes never overlap. Tick colours derive from the semantic pair via
   color-mix, so brands + the light theme inherit them for free.
   prefers-reduced-motion KEEPS the colour flash (colour change is not vestibular
   motion, and without a transient, silent swaps go unseen) and kills only the
   decorative pulses. */
:root {
  --tick-up:   color-mix(in oklab, var(--c-up) 72%, #fff);
  --tick-down: color-mix(in oklab, var(--c-down) 72%, #fff);
}
:root[data-theme="light"] {
  --tick-up:   color-mix(in oklab, var(--c-up) 60%, #000);
  --tick-down: color-mix(in oklab, var(--c-down) 60%, #000);
}
.lv-flash { display: inline; }
.lv-flash.lv-up   { animation: lvTickUp   950ms cubic-bezier(0.2, 0, 0.38, 0.9) 1; }
.lv-flash.lv-down { animation: lvTickDown 950ms cubic-bezier(0.2, 0, 0.38, 0.9) 1; }
@keyframes lvTickUp   { 0%, 16% { color: var(--tick-up); }   100% { color: currentColor; } }
@keyframes lvTickDown { 0%, 16% { color: var(--tick-down); } 100% { color: currentColor; } }
/* Persistent direction glyph beside the P&L — steady SIGN colour (position vs
   entry), never the transient tick colour. Direction is never colour-only. */
.lv-arrow { font-size: 0.5625rem; margin-right: 3px; vertical-align: 1px; }
.lv-arrow.up { color: var(--c-up); } .lv-arrow.down { color: var(--c-down); }
/* Data-state chip: amber for SIM / DELAYED so neither is mistaken for real-time;
   green for a genuine LIVE feed. */
.lv-chip {
  font-family: var(--f-mono); font-size: 0.5625rem; letter-spacing: .08em; font-weight: 600;
  color: var(--c-watch); border: 1px solid currentColor; border-radius: 999px;
  padding: 0px 5px; margin-left: 6px; vertical-align: 1px;
  animation: lvPulse 2.4s ease-in-out infinite;
}
.lv-chip-live { color: var(--c-up); }
/* The underlying's live quote riding along on an option row (context only). */
.lv-underlying { color: var(--fg-3); }
.lv-underlying .lv-u-arrow { font-size: 0.5rem; margin-left: 2px; }
.lv-underlying .lv-u-arrow.up { color: var(--c-up); }
.lv-underlying .lv-u-arrow.down { color: var(--c-down); }
@keyframes lvPulse { 0%,100% { opacity: 1; } 50% { opacity: .55; } }
/* Stale = FEED problem while the session is open (grey + hollow dot). A closed
   market is NOT stale: marks hold full-strength colour with an "At close" chip. */
.lv-stale { color: var(--fg-3) !important; }
.lv-stale-dot { color: var(--fg-3); margin-right: 3px; font-size: 0.5625rem; }
.lv-spark { display: block; margin-top: 3px; opacity: .8; margin-left: auto; }
@media (prefers-reduced-motion: reduce) {
  /* Colour flashes STAY (no transform in the keyframes). Only decoration stops. */
  .lv-chip { animation: none; }
}

/* ── "What's new" announcement modal + CSS fireworks ────────────────────────
   A one-time celebration for a shipped feature. Fireworks are pure CSS box-
   shadow bursts (no libraries); disabled under prefers-reduced-motion. */
.announce-back {
  position: fixed; inset: 0; z-index: 320;
  background: rgba(2, 4, 8, 0.62);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  animation: rpIn 200ms ease;
}
.announce {
  position: relative; overflow: hidden;
  width: min(460px, 100%);
  background: linear-gradient(180deg, color-mix(in oklab, var(--accent) 10%, var(--bg-1)), var(--bg-1));
  border: 1px solid color-mix(in oklab, var(--accent) 34%, var(--border-2));
  border-radius: var(--radius-lg); box-shadow: var(--shadow-2);
}
.announce-body { position: relative; z-index: 2; padding: 26px 24px 22px; text-align: center; }
.announce-badge {
  display: inline-block; font-family: var(--f-mono); font-size: 0.65625rem; font-weight: 700;
  letter-spacing: .14em; color: var(--bg-0); background: var(--accent);
  padding: 3px 9px; border-radius: 999px; margin-bottom: 12px;
}
.announce-title { font-size: 1.375rem; font-weight: 700; color: var(--fg-0); margin: 0 0 8px; letter-spacing: -0.01em; }
.announce-copy { font-size: 0.84375rem; line-height: 1.55; color: var(--fg-1); margin: 0 auto 18px; max-width: 380px; }
.announce-acts { display: flex; gap: 10px; justify-content: center; }
.announce-acts .btn { padding: 9px 18px; font-size: 0.8125rem; }

/* Fireworks: each <i> launches (translateY) then bursts via a spray of
   box-shadow points that expand outward and fade. */
.announce-fw { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.announce-fw i {
  position: absolute; top: 58%; width: 4px; height: 4px; border-radius: 50%;
  opacity: 0; transform: translateY(0);
}
.announce-fw i:nth-child(1) { left: 22%; --fw: var(--c-up);    animation: fwLaunch 2.6s ease-out 0.2s infinite, fwBurst 2.6s ease-out 0.2s infinite; }
.announce-fw i:nth-child(2) { left: 50%; --fw: var(--c-trim);  animation: fwLaunch 2.6s ease-out 0.9s infinite, fwBurst 2.6s ease-out 0.9s infinite; }
.announce-fw i:nth-child(3) { left: 74%; --fw: var(--c-add);   animation: fwLaunch 2.6s ease-out 1.5s infinite, fwBurst 2.6s ease-out 1.5s infinite; }
.announce-fw i:nth-child(4) { left: 38%; --fw: var(--c-watch); animation: fwLaunch 2.6s ease-out 2.0s infinite, fwBurst 2.6s ease-out 2.0s infinite; }
@keyframes fwLaunch {
  0%   { opacity: 0; transform: translateY(40px); }
  18%  { opacity: 1; transform: translateY(-30px); }
  22%  { opacity: 1; transform: translateY(-34px); }
  100% { opacity: 0; transform: translateY(-34px); }
}
@keyframes fwBurst {
  0%, 20% { box-shadow: 0 0 0 0 var(--fw); }
  40% {
    box-shadow:
      0 -34px 0 0 var(--fw), 24px -24px 0 0 var(--fw), 34px 0 0 0 var(--fw),
      24px 24px 0 0 var(--fw), 0 34px 0 0 var(--fw), -24px 24px 0 0 var(--fw),
      -34px 0 0 0 var(--fw), -24px -24px 0 0 var(--fw);
  }
  75% {
    box-shadow:
      0 -60px 0 0 transparent, 42px -42px 0 0 transparent, 60px 0 0 0 transparent,
      42px 42px 0 0 transparent, 0 60px 0 0 transparent, -42px 42px 0 0 transparent,
      -60px 0 0 0 transparent, -42px -42px 0 0 transparent;
  }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .announce-fw { display: none; }
  .announce-back { animation: none; }
}

/* Live sparkline on a mobile position row — its own line under the price. */
.mpos-spark { display: block; margin-top: 4px; }
.mpos-spark .lv-spark { margin-left: 0; margin-top: 0; }

/* ── Owner-only assistant ──────────────────────────────────────────────────── */
.asst-fab {
  position: fixed; right: 20px; bottom: 20px; z-index: 250;
  width: 48px; height: 48px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--accent); color: #fff;
  border: 1px solid color-mix(in oklab, var(--accent) 60%, #000);
  box-shadow: 0 6px 20px rgba(0,0,0,0.35), 0 0 0 1px rgba(255,255,255,0.04) inset;
  transition: transform 120ms ease, background 120ms ease;
}
.asst-fab:hover { transform: translateY(-1px); }
.asst-fab.open { background: var(--bg-3); color: var(--fg-1); border-color: var(--border-2); }

.asst-panel {
  position: fixed; right: 20px; bottom: 20px; z-index: 251;
  width: 380px; max-width: calc(100vw - 24px);
  height: 560px; max-height: calc(100vh - 40px);
  display: flex; flex-direction: column;
  background: var(--bg-1); border: 1px solid var(--border-2);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: 0 18px 50px rgba(0,0,0,0.45);
}
.asst-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 11px 14px; border-bottom: 1px solid var(--border-2);
  background: var(--bg-2);
}
.asst-title { display: flex; align-items: center; gap: 8px; font-size: 0.8125rem; font-weight: 600; color: var(--fg-0); }
.asst-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--sinux-emerald); box-shadow: 0 0 8px var(--sinux-emerald); }
.asst-close { background: none; border: none; color: var(--fg-2); cursor: pointer; font-size: 0.875rem; padding: 4px; line-height: 1; }
.asst-close:hover { color: var(--fg-0); }

.asst-msgs { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.asst-empty { color: var(--fg-2); font-size: 0.8125rem; line-height: 1.5; }
.asst-empty p { margin: 0 0 12px; }
.asst-hints { display: flex; flex-direction: column; gap: 7px; }
.asst-hint {
  text-align: left; background: var(--bg-2); border: 1px solid var(--border-2);
  color: var(--fg-1); border-radius: var(--radius); padding: 8px 11px; font-size: 0.78125rem; cursor: pointer;
}
.asst-hint:hover { border-color: var(--accent); color: var(--fg-0); }

.asst-msg { display: flex; flex-direction: column; gap: 8px; max-width: 100%; }
.asst-msg.user { align-items: flex-end; }
.asst-bubble {
  padding: 9px 12px; border-radius: 12px; font-size: 0.8125rem; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word; max-width: 90%;
}
.asst-msg.user .asst-bubble { background: var(--accent); color: #fff; border-bottom-right-radius: 4px; }
.asst-msg.bot .asst-bubble { background: var(--bg-2); color: var(--fg-0); border: 1px solid var(--border-2); border-bottom-left-radius: 4px; }

.asst-typing { display: inline-flex; gap: 4px; }
.asst-typing span { width: 6px; height: 6px; border-radius: 50%; background: var(--fg-3); animation: asstBlink 1.2s infinite ease-in-out; }
.asst-typing span:nth-child(2) { animation-delay: 0.2s; }
.asst-typing span:nth-child(3) { animation-delay: 0.4s; }
@keyframes asstBlink { 0%, 80%, 100% { opacity: 0.3; } 40% { opacity: 1; } }

.asst-prop {
  background: var(--bg-2); border: 1px solid var(--border-2); border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: 10px 12px; max-width: 100%; font-size: 0.78125rem;
}
.asst-prop.is-applied { border-left-color: var(--c-up); }
.asst-prop.is-failed { border-left-color: var(--c-down); }
.asst-prop.is-cancelled { opacity: 0.6; }
.asst-prop-head { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
.asst-prop-kind { font-size: 0.65625rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent); }
.asst-prop-label { font-weight: 600; color: var(--fg-0); font-size: 0.78125rem; }
.asst-prop-reason { color: var(--fg-2); margin-bottom: 8px; line-height: 1.45; }
.asst-prop-diff { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.asst-diff-row { display: flex; align-items: center; gap: 8px; font-variant-numeric: tabular-nums; }
.asst-diff-k { color: var(--fg-2); min-width: 82px; font-size: 0.71875rem; }
.asst-diff-before { color: var(--fg-2); text-decoration: line-through; }
.asst-diff-arrow { color: var(--fg-3); }
.asst-diff-after { color: var(--c-up); font-weight: 600; }
.asst-prop-actions { display: flex; gap: 8px; }
.asst-prop-note { font-size: 0.75rem; color: var(--fg-2); }
.asst-prop-note.ok { color: var(--c-up); }
.asst-prop-note.bad { color: var(--c-down); }

.asst-input-row { display: flex; align-items: flex-end; gap: 8px; padding: 10px; border-top: 1px solid var(--border-2); background: var(--bg-2); }
.asst-input {
  flex: 1; resize: none; max-height: 120px; min-height: 20px;
  background: var(--bg-1); border: 1px solid var(--border-2); border-radius: var(--radius);
  color: var(--fg-0); font: inherit; font-size: 0.8125rem; padding: 8px 10px; line-height: 1.4;
}
.asst-input:focus { outline: none; border-color: var(--accent); }
.asst-send {
  width: 34px; height: 34px; flex-shrink: 0; border-radius: var(--radius); cursor: pointer;
  background: var(--accent); color: #fff; border: none; font-size: 1rem; line-height: 1;
}
.asst-send:disabled { opacity: 0.4; cursor: default; }

@media (max-width: 560px) {
  .asst-panel { right: 8px; left: 8px; bottom: 8px; width: auto; height: 72vh; }
  .asst-fab { right: 14px; bottom: 14px; }
}
.mpos-metaline .lv-underlying { white-space: nowrap; }
.recap .pnl + .pnl-sub { margin-top: 6px; }
.recap .pnl-sub + .pnl-sub { margin-top: 3px; }

/* ── Analyst profile ──────────────────────────────────────────────────────── */
/* A tapped name reads as interactive without shouting — the name underlines on
   hover/focus; the whole chip stays inline. */
.analyst.analyst-tap { cursor: pointer; border-radius: 5px; }
.analyst.analyst-tap:hover, .analyst.analyst-tap:focus-visible { text-decoration: underline; text-underline-offset: 2px; outline: none; }
.analyst.analyst-tap:focus-visible { box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent) 50%, transparent); }

.swatch.lg { width: 40px; height: 40px; border-radius: 10px; }

/* The card rides the shared .flyout drawer (right on desktop, full sheet on
   mobile). A thin accent spine in the analyst's own colour is the signature. */
.an-flyout { border-left: 3px solid var(--col, var(--accent)); }
.an-hdr { align-items: flex-start; }
.an-id { display: flex; gap: 12px; align-items: center; min-width: 0; }
.an-pic { border-radius: 10px; }
.an-id-txt { min-width: 0; }
.an-name { font-size: 1.0625rem; font-weight: 700; color: var(--fg-0); letter-spacing: 0.01em; }
.an-tag {
  display: inline-block; margin-top: 6px; font-size: 0.71875rem; font-weight: 600;
  letter-spacing: 0.03em; text-transform: uppercase;
  color: color-mix(in oklab, var(--col, var(--accent)) 78%, var(--fg-1));
}
.an-hdr-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.an-body { display: flex; flex-direction: column; gap: 16px; }
/* Restrained inline stats — a single line, NOT a grid of tiles. */
.an-stats { display: flex; flex-wrap: wrap; gap: 22px; padding: 2px 0 2px; border-bottom: 1px solid var(--border-2); padding-bottom: 14px; }
.an-stat { display: flex; flex-direction: column; gap: 3px; }
.an-stat-v { font-size: 1rem; font-weight: 700; color: var(--fg-0); font-variant-numeric: tabular-nums; }
.an-stat-v.up { color: var(--c-up); } .an-stat-v.down { color: var(--c-down); }
.an-stat-l { font-size: 0.65625rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-3); }

/* Risk note as a pull-quote — the motif that makes the card feel authored. */
.an-risk {
  margin: 0; padding: 2px 0 2px 14px; border-left: 3px solid color-mix(in oklab, var(--col, var(--accent)) 60%, var(--border-2));
  font-size: 0.9375rem; line-height: 1.5; color: var(--fg-0); font-style: italic;
}
.an-note { margin: 0; font-size: 0.84375rem; line-height: 1.6; color: var(--fg-1); }
.an-empty { color: var(--fg-2); font-size: 0.8125rem; line-height: 1.5; }

/* Inline editor (self-service + owner). */
.an-edit { display: flex; flex-direction: column; gap: 14px; }
.an-field { display: flex; flex-direction: column; gap: 5px; }
.an-field-l { font-size: 0.75rem; color: var(--fg-1); font-weight: 600; }
.an-field-l em { font-style: normal; font-weight: 400; color: var(--fg-3); }
.an-input {
  background: var(--bg-1); border: 1px solid var(--border-2); border-radius: var(--radius);
  color: var(--fg-0); font: inherit; font-size: 0.84375rem; padding: 8px 10px; resize: vertical;
}
.an-input:focus { outline: none; border-color: var(--accent); }
.an-err { font-size: 0.78125rem; color: var(--c-down); }
.an-edit-actions { display: flex; gap: 8px; }

/* The style caption under a name in Event / Position detail headers — the fix for
   acting on a signal without knowing the analyst's style. */
.an-caption { margin-top: 6px; font-size: 0.71875rem; line-height: 1.4; color: var(--fg-2); }
.an-caption .an-tag { display: inline; margin: 0; font-size: 0.6875rem; }
.an-caption-dot { margin: 0 6px; color: var(--fg-3); }
.an-caption-risk { color: var(--fg-2); }

/* Contract detail (strike · expiry) as a quiet sub-line under the instrument pill
   in the ledger positions table — brings back strike/expiry without a new column. */
.inst-contract { margin-top: 6px; font-size: 0.6875rem; line-height: 1.3; color: var(--fg-2); letter-spacing: 0.01em; white-space: nowrap; }
.inst-contract .ic-strike { color: var(--fg-1); font-weight: 600; }
.inst-contract .ic-sep { color: var(--fg-3); }
