/* ── Self-hosted fonts ────────────────────────────────────────────────────── */
@font-face { font-family: 'Play'; src: url('/static/fonts/Play-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Play'; src: url('/static/fonts/Play-Bold.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

/* ── Reset & base ─────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Form elements don't inherit font-family by default — opt them in */
button, input, select, textarea { font-family: inherit; }

:root {
  --bg:          #0a0d11;
  --bg2:         #0e1219;
  --bg3:         #131820;
  --bg4:         #1a2028;
  --border:      #182028;
  --border-hi:   #222e3a;

  /* ── Contrast ladder (ratio vs #0a0d11) ── */
  /* 2.0  muted · 5.5  dim · 6.5  text/accent · 7.5  mid · 11.0  bright */
  --text-muted:  #3f4549;          /* 2.0:1 — decorative borders, corner ticks */
  --text-dim:    #808992;          /* 5.5:1 — labels, breadcrumbs, secondary */
  --text:        #8c969f;          /* 6.5:1 — body text */
  --text-mid:    #97a2ac;          /* 7.5:1 — inputs, tooltips */
  --text-bright: #b7c5d0;         /* 11.0:1 — headings, important values */
  --accent:      #5a9cc5;          /* 6.5:1 — links, active indicators */
  --accent-dim:  #528fb5;          /* 5.5:1 — button borders */
  --accent-bg:   rgba(90, 156, 197, 0.06);
  --accent-line: rgba(90, 156, 197, 0.2);
  --accent-hover:rgba(90, 156, 197, 0.15);
  --accent-select:rgba(90, 156, 197, 0.3);

  /* ── Data / semantic colours (6.0:1 base, 7.0:1 -hi hover) ── */
  --sell:        #c17e65;          /* 6.0:1 — warm rust */
  --sell-hi:     #d2896e;          /* 7.0:1 */
  --sell-fade:   rgba(193, 126, 101, 0.3);
  --sell-fade-line: rgba(193, 126, 101, 0.8);  /* depth chart border */
  --sell-fade-fill: rgba(193, 126, 101, 0.08); /* depth chart area fill */
  --buy:         var(--accent);    /* aliases --accent so preset overrides auto-propagate */
  --buy-hi:      #64a5c8;          /* 7.0:1 step up from merged base */
  --buy-fade:    rgba(90, 156, 197, 0.3);
  --buy-fade-line: rgba(90, 156, 197, 0.8);    /* depth chart border */
  --buy-fade-fill: rgba(90, 156, 197, 0.08);   /* depth chart area fill */
  --green:       #5c9e5c;          /* 6.0:1 — desaturated green */
  --green-hi:    #64ab64;          /* 7.0:1 */
  --orange:      #b0884a;          /* 6.0:1 — desaturated amber */
  --orange-hi:   #bf9451;          /* 7.0:1 */
  --red:         #c06060;          /* 6.0:1 — desaturated red, dimmed to match --sell / --green visual weight */
  --red-hi:      #cd6a6a;          /* 7.0:1 */
  --red-fade:    rgba(192, 96, 96, 0.15);  /* tinted background for destructive-armed states */

  /* ── Chart data series — named aliases over semantic colors ─────── */
  /* Chart data is semantically distinct from UI/table usage, but can reuse
   * the same hex values. Dedicated variable names give us decoupled naming
   * (if we ever want to tweak just the chart AVG color, we change --chart-avg
   * independently from --accent). No dedicated palette — context disambiguates.
   * Orange is the only semantic color NOT reused — kept free for warnings. */
  --chart-avg:   var(--accent);   /* AVG + primary region */
  --chart-ma7:   var(--green);    /* 7D moving average */
  --chart-ma28:  var(--orange);   /* 28D moving average */
  --chart-hilo:  var(--sell);     /* HILO swatch/solid color */
  --chart-vol:        var(--bg3);          /* VOL bars — subtle background rectangles */
  --chart-vol-toggle: var(--text-bright);  /* VOL toggle when ON — neutral bright (no hue) */

  /* HILO band opacity variants — rust at low alpha for subtle bands */
  --chart-hilo-fade-border: rgba(193, 126, 101, 0.36);
  --chart-hilo-fade-fill:   rgba(193, 126, 101, 0.12);

  /* Multi-region per-region alphas — applied to the dynamic --region-N
   * hue in chart.ts via rgba() / blend math. Alphas are the only piece
   * that's tunable design-system-wide; the hue itself is per-region. */
  --chart-multi-vol-alpha:         0.15;  /* stacked volume bar fill (pre-blended over --bg → opaque rgb) */
  --chart-multi-vol-hover-alpha:   0.25;  /* hover bump, matches single-region --bg3 → --bg4 feel */
  --chart-multi-hilo-border-alpha: 0.35;  /* band hairline border */
  --chart-multi-hilo-fill-alpha:   0.10;  /* translucent fill between High and Low */
  --chart-multi-ma-alpha:          0.75;  /* dashed MA lines — subordinate to solid AVG */

  /* ── Multi-region overlay palette ─────────────────────────────────
   * Indexed palette used by chart-helpers.ts regionColor(i). Regions 0
   * and 1 alias the semantic palette (primary = accent, secondary = orange)
   * so they auto-track brightness presets. Regions 2-6 are independent
   * and get explicit overrides in each preset block below. */
  --region-0: var(--accent);
  --region-1: var(--orange);
  --region-2: #9a80c0;   /* violet */
  --region-3: #5ea8b0;   /* cyan-teal */
  --region-4: #c07888;   /* rose */
  --region-5: #a09560;   /* mustard */
  --region-6: #8d82c5;   /* indigo */

  --font-sans:   'Play', system-ui, sans-serif;
  --sidebar-w:      250px;
  --topbar-h:       38px;
  --ticker-h:       26px;

  /* ── Font size tiers (Medium default) ── */
  --sz-glyph:   9px;
  --sz-label:   11px;
  --sz-data:    13px;
  --sz-heading: 15px;

  /* Stat popover — pinned decomposition panel on aggregated stats.
   * Z-index ladder (top to bottom):
   *   .chart-tooltip[data-chart-tooltip] / .app-tooltip   9999   transient hover
   *   .stat-popover                                       9998   pinned panel
   *   .depth-section.depth-fullscreen                     9001   (inline)
   *   .chart-section.chart-fullscreen                     9000   (inline) */
  --z-stat-popover: 9998;
}
:root.size-sm {
  --sz-glyph: 8px; --sz-label: 10px; --sz-data: 12px; --sz-heading: 14px;
}
:root.size-lg {
  --sz-glyph: 10px; --sz-label: 12px; --sz-data: 14px; --sz-heading: 16px;
}

/* ── Brightness presets ───────────────────────────────────────────
 * Symmetric ±1.5 WCAG ratio shift on text, ±1.0 on semantic.
 *
 * RGBA COUPLING RULE: every preset block that overrides a base RGB
 * MUST also override the matching rgba variants with the new RGB
 * and the same opacity. --sell-fade, --sell-fade-line, --sell-fade-fill
 * all derive from --sell; --buy-* from --buy; --accent-bg/hover/line/select
 * from --accent; --red-fade from --red; --chart-hilo-fade-* from --sell.
 * Do not let the rgba values drift from their base on palette changes. */
:root.brightness-dim {
  /* text ladder */
  --text-muted: #2b3136;
  --text-dim: #636b72;
  --text: #737c83;
  --text-mid: #828a92;
  --text-bright: #a9b4bd;

  /* accent family */
  --accent-dim: #42759a;
  --accent: #4d84a9;

  /* semantic bases (--buy omitted: auto-tracks via var(--accent)) */
  --sell: #b17360;
  --sell-hi: #c17e65;
  --buy-hi: #528fb5;
  --green: #529252;
  --green-hi: #5c9e5c;
  --orange: #9e7b43;
  --orange-hi: #b0884a;
  --red: #b05858;
  --red-hi: #c06060;

  /* rgba variants (base RGB from dim preset, same opacities) */
  --sell-fade:      rgba(177, 115, 96, 0.3);
  --sell-fade-line: rgba(177, 115, 96, 0.8);
  --sell-fade-fill: rgba(177, 115, 96, 0.08);
  --buy-fade:       rgba(77, 132, 169, 0.3);
  --buy-fade-line:  rgba(77, 132, 169, 0.8);
  --buy-fade-fill:  rgba(77, 132, 169, 0.08);
  --red-fade:       rgba(176, 88, 88, 0.15);
  --accent-bg:      rgba(77, 132, 169, 0.06);
  --accent-line:    rgba(77, 132, 169, 0.2);
  --accent-hover:   rgba(77, 132, 169, 0.15);
  --accent-select:  rgba(77, 132, 169, 0.3);
  --chart-hilo-fade-border: rgba(177, 115, 96, 0.36);
  --chart-hilo-fade-fill:   rgba(177, 115, 96, 0.12);

  /* borders */
  --border: #121820;
  --border-hi: #1a232e;

  /* multi-region (regions 2-6 only; 0/1 auto-track via var references) */
  --region-2: #866bb6;
  --region-3: #4d969e;
  --region-4: #ad6676;
  --region-5: #8d8355;
  --region-6: #786bb8;
}

:root.brightness-hi {
  /* text ladder */
  --text-muted: #5c6366;
  --text-dim: #929ca5;
  --text: #9ea9b3;
  --text-mid: #abb6c0;
  --text-bright: #c4d0db;

  /* accent family */
  --accent-dim: #63a1c8;
  --accent: #6eaed4;

  /* semantic bases (--buy omitted: auto-tracks via var(--accent)) */
  --sell: #d28e72;
  --sell-hi: #dd9a80;
  --buy-hi: #7ab9dc;
  --green: #6bab6b;
  --green-hi: #78b878;
  --orange: #bf9451;
  --orange-hi: #ce9f5a;
  --red: #d17070;
  --red-hi: #db7f7f;

  /* rgba variants (base RGB from bright preset, same opacities) */
  --sell-fade:      rgba(210, 142, 114, 0.3);
  --sell-fade-line: rgba(210, 142, 114, 0.8);
  --sell-fade-fill: rgba(210, 142, 114, 0.08);
  --buy-fade:       rgba(110, 174, 212, 0.3);
  --buy-fade-line:  rgba(110, 174, 212, 0.8);
  --buy-fade-fill:  rgba(110, 174, 212, 0.08);
  --red-fade:       rgba(209, 112, 112, 0.15);
  --accent-bg:      rgba(110, 174, 212, 0.06);
  --accent-line:    rgba(110, 174, 212, 0.2);
  --accent-hover:   rgba(110, 174, 212, 0.15);
  --accent-select:  rgba(110, 174, 212, 0.3);
  --chart-hilo-fade-border: rgba(210, 142, 114, 0.36);
  --chart-hilo-fade-fill:   rgba(210, 142, 114, 0.12);

  /* borders */
  --border: #1e2832;
  --border-hi: #2c3a48;

  /* multi-region */
  --region-2: #ac96cc;
  --region-3: #77b8c0;
  --region-4: #cd8b9a;
  --region-5: #b2a674;
  --region-6: #a599cf;
}

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--sz-data);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'kern' 1, 'liga' 1;
}


/* ── Topbar ───────────────────────────────────────────────────────────────── */
.topbar {
  position: fixed; top: 0; left: 0; right: 0; height: var(--topbar-h);
  background: var(--bg2); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0; z-index: 100;
}
.topbar-brand {
  display: flex; align-items: center; gap: 8px;
  width: var(--sidebar-w);
  padding: 0 16px;
  flex-shrink: 0;
  border-right: 1px solid var(--border);
}
.topbar-main {
  display: flex; align-items: center; justify-content: space-between; flex: 1;
  padding: 0;
}
.app-title    { font-size: var(--sz-heading); font-weight: 700; color: var(--text-bright); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.beta-badge { font-size: var(--sz-heading); font-weight: 700; color: var(--accent); border: none; padding: 0; text-transform: uppercase; letter-spacing: 0.08em; vertical-align: baseline; line-height: 1; }

/* Status bar */
#status-bar { display: flex; align-items: center; gap: 10px; padding-right: 16px; }
.status-divider { color: var(--border); font-size: var(--sz-data); margin: 0 2px; }
.topbar-discord { color: var(--text-dim); display: flex; align-items: center; transition: color 0.15s; }
.topbar-discord:hover { color: var(--accent); }
.status-indicators { display: flex; align-items: center; gap: 16px; }
.status-pill { display: flex; align-items: center; gap: 5px; font-size: var(--sz-label); color: var(--text-dim); white-space: nowrap; text-transform: uppercase; letter-spacing: 0.08em; }
.status-dot { width: 6px; height: 6px; border-radius: 1px; flex-shrink: 0; }
.status-dot.green  { background: var(--green); }
.status-dot.yellow { background: var(--orange); }
.status-dot.red    { background: var(--red); }
.status-dot.pulse  { animation: dot-pulse 2s ease-in-out infinite; }
@keyframes dot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.loading-dots { display: inline-block; width: 2ch; text-align: left; }
.loading-dots::after {
  content: '';
  animation: dotReveal 2s steps(1, end) infinite;
  font-feature-settings: 'liga' 0;
  font-variant-ligatures: none;
}
/* Zero-width non-joiners (\200C) between dots prevent any ligature formation */
@keyframes dotReveal {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '.\200C.'; }
  75%  { content: '.\200C.\200C.'; }
}

/* SSO widget
   - Login button = CTA with full accent border (stands out)
   - Logged-in state = passive identity display with subtle left border (like a separator) */
.sso-widget { display: flex; align-items: stretch; height: var(--topbar-h); }

.sso-login-btn {
  display: inline-flex; align-items: center;
  height: var(--topbar-h); padding: 0 16px;
  font-size: var(--sz-label); text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--accent); text-decoration: none;
  border: 1px solid var(--accent-dim);
  background: transparent;
  transition: background-color 0.15s, border-color 0.15s;
}
.sso-login-btn:hover {
  background: var(--accent-hover);
  border-color: var(--accent);
}

.sso-char {
  display: flex; align-items: center; gap: 8px;
  height: var(--topbar-h); padding: 0 12px;
  border-left: 1px solid var(--border);
  background: transparent;
}
.sso-portrait { display: block; border-radius: 1px; }
.sso-name {
  font-size: var(--sz-label);
  color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em;
  white-space: nowrap;
}
.sso-logout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--sz-data);
  color: var(--text);
  background: none; border: none; cursor: pointer;
  padding: 0 4px; line-height: 1;
  transition: color 0.15s;
}
.sso-logout:hover { color: var(--red); }

/* When SSO widget is present, flush it to the topbar right edge */
#status-bar:has(#sso-widget) { padding-right: 0; }

/* Top nav — segmented buttons */
.top-nav { display: flex; gap: 0; height: var(--topbar-h); align-items: center; }
.nav-btn {
  padding: 0 16px; height: var(--topbar-h); font-size: var(--sz-label);
  background: transparent; border: none; border-right: 1px solid var(--border); color: var(--text);
  cursor: pointer; text-transform: uppercase; letter-spacing: 0.08em;
  display: flex; align-items: center;
  position: relative; transition: color 0.15s, background 0.15s;
}
.nav-btn:hover { color: var(--text-mid); background: var(--bg3); }
.nav-btn.active { color: var(--text-bright); background: var(--bg); }
/* Active bottom accent bar */
.nav-btn.active::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 1px;
  background: var(--accent);
}

.mobile-back-btn { display: none; }

/* Sidebar search */
.sidebar-search {
  position: sticky; top: 0; z-index: 11;
  height: var(--topbar-h); padding: 0; background: var(--bg3);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: stretch;
}
.search-wrap { position: relative; flex: 1; min-width: 0; display: flex; }
#search-input {
  width: 100%; padding: 0 52px 0 16px; font-size: var(--sz-data);
  background: transparent; border: none; color: var(--text-mid);
  outline: none; -webkit-appearance: none; appearance: none;
  color-scheme: dark;
}
#search-input:focus { border-color: var(--accent-dim); }
#search-input::placeholder { color: var(--text-dim); opacity: 1; }
#search-input:-webkit-autofill,
#search-input:-webkit-autofill:hover,
#search-input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--bg3) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
}
.search-save,
.search-clear {
  position: absolute; top: 50%; transform: translateY(-50%);
  background: none; border: none; color: var(--text-dim);
  cursor: pointer; font-size: 0; line-height: 0; padding: 0;
  font-family: inherit; width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
}
.search-save::before,
.search-save::after,
.search-clear::before,
.search-clear::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 1px;
  background-color: currentColor;
  transform-origin: center;
}
.search-save::before { transform: translate(-50%, -50%); }
.search-save::after { transform: translate(-50%, -50%) rotate(90deg); }
.search-clear::before { transform: translate(-50%, -50%) rotate(45deg); }
.search-clear::after { transform: translate(-50%, -50%) rotate(-45deg); }
.search-save { right: 28px; }
.search-clear { right: 6px; }
.search-save:hover,
.search-clear:hover { color: var(--text-mid); }
.search-save:disabled {
  color: var(--text-muted);
  cursor: not-allowed;
}
.tree-node.filter-hidden { display: none; }


/* ── Layout ───────────────────────────────────────────────────────────────── */
.layout {
  display: flex; padding-top: var(--topbar-h); height: calc(100vh - var(--ticker-h));
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  background: var(--bg2); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  height: 100%;
  position: relative;
}
#tree-container { flex: 1; overflow-y: auto; position: relative; padding-top: 6px; }
#quickbar-tree { flex: 1; overflow-y: auto; padding-top: 6px; }
/* Root-level tree group stagger on load */
#tree-container > .tree-node,
#quickbar-tree  > .tree-node { animation: fadeSlideIn 0.25s ease both; }
#tree-container > .tree-node:nth-child(1),
#quickbar-tree  > .tree-node:nth-child(1)  { animation-delay: 0.02s; }
#tree-container > .tree-node:nth-child(2),
#quickbar-tree  > .tree-node:nth-child(2)  { animation-delay: 0.04s; }
#tree-container > .tree-node:nth-child(3),
#quickbar-tree  > .tree-node:nth-child(3)  { animation-delay: 0.06s; }
#tree-container > .tree-node:nth-child(4),
#quickbar-tree  > .tree-node:nth-child(4)  { animation-delay: 0.08s; }
#tree-container > .tree-node:nth-child(5),
#quickbar-tree  > .tree-node:nth-child(5)  { animation-delay: 0.10s; }
#tree-container > .tree-node:nth-child(6),
#quickbar-tree  > .tree-node:nth-child(6)  { animation-delay: 0.12s; }
#tree-container > .tree-node:nth-child(7),
#quickbar-tree  > .tree-node:nth-child(7)  { animation-delay: 0.14s; }
#tree-container > .tree-node:nth-child(8),
#quickbar-tree  > .tree-node:nth-child(8)  { animation-delay: 0.16s; }
#tree-container > .tree-node:nth-child(9),
#quickbar-tree  > .tree-node:nth-child(9)  { animation-delay: 0.18s; }
#tree-container > .tree-node:nth-child(10),
#quickbar-tree  > .tree-node:nth-child(10) { animation-delay: 0.20s; }
#tree-container > .tree-node:nth-child(n+11),
#quickbar-tree  > .tree-node:nth-child(n+11) { animation-delay: 0.22s; }

/* Quickbar is auto-expanded, so children come with their parent — no independent per-category stagger */
#quickbar-tree .tree-children.open > .tree-node,
#quickbar-tree .type-item { animation: none; }
#tree-container.scroll-top { box-shadow: inset 0 8px 6px -6px rgba(0,0,0,0.4); }
#tree-container.scroll-bottom { box-shadow: inset 0 -8px 6px -6px rgba(0,0,0,0.4); }
#tree-container.scroll-top.scroll-bottom {
  box-shadow: inset 0 8px 6px -6px rgba(0,0,0,0.4), inset 0 -8px 6px -6px rgba(0,0,0,0.4);
}
/* Tree */
.tree-node { user-select: none; }
.tree-label {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 12px; cursor: pointer; font-size: var(--sz-data);
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border-left: 1px solid transparent; transition: background 0.1s;
}
.tree-label:hover { background: var(--bg3); color: var(--text-mid); }
.tree-label.active { color: var(--text-bright); border-left-color: var(--accent); }
.tree-label .arrow {
  font-size: var(--sz-data); color: var(--text-dim); width: 10px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: color 0.1s, transform 0.2s ease;
}
.tree-label button.arrow {
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.tree-label.tree-split-label { gap: 0; }
.tree-label.tree-split-label .arrow {
  align-self: stretch;
  min-width: 18px;
  margin: -4px 0 -4px -4px;
}
.tree-label.tree-split-label .tree-row-link {
  align-self: stretch;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  padding-left: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tree-label-text,
.quickbar-group-text {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tree-row-link .tree-count { flex-shrink: 0; }
.tree-label:hover .arrow { color: var(--text); }
.tree-label.open .arrow { transform: rotate(90deg); }
.tree-label.in-path { border-left-color: var(--border-hi); }
.tree-children { display: none; }
.tree-children.open { display: block; }
/* Stagger animation on tree children */
.tree-children.open > .tree-node { animation: fadeSlideIn 0.2s ease both; }
.tree-children.open > .tree-node:nth-child(1)  { animation-delay: 0s; }
.tree-children.open > .tree-node:nth-child(2)  { animation-delay: 0.02s; }
.tree-children.open > .tree-node:nth-child(3)  { animation-delay: 0.04s; }
.tree-children.open > .tree-node:nth-child(4)  { animation-delay: 0.06s; }
.tree-children.open > .tree-node:nth-child(5)  { animation-delay: 0.08s; }
.tree-children.open > .tree-node:nth-child(6)  { animation-delay: 0.10s; }
.tree-children.open > .tree-node:nth-child(7)  { animation-delay: 0.12s; }
.tree-children.open > .tree-node:nth-child(8)  { animation-delay: 0.14s; }
.tree-children.open > .tree-node:nth-child(9)  { animation-delay: 0.16s; }
.tree-children.open > .tree-node:nth-child(10) { animation-delay: 0.18s; }
.tree-children.open > .tree-node:nth-child(n+11) { animation-delay: 0.20s; }

/* Types list (leaf nodes) */
.type-item {
  display: block; padding: 3px 12px 3px 50px; cursor: pointer; font-size: var(--sz-data); /* left padding overridden by JS per depth */
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border-left: 1px solid transparent; transition: background 0.08s, color 0.08s;
  animation: fadeSlideIn 0.2s ease both; text-decoration: none;
}
.type-item:nth-child(1)  { animation-delay: 0s; }
.type-item:nth-child(2)  { animation-delay: 0.02s; }
.type-item:nth-child(3)  { animation-delay: 0.04s; }
.type-item:nth-child(4)  { animation-delay: 0.06s; }
.type-item:nth-child(5)  { animation-delay: 0.08s; }
.type-item:nth-child(6)  { animation-delay: 0.10s; }
.type-item:nth-child(7)  { animation-delay: 0.12s; }
.type-item:nth-child(8)  { animation-delay: 0.14s; }
.type-item:nth-child(9)  { animation-delay: 0.16s; }
.type-item:nth-child(10) { animation-delay: 0.18s; }
.type-item:nth-child(n+11) { animation-delay: 0.20s; }
.type-item:hover { background: var(--bg3); color: var(--text-mid); }
.type-item.active { color: var(--text-bright); border-left-color: var(--accent); }
.tree-count { color: var(--text-dim); font-size: var(--sz-label); margin-left: 4px; }
.tree-label-link { color: inherit; text-decoration: none; }

/* All Items top-level entry in the Browse tree. Carries .tree-label so it
   inherits padding, cursor, hover-transition, base colors, AND the 1px
   border-left width used by group rows (so the active-state left border
   matches in thickness, not just color). border-bottom acts as the divider
   from the market-group tree below — inside the row's hover box so hover
   fills edge-to-edge with no gap. Extra padding-bottom gives breathing
   room above the divider line. */
.tree-all-items {
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  padding-bottom: 6px;
}
.tree-all-items.active { border-left-color: var(--accent); }
.tree-all-items.in-path { border-left-color: var(--border-hi); }
/* Marker width-matched to .arrow (~10px) so "All Items" text aligns with
   the group-name column below. Font-size dropped to --sz-label so the
   filled square doesn't dominate. */
.tree-all-items .tree-all-items-marker {
  display: inline-block;
  width: 10px;
  text-align: center;
  color: var(--text-dim);
  font-size: var(--sz-label);
}
.tree-all-items .tree-label-link { color: inherit; }

.browse-searches-label,
.browse-groups-label {
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--sz-label);
}
.browse-searches-title,
.browse-groups-title {
  flex: 1 1 auto;
  min-width: 0;
}
.browse-search-section-actions,
.quickbar-section-actions {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  margin-left: 4px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.browse-searches-label:hover .browse-search-section-actions,
.browse-searches-label:focus-within .browse-search-section-actions,
.quickbar-section-label:hover .quickbar-section-actions,
.quickbar-section-label:focus-within .quickbar-section-actions {
  opacity: 1;
}
.browse-search-row {
  gap: 4px;
  position: relative;
  padding-left: 22px;
}
.browse-search-row[draggable="true"],
.browse-search-folder-label[draggable="true"] {
  cursor: grab;
}
.browse-search-row[draggable="true"]:active,
.browse-search-folder-label[draggable="true"]:active {
  cursor: grabbing;
}
.browse-search-link {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.browse-search-folder-label {
  gap: 0;
  position: relative;
}
.browse-search-folder-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.browse-search-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 2px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.browse-search-row:hover .browse-search-actions,
.browse-search-row:focus-within .browse-search-actions,
.browse-search-row.delete-armed .browse-search-actions,
.browse-search-folder-label:hover .browse-search-actions,
.browse-search-folder-label:focus-within .browse-search-actions,
.browse-search-folder-label.delete-armed .browse-search-actions {
  opacity: 1;
}
.browse-search-action {
  background-color: transparent;
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text);
  cursor: pointer;
  font-size: var(--sz-label);
  height: 18px;
  line-height: 1;
  min-width: 18px;
  padding: 0 4px;
}
.browse-search-action:hover,
.browse-search-action:focus-visible {
  background-color: var(--bg3);
  border-color: var(--border-hi);
  color: var(--text-mid);
}
.browse-search-delete:is(:hover, :focus-visible),
.browse-search-delete.armed,
.browse-search-folder-delete:is(:hover, :focus-visible),
.browse-search-folder-delete.armed {
  color: var(--red);
}
.browse-search-delete.armed,
.browse-search-folder-delete.armed {
  border-color: var(--red);
  min-width: 52px;
}
.browse-search-drop-before::before,
.browse-search-drop-after::after {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  height: 1px;
  background-color: var(--accent);
  pointer-events: none;
}
.browse-search-drop-before::before {
  top: 0;
}
.browse-search-drop-after::after {
  bottom: 0;
}
.browse-search-drop-into {
  border-left-color: var(--accent);
  background-color: var(--accent-bg);
}
.browse-search-drop-invalid {
  border-left-color: var(--red);
  color: var(--red);
}
.browse-search-editor {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px 6px 28px;
}
.browse-search-editor-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.browse-search-editor-label {
  color: var(--text-dim);
  font-size: var(--sz-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.browse-search-editor-input {
  width: 100%;
  min-width: 0;
  background-color: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text-mid);
  color-scheme: dark;
  font-size: var(--sz-data);
  padding: 4px 8px;
}
.browse-search-editor-input::placeholder {
  color: var(--text-dim);
  opacity: 1;
}
.browse-search-editor-input:focus,
.browse-search-editor-input:focus-visible {
  border-color: var(--accent);
  outline: none;
}
.browse-search-folder-editor {
  flex-direction: row;
  align-items: center;
  gap: 0;
  overflow: visible;
  flex-wrap: nowrap;
  padding-top: 4px;
  padding-right: 12px;
  padding-bottom: 4px;
}
.browse-search-folder-editor .arrow {
  pointer-events: none;
}
.browse-search-folder-name-input {
  flex: 1 1 0;
  width: auto;
}
.browse-search-folder-editor .browse-search-folder-actions {
  flex: 0 0 auto;
  margin-left: 4px;
}
.browse-search-folder-editor .browse-search-editor-feedback {
  flex: 1 0 100%;
  padding-left: 24px;
}
.browse-search-editor-actions {
  display: flex;
  gap: 4px;
}
.browse-search-editor-feedback {
  display: none;
  color: var(--red);
  font-size: var(--sz-label);
  line-height: 1.25;
}
.browse-search-editor-feedback.show {
  display: block;
}
.browse-search-editor-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text);
  cursor: pointer;
  font-size: var(--sz-label);
  letter-spacing: 0.08em;
  line-height: 1.2;
  padding: 5px 10px;
  text-transform: uppercase;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.browse-search-editor-btn:hover,
.browse-search-editor-btn:focus-visible {
  background-color: var(--bg3);
  border-color: var(--border-hi);
  color: var(--text-mid);
  outline: none;
}
.browse-search-editor-btn-primary {
  background-color: var(--bg2);
  border-color: var(--border);
  color: var(--text);
}

.loading-msg, .empty-msg { padding: 12px 16px; color: var(--text); font-size: var(--sz-data); }

.quickbar-section-label {
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--sz-label);
}
.quickbar-section-title {
  flex: 1 1 auto;
  min-width: 0;
}
.quickbar-folder-label {
  gap: 0;
  position: relative;
}
.quickbar-folder-label[draggable="true"] {
  cursor: grab;
}
.quickbar-folder-label[draggable="true"]:active {
  cursor: grabbing;
}
.quickbar-folder-link {
  min-width: 0;
}
.quickbar-folder-name {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.quickbar-folder-name-input {
  flex: 1 1 auto;
  min-width: 0;
  background-color: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text-mid);
  font-size: var(--sz-data);
  padding: 4px 8px;
  color-scheme: dark;
}
.quickbar-folder-name-input::placeholder {
  color: var(--text-dim);
  opacity: 1;
}
.quickbar-folder-name-input:focus,
.quickbar-folder-name-input:focus-visible {
  border-color: var(--accent);
  outline: none;
}
.quickbar-folder-actions {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  margin-left: 4px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.quickbar-folder-label:hover .quickbar-folder-actions,
.quickbar-folder-label:focus-within .quickbar-folder-actions {
  opacity: 1;
}
.quickbar-folder-action {
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background-color: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: var(--sz-label);
  line-height: 1;
}
.quickbar-folder-action:hover,
.quickbar-folder-action:focus-visible {
  color: var(--text-mid);
  border-color: var(--border-hi);
  background-color: var(--bg3);
}
.quickbar-folder-delete {
  min-width: 18px;
}
.quickbar-folder-delete:is(:hover, :focus-visible) {
  color: var(--red);
}
.quickbar-folder-item {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 12px 0 0;
}
.quickbar-folder-item-link {
  align-self: stretch;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 3px;
  padding-bottom: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: inherit;
  text-decoration: none;
}
.quickbar-folder-item-remove {
  flex: 0 0 auto;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background-color: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: var(--sz-label);
  line-height: 1;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.quickbar-folder-item:hover .quickbar-folder-item-remove,
.quickbar-folder-item:focus-within .quickbar-folder-item-remove {
  opacity: 1;
}
.quickbar-folder-item-remove:hover,
.quickbar-folder-item-remove:focus-visible {
  color: var(--red);
  border-color: var(--border-hi);
  background-color: var(--bg3);
}
.quickbar-drop-target {
  border-left-color: var(--accent);
  background-color: var(--accent-bg);
}
.type-item.quickbar-drop-target {
  border-left-color: var(--accent);
  background-color: var(--accent-bg);
}
.quickbar-drop-copy {
  border-left-color: var(--green);
}
.quickbar-drop-invalid {
  border-left-color: var(--red);
  color: var(--red);
}
.quickbar-folder-drop-before::before,
.quickbar-folder-drop-after::after {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  height: 1px;
  background-color: var(--accent);
  pointer-events: none;
}
.quickbar-folder-drop-before::before {
  top: 0;
}
.quickbar-folder-drop-after::after {
  bottom: 0;
}
.quickbar-folder-drop-into {
  border-left-color: var(--accent);
  background-color: var(--accent-bg);
}

/* Inline-style replacements — used by TS modules */
.chart-empty-msg { display: flex; align-items: center; justify-content: center; height: 100%; }
.chart-empty-msg span { color: var(--text); font-size: var(--sz-data); }
.type-item-size { font-size: var(--sz-data); }
.btn-disabled { opacity: 0.5; pointer-events: none; }

/* ── Main panel ───────────────────────────────────────────────────────────── */
.main-panel { flex: 1; overflow-y: auto; padding: 16px 22px 22px; }

/* Breadcrumb */
.breadcrumb { padding: 4px 0 6px; font-size: var(--sz-label); color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em; animation: fadeIn 0.25s ease; }
.breadcrumb span, .breadcrumb .bc-link { cursor: pointer; transition: color 0.1s; }
.breadcrumb span:hover, .breadcrumb .bc-link:hover { color: var(--text-mid); }
.bc-link { color: inherit; text-decoration: none; }
.breadcrumb .bc-current { cursor: default; }
.breadcrumb .bc-current:hover { color: inherit; }
.breadcrumb .bc-sep { font-size: var(--sz-data); color: var(--text-dim); margin: 0 5px; cursor: default; }
.breadcrumb .bc-sep:hover { color: var(--text-dim); }

/* Item header */
.item-header {
  display: flex; align-items: baseline; gap: 8px;
  margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid var(--border);
  animation: fadeSlideDown 0.3s ease;
}
.item-header h2 { font-size: var(--sz-heading); font-weight: 700; color: var(--text-bright); letter-spacing: 0.08em; text-transform: uppercase; }
#item-meta, #cat-meta { font-size: var(--sz-label); color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em; }

/* ── Item view flex layout ────────────────────────────────────────────────── */
#item-view {
  display: flex;
  flex-direction: column;
  /* 100vh minus topbar, ticker, and main-panel padding (16px top + 22px bottom) */
  height: calc(100vh - var(--topbar-h) - var(--ticker-h) - 16px - 22px);
  /* Hard containment: any brief overflow during depth-chart transitions or wide
   * filter-bar wrapping must never propagate up to main-panel's overflow-y: auto. */
  overflow: hidden;
}
#item-view > .breadcrumb,
#item-view > .item-header {
  flex-shrink: 0;
}
#category-view {
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--topbar-h) - var(--ticker-h) - 16px - 22px);
}
#category-view > .breadcrumb,
#category-view > .item-header {
  flex-shrink: 0;
}
/* Category view has a non-scrolling outer wrapper so the corner-tick pseudo-
   elements (which are position:absolute) stay pinned to the viewport corners
   instead of scrolling with the scroll container's content. The inner
   #cat-table-wrap is the actual scroll container. */
#category-view > .table-wrap-outer {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}
#category-view > .table-wrap-outer > .table-wrap {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
#category-view .table-wrap.loaded {
  animation: fadeSlideIn 0.3s ease both;
}

/* Chart section — 35% of item-view */
.chart-section {
  flex: 0 0 35%;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  overflow: visible;
  transition: flex-basis 0.25s ease, min-height 0.25s ease, opacity 0.2s ease;
}
.chart-section[hidden] {
  display: none !important;
}
@keyframes chartPanelOn {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
@keyframes chartPanelOff {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}
.chart-section.chart-fullscreen {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  z-index: 9000;
  background-color: var(--bg);
  flex: none;
  min-height: unset;
  overflow: visible;
  padding: 12px 20px;
  animation: chartPanelOn 0.4s ease-out forwards;
}
.chart-section.chart-closing {
  animation: chartPanelOff 0.3s ease-in forwards;
}
.chart-section.chart-fullscreen .item-chart-wrap {
  flex: 1;
}
.chart-section.chart-fullscreen .chart-fullscreen-btn {
  display: none;
}
.chart-fullscreen-close {
  display: none;
  border: 1px solid var(--border);
  background-color: var(--bg2);
  color: var(--text);
  font-size: var(--sz-label);
  padding: 5px 10px;
  line-height: 1.2;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-radius: 2px;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.chart-fullscreen-close .close-icon {
  font-size: var(--sz-data);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  height: 1em;
}
.chart-fullscreen-close:hover { color: var(--text-mid); border-color: var(--border-hi); background-color: var(--bg3); }
.chart-section.chart-fullscreen .chart-fullscreen-close {
  display: inline-flex;
}
.chart-section .item-chart-wrap {
  flex: 1;
  min-height: 0;
  height: auto;
}

#item-view.history-hidden #orders-section {
  flex: 1 1 auto;
}

/* ── Flip wrapper ──────────────────────────────────────────────────────── */
/* View-state wrapper — three-state grid drawer:
 *   default (chart):  grid-template-columns: 1fr 0fr   → chart 100%, table 0
 *   .flipped (table):  grid-template-columns: 0fr 1fr   → chart 0, table 100%
 *   .split    (both):  grid-template-columns: 1fr 1fr   → 50/50
 * Transitions between any two states animate fr-values smoothly so the user
 * sees "drawers" slide open or closed. Modern browsers animate fr values
 * natively (Chrome/Firefox/Safari, 2023+). */
.chart-flip-wrapper {
  flex: 1;
  min-height: 0;
  display: grid;
  /* Entry animation mirrors .orders-column — both chart and table faces
   * slide in together on page load, synced with the orders grid below. */
  animation: fadeSlideIn 0.3s ease 0.15s both;
  /* minmax(0, Nfr) lets the 0fr track truly collapse to zero width —
   * without it, CSS Grid's default min-content floor leaves a tiny sliver
   * of the "hidden" face visible at the edge. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 0fr);
  grid-template-rows: 1fr;
  /* Explicit column-gap longhand (not the `gap` shorthand) — some older
   * browsers skip interpolating the shorthand in transitions but animate
   * column-gap reliably. 0.4s matches grid-template-columns so entering/
   * leaving BOTH opens/closes the gap smoothly alongside the drawer slide. */
  column-gap: 0;
  /* 0.25s ease matches the depth chart's panel expand/collapse (design
   * system convention: panel animations). */
  transition: grid-template-columns 0.25s ease,
              column-gap 0.25s ease;
  overflow: hidden;
}
.chart-flip-wrapper.flipped {
  grid-template-columns: minmax(0, 0fr) minmax(0, 1fr);
}
.chart-flip-wrapper.split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 20px;  /* matches .orders-grid sell/buy separation; animates from 0 */
}
.flip-face {
  overflow: hidden;
  min-width: 0;
  min-height: 0;
}
.flip-face-back {
  display: flex;
  flex-direction: column;
}
/* Override .item-chart-wrap's base clamp(160-340px) height and 4px bottom margin.
 * The face is a grid cell; the base clamp would over-constrain its height.
 * position: relative keeps the chart tooltip (absolutely positioned inside)
 * anchored to this container — otherwise it resolves against the viewport. */
.chart-flip-wrapper #item-history {
  width: 100%;
  height: 100%;
  margin: 0;
  position: relative;
}
@media (prefers-reduced-motion: reduce) {
  .chart-flip-wrapper { transition: none; }
}

/* ── History table ─────────────────────────────────────────────────────── */
#item-history-table .table-wrap-outer {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
#item-history-table .table-wrap {
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.history-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: var(--sz-data);
}
.history-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}
.history-table td {
  padding: 4px 10px;
  color: var(--text);
  white-space: nowrap;
}
/* Multi-region primary-only indicator columns (LOW/HIGH/VOL/ORDERS/MAs) —
 * mirrors the chart tooltip's .dim-row treatment. The color signals that
 * the data represents only the primary region, not the full multi-region
 * selection. Accepted design-system extension of the existing .dim-row
 * pattern for non-primary overlay data. */
.history-table th.dim-primary,
.history-table td.dim-primary {
  color: var(--text-muted);
}
/* Row hover inherited from global `tbody tr:hover { background: var(--bg3) }` —
 * matches orders/category tables; don't override or the hover becomes invisible. */
/* Per-region color indicator — used by the history-table multi-region
 * column headers and the multi-region chart tooltip. 8x8 square, inline
 * with the region name, margin-right spaces it from the label text.
 * translateY(-1px) compensates for vertical-align: middle aligning to
 * the x-height midpoint — which sits low under all-caps labels (cap-
 * height optical center is ~1px higher). Without this, the swatch
 * reads as "floating below" the region name in both surfaces. */
.region-swatch {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 5px;
  vertical-align: middle;
  transform: translateY(-1px);
  border-radius: 1px;
}
/* Truncate multi-region column header region names — the metric suffix
 * (AVG/HIGH/LOW/VOL/ORD/MA) stays visible, the region name clips with
 * ellipsis. Hover shows the full name via the existing [data-tip] global
 * tooltip. 55px lands below DOMAIN's natural width so every region name
 * truncates uniformly (no mix of full + clipped names across columns),
 * giving multi-region columns a consistent visual slot.
 *
 * Structure: <span.region-label> wraps <span.region-name> + suffix text
 * as an inline-flex container with align-items: baseline. This sidesteps
 * the inline-block + overflow:hidden baseline quirk — where the span's
 * baseline shifts to the bottom margin edge and no vertical-align value
 * cleanly aligns the truncated name with the adjacent suffix. Flex items
 * use their first-baseline (text baseline) for alignment regardless of
 * overflow property, so name + suffix sit on the same line. */
.history-table thead th .region-label {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
.history-table thead th .region-name {
  max-width: 55px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Orders section — 65% of item-view */
.orders-section {
  flex: 1 1 65%;
  overflow: hidden;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin-top: 10px;
}

/* Side-by-side orders layout */
.orders-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  align-items: stretch;
  flex: 1;
  min-height: 0;
}
.orders-column { min-width: 0; animation: fadeSlideIn 0.3s ease 0.15s both; display: flex; flex-direction: column; min-height: 0; }
.orders-column:last-child { animation-delay: 0.25s; }
.orders-column .table-wrap-outer { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.orders-column .table-wrap { flex: 1; min-height: 0; overflow-y: auto; }

/* Section labels — left border bar with trailing line */
/* Section titles hidden — order counts moved to stats bar */
.section-title { display: none; }

/* Tables */
.table-wrap {
  overflow-x: auto; border: 1px solid var(--border); background: var(--bg2); margin-bottom: 16px;
  position: relative;
}
.table-wrap:last-child { margin-bottom: 0; }
.table-wrap-outer {
  position: relative;
}
/* Corner tick marks live on the non-scrolling table frame so they stay pinned
   to the visible table corners, matching the category/all-items table. */
.table-wrap-outer::before,
.table-wrap-outer::after {
  content: ''; position: absolute;
  width: 5px; height: 5px;
  border-color: var(--text-muted); border-style: solid;
  pointer-events: none; z-index: 2;
}
.table-wrap-outer::before { top: 3px; left: 3px; border-width: 1px 0 0 1px; }
.table-wrap-outer::after  { bottom: 3px; right: 3px; border-width: 0 1px 1px 0; }

table { width: 100%; border-collapse: collapse; }
td, th { font-variant-numeric: tabular-nums; }
thead th {
  background: var(--bg3); padding: 6px 10px; text-align: left;
  font-size: var(--sz-label); color: var(--text); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  border-bottom: 1px solid var(--border); white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
}

tbody tr { border-bottom: 1px solid rgba(255, 255, 255, 0.015); transition: background 0.08s; }
tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.006); }
tbody tr:hover { background: var(--bg3); }
tbody tr:hover .col-item { color: var(--text-mid); }
/* Row stagger animation */
tbody tr { animation: rowFadeIn 0.15s ease both; }
tbody tr:nth-child(1)  { animation-delay: 0s; }
tbody tr:nth-child(2)  { animation-delay: 0.015s; }
tbody tr:nth-child(3)  { animation-delay: 0.03s; }
tbody tr:nth-child(4)  { animation-delay: 0.045s; }
tbody tr:nth-child(5)  { animation-delay: 0.06s; }
tbody tr:nth-child(6)  { animation-delay: 0.075s; }
tbody tr:nth-child(7)  { animation-delay: 0.09s; }
tbody tr:nth-child(8)  { animation-delay: 0.105s; }
tbody tr:nth-child(9)  { animation-delay: 0.12s; }
tbody tr:nth-child(10) { animation-delay: 0.135s; }
tbody tr:nth-child(n+11) { animation-delay: 0.15s; }

tbody td {
  padding: 6px 10px; font-size: var(--sz-data); text-align: left;
  white-space: nowrap; color: var(--text); line-height: 1.4;
}

.vol-total  { color: var(--text); }
.col-dim    { color: var(--text-dim); }

/* ── Chart toolbar ────────────────────────────────────────────────────────── */
.chart-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  animation: fadeIn 0.3s ease 0.05s both;
  padding: 4px 0;
  margin-bottom: 4px;
  position: relative;
  z-index: 10;
  flex-shrink: 0;
}
/* ── Region dropdown (custom multi-select) ──────────────────────────────── */
.region-dropdown {
  position: relative;
  display: inline-block;
}
.region-dropdown-btn {
  position: relative;
  background-color: var(--bg2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 4px 24px 4px 8px;
  font-size: var(--sz-data);
  cursor: pointer;
  white-space: nowrap;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.region-dropdown-btn::after {
  content: '\25BE';
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-dim);
  font-size: var(--sz-data);
  pointer-events: none;
  transition: color 0.15s, transform 0.15s;
}
.region-dropdown-btn:hover { color: var(--text-mid); border-color: var(--border-hi); background-color: var(--bg3); }
.region-dropdown-btn:hover::after { color: var(--text-mid); }
.region-dropdown-btn:focus { outline: none; border-color: var(--accent-dim); }
/* Open state — panel is visible */
.region-dropdown:has(.region-dropdown-panel:not(.hidden)) .region-dropdown-btn {
  border-color: var(--accent);
  color: var(--text-bright);
}
.region-dropdown:has(.region-dropdown-panel:not(.hidden)) .region-dropdown-btn::after {
  color: var(--accent);
  transform: translateY(-50%) rotate(180deg);
}
.region-dropdown-panel {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 2px;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  min-width: 200px;
  max-height: 300px;
  overflow: hidden;
  z-index: 100;
  display: flex;
  flex-direction: column;
}
.region-dropdown-items {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}
.region-dropdown-options { display: contents; }
.region-dropdown-panel.hidden { display: none; }
.region-dropdown-search {
  display: block;
  width: 100%;
  margin: 0;
  padding: 6px 12px;
  background-color: var(--bg3);
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  color: var(--text-mid);
  font-size: var(--sz-data);
  line-height: 1.4;
  outline: none;
  flex-shrink: 0;
}
.region-dropdown-search::placeholder {
  color: var(--text-dim);
  opacity: 1;
}
.region-dropdown-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  font-size: var(--sz-data);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
/* First/last items get extra vertical padding (symmetric) so hover fills all the way to the edges */
.region-dropdown-items > .region-dropdown-item:first-child { padding-top: 6px; padding-bottom: 6px; }
.region-dropdown-items > .region-dropdown-item:last-child { padding-top: 6px; padding-bottom: 6px; }
.region-dropdown-item:hover { background-color: var(--bg3); }
.region-dropdown-item input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  cursor: pointer;
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  background-color: var(--bg);
  border: 1px solid var(--border);
  border-radius: 1px;
  position: relative;
}
.region-dropdown-item input[type="checkbox"]:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}
.region-dropdown-item input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 3px;
  top: 0px;
  width: 4px;
  height: 7px;
  border: solid var(--bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.region-dropdown-sep {
  border: none;
  border-top: 1px solid var(--border);
  margin: 0;
}
/* Sliding tumbler period selector */
.chart-period-btns,
.scope-period-btns {
  display: flex;
  position: relative;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0;
}
/* Shared tumbler track — used by chart period selector + settings S/M/L tumbler.
 * Extends 1px above and below so its accent border REPLACES the container's gray
 * border at the active button's extent (no double-border effect). Side effect:
 * active button is 2px taller visually than non-active — acceptable trade-off. */
.chart-period-btns .tumbler-track,
.scope-period-btns .tumbler-track,
.settings-tumbler .tumbler-track,
.chart-view-btns .tumbler-track {
  position: absolute;
  top: -1px;
  left: 0;
  height: calc(100% + 2px);
  background-color: var(--bg3);
  border: 1px solid var(--accent);
  border-radius: 2px;
  transition: left 0.2s ease, width 0.2s ease;
  pointer-events: none;
  z-index: 1;
}
.chart-period-btn,
.scope-period-btn {
  background: none;
  color: var(--text);
  border: none;
  border-right: 1px solid var(--border);
  padding: 5px 10px;
  font-size: var(--sz-label);
  cursor: pointer;
  position: relative;
  z-index: 2;
  transition: color 0.15s, background 0.15s;
}
.chart-period-btn:last-child,
.scope-period-btn:last-child { border-right: none; }
.chart-period-btn:not(.active):hover,
.scope-period-btn:not(.active):hover { color: var(--text-mid); background-color: var(--bg3); }
.chart-period-btn.active,
.scope-period-btn.active { color: var(--accent); border-right-color: transparent; }
/* Hide the predecessor's border-right so the track's left accent shows through */
.chart-period-btn:has(+ .chart-period-btn.active),
.scope-period-btn:has(+ .scope-period-btn.active) { border-right-color: transparent; }

/* View-mode tumbler — mirrors .chart-period-btns layout */
.chart-view-btns {
  display: flex;
  position: relative;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0;
}
.chart-view-btn {
  background: none;
  color: var(--text);
  border: none;
  border-right: 1px solid var(--border);
  padding: 5px 10px;
  font-size: var(--sz-label);
  cursor: pointer;
  position: relative;
  z-index: 2;
  transition: color 0.15s, background 0.15s;
}
.chart-view-btn:last-child { border-right: none; }
.chart-view-btn:not(.active):hover { color: var(--text-mid); background-color: var(--bg3); }
.chart-view-btn.active { color: var(--accent); border-right-color: transparent; }
.chart-view-btn:has(+ .chart-view-btn.active) { border-right-color: transparent; }

/* ── Price history chart ──────────────────────────────────────────────────── */
.item-chart-wrap {
  position: relative;
  height: clamp(160px, calc((100vh - var(--topbar-h)) * 0.33), 340px);
  margin-bottom: 4px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 6px 8px 4px;
  animation: fadeIn 0.3s ease 0.1s both;
}
/* When inside chart-section, let flex control the height */
.chart-section .item-chart-wrap {
  height: auto;
  flex: 1;
  min-height: 0;
  margin-bottom: 0;
}
/* Corner tick marks */
.item-chart-wrap::before,
.item-chart-wrap::after {
  content: '';
  position: absolute;
  width: 5px; height: 5px;
  border-color: var(--text-muted);
  border-style: solid;
  pointer-events: none;
  z-index: 1;
}
.item-chart-wrap::before { top: 3px; left: 3px; border-width: 1px 0 0 1px; }
.item-chart-wrap::after  { bottom: 3px; right: 3px; border-width: 0 1px 1px 0; }

/* Chart tooltip — HTML (external) tooltip rendered into the chart wrapper.
 * Replaces Chart.js native canvas tooltip so we get crisp column alignment via
 * grid + tabular-nums and full theme integration. */
.chart-tooltip {
  /* Base rule — used by tooltips appended INSIDE a chart wrap element
   * (depth chart). Wrap-relative positioning (caretX/caretY offsets)
   * works with position: absolute. The history chart's body-attached
   * variant (see .chart-tooltip[data-chart-tooltip] below) overrides to
   * position: fixed with viewport coords for its separate use case. */
  position: absolute;
  pointer-events: none;
  z-index: 10;
  /* --bg (page background tier, darkest) — vol bars are bg3, vol hover bg4, so the
   * tooltip uses the darkest tier to clearly read as a distinct floating overlay. */
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 8px 10px;
  font-size: var(--sz-data);
  color: var(--text);
  opacity: 0;
  transition: opacity 0.1s ease;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* History chart tooltip — body-attached variant, tagged with the
 * data-chart-tooltip attribute. position: fixed escapes chart-wrap
 * ancestors that clip for the flip animation (.chart-flip-wrapper,
 * .flip-face), and lets a tall multi-region tooltip with every toggle
 * on extend into free viewport space above/below the chart without
 * getting cropped. z-index: 9999 matches the .app-tooltip tier — both
 * are body-attached tooltips that need to clear chart-fullscreen (9000)
 * and depth-fullscreen (9001) overlays. */
.chart-tooltip[data-chart-tooltip] {
  position: fixed;
  z-index: 9999;
}
.chart-tooltip-title {
  font-weight: 700;
  color: var(--text-bright);
  margin-bottom: 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.chart-tooltip-rows {
  display: grid;
  grid-template-columns: auto 1fr auto;
  column-gap: 12px;
  row-gap: 2px;
  align-items: center;
}
.chart-tooltip-swatch {
  width: 8px;
  height: 8px;
  display: inline-block;
}
.chart-tooltip-label {
  color: var(--text);
}
.chart-tooltip-value {
  color: var(--text);
  text-align: right;
}
/* Multi-region: indicator rows (Vol/MAs/Hi/Lo) only carry primary region data,
 * so they're dimmed to communicate "not part of your multi-region selection".
 * The .dim-row class is applied directly to each grid cell (swatch/label/value)
 * since they're flat siblings in the grid, not nested under a row wrapper. */
.chart-tooltip-label.dim-row,
.chart-tooltip-value.dim-row {
  color: var(--text-muted);
}
/* Placeholder for days where no dataset has a value — spans the grid so it
 * centers cleanly in the tooltip body. */
.chart-tooltip-no-data {
  grid-column: 1 / -1;
  color: var(--text-dim);
  text-align: center;
  padding: 2px 0;
}
/* Multi-region columnar tooltip table. Wrapped in .chart-tooltip-multi-wrap
 * so it reads as a proper table (border + corner ticks, mirroring table frames).
 * Thead th inherits most of its styling from the global thead th rule — dark
 * background, uppercase, letter-spacing, sticky, border-bottom, 700 weight,
 * --sz-label font-size. Only color (softer) and font-size scope are overridden.
 * Missing-data tbody cells use --text-muted, matching .dim-row/.chart-tooltip-
 * orders.dim-row for suppressed tooltip data. All values via CSS vars so both
 * brightness and font-size presets propagate. */
.chart-tooltip-multi-wrap {
  position: relative;
  border: 1px solid var(--border);
  background: var(--bg2);
  margin-top: 2px;
}
.chart-tooltip-multi-wrap::before,
.chart-tooltip-multi-wrap::after {
  content: ''; position: absolute;
  width: 5px; height: 5px;
  border-color: var(--text-muted); border-style: solid;
  /* z-index: 2 is load-bearing — the inner <thead th> inherits the global
   * `thead th { position: sticky; z-index: 1 }` rule (style.css:801-807),
   * which creates a stacking context that would otherwise paint over these
   * corner ticks. Keeping the pseudos above by one tier. */
  pointer-events: none; z-index: 2;
}
.chart-tooltip-multi-wrap::before { top: 3px; left: 3px; border-width: 1px 0 0 1px; }
.chart-tooltip-multi-wrap::after  { bottom: 3px; right: 3px; border-width: 0 1px 1px 0; }

.chart-tooltip-multi {
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: var(--sz-label);
}
.chart-tooltip-multi th,
.chart-tooltip-multi td {
  padding: 4px 10px;
  text-align: left;
  color: var(--text);
  white-space: nowrap;
}
/* Row labels are <th> in <tbody> — browser default bold is wrong here;
 * metric row headers should read at normal weight (thead column headers
 * stay bold via the global thead th rule). Color stays --text (inherited
 * from the .chart-tooltip-multi th,td base rule) matching single-region's
 * .chart-tooltip-label and the main history table's thead. */
.chart-tooltip-multi .chart-tooltip-metric {
  font-weight: 400;
}
.chart-tooltip-multi td.dim {
  color: var(--text-muted);
}

.col-minvol { color: var(--text); }
.col-loc    { width: 100%; max-width: 200px; overflow: hidden; }
.col-issued { color: var(--text); }

/* Location cell contents */
.loc-cell { display: flex; align-items: center; gap: 4px; overflow: hidden; position: relative; }
.loc-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Restricted structure indicator */
.loc-restricted { opacity: 0.5; }
.restricted-mark { color: var(--orange); font-size: var(--sz-data); flex-shrink: 0; cursor: default; line-height: 1; }
/* Global app tooltip — a single element lifted to <body>, positioned via JS
 * (see static/src/tooltip.ts). Escapes all overflow ancestors, replaces the
 * broken CSS pseudo tooltip (which was clipped by .loc-cell / .col-loc's
 * overflow: hidden) AND the browser-native title="" tooltips with a themed
 * version matching the chart tooltip aesthetic. */
.app-tooltip {
  position: fixed;
  pointer-events: none;
  z-index: 9999;
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 4px 10px;
  font-size: var(--sz-data);
  color: var(--text);
  opacity: 0;
  transition: opacity 0.1s ease;
  max-width: 320px;
  line-height: 1.4;
  overflow-wrap: break-word;
  font-variant-numeric: tabular-nums;
}
.app-tooltip.visible { opacity: 1; }
.btn-copy {
  flex-shrink: 0; opacity: 0; padding: 0 4px; font-size: var(--sz-label); line-height: 1;
  background: transparent;
  border: none; color: var(--text-dim);
  cursor: pointer; transition: opacity 0.1s;
  display: flex; align-items: center;
}
tr:hover .btn-copy { opacity: 1; }
.btn-copy:hover { color: var(--accent); }
.btn-copy.copied { color: var(--green); opacity: 1; }

/* Price colours */
.price-sell { color: var(--sell); }
.price-buy  { color: var(--buy); }

/* Security status colours */
.sec-hi   { color: var(--green); }
.sec-lo   { color: var(--orange); }
.sec-null { color: var(--red); }
.sec-wh   { color: var(--text-dim); }

/* Expand/collapse rows */
.row-preview-hidden { display: none; }

/* ── Arbitrage calculator ─────────────────────────────────────────────────── */
.arb-filters {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  margin-bottom: 20px; padding: 10px 14px;
  background: var(--bg2); border: 1px solid var(--border);
}
.filter-group { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.filter-sep   { width: 1px; background: var(--border); align-self: stretch; min-height: 38px; margin: 0 4px; }
.arb-filters button {
  padding: 5px 20px; font-size: var(--sz-label);
  background: var(--accent-bg); border: 1px solid var(--accent-dim); color: var(--accent);
  cursor: pointer; border-radius: 2px; align-self: flex-end;
  text-transform: uppercase; letter-spacing: 0.08em;
  transition: background 0.15s, border-color 0.15s;
}
.arb-filters button:hover { background: var(--accent-hover); border-color: var(--accent); }
.arb-filters button:disabled { opacity: 0.5; cursor: default; }
.arb-filters label {
  display: flex; flex-direction: column; gap: 3px;
  font-size: var(--sz-label); color: var(--text-dim); text-transform: uppercase; letter-spacing: .08em;
}
.arb-filters input, .arb-filters select {
  padding: 4px 8px; font-size: var(--sz-data);
  background-color: var(--bg2); border: 1px solid var(--border); color: var(--text-mid);
  border-radius: 2px; -webkit-appearance: none; appearance: none; color-scheme: dark;
  font-variant-numeric: tabular-nums;
}
.arb-filters input { width: 120px; }
.arb-filters select { width: 170px; }
.arb-filters input:focus, .arb-filters select:focus { border-color: var(--accent-dim); outline: none; }
.arb-filters input::placeholder { color: var(--text-dim); opacity: 1; }
.arb-filters input:-webkit-autofill,
.arb-filters input:-webkit-autofill:hover,
.arb-filters input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--bg2) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
}
.jumps-primary   { color: var(--text-bright); }
.jumps-secondary { font-size: var(--sz-label); color: var(--text-dim); }

.arb-summary { margin-bottom: 8px; font-size: var(--sz-label); color: var(--text-dim); }
.col-item { width: 100%; text-align: left !important; cursor: pointer; }
.col-item-link { color: inherit; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: inline-block; max-width: 100%; vertical-align: middle; }
.col-item-link:hover { color: inherit; }

/* VirtualList spacer rows — pure height, no padding/border. The inner <td>
   also has line-height: 0 + font-size: 0 so it can't grow from intrinsic
   line-box sizing when the spacer asks for height: 0 (top spacer on initial
   render). Without this, a line-box inherits the cell's line-height (~1.4 ×
   font-size = ~15 px) and pushes the first real row off Playwright's
   visibility check. */
.virt-spacer,
.virt-spacer > td {
  padding: 0 !important;
  border: 0 !important;
  line-height: 0 !important;
  font-size: 0 !important;
}

/* Disable the global rowFadeIn animation on category rows. VirtualList
   re-renders the viewport on every scroll frame; re-triggering a 0.15s
   fade each time produces visible flicker. Group/order tables keep the
   animation since they render once, not continuously. */
#cat-tbody tr { animation: none; }

/* Fixed table layout for the category table — prevents column-width drift as
   VirtualList recycles rows with different content lengths during scroll.
   Per-column widths are set via inline styles by _buildCatThead, computed
   from actual data via _measureColumnWidths in category-view.ts.
   Only col-star and col-sparkline have CSS widths: they don't vary with data,
   and the skeleton thead (rendered before data arrives) needs them pinned
   so the loading state doesn't reshuffle layout once measurement finishes. */
#cat-table { table-layout: fixed; width: 100%; }
#cat-table th.col-star { width: 28px; }
#cat-table th.col-sparkline { width: 80px; }

.col-total { min-width: 100px; color: var(--buy); }
.col-margin-hi   { color: var(--green); }
.col-margin-mid  { color: var(--orange); }
.col-margin-lo   { color: var(--text); }
.jumps-lo      { color: var(--green); }
.jumps-mid     { color: var(--orange); }
.jumps-hi      { color: var(--sell); }
.jumps-unknown { color: var(--text-dim); }

/* Route type colours — X/X/X in Arb V2 jumps column */
.col-jumps { min-width: 80px; white-space: nowrap; }
.route-any    { color: var(--red); }     /* red    — any sec (fastest) */
.route-lowsec { color: var(--orange); }  /* orange — low+hi sec */
.route-hisec  { color: var(--green); }   /* green  — hi-sec only */
.route-none   { color: var(--text-dim); }  /* dim    — unreachable */

/* Sortable column headers — arrow always inline (transparent) to reserve space, no layout shift */
th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable:hover { color: var(--text-mid); }
th.sort-asc, th.sort-desc,
th.sort-asc:hover, th.sort-desc:hover { color: var(--text-bright); }
/* Reserve sort-arrow slot on ALL thead cells (not just .sortable) so sortable and
 * non-sortable tables have identical header heights. Non-sortable cells keep the
 * pseudo-element invisible via color: transparent. */
thead th::after { content: ' \25BE'; font-size: var(--sz-data); font-weight: 400; color: transparent; }
th.sortable:not(.sort-asc):not(.sort-desc):hover::after { color: var(--text-dim); }
th.sort-asc::after  { content: ' \25B4'; color: var(--accent); }
th.sort-desc::after { content: ' \25BE'; color: var(--accent); }

/* Arb location cell */
.col-arb-loc { min-width: 160px; max-width: 220px; text-align: left !important; }
.arb-loc-cell { display: flex; flex-direction: column; gap: 2px; overflow: hidden; }
.arb-loc-top {
  display: flex; align-items: center; gap: 4px; overflow: hidden;
}
.arb-loc-top .loc-text {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.arb-loc-region { font-size: var(--sz-label); color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Toggle switch — ship button */
.toggle-switch {
  position: relative; display: inline-block; width: 34px; height: 18px;
}
.toggle-switch input { display: none; }
.toggle-slider {
  position: absolute; cursor: pointer;
  top: 0; left: 0; right: 0; bottom: 0;
  background: var(--bg); border: 1px solid var(--border); border-radius: 2px;
  transition: border-color .2s;
}
.toggle-slider:hover { border-color: var(--border-hi); }
.toggle-slider::before {
  content: ''; position: absolute;
  height: 12px; width: 12px; left: 2px; top: 2px;
  background: var(--text-dim); border-radius: 1px; transition: transform .2s, background .2s;
}
.toggle-switch input:checked + .toggle-slider { border-color: var(--accent-dim); }
.toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(16px); background: var(--accent);
}

/* ── Select dropdown styling ──────────────────────────────────────────────── */
select {
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%233a4858'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  padding-right: 22px !important;
  color-scheme: dark;
}
select option {
  background: var(--bg2);
  color: var(--text-mid);
  border: none;
}

/* ── Number input spinner styling ────────────────────────────────────────── */
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Utility */
.hidden { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }
/* Scrollbar — Firefox */
* { scrollbar-width: thin; scrollbar-color: var(--border) var(--bg); }
/* Scrollbar — Webkit (Chrome, Edge, Safari) */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
::selection { background: var(--accent-select); color: var(--text-bright); }

/* ── Skeleton loading ────────────────────────────────────────────────────── */
@keyframes skeletonPulse {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 0.6; }
}
.skeleton-bar {
  background: var(--border);
  animation: skeletonPulse 1.5s ease-in-out infinite;
  border-radius: 1px;
}
/* Chart skeleton */
.chart-skeleton {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 8px 12px;
}
.chart-skeleton-prices {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  padding: 4px 0;
}
.chart-skeleton-prices .skeleton-bar {
  height: 1px;
  width: 100%;
}
.chart-skeleton-volume {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 28%;
  padding-top: 4px;
  border-top: 1px solid var(--border);
}
.chart-skeleton-volume .skeleton-bar {
  flex: 1;
  border-radius: 1px 1px 0 0;
}
/* Stats skeleton */
.stat-skeleton .skeleton-value {
  width: 72px;
  height: 11px;
  margin-top: 2px;
}
/* Table skeleton — fill available space */
.skeleton-row { animation: none !important; opacity: 1; }
.skeleton-row td {
  padding: 5px 10px;
}
.skeleton-row .skeleton-bar {
  height: 11px;
}

/* ── Keyframe animations ─────────────────────────────────────────────────── */
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes fadeSlideDown {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeSlideIn {
  from { opacity: 0; transform: translateX(-4px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes rowFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── Sidebar tabs ────────────────────────────────────────────────────────── */
.sidebar-tabs {
  display: flex;
  height: var(--topbar-h);
  border-bottom: 1px solid var(--border);
}
.sidebar-tab-btn {
  flex: 1;
  padding: 0 4px;
  margin-bottom: -1px; /* overlap container's border-bottom so active tab's accent replaces it */
  text-align: center;
  font-size: var(--sz-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
  background: none;
  border: none;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid transparent;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.sidebar-tab-btn:last-child { border-right: none; }
.sidebar-tab-btn:hover { color: var(--text-mid); background: var(--bg3); }
.sidebar-tab-btn.active { color: var(--text-bright); border-bottom-color: var(--accent); }
.sidebar-feedback {
  position: absolute;
  top: calc(var(--topbar-h) * 2);
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  min-height: 32px;
  padding: 6px 10px;
  box-sizing: border-box;
  background-color: var(--bg2);
  border-left: 2px solid var(--accent);
  border-bottom: 1px solid var(--border);
  color: var(--text-bright);
  font-size: var(--sz-data);
  opacity: 0;
  overflow-wrap: break-word;
  pointer-events: none;
  transform: translateY(-2px);
  transition: opacity 0.25s ease, transform 0.25s ease;
  white-space: pre-wrap;
  z-index: 100;
}
.sidebar-feedback.show {
  opacity: 1;
  transform: translateY(0);
}
.sidebar-feedback.error {
  border-left-color: var(--red);
  color: var(--red);
}
.quickbar-empty-msg {
  padding: 12px 16px;
  font-size: var(--sz-data);
  color: var(--text);
  line-height: 1.6;
}

/* ── Analytics row ───────────────────────────────────────────────────────── */
.analytics-row {
  display: flex;
  gap: 16px;
  padding: 6px 0 4px;
  flex-wrap: wrap;
}
.analytics-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.analytics-stat .stat-label {
  font-size: var(--sz-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
}
.analytics-stat .stat-value {
  font-size: var(--sz-data);
  color: var(--text-bright);
  font-variant-numeric: tabular-nums;
}

.analytics-stat .text-sell { color: var(--sell); }
.analytics-stat .text-buy { color: var(--buy); }
.analytics-stat .text-green { color: var(--green); }
.analytics-stat .text-red { color: var(--red); }

/* Indicator span sits next to a value (e.g. delta arrow + percent next to a number).
 * Number stays bright for legibility, indicator carries the directional color signal —
 * matches the ticker / category table pattern (color is for indicators, not data). */
.analytics-stat .stat-indicator {
  font-size: var(--sz-data);
  font-variant-numeric: tabular-nums;
}

/* Direction arrow inside an indicator (▲ ▼). Smaller than the surrounding text since
 * the triangle reads "loud" at the same size — sz-label brings it back to a tasteful
 * accent. Used in chart stats and category table delta columns. */
.dir-arrow {
  font-size: var(--sz-label);
}

/* Inline stats in toolbar/filter bar */
.toolbar-stats {
  display: flex;
  gap: 12px;
  align-items: center;
}
.toolbar-stats .analytics-stat {
  flex-direction: row;
  gap: 4px;
  align-items: baseline;
}
.toolbar-spacer { flex: 1; }

/* ── Stat popover ──────────────────────────────────────────────────────────
 * Pinned decomposition panel shown when a user clicks a stat's .stat-popover-
 * trigger (e.g. AVG PRICE ▾) while scope is multi-region or multi-location.
 * Body-attached, position: fixed, anchored to the clicked stat's bounding
 * rect by JS in stat-popover.ts. Same z-index tier family as chart tooltip —
 * see --z-stat-popover token above. */
.stat-popover {
  position: fixed;
  z-index: var(--z-stat-popover);
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 8px 10px;
  min-width: 180px;
  max-width: 320px;
  max-height: 320px;
  overflow-y: auto;
  font-size: var(--sz-data);
  color: var(--text);
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.25s ease-out, transform 0.25s ease-out;
}
.stat-popover.stat-popover-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .stat-popover,
  .stat-popover.stat-popover-visible {
    transition: opacity 0.04s ease;
    transform: none;
  }
}
/* Title matches the chart-tooltip title convention: inherits --sz-data,
 * font-weight: 700, --text-bright, divider below. No uppercase, no letter-
 * spacing — those are reserved for inline labels, not panel headings. */
.stat-popover-title {
  font-weight: 700;
  color: var(--text-bright);
  margin-bottom: 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.stat-popover-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  padding: 3px 0;
}
.stat-popover-label {
  color: var(--text);
  min-width: 0;
  flex: 1;
}
.stat-popover-label .region-swatch {
  margin-right: 5px;
}
.stat-popover-sub {
  display: block;
  font-size: var(--sz-label);
  color: var(--text);
  margin-top: 1px;
  margin-left: 13px; /* swatch width (8px) + margin-right (5px) */
  opacity: 0.7;
}
.stat-popover-label.no-swatch .stat-popover-sub {
  margin-left: 0;
}
.stat-popover-value {
  color: var(--text-bright);
  white-space: nowrap;
  flex: 0 0 auto;
}
.stat-popover-value.text-sell { color: var(--sell); }
.stat-popover-value.text-buy { color: var(--buy); }
.stat-popover-value.text-green { color: var(--green); }
.stat-popover-value.text-red { color: var(--red); }

/* Indicator span inside a delta-split value (Δ PRICE). Main ISK number stays
 * in --text-bright (inherited from .stat-popover-value); only the arrow+pct
 * carries the directional color. Matches the toolbar .stat-indicator pattern. */
.stat-popover-indicator-text {
  margin-left: 6px;
}
.stat-popover-indicator-text.text-green { color: var(--green); }
.stat-popover-indicator-text.text-red { color: var(--red); }
.stat-popover-indicator-text .dir-arrow { font-size: var(--sz-label); }

/* Trigger — applied to an .analytics-stat when popover is available for it.
 * Only the ▾ indicator changes color on hover/open. The stat's value keeps
 * its semantic color (--sell for BEST SELL, --buy for BEST BUY, etc.) —
 * matches the existing toolbar convention across all UI states. */
.stat-popover-trigger {
  cursor: pointer;
  user-select: none;
}
.stat-popover-trigger:hover .stat-popover-indicator,
.stat-popover-trigger[data-popover-open="true"] .stat-popover-indicator {
  color: var(--text-bright);
}
.stat-popover-indicator {
  display: inline-block;
  margin-left: 4px;
  font-size: var(--sz-label);
  color: var(--text);
  transition: color 0.12s ease;
}

/* ── Filter bar ──────────────────────────────────────────────────────────── */
/* Filter bar is a vertical stack of .filter-bar-row children by default. At 2560px
 * and above (QHD / "2K" and ultrawide) the rows flatten into a single flex row
 * via `display: contents` so everything sits on one line. The first row's spacer
 * is hidden at wide widths and `order` pushes both stat clusters to the end. */
.filter-bar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 0;
  margin: 0 0 4px;
  flex-shrink: 0;
}
.filter-bar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.market-scope-bar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 0;
  margin: 0 0 6px;
  flex-shrink: 0;
}
.market-scope-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
@media (min-width: 2560px) {
  .filter-bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .filter-bar-row {
    display: contents;
  }
  .market-scope-bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .market-scope-row {
    display: contents;
  }
  /* Row 1's spacer becomes redundant when flattened — only row 2's spacer grows */
  .filter-bar-row:first-child .filter-spacer {
    display: none;
  }
  /* Push both analytics clusters to the end of the single flattened row */
  #analytics-row-1 { order: 2; }
  #analytics-row-2 { order: 3; }
}
/* Below 1600px (narrow/tight screens like 1440), the default 2-row layout breaks
 * visually — stats1 doesn't fit on the pickers row and wraps within it, creating
 * an interleaved "pickers → stats1 → values+depth+stats2" sandwich. Instead,
 * flatten the rows (display: contents) + order the stats to the very end so
 * filters always come first and stats always come last, wherever they land. */
@media (max-width: 1599px) {
  .filter-bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .filter-bar-row {
    display: contents;
  }
  .market-scope-bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .market-scope-row {
    display: contents;
  }
  /* No spacers needed — filters flow left, stats flow after via order */
  .filter-spacer { display: none; }
  #analytics-row-1 { order: 10; }
  #analytics-row-2 { order: 11; }
}
.filter-bar .region-dropdown-btn,
.market-scope-bar .region-dropdown-btn,
.chart-toolbar .region-dropdown-btn {
  width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}
.filter-bar label:not(.region-dropdown-item),
.market-scope-bar label:not(.region-dropdown-item) {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: var(--sz-label);
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
/* Filter bar number inputs (price min/max, quantity) + any select — styled to
 * mirror .region-dropdown-btn: same chrome (bg2), same border, same hover state
 * (border-hi + bg3), same focus/active accent border. Number tier (sz-data 13px)
 * since the user types values into these. */
.filter-bar input:not([type="checkbox"]):not(.region-dropdown-search),
.market-scope-bar input:not([type="checkbox"]):not(.region-dropdown-search),
.filter-bar select {
  padding: 4px 8px;
  font-size: var(--sz-data);
  font-variant-numeric: tabular-nums;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text);
  transition: border-color 0.15s, background-color 0.15s;
  -webkit-appearance: none;
  appearance: none;
  color-scheme: dark;
  width: 120px;
}
/* Rule order matters here: hover → focus → .active. All three selectors share the
 * same specificity (0,4,1) via the matching :not(.region-dropdown-search), so the
 * later-declared rule wins for equal-specificity conflicts. Focus therefore beats
 * hover (so a focused field keeps its accent border even when hovered), and .active
 * beats both (so a filled field always shows accent regardless of hover/focus). */
.filter-bar input:not([type="checkbox"]):not(.region-dropdown-search):hover,
.market-scope-bar input:not([type="checkbox"]):not(.region-dropdown-search):hover,
.filter-bar select:hover {
  border-color: var(--border-hi);
  background-color: var(--bg3);
}
.filter-bar input:not([type="checkbox"]):not(.region-dropdown-search):focus,
.market-scope-bar input:not([type="checkbox"]):not(.region-dropdown-search):focus,
.filter-bar select:focus {
  border-color: var(--accent);
  outline: none;
}
.filter-bar input:not([type="checkbox"])::placeholder,
.market-scope-bar input:not([type="checkbox"])::placeholder { color: var(--text-dim); opacity: 1; }
/* Active filter indicator — input has a value (set by JS on input/change).
 * :not(.region-dropdown-search) added for specificity parity with :hover/:focus. */
.filter-bar input:not([type="checkbox"]):not(.region-dropdown-search).active,
.market-scope-bar input:not([type="checkbox"]):not(.region-dropdown-search).active,
.filter-bar select.active { border-color: var(--accent); }

.market-scope-clear {
  width: 25px;
  height: 25px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: var(--sz-label);
  line-height: 1;
  color: var(--text);
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.market-scope-clear:hover {
  color: var(--text-mid);
  border-color: var(--border-hi);
  background-color: var(--bg3);
}
.market-scope-clear:focus {
  outline: none;
  border-color: var(--accent);
}
.type-item.quickbar-scope-muted.active {
  border-left-color: var(--accent);
}

/* Security status toggles */
.filter-sec-group { display: flex; gap: 4px; align-items: center; }
/* Filter bar toggle groups — unified frame-button styling matching .chart-toggle-item.
 * All groups (sec / struct / orders / history / depth) share base rules; per-group overrides
 * only cover the checked-state color so each toggle type can use its own semantic
 * indicator color (green/orange/red for sec tiers, accent for struct/orders/history/depth). */
.filter-sec-toggle,
.filter-struct-toggle,
.filter-orders-toggle,
.filter-history-toggle,
.filter-depth-toggle {
  position: relative;
  cursor: pointer;
}
.filter-sec-toggle input,
.filter-struct-toggle input,
.filter-orders-toggle input,
.filter-history-toggle input,
.filter-depth-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.filter-sec-toggle span,
.filter-struct-toggle span,
.filter-orders-toggle span,
.filter-history-toggle span,
.filter-depth-toggle span {
  display: inline-block;
  padding: 5px 10px;
  font-size: var(--sz-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.filter-sec-toggle span:hover,
.filter-struct-toggle span:hover,
.filter-orders-toggle span:hover,
.filter-history-toggle span:hover,
.filter-depth-toggle span:hover {
  color: var(--text-mid);
  border-color: var(--border-hi);
  background-color: var(--bg3);
}
/* Sec toggles use the 4-level security color system (hi green / lo orange / null red) */
#filter-sec-hi:checked + span,
#scope-sec-hi:checked + span   { border-color: var(--green);  color: var(--green);  }
#filter-sec-lo:checked + span,
#scope-sec-lo:checked + span   { border-color: var(--orange); color: var(--orange); }
#filter-sec-null:checked + span,
#scope-sec-null:checked + span { border-color: var(--red);    color: var(--red);    }
/* Struct / orders / history / depth toggles share the accent color for active state */
.filter-struct-toggle input:checked + span,
.filter-orders-toggle input:checked + span,
.filter-history-toggle input:checked + span,
.filter-depth-toggle input:checked + span {
  border-color: var(--accent);
  color: var(--accent);
}
.filter-history-toggle span,
.filter-depth-toggle span {
  color: var(--text-dim);
}

/* Group containers — just flex layout */
.filter-struct-group,
.filter-orders-group,
.filter-noscam-group,
.filter-depth-group { display: flex; gap: 4px; align-items: center; }

/* Depth chart container */
.depth-chart-wrap {
  position: relative;
  height: 275px;
  flex-shrink: 0;
  margin-bottom: 8px;
  background: var(--bg2);
  border: 1px solid var(--border);
  padding: 6px 8px 4px;
  overflow: hidden;
  transition: height 0.25s ease, opacity 0.2s ease, margin 0.25s ease, padding 0.25s ease;
}
.depth-chart-wrap.depth-collapsed {
  height: 0; opacity: 0;
  margin-bottom: 0; padding-top: 0; padding-bottom: 0;
  border-color: transparent;
}
.depth-chart-wrap.depth-entering {
  transition: height 0.25s ease, opacity 0.2s ease, margin 0.25s ease, padding 0.25s ease;
}
.depth-chart-wrap canvas { width: 100% !important; height: 100% !important; }
/* Corner tick marks — matching history chart */
.depth-chart-wrap::before,
.depth-chart-wrap::after {
  content: '';
  position: absolute;
  width: 5px; height: 5px;
  border-color: var(--text-muted);
  border-style: solid;
  pointer-events: none;
  z-index: 1;
}
.depth-chart-wrap::before { top: 3px; left: 3px; border-width: 1px 0 0 1px; }
.depth-chart-wrap::after  { bottom: 3px; right: 3px; border-width: 0 1px 1px 0; }

/* Depth section — wrapper for filter bar + depth chart */
.depth-section { display: contents; }
/* Depth fullscreen button — inline in filter bar, matches chart-fullscreen-btn */
.depth-fullscreen-btn {
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text);
  font-size: var(--sz-data);
  padding: 0;
  line-height: 1.2;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 25px;
  height: 25px;
  flex-shrink: 0;
}
.depth-fullscreen-btn:hover { color: var(--text-mid); border-color: var(--border-hi); background-color: var(--bg3); }
.depth-fullscreen-close {
  display: none;
  border: 1px solid var(--border);
  background-color: var(--bg2);
  color: var(--text);
  font-size: var(--sz-label);
  padding: 5px 10px;
  line-height: 1.2;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-radius: 2px;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.depth-fullscreen-close .close-icon {
  font-size: var(--sz-data);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  height: 1em;
}
.depth-fullscreen-close:hover { color: var(--text-mid); border-color: var(--border-hi); background-color: var(--bg3); }
/* Depth fullscreen mode — filter bar + depth chart only */
.depth-section.depth-fullscreen {
  display: flex; flex-direction: column;
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  z-index: 9001;
  background-color: var(--bg); padding: 12px 20px;
  animation: chartPanelOn 0.4s ease-out forwards;
}
.depth-section.depth-fullscreen .depth-chart-wrap { flex: 1; height: auto; }
.depth-section.depth-fullscreen .depth-fullscreen-btn { display: none; }
.depth-section.depth-fullscreen .depth-fullscreen-close { display: inline-flex; }
.depth-section.depth-closing { animation: chartPanelOff 0.3s ease-in forwards; }

/* When depth is active, collapse history chart */
.chart-section.depth-active { flex: 0 0 0; min-height: 0; opacity: 0; pointer-events: none; }

/* Filter group separator (thin vertical line) */
.filter-sep {
  width: 1px;
  height: 18px;
  background-color: var(--border);
  flex-shrink: 0;
  margin: 0 6px;
}

/* Filter spacer (pushes clear button to the right) */
.filter-spacer { flex: 1; }

/* ── Chart controls ──────────────────────────────────────────────────────── */
.chart-fullscreen-btn {
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text);
  font-size: var(--sz-data);
  padding: 0;
  line-height: 1.2;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 25px;
  height: 25px;
  flex-shrink: 0;
}
.chart-fullscreen-btn:hover { color: var(--text-mid); border-color: var(--border-hi); background-color: var(--bg3); }

/* Dataset toggles — cockpit button style */
.chart-toggles-inline {
  display: flex;
  align-items: center;
  gap: 4px;
}
.chart-toggle-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  font-size: var(--sz-label);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
  cursor: pointer;
  user-select: none;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 2px;
  background-color: var(--bg2);
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.chart-toggle-item:hover { color: var(--text-mid); border-color: var(--border-hi); background-color: var(--bg3); }
.chart-toggle-item input { position: absolute; opacity: 0; pointer-events: none; }
.chart-toggle-item .toggle-swatch { display: none; }
/* Checked: border + text take the dataset color (same pattern as sec toggles) */
.chart-toggle-item.checked { border-color: var(--toggle-color); color: var(--toggle-color); }

/* Old fullscreen overlay removed — fullscreen is now a CSS class on .chart-section */

/* ── Ticker bar ──────────────────────────────────────────────────────────── */
.quickbar-ticker {
  height: var(--ticker-h);
  background-color: var(--bg2);
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  overflow: hidden;
  font-size: var(--sz-label);
  line-height: var(--ticker-h);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
}

/* #ticker-items — quickbar ticker scrolling container */
#ticker-items {
  flex: 1;
  overflow: hidden;
  white-space: nowrap;
  min-width: 0;
  padding-left: 10px;
  opacity: 0;
  transition: opacity 0.4s ease;
}
#ticker-items.ready { opacity: 1; }
.ticker-empty { color: var(--text); font-size: var(--sz-label); }
#ticker-items .ticker-scroll {
  display: inline-block;
}
#ticker-items.scrolling .ticker-scroll {
  animation: tickerItemsScroll var(--ticker-duration, 30s) linear infinite;
}
.quickbar-ticker:hover #ticker-items.scrolling .ticker-scroll {
  animation-play-state: paused;
}
.tab-hidden .ticker-scroll {
  animation-play-state: paused !important;
}
@keyframes tickerItemsScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.ticker-item-name { color: var(--text); }
.ticker-item-sep { color: var(--text-dim); margin: 0; padding: 0 6px; display: inline-block; text-align: center; }
.ticker-item-price { color: var(--text-bright); font-variant-numeric: tabular-nums; }
.ticker-plex-label {
  color: var(--text);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.ticker-plex-price { color: var(--text-bright); font-variant-numeric: tabular-nums; }
.ticker-plex-change { font-variant-numeric: tabular-nums; }

/* Numbers in the ticker render at data tier (13px) while item names + "PLEX" label
 * stay at the parent's sz-label (11px). Treats item names as labels for the price
 * that follows — same hierarchy as label/value pairs elsewhere in the app.
 * Arrows inside change spans are shrunk via .dir-arrow (see above). */
.ticker-item-price,
.ticker-plex-price,
.ticker-item-up,
.ticker-item-down {
  font-size: var(--sz-data);
}
.ticker-item {
  display: inline-block;
  font-size: var(--sz-label);
  cursor: pointer;
  color: var(--text);
  text-decoration: none;
  transition: color 0.1s, background 0.1s;
}
.ticker-item:hover { color: var(--text-mid); background: var(--bg3); }
.ticker-item:hover .ticker-item-name { color: var(--text-mid); }
.ticker-item-up   { color: var(--green);    }
.ticker-item-down { color: var(--red); }
.ticker-item-flat { color: var(--text);     }
/* PLEX section — pinned right, separated */
.ticker-plex {
  border-left: 1px solid var(--border);
  flex-shrink: 0;
  padding: 0 10px;
  font-size: var(--sz-label);
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.4s ease, color 0.1s, background 0.1s;
  display: flex;
  align-items: center;
  gap: 6px;
}
.ticker-plex:hover { color: var(--text-mid); background: var(--bg3); }
.ticker-plex:hover .ticker-plex-label { color: var(--text-mid); }

/* ── m3 column + star + change + item header icons ──────────────────────── */

/* Category table star column */
th.col-star { padding: 0 0 0 10px; }
td.col-star { padding: 0 0 0 10px; text-align: center; }

/* % Change column */
th.col-change { width: 72px; }
td.col-change { width: 72px; font-variant-numeric: tabular-nums; }
.change-pos { color: var(--green); }
.change-neg { color: var(--red); }
.change-neu { color: var(--text); }
td.text-sell { color: var(--sell); }
td.text-buy { color: var(--buy); }

/* Sparkline column */
th.col-sparkline { width: 80px; min-width: 80px; }
td.col-sparkline { width: 80px; min-width: 80px; padding: 2px 10px !important; }
.sparkline { display: block; image-rendering: pixelated; }

/* Item name copy button (category table) */
.cat-name-copy {
  background: none;
  border: none;
  padding: 0 4px;
  font-size: var(--sz-label);
  color: transparent;
  cursor: pointer;
  transition: color 0.15s;
  line-height: 1;
  vertical-align: middle;
}
tr:hover .cat-name-copy { color: var(--text-dim); }
tr:hover .cat-name-copy:hover { color: var(--accent); }
tr:hover .cat-name-copy.copied,
tr .cat-name-copy.copied { color: var(--green); }
.quickbar-folder-remove {
  background: none;
  border: none;
  padding: 0 4px;
  font-size: var(--sz-label);
  color: transparent;
  cursor: pointer;
  transition: color 0.15s;
  line-height: 1;
  vertical-align: middle;
}
tr:hover .quickbar-folder-remove { color: var(--text-dim); }
tr:hover .quickbar-folder-remove:hover,
.quickbar-folder-remove:focus-visible { color: var(--red); }

@media (hover: none), (max-width: 767px) {
  .quickbar-folder-remove {
    min-width: 44px;
    height: 44px;
    padding: 0;
    color: var(--text);
  }
}

/* Quickbar star */
.quickbar-star {
  background: none;
  border: none;
  font-size: var(--sz-data);
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s;
  line-height: 1;
}
.quickbar-star:hover { color: var(--accent); }
.quickbar-star.saved { color: var(--accent); }

.item-m3 {
  font-size: var(--sz-label);
  color: var(--text-dim);
}

/* Copy button (item header context) */
.copy-btn {
  font-size: var(--sz-label);
  vertical-align: middle;
  background: none;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s;
  line-height: 1;
}
.copy-btn:hover { color: var(--accent); }
.copy-btn.copied { color: var(--green); }

/* Category star (.cat-star) */
.cat-star {
  background: none;
  border: none;
  padding: 0 4px;
  font-size: var(--sz-data);
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.15s;
  line-height: 1;
}
.cat-star:hover { color: var(--accent); }
.cat-star.saved { color: var(--accent); }

.quickbar-star-picker {
  position: fixed;
  z-index: 100;
  background-color: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 8px;
  color: var(--text);
  animation: fadeSlideDown 0.3s ease 0.15s both;
}

.quickbar-star-picker-header {
  border-bottom: 1px solid var(--border);
  padding: 0 0 6px;
  margin-bottom: 6px;
}

.quickbar-star-picker-title {
  font-size: var(--sz-label);
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}

.quickbar-star-picker-item {
  margin-top: 2px;
  font-size: var(--sz-data);
  line-height: 1.25;
  color: var(--text-bright);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.quickbar-star-picker-action,
.quickbar-star-picker-folder {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 2px;
  background-color: var(--bg3);
  color: var(--text);
  font-size: var(--sz-data);
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
}

.quickbar-star-picker-action {
  padding: 5px 7px;
  margin-bottom: 6px;
}

.quickbar-star-picker-action.danger {
  color: var(--red);
  border-color: var(--red);
}

.quickbar-star-picker-list {
  max-height: min(320px, 55vh);
  overflow-y: auto;
}

.quickbar-star-picker-folder {
  display: flex;
  align-items: center;
  padding: 5px 7px 5px var(--indent, 7px);
  margin-top: 2px;
}

.quickbar-star-picker-action:hover,
.quickbar-star-picker-action:focus-visible,
.quickbar-star-picker-folder:hover,
.quickbar-star-picker-folder:focus-visible {
  border-color: var(--border-hi);
  color: var(--text-mid);
}

.quickbar-star-picker-folder[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

.quickbar-star-picker-folder[aria-pressed="true"]:hover,
.quickbar-star-picker-folder[aria-pressed="true"]:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.quickbar-star-picker-folder-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Settings ────────────────────────────────────────────────────────────── */
.topbar-settings { background: none; border: none; color: var(--text-dim); cursor: pointer; padding: 4px; display: flex; align-items: center; transition: color 0.15s; }
.topbar-settings:hover { color: var(--accent); }

.settings-panel {
  position: absolute; top: var(--topbar-h); right: 16px; z-index: 100;
  background: var(--bg2); border: 1px solid var(--border); padding: 12px 16px;
  min-width: 275px;
}
/* Settings-scoped region dropdown stretches to popup width so the button and
   dropdown panel share a visual column instead of the default 200px island.
   Text is left-aligned inside the button (arrow stays right via ::after). */
#settings-region-dropdown { display: block; }
#settings-region-dropdown .region-dropdown-btn {
  width: 100%;
  max-width: none;
  text-align: left;
}
#settings-region-dropdown .region-dropdown-panel { width: 100%; min-width: 0; }
/* Stretch the font-size / brightness tumblers to the full popup width so the
   tumbler track doesn't leave an empty-looking rectangle to the right of its
   last button. */
.settings-panel .settings-tumbler { width: 100%; }
.settings-panel .settings-opt { flex: 1; text-align: center; }
/* Layer the tumbler so the accent track border stays visible when the adjacent
   non-active button is hovered:
   - non-active buttons sit below the track (so their hover bg can't paint over
     the track's accent border at the seam),
   - the active button sits above the track so its text renders on top of the
     track's background. */
.settings-panel .settings-opt { position: relative; z-index: 2; }
.settings-panel .settings-tumbler .tumbler-track { z-index: 3; }
.settings-panel .settings-opt.active { z-index: 4; }
/* Use visibility instead of display so offsetWidth/offsetParent calculations work while hidden */
.settings-panel.hidden { visibility: hidden; pointer-events: none; }
.settings-header {
  font-size: var(--sz-label); color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 10px; border-bottom: 1px solid var(--border); padding-bottom: 6px;
}
.settings-label {
  font-size: var(--sz-label); color: var(--text-dim);
  text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 4px;
}
.settings-tumbler {
  display: flex; gap: 0; border: 1px solid var(--border); border-radius: 2px;
  position: relative;
  background: var(--bg2);
}
.settings-opt {
  font-size: var(--sz-label);
  padding: 5px 10px; background: none; border: none; border-right: 1px solid var(--border);
  color: var(--text); cursor: pointer; text-transform: uppercase; letter-spacing: 0.08em;
  position: relative;
  z-index: 2;
  transition: color 0.15s, background 0.15s;
}
.settings-opt:last-child { border-right: none; }
.settings-opt:not(.active):hover { color: var(--text-mid); background: var(--bg3); }
.settings-opt.active { color: var(--accent); border-right-color: transparent; }
/* Hide the right border of the button BEFORE the active one so the track's left accent shows through */
.settings-opt:has(+ .settings-opt.active) { border-right-color: transparent; }

/* ── Responsive ──────────────────────────────────────────────────────────── */

/* Tablet: narrower sidebar, tighter spacing */
@media (max-width: 1023px) {
  :root { --sidebar-w: 200px; }
  .main-panel { padding: 12px 14px 14px; }
  .orders-grid { gap: 12px; }
}

/* Phone: two-panel layout (sidebar ↔ content) */
@media (max-width: 767px) {
  :root { --sidebar-w: 100%; }

  .topbar { min-height: var(--topbar-h); }
  .topbar-brand { width: auto; flex: 1; }

  .top-nav { display: none; }

  #status-bar { flex-wrap: wrap; gap: 4px; }

  .layout {
    flex-direction: column;
    height: calc(100vh - var(--ticker-h));
    padding-top: var(--topbar-h);
  }

  .sidebar {
    width: 100%; flex-shrink: 0;
    border-right: none; border-bottom: 1px solid var(--border);
    height: 100%;
    transition: none;
  }
  .main-panel {
    padding: 10px 12px 12px;
    display: none;
  }

  body.showing-content .sidebar { display: none; }
  body.showing-content .main-panel { display: flex; flex-direction: column; flex: 1; overflow-y: auto; }

  /* Mobile back button — only visible when content panel is showing */
  .mobile-back-btn {
    display: none; align-items: center; gap: 4px;
    background: none; border: none; border-right: 1px solid var(--border);
    color: var(--accent); font-size: var(--sz-label);
    text-transform: uppercase; letter-spacing: 0.08em;
    padding: 0 12px; height: var(--topbar-h); cursor: pointer;
  }
  body.showing-content .mobile-back-btn { display: flex; }
  body.showing-content .topbar-brand { display: none; }
  .mobile-back-btn:hover { color: var(--text-bright); }
  .mobile-back-btn .arrow { font-size: var(--sz-data); }

  .quickbar-folder-actions {
    gap: 4px;
  }
  .quickbar-folder-action,
  .browse-search-action {
    min-width: 44px;
    height: 44px;
  }
  .browse-search-actions,
  .browse-search-folder-label .browse-search-actions {
    opacity: 1;
  }
  .browse-search-section-actions,
  .quickbar-section-actions {
    opacity: 1;
  }
  .quickbar-folder-item-remove {
    min-width: 44px;
    height: 44px;
    color: var(--text);
    opacity: 1;
  }

  .orders-grid { grid-template-columns: 1fr; gap: 8px; }

  .filter-bar,
  .market-scope-bar { gap: 4px; }
  .filter-bar input,
  .market-scope-bar input { width: 80px; }

  /* Stats: stack vertically on mobile, tighter */
  .toolbar-stats { gap: 6px; flex-wrap: wrap; }
  .toolbar-stats .analytics-stat { font-size: var(--sz-label); }

  /* History is hidden via the persistent HISTORY control; visible history uses half the item pane on phone. */
  #chart-section { display: none; }
  #chart-section:not([hidden]) { display: flex; flex: 0 0 50%; }
  #orders-section { flex: 1; }

  /* Chart toolbar: compact on mobile */
  #chart-section:not([hidden]) .chart-toolbar { flex-wrap: wrap; gap: 4px; }
  #chart-section:not([hidden]) .chart-period-btns { order: -1; }

  .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* Compact columns on phone — all visible, tables scroll horizontally */
  .col-loc { max-width: 120px; }

  /* Compact main panel padding */
  .item-header { flex-wrap: wrap; gap: 4px; }
  .item-header h2 { font-size: var(--sz-data); }
  .breadcrumb { font-size: var(--sz-label); }

  .filter-sec-toggle,
  .filter-struct-toggle,
  .filter-orders-toggle,
  .filter-history-toggle,
  .filter-depth-toggle,
  .chart-toggle-item,
  .chart-period-btn,
  .scope-period-btn,
  .market-scope-clear,
  .sidebar-tab-btn { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; }

  .type-item { min-height: 36px; display: flex; align-items: center; }
  .tree-label { min-height: 36px; display: flex; align-items: center; }
  .tree-label.tree-split-label .arrow { min-width: 44px; }

  .quickbar-ticker { height: auto; min-height: var(--ticker-h); }
}

/* ── Quickbar action buttons (import / export / clear) ──────────────────── */

.quickbar-actions {
  display: flex;
  padding: 0;                      /* hovers span edge-to-edge of the sidebar */
  border-bottom: 1px solid var(--border);
  position: relative;              /* anchor for .quickbar-feedback overlay */
}

.quickbar-actions.hidden {
  display: none;
}

.quickbar-action-btn {
  flex: 1;             /* equal-width fill across the five Quickbar controls */
  box-sizing: border-box;  /* percentages in .clear-armed override include border + padding */
  background: transparent;
  border: none;
  border-right: 1px solid var(--border);  /* dividers between buttons (matches .sidebar-tab-btn pattern) */
  color: var(--text);
  font-family: inherit;
  font-size: var(--sz-data);
  padding: 7px 8px;    /* taller hit area than the codebase 4px default — exception so the icon row reads as a distinct toolbar */
  cursor: pointer;
  border-radius: 0;
  position: relative;  /* anchor for label spans */
  transition: color 0.15s, background 0.15s, opacity 0.15s ease;
}

/* :last-of-type (not :last-child) — #quickbar-feedback is the literal last child;
 * we want the LAST BUTTON (collapse) to drop its border against the sidebar edge. */
.quickbar-action-btn:last-of-type { border-right: none; }

.quickbar-action-btn:hover:not(:disabled) {
  color: var(--text-mid);
  background: var(--bg3);
}

.quickbar-action-btn:disabled {
  color: var(--text-muted);
  cursor: not-allowed;
}

/* Clear button cross-fades between idle (✕) and armed ("Confirm?") labels.
 * The armed label is an absolute-positioned overlay that extends 200% of the
 * clear button's width — 50% of the action bar — covering the adjacent collapse
 * button. No flex-layout change: clear stays at 25%, collapse fades opacity, and
 * the overlay hides the collapse state transition behind a red "Confirm?" popup. */
#btn-quickbar-clear .lbl-idle,
#btn-quickbar-clear .lbl-armed {
  transition: opacity 0.15s ease-in-out;
}

#btn-quickbar-clear .lbl-armed {
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;                     /* 2x clear's 25% = 50% of the action bar */
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Solid composite of --red at 15% over --bg2 so the overlay fully hides the
   * clear button's border-right and any hover state underneath. Visually
   * identical to rgba(--red, 0.15) layered on the sidebar background. */
  background: color-mix(in srgb, var(--red) 15%, var(--bg2));
  color: var(--red);
  opacity: 0;
  z-index: 2;                      /* above the collapse button underneath */
  pointer-events: none;
}

#btn-quickbar-clear.armed .lbl-idle {
  opacity: 0;
}

#btn-quickbar-clear.armed .lbl-armed {
  opacity: 1;
  pointer-events: auto;            /* clickable Confirm? target when armed */
}

/* While armed, suppress the clear button's own hover/background so nothing
 * shows through along the overlay's left/right edges. */
#btn-quickbar-clear.armed,
#btn-quickbar-clear.armed:hover {
  background: transparent;
  color: var(--text);
}

/* Collapse button fades under the armed overlay. */
#btn-quickbar-collapse {
  transition: opacity 0.15s ease-in-out;
}

.quickbar-actions.clear-armed #btn-quickbar-collapse {
  opacity: 0;
  pointer-events: none;
}

/* Collapse/expand button cross-fades between two inline SVG icons. */
#btn-quickbar-collapse .lbl-collapse,
#btn-quickbar-collapse .lbl-expand {
  transition: opacity 0.15s ease-in-out;
}

#btn-quickbar-collapse svg {
  display: block;     /* drop the inline baseline gap so the icon centers cleanly */
  margin: 0 auto;
}

#btn-quickbar-collapse .lbl-expand {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
}

#btn-quickbar-collapse.expanded-mode .lbl-collapse {
  opacity: 0;
}

#btn-quickbar-collapse.expanded-mode .lbl-expand {
  opacity: 1;
}

/* ── Quickbar feedback (overlays the action bar) ──────────────────────── */

.quickbar-feedback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: 0 10px;
  font-size: var(--sz-data);
  color: var(--text-bright);
  background: var(--bg2);
  border-left: 2px solid var(--accent);
  opacity: 0;
  transition: opacity 0.25s ease-in-out;
  pointer-events: none;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.quickbar-feedback.show {
  opacity: 1;
}

.quickbar-feedback.error {
  border-left-color: var(--red);
  color: var(--red);
}

/* Block button clicks while the feedback overlay is showing */
.quickbar-actions.feedback-active .quickbar-action-btn {
  pointer-events: none;
}
