/* ============================================================
   FlowTrade v4 — Dark theme (faithful port of original Tailwind)
   All values mirror the hex codes from the Next.js source.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');

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

html, body {
  height: 100%; width: 100%;
  overflow: hidden;
  background: #131722;
  color: #d1d4dc;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
input, select { font-family: inherit; }
.font-mono, .mono { font-family: 'JetBrains Mono', Menlo, Monaco, Consolas, monospace; }
.tabular-nums { font-variant-numeric: tabular-nums; }

/* ============================================================
   Layout shell — mirrors TradingPlatform.tsx
   ============================================================ */
.terminal {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  background: #131722;
  color: #d1d4dc;
}

.terminal-body {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.terminal-main {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.chart-column {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.chart-area {
  position: relative;
  flex: 1;
  overflow: hidden;
  background: #131722;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.chart-stack {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  position: relative;
}

.chart-canvas-wrap, #chart-container {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  min-width: 0;
}

.rsi-divider {
  height: 1px;
  background: #2a2e39;
}

.rsi-pane {
  flex-shrink: 0;
  position: relative;
  overflow: visible;
}

.resize-handle {
  width: 1px;
  background: #2a2e39;
  cursor: col-resize;
  flex-shrink: 0;
  position: relative;
  transition: background 0.15s;
}
.resize-handle:hover, .resize-handle.dragging {
  background: #2962ff;
}
.resize-handle::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: -3px; right: -3px;
}

/* RSI pane resize handle (horizontal drag = vertical resize) */
.rsi-resize-handle {
  height: 4px;
  background: #2a2e39;
  cursor: row-resize;
  flex-shrink: 0;
  position: relative;
  transition: background 0.15s;
  z-index: 10;
}
.rsi-resize-handle:hover, .rsi-resize-handle.dragging {
  background: #2962ff;
}
.rsi-resize-handle::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: -3px; bottom: -3px;
}

/* A script's band is drawn inside the price window, so its handle is laid over
   the window at the edge of the band rather than being a row of the stack. */
.oscillator-resize-handle {
  position: absolute;
  left: 0; right: 0;
  bottom: 190px;
  height: 4px;
  background: transparent;
  cursor: row-resize;
  z-index: 11;
}
.oscillator-resize-handle::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: 0;
  height: 1px;
  background: #2a2e39;
}
.oscillator-resize-handle:hover::after, .oscillator-resize-handle.dragging::after {
  background: #2962ff;
}
.oscillator-resize-handle::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: -3px; bottom: -3px;
}

/* Indicator settings, grouped by the indicator they belong to. The row that
   switches an indicator on stays; its settings are offered while it is on. */
.settings-ind-head {
  border-bottom: 1px solid #2a2e39;
  padding-bottom: 6px;
  margin-bottom: 4px;
}
.settings-ind-head .lbl {
  color: #d1d4dc;
  font-weight: 600;
}
.settings-ind-state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.settings-ind-state label {
  font-size: 11px;
  color: #787b86;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.settings-ind-body {
  margin-bottom: 10px;
}

.right-panel {
  flex-shrink: 0;
  background: #131722;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

/* The edge the ledger drawer is resized by. Hidden wherever the panel stands beside
   the chart — there it is already the full height of the row, and an edge that could
   only ever give room back would be a handle that lies. The stacked sheet shows it. */
.panel-height-handle { display: none; }

/* ============================================================
   Top bar — mirrors TopBar.tsx
   ============================================================ */
.topbar {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 44px;
  border-bottom: 1px solid #2a2e39;
  background: #131722;
  padding: 0 8px;
  color: #d1d4dc;
  flex-shrink: 0;
}

/* The administrator's announcement row. flex-shrink: 0 keeps its height, and the
   chart column — the only flex child allowed to give — loses exactly as much;
   the ResizeObserver on #chart-container redraws the candles afterwards. */
.site-announcement {
  flex-shrink: 0;
  background: rgba(41, 98, 255, 0.16);
  border-bottom: 1px solid #2a2e39;
  color: #d1d4dc;
  font-size: 13px;
  line-height: 1.4;
  padding: 7px 12px;
  text-align: center;
}

.site-announcement[hidden] { display: none; }

.symbol-trigger {
  display: flex;
  align-items: center;
  gap: 4px;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 13px;
  font-weight: 600;
  color: #d1d4dc;
}
.symbol-trigger:hover { background: #2a2e39; }
.symbol-trigger .chev { opacity: 0.6; }

.icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  width: 28px;
  border-radius: 4px;
  color: #787b86;
}
.icon-btn:hover { background: #2a2e39; color: #d1d4dc; }
.icon-btn.active { background: #2962ff; color: white; }
.icon-btn svg { width: 16px; height: 16px; }

.divider-v {
  height: 20px;
  width: 1px;
  background: #2a2e39;
  margin: 0 4px;
}

.tf-group { display: flex; align-items: center; gap: 0; }
.tf-btn {
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 12px;
  font-weight: 500;
  color: #787b86;
}
.tf-btn:hover { background: #2a2e39; color: #d1d4dc; }
.tf-btn.active { background: #2a2e39; color: #d1d4dc; }
/* The caret is the second target inside the hour chip: the body of the chip sets
   the hour the chart is drawn at, the arrow opens the rest of them. It carries no
   label, so it takes only the width of the chevron and sits flush against the chip. */
.tf-btn.tf-caret { padding: 4px 5px 4px 2px; display: inline-flex; align-items: center; }

.spacer { flex: 1; }

.last-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  background: #1e222d;
  border-radius: 4px;
  padding: 4px 8px;
  margin-left: 8px;
}
.last-pill .lbl { font-size: 10px; color: #787b86; text-transform: uppercase; }
.last-pill .val { font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 600; color: #d1d4dc; }

.profile {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 6px;
  height: 28px;
  color: #787b86;
}
.profile-avatar {
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background: linear-gradient(135deg, #9c27b0, #6a1b9a);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  color: white;
}
.profile-name {
  font-size: 12px;
  max-width: 96px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Dropdown */
.dropdown {
  position: relative;
}
.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 4px;
  min-width: 220px;
  max-height: 360px;
  overflow-y: auto;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.5);
  z-index: 100;
  padding: 4px 0;
}
/* Menus anchored to the right end of the top bar hang off their own right
   edge, or the panel runs off-screen. */
.dropdown-menu.right {
  left: auto;
  right: 0;
}
/* The display menu lists three groups and would otherwise open already
   scrolled on a short window. */
#chart-tools-menu { max-height: min(70vh, 520px); }
.dropdown-label {
  padding: 6px 12px;
  font-size: 12px;
  color: #787b86;
}
.dropdown-sep {
  height: 1px;
  background: #2a2e39;
  margin: 4px 0;
}
.dropdown-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 6px 12px;
  font-size: 12px;
  color: #d1d4dc;
  cursor: pointer;
}
.dropdown-item:hover { background: #2a2e39; }
.dropdown-item .ticker { font-weight: 600; }
.dropdown-item .name { color: #787b86; font-size: 11px; }

/* ============================================================
   Left toolbar — mirrors LeftToolbar.tsx
   ============================================================ */
.left-toolbar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 40px;
  border-right: 1px solid #2a2e39;
  background: #131722;
  padding: 8px 0;
  flex-shrink: 0;
}
.tool {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  width: 32px;
  border-radius: 4px;
  color: #787b86;
}
.tool:hover { background: #2a2e39; color: #d1d4dc; }
.tool.active { background: #2962ff; color: white; }
.tool svg { width: 16px; height: 16px; }

/* A category is one button with a chevron in its corner. The rail keeps its
   40px width and its one-slot-per-reach, and the chevron is the only signal that
   there is more inside — an extra row per category would push the bottom of the
   rail off a short screen. */
.tool-group {
  position: relative;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
}
.tool-caret {
  position: absolute;
  right: 1px;
  bottom: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 11px;
  border-radius: 2px;
  color: #787b86;
}
.tool-caret svg { width: 8px; height: 8px; }
.tool-group:hover .tool-caret { color: #d1d4dc; }
.tool.active ~ .tool-caret { color: rgba(255, 255, 255, 0.8); }
.tool-divider {
  width: 24px;
  height: 1px;
  margin: 5px 0;
  background: #2a2e39;
  flex-shrink: 0;
}

/* The flyout is fixed, not absolute: it is appended to the document body so no
   ancestor's overflow can clip it, and it is placed beside the tool it belongs to. */
.tool-flyout {
  position: fixed;
  z-index: 90;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 178px;
  max-width: 240px;
  padding: 4px;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  background: #131722;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
/* An invisible apron around the menu. The pointer travels a few pixels of
   nothing between the rail button and the menu, and a hover area that stops at
   the border makes that strip count as "left". The apron only has to cover that
   gap — 4px of it — so it stays at 6px instead of reaching far enough to steal
   the click meant for the button next door. */
.tool-flyout::before {
  content: '';
  position: absolute;
  inset: -8px -6px;
}
/* A group with more rows than the window has room for scrolls inside itself, and
   keeps its heading at the top so the trader still knows which family of tools is
   open halfway down the list. */
.tool-flyout.clipped {
  overflow-y: auto;
  overscroll-behavior: contain;
}
.tool-flyout.clipped .tool-flyout-heading {
  position: sticky;
  top: 0;
  background: #131722;
  z-index: 1;
}
.tool-flyout-heading {
  padding: 4px 8px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #787b86;
}
.tool-flyout-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 12px;
  color: #d1d4dc;
  text-align: left;
}
.tool-flyout-item svg { width: 15px; height: 15px; flex-shrink: 0; color: #787b86; }
.tool-flyout-item:hover { background: #2a2e39; }
.tool-flyout-item:hover svg { color: #d1d4dc; }
.tool-flyout-item.active { background: #2962ff; color: #ffffff; }
.tool-flyout-item.active svg { color: #ffffff; }
/* The mouse-over line: what to do with the tool once it is armed. It hangs
   outside the menu to the right rather than unfolding inside it, because a menu
   that grows when you hover it moves the row you were aiming at — and a row that
   moves under the pointer is a row that cannot be clicked. It is in the DOM from
   the moment the menu opens and only its opacity waits for the cursor, so
   nothing reflows on the way in. */
.tool-flyout-use {
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  width: max-content;
  max-width: 210px;
  padding: 5px 8px;
  border: 1px solid #2a2e39;
  border-radius: 4px;
  background: #1e222d;
  color: #b2b5be;
  font-size: 11px;
  font-weight: 400;
  line-height: 1.35;
  white-space: normal;
  text-align: left;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
}
.tool-flyout-item:hover .tool-flyout-use,
.tool-flyout-item:focus-visible .tool-flyout-use { opacity: 1; }
.tool-flyout-item:hover { z-index: 2; }
.tool-flyout-use:empty { display: none; }
/* Inside a scrolling menu the bubble cannot hang outside: a scroll box clips what
   it scrolls, and a sentence that is clipped is a sentence that was never written.
   It belongs under its row here, the way it does on the phone, because the row is
   the only thing it is allowed to be measured against. */
.tool-flyout.clipped .tool-flyout-use {
  left: 8px;
  right: 8px;
  top: calc(100% + 2px);
  transform: none;
  max-width: none;
}
/* Under the phone strip the menu sits below a horizontal rail, so the tip has no
   room to its right and belongs under the row instead. */
@media (max-width: 768px) {
  .tool-flyout-use {
    left: 8px;
    right: 8px;
    top: calc(100% + 4px);
    transform: none;
    max-width: none;
  }
}

/* ============================================================
   Selected drawing — action bar over the chart
   ============================================================ */
.drawing-actions {
  position: absolute;
  z-index: 6;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  max-width: calc(100% - 8px);
  padding: 4px 6px;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  background: rgba(19, 23, 34, 0.96);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
}
.drawing-actions-group { display: flex; align-items: center; gap: 3px; }
.drawing-actions-group + .drawing-actions-group {
  padding-left: 6px;
  border-left: 1px solid #2a2e39;
}
.drawing-swatch {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid #2a2e39;
  flex-shrink: 0;
}
.drawing-swatch:hover { border-color: #d1d4dc; }
.drawing-swatch.active { border-color: #ffffff; box-shadow: 0 0 0 1px #2962ff; }
.drawing-style {
  display: flex;
  align-items: center;
  width: 22px;
  height: 16px;
  border-radius: 3px;
  padding: 0 2px;
}
.drawing-style::after {
  content: '';
  display: block;
  width: 100%;
  border-top: 2px solid #787b86;
}
.drawing-style-dashed::after { border-top-style: dashed; }
.drawing-style-dotted::after { border-top-style: dotted; }
.drawing-style:hover { background: #2a2e39; }
.drawing-style.active { background: #2a2e39; }
.drawing-style.active::after { border-top-color: #d1d4dc; }
.drawing-width {
  min-width: 18px;
  height: 18px;
  border-radius: 3px;
  font-size: 10px;
  font-family: 'JetBrains Mono', monospace;
  color: #787b86;
}
.drawing-width:hover, .drawing-width.active { background: #2a2e39; color: #d1d4dc; }
.drawing-action {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 20px;
  padding: 0 6px;
  border-radius: 4px;
  font-size: 11px;
  color: #787b86;
  white-space: nowrap;
}
.drawing-action svg { width: 12px; height: 12px; }
.drawing-action:hover { background: #2a2e39; color: #d1d4dc; }
.drawing-action.active { background: #2962ff; color: #ffffff; }
.drawing-action-danger:hover { background: rgba(239, 83, 80, 0.16); color: #ef5350; }

/* ============================================================
   Chart header — mirrors ChartHeader.tsx
   ============================================================ */
.chart-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  border-bottom: 1px solid #2a2e39;
  background: #131722;
  padding: 6px 12px;
  font-size: 12px;
  color: #d1d4dc;
  flex-shrink: 0;
}

.chart-header .name-group {
  display: flex;
  align-items: center;
  gap: 4px;
}
.chart-header .name-group .name { font-weight: 600; }
.chart-header .name-group .sep { color: #787b86; }
.chart-header .name-group .muted { color: #787b86; }

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(38,166,154,0.15);
  color: #26a69a;
  font-size: 9px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 4px;
}
.status-badge.simulated {
  background: rgba(255,193,7,0.15);
  color: #ffc107;
}
/* A closed market has no pulse to show. */
.status-badge.closed {
  background: rgba(120,123,134,0.16);
  color: #9aa0aa;
}
.status-badge.closed .live-dot::before {
  animation: none;
  opacity: 0;
}
.live-dot {
  position: relative;
  display: inline-flex;
  height: 6px;
  width: 6px;
}
.live-dot::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: currentColor;
  animation: ping 1.5s cubic-bezier(0,0,0.2,1) infinite;
  opacity: 0.75;
}
.live-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: currentColor;
}
@keyframes ping {
  75%, 100% { transform: scale(2); opacity: 0; }
}

.candle-countdown {
  display: flex;
  align-items: center;
  gap: 6px;
}
.countdown-bar {
  position: relative;
  height: 12px;
  width: 64px;
  overflow: hidden;
  border-radius: 2px;
  background: #2a2e39;
}
.countdown-bar-fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 2px;
  transition: width 1s linear, background-color 0.3s ease;
}
.countdown-text {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.price-box {
  display: flex;
  align-items: center;
  gap: 4px;
}
.price-box .sell, .price-box .buy {
  display: flex;
  flex-direction: column;
  padding: 2px 8px;
  border-radius: 4px;
  cursor: pointer;
}
.price-box .sell { background: rgba(239,83,80,0.15); }
.price-box .sell:hover { background: rgba(239,83,80,0.30); }
.price-box .buy { background: rgba(41,98,255,0.15); }
.price-box .buy:hover { background: rgba(41,98,255,0.30); }
.price-box .sell .num { color: #ef5350; font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 600; }
.price-box .buy .num { color: #2962ff; font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 600; }
.price-box .lbl { font-size: 8px; text-transform: uppercase; letter-spacing: 0.05em; }
.price-box .sell .lbl { color: #ef5350; }
.price-box .buy .lbl { color: #2962ff; }

.ohlc {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
}
.ohlc .k { color: #787b86; }
.ohlc .chg.up { color: #26a69a; }
.ohlc .chg.down { color: #ef5350; }

/* Pin bar counter — shows count of pin bar patterns in visible candles */
.pin-bar-counter {
  display: flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(255, 193, 7, 0.1);
  border: 1px solid rgba(255, 193, 7, 0.3);
  color: #ffc107;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
.pin-bar-counter:hover {
  background: rgba(255, 193, 7, 0.2);
  border-color: rgba(255, 193, 7, 0.5);
}
.pin-bar-counter .pin-bull { color: #26a69a; }
.pin-bar-counter .pin-bear { color: #ef5350; }

.indicator-pills {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  color: #787b86;
}
.pill {
  background: #1e222d;
  padding: 2px 6px;
  border-radius: 4px;
}
.pill.rsi { color: #26a69a; cursor: pointer; }
.pill.rsi:hover { background: #2a2e39; }
/* Indicator pills are buttons: double-click opens their settings. */
button.pill { border: 0; font: inherit; cursor: pointer; }
button.pill:hover { background: #2a2e39; }
.pill.script-pill { color: #61afef; background: rgba(41, 98, 255, 0.2); }
.pill.has-error { box-shadow: inset 0 0 0 1px #ef5350; }
/* The remove control sits inside the pill, so it needs its own hit area. */
.pill-x {
  margin-left: 6px;
  padding: 0 2px;
  border-radius: 3px;
  color: #787b86;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
}
.pill-x:hover { color: #ef5350; background: rgba(239, 83, 80, 0.15); }

/* View controls sit with the indicator pills but are not indicators: they change
   how the chart behaves, so they read as a button that is on or off. */
.chart-view-controls {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
}
.view-toggle {
  border: 1px solid #2a2e39;
  background: #1e222d;
  color: #787b86;
  font: inherit;
  padding: 2px 6px;
  border-radius: 4px;
  cursor: pointer;
}
.view-toggle:hover { background: #2a2e39; color: #d1d4dc; }
.view-toggle.active {
  color: #26a69a;
  border-color: rgba(38, 166, 154, 0.4);
  background: rgba(38, 166, 154, 0.12);
}

/* ============================================================
   Right panel — mirrors AlertsPanel.tsx
   ============================================================ */
.right-tabs {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #2a2e39;
  padding: 0 8px;
  flex-shrink: 0;
}
/* Nine tabs do not fit the panel's narrowest legal width, and this strip is the only way
   to any of them, so it slides sideways instead of clipping the last ones off. The
   scrollbar is hidden rather than styled: the strip is barely taller than a tab, and a
   bar would sit where the active tab's underline is. */
.right-tabs .tabs {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.right-tabs .tabs::-webkit-scrollbar { display: none; }
.right-tab {
  position: relative;
  flex: 0 0 auto;
  padding: 8px 12px;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 500;
  color: #787b86;
}
.right-tab:hover { color: #d1d4dc; }
.right-tab.active { color: #d1d4dc; }
.right-tab.active::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%;
  height: 2px;
  background: #2962ff;
}
.right-tab .count {
  display: inline-block;
  background: #2962ff;
  color: white;
  font-size: 9px;
  font-weight: 700;
  padding: 1px 4px;
  border-radius: 8px;
  margin-left: 4px;
}
.right-tab .live-indicator {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #26a69a;
  margin-left: 4px;
  vertical-align: middle;
}

.right-content {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}
.right-content::-webkit-scrollbar { width: 8px; }
.right-content::-webkit-scrollbar-track { background: #131722; }
.right-content::-webkit-scrollbar-thumb { background: #2a2e39; border-radius: 4px; }

/* Collapsing the panel is the trader's own way back to a full-width chart. The
   floating widget's "Close panel" hides it outright; this keeps a rail on screen
   so the way out is also the way in, and the choice is a terminal setting, so the
   next visit opens the way the last one closed. */
.right-tabs-actions { display: flex; align-items: center; flex-shrink: 0; gap: 4px; margin-left: 8px; padding-left: 8px; border-left: 1px solid #2a2e39; }
#right-collapse { color: #d1d4dc; background: #1e222d; }
#right-collapse:hover { background: #2a2e39; }
#right-collapse svg { transition: transform 0.15s ease; }
body.panel-collapsed .right-content { display: none; }
body.panel-collapsed #right-resize-handle { display: none; }
/* Collapsed, the strip is the whole panel and its height is the strip's; an edge that
   could only be dragged into a drawer that is not open would be a handle that lies. */
body.panel-collapsed .panel-height-handle { display: none; }
body.panel-collapsed .right-panel { width: 40px !important; min-width: 0 !important; }
body.panel-collapsed .right-tabs { flex-direction: column; justify-content: flex-start; padding: 6px 0; border-bottom: none; }
body.panel-collapsed .right-tabs .tabs,
body.panel-collapsed #right-create-alert { display: none; }
body.panel-collapsed #right-collapse svg { transform: rotate(180deg); }

.tab-toolbar {
  display: flex;
  align-items: center;
  gap: 4px;
  border-bottom: 1px solid #2a2e39;
  padding: 4px 8px;
}
.tab-toolbar .search-wrap {
  position: relative;
  flex: 1;
}
.tab-toolbar input.search {
  width: 100%;
  height: 28px;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 4px;
  color: #d1d4dc;
  font-size: 12px;
  padding: 0 8px 0 24px;
  outline: none;
}
.tab-toolbar input.search:focus { border-color: #2962ff; }
.tab-toolbar input.search::placeholder { color: #787b86; }
.tab-toolbar .search-wrap svg {
  position: absolute;
  left: 6px; top: 50%;
  transform: translateY(-50%);
  color: #787b86;
  width: 14px; height: 14px;
}

/* The filter bar each row pane carries: the funnel says which rows are listed, the lines say how
   much of each row shows, and the label between them answers both at once. It is the only place
   that can say "4 of 61", and a filtered list without that sentence reads as a short account. */
.pane-bar { background: #131722; }
.pane-bar-label {
  margin-left: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  color: #787b86;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Compact drops the sentences under a row and keeps its headline and its number. Density is a
   stylesheet rather than a re-render: the same rows stay on screen at the same scroll, only less
   is said about each one. */
.list-compact .alert-list li .meta,
.list-compact .history-list li .prices,
.list-compact .position-list li .sltp,
.list-compact .position-list li .pos-origin,
.list-compact .position-list li .cur { display: none; }
.list-compact .alert-list li,
.list-compact .history-list li,
.list-compact .position-list li { padding-top: 4px; padding-bottom: 4px; }

/* Alert list */
.alert-list { list-style: none; }
.alert-list li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid #2a2e39;
}
.alert-list li:hover { background: #1e222d; }
.alert-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px; height: 20px;
}
.alert-icon .circle {
  width: 20px; height: 20px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: white;
  font-size: 9px;
  font-weight: 700;
}
.alert-icon svg { width: 16px; height: 16px; }
.alert-text { flex: 1; min-width: 0; }
.alert-text .cond { font-size: 12px; color: #d1d4dc; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alert-text .meta {
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  color: #787b86;
}
.alert-text .meta .sym { color: #d1d4dc; font-weight: 500; }
.alert-text .meta .status.active { color: #26a69a; }
.alert-text .meta .status.triggered { color: #ffc107; }
.alert-time { font-size: 10px; color: #787b86; }
.alert-del {
  margin-left: 4px;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px;
  color: #787b86;
  opacity: 0;
  transition: opacity 0.15s;
}
.alert-list li:hover .alert-del { opacity: 1; }
.alert-del:hover { background: rgba(239,83,80,0.2); color: #ef5350; }

.right-footer-summary {
  border-top: 1px solid #2a2e39;
  padding: 4px 8px;
  font-size: 10px;
  color: #787b86;
  flex-shrink: 0;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px;
  text-align: center;
  height: 100%;
  color: #787b86;
}
.empty-state .icon-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: #1e222d;
}
.empty-state .icon-wrap svg { width: 20px; height: 20px; color: #787b86; }
.empty-state .text { font-size: 12px; }
.empty-state .sub { font-size: 10px; }
.empty-state .create-btn {
  margin-top: 4px;
  background: #2962ff;
  color: white;
  font-size: 10px;
  font-weight: 500;
  padding: 4px 12px;
  border-radius: 4px;
}
.empty-state .create-btn:hover { background: #1e4bd8; }

/* Positions panel */
.positions-account {
  border-bottom: 1px solid #2a2e39;
  background: #1e222d;
  padding: 12px;
}
.positions-account .row1 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
}
.positions-account .label { color: #787b86; display: flex; align-items: center; gap: 4px; }
.positions-account .label svg { width: 12px; height: 12px; }
.positions-account .equity {
  margin-top: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 18px;
  font-weight: 700;
  color: #d1d4dc;
}
.positions-account .row3 {
  margin-top: 2px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 10px;
}
.positions-account .bal { font-family: 'JetBrains Mono', monospace; color: #787b86; }
.positions-account .pct.up { color: #26a69a; font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.positions-account .pct.down { color: #ef5350; font-family: 'JetBrains Mono', monospace; font-weight: 600; }

.positions-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #2a2e39;
  padding: 6px 12px;
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #787b86;
}

.position-list { list-style: none; }
.position-list li {
  padding: 8px 12px;
  border-bottom: 1px solid #2a2e39;
  cursor: pointer;
  border-left: 2px solid transparent;
}
.position-list li:hover { background: #1e222d; }
.position-list li.active { border-left-color: #2962ff; background: rgba(41,98,255,0.05); }
.position-list .top-row { display: flex; align-items: center; justify-content: space-between; }
.position-list .info { display: flex; align-items: center; gap: 6px; }
.position-list .side-badge {
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  border-radius: 4px;
}
.position-list .side-badge.buy { background: rgba(38,166,154,0.2); color: #26a69a; }
.position-list .side-badge.sell { background: rgba(239,83,80,0.2); color: #ef5350; }
.position-list .side-badge svg { width: 12px; height: 12px; }
.position-list .sym { font-size: 12px; font-weight: 600; }
.position-list .viewing-tag {
  background: rgba(41,98,255,0.15);
  color: #2962ff;
  font-size: 8px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 4px;
  border-radius: 4px;
}
.position-list .pos-meta { font-size: 10px; color: #787b86; }
.position-list .close-btn {
  font-size: 10px;
  font-weight: 500;
  color: #787b86;
  padding: 2px 6px;
  border-radius: 4px;
}
.position-list .close-btn:hover { background: rgba(239,83,80,0.2); color: #ef5350; }
.position-list .bottom-row {
  margin-top: 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 10px;
}
.position-list .cur { font-family: 'JetBrains Mono', monospace; color: #787b86; }
.position-list .pnl.up { color: #26a69a; font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.position-list .pnl.down { color: #ef5350; font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.position-list .sltp { display: flex; gap: 8px; margin-top: 4px; font-size: 9px; }
.position-list .sl { background: rgba(239,83,80,0.1); color: #ef5350; padding: 2px 4px; border-radius: 4px; }
.position-list .tp { background: rgba(38,166,154,0.1); color: #26a69a; padding: 2px 4px; border-radius: 4px; }
.position-list .lock { background: rgba(255,193,7,0.14); color: #ffc107; padding: 2px 4px; border-radius: 4px; font-family: 'JetBrains Mono', monospace; }
/* Which signal opened the trade, what it said, and the bar it read it on. The reason is the
   longest of the three and the row is narrow, so it is the line that wraps rather than the
   source chip or the bar button — a clipped reason is a row that no longer says what fired. */
.position-list .pos-origin { display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px; margin-top: 4px; font-size: 9px; color: #9aa0ac; }
.position-list .pos-origin .src { background: rgba(41,98,255,0.14); color: #7a9bff; padding: 2px 4px; border-radius: 4px; font-family: 'JetBrains Mono', monospace; }
.position-list .pos-origin .why { flex: 1 1 auto; min-width: 0; line-height: 1.35; }
.position-list .pos-origin .bar { background: transparent; border: none; border-bottom: 1px dotted #787b86; color: #d1d4dc; font-size: 9px; font-family: 'JetBrains Mono', monospace; padding: 0 1px; cursor: pointer; }
.position-list .pos-origin .bar:hover { color: #7a9bff; border-bottom-color: #7a9bff; }

.positions-footer {
  border-top: 1px solid #2a2e39;
  background: #1e222d;
  padding: 6px 12px;
  font-size: 10px;
}
.positions-footer .row { display: flex; align-items: center; justify-content: space-between; }
.positions-footer .lbl { color: #787b86; }
.positions-footer .val.up { color: #26a69a; font-family: 'JetBrains Mono', monospace; font-weight: 600; }
.positions-footer .val.down { color: #ef5350; font-family: 'JetBrains Mono', monospace; font-weight: 600; }

/* History panel */
.history-summary {
  border-bottom: 1px solid #2a2e39;
  background: #1e222d;
  padding: 12px;
}
.history-summary .row { display: flex; align-items: center; justify-content: space-between; font-size: 12px; }
.history-summary .lbl { color: #787b86; }
.history-summary .val.up { color: #22c55e; font-family: 'JetBrains Mono', monospace; font-weight: 700; }
.history-summary .val.down { color: #ef4444; font-family: 'JetBrains Mono', monospace; font-weight: 700; }
.history-summary .sub { margin-top: 4px; display: flex; align-items: center; justify-content: space-between; font-size: 10px; color: #787b86; }

.history-list { list-style: none; }
.history-list li {
  padding: 8px 12px;
  border-bottom: 1px solid #2a2e39;
}
.history-list li:hover { background: #1e222d; }
.history-list .top { display: flex; align-items: center; justify-content: space-between; }
.history-list .info { display: flex; align-items: center; gap: 8px; }
.history-list .side-icon {
  display: flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  border-radius: 4px;
}
.history-list .side-icon.buy { background: rgba(34,197,94,0.2); color: #22c55e; }
.history-list .side-icon.sell { background: rgba(239,68,68,0.2); color: #ef4444; }
.history-list .side-icon svg { width: 12px; height: 12px; }
.history-list .sym { font-size: 12px; font-weight: 600; }
.history-list .side-text { font-size: 10px; color: #787b86; text-transform: uppercase; }
.history-list .prices { font-size: 10px; color: #787b86; margin-top: 2px; }
.history-list .pnl { font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 600; }
.history-list .pnl.up { color: #22c55e; }
.history-list .pnl.down { color: #ef4444; }
.history-list .time { font-size: 9px; color: #787b86; }

/* Log rows: the timeframe and date sit under the clock, and a close is written
   under the signal that caused it rather than as its own row. */
.log-meta { font-size: 9px; color: #787b86; opacity: 0.8; margin-top: 2px; }
.log-result { color: #d1d4dc; }
.log-arrow { color: #787b86; }
li.jumpable { cursor: pointer; }
li.jumpable:hover { background: #262b38; }

/* Where the replay was cut. It marks a bar on the time axis, so it is a canvas
   overlay re-projected on pan and zoom rather than a saved drawing. */
#replay-cut-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px dashed #ffc107;
  z-index: 6;
  pointer-events: none;
}

/* While the cut is armed the line is a preview of the bar under the scissors,
   not yet the cut itself, so it reads lighter than a committed one. */
#replay-cut-line.ghost { opacity: 0.55; }

/* Armed scissors ride the cursor: the icon's blades cross at 13,12, which is
   also the aim point, so the bar they hover is the bar that gets cut. The
   crosshair behind it keeps the aim precise on a browser that declines a custom
   cursor. */
#chart-container.cut-armed {
  cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='24'%20height='24'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23ffc107'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='6'%20cy='6'%20r='3'/%3E%3Ccircle%20cx='6'%20cy='18'%20r='3'/%3E%3Cpath%20d='M8.1%207.9L20%2018M20%206L8.1%2016.1'/%3E%3C/svg%3E") 13 12, crosshair;
}

/* ============================================================
   Bottom bar — mirrors BottomBar.tsx
   ============================================================ */
.bottombar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid #2a2e39;
  background: #131722;
  padding: 0 12px;
  height: 28px;
  font-size: 10px;
  color: #787b86;
  flex-shrink: 0;
}
.bottombar .group { display: flex; align-items: center; gap: 8px; }
.bottombar .paper-trading {
  display: flex;
  align-items: center;
  gap: 4px;
  border-radius: 4px;
  padding: 2px 6px;
  cursor: pointer;
}
.bottombar .paper-trading:hover { background: #2a2e39; }
.bottombar .pipe { color: #2a2e39; }
.bottombar .connected { color: #26a69a; }
.bottombar .equity-btn {
  border-radius: 4px;
  padding: 2px 6px;
  color: #d1d4dc;
  cursor: pointer;
}
.bottombar .equity-btn:hover { background: #2a2e39; }
.bottombar .equity-val { font-family: 'JetBrains Mono', monospace; font-weight: 600; font-variant-numeric: tabular-nums; }

.bottombar .nav-arrow {
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px;
}
.bottombar .nav-arrow:hover { background: #2a2e39; color: #d1d4dc; }
.bottombar .nav-arrow svg { width: 12px; height: 12px; }
.bottombar .date-now { font-family: 'JetBrains Mono', monospace; font-variant-numeric: tabular-nums; color: #d1d4dc; }

.bottombar .zoom-bar {
  display: flex;
  align-items: center;
  gap: 2px;
  border: 1px solid #2a2e39;
  border-radius: 4px;
  padding: 0 2px;
}
.bottombar .zoom-btn {
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 4px;
  color: #787b86;
}
.bottombar .zoom-btn:hover { background: #2a2e39; color: #d1d4dc; }
.bottombar .zoom-btn svg { width: 12px; height: 12px; }
.bottombar .zoom-val {
  min-width: 32px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: #d1d4dc;
  font-variant-numeric: tabular-nums;
}

.bottombar .range-group { display: flex; align-items: center; gap: 2px; }
.bottombar .range-btn {
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 10px;
  color: #787b86;
}
.bottombar .range-btn:hover { background: #2a2e39; color: #d1d4dc; }
.bottombar .range-btn.active { background: #2a2e39; color: #d1d4dc; }

.bottombar .server-time { font-family: 'JetBrains Mono', monospace; color: #d1d4dc; font-variant-numeric: tabular-nums; }

/* ============================================================
   Trade drawer (Sheet) — mirrors TradeDrawer.tsx
   ============================================================ */
.sheet-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 200;
  display: none;
}
.sheet-overlay.open { display: block; }
.sheet {
  position: fixed;
  top: 0; right: 0;
  height: 100vh;
  width: 100%;
  max-width: 448px;
  background: #131722;
  border-left: 1px solid #2a2e39;
  z-index: 201;
  transform: translateX(100%);
  transition: transform 0.25s;
  display: flex;
  flex-direction: column;
  color: #d1d4dc;
}
.sheet.open { transform: translateX(0); }
.sheet-header {
  border-bottom: 1px solid #2a2e39;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.sheet-title { font-size: 16px; font-weight: 600; color: #d1d4dc; }
.sheet-subtitle { font-size: 12px; color: #787b86; }
.sheet-close {
  padding: 4px;
  border-radius: 4px;
  color: #787b86;
}
.sheet-close:hover { background: #2a2e39; color: #d1d4dc; }
.sheet-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.bid-ask-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.bid-ask-box {
  border-radius: 6px;
  padding: 8px;
}
.bid-ask-box.sell { border: 1px solid rgba(239,83,80,0.3); background: rgba(239,83,80,0.1); }
.bid-ask-box.buy { border: 1px solid rgba(41,98,255,0.3); background: rgba(41,98,255,0.1); }
.bid-ask-box .lbl { font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; }
.bid-ask-box.sell .lbl { color: #ef5350; }
.bid-ask-box.buy .lbl { color: #2962ff; }
.bid-ask-box .val { font-family: 'JetBrains Mono', monospace; font-size: 14px; font-weight: 600; }
.bid-ask-box.sell .val { color: #ef5350; }
.bid-ask-box.buy .val { color: #2962ff; }

.field-label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  color: #787b86;
}

/* Small readout under a form field — e.g. the SL distance in pips. */
.hint {
  margin-top: 4px;
  font-size: 10px;
  color: #787b86;
  font-family: 'JetBrains Mono', monospace;
}

.tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: #1e222d;
  border-radius: 6px;
  padding: 4px;
  gap: 2px;
}
.tab-btn {
  padding: 6px;
  font-size: 12px;
  font-weight: 500;
  color: #787b86;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
.tab-btn:hover { color: #d1d4dc; }
.tab-btn.active.buy { background: #26a69a; color: white; }
.tab-btn.active.sell { background: #ef5350; color: white; }
.tab-btn.active.blue { background: #2962ff; color: white; }
.tab-btn svg { width: 12px; height: 12px; }

.input-field {
  width: 100%;
  height: 36px;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 4px;
  color: #d1d4dc;
  font-size: 14px;
  padding: 0 10px;
  outline: none;
  font-family: 'JetBrains Mono', monospace;
}
.input-field:focus { border-color: #2962ff; }

.size-presets { display: flex; gap: 4px; margin-top: 6px; }
.size-presets button {
  background: #1e222d;
  color: #787b86;
  font-size: 10px;
  padding: 4px 8px;
  border-radius: 4px;
}
.size-presets button:hover { background: #2a2e39; color: #d1d4dc; }

.summary-box {
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  padding: 12px;
  font-size: 12px;
}
.summary-box .row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.summary-box .row + .row { margin-top: 6px; padding-top: 6px; border-top: 1px solid #2a2e39; }
.summary-box .val { font-family: 'JetBrains Mono', monospace; color: #d1d4dc; }

.error-box {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(239,83,80,0.4);
  background: rgba(239,83,80,0.1);
  padding: 8px;
  border-radius: 6px;
  font-size: 12px;
  color: #ef5350;
}

.submit-btn {
  height: 40px;
  width: 100%;
  font-weight: 600;
  color: white;
  border-radius: 4px;
  font-size: 13px;
}
.submit-btn.buy { background: #26a69a; }
.submit-btn.buy:hover { background: #1e8475; }
.submit-btn.sell { background: #ef5350; }
.submit-btn.sell:hover { background: #d23f3f; }

.sheet-foot-note { text-align: center; font-size: 10px; color: #787b86; }

/* ============================================================
   Alert dialog
   ============================================================ */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
}
.modal-overlay.open { display: flex; }
.modal {
  background: #131722;
  border: 1px solid #2a2e39;
  border-radius: 8px;
  width: 100%;
  max-width: 448px;
  max-height: 90vh;
  overflow-y: auto;
  padding: 20px;
  color: #d1d4dc;
}
/* The strip of a dialog that moves the whole panel. It has to look grabbable
   before the hand gets there, or a trader never finds out the dialog can move. */
.modal-drag-handle {
  cursor: grab;
  user-select: none;
  touch-action: none;
}
.modal-drag-handle.dragging { cursor: grabbing; }
.modal-drag-handle button { cursor: pointer; }
.modal-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 4px;
}
.modal-title svg { color: #2962ff; width: 16px; height: 16px; }
.modal-desc { font-size: 12px; color: #787b86; margin-bottom: 16px; }

.op-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 12px;
}
.op-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 1px solid #2a2e39;
  background: #1e222d;
  color: #787b86;
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
}
.op-btn:hover { background: #2a2e39; color: #d1d4dc; }
.op-btn.active { border-color: #2962ff; background: rgba(41,98,255,0.1); color: #d1d4dc; }
.op-btn svg { width: 12px; height: 12px; }

.preview-box {
  border: 1px solid #2a2e39;
  background: #0d1117;
  padding: 10px;
  border-radius: 6px;
  font-size: 12px;
  margin-bottom: 12px;
}
.preview-box .lbl {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #787b86;
  margin-bottom: 4px;
}
.preview-box .preview-text {
  font-family: 'JetBrains Mono', monospace;
  color: #d1d4dc;
}
.preview-box .preview-text .sym { color: #2962ff; font-weight: 600; }
.preview-box .preview-text .muted { color: #787b86; }

.alert-config-box {
  border-top: 1px solid #2a2e39;
  padding-top: 12px;
  margin-top: 12px;
}
.alert-config-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 1px solid #2a2e39;
  background: #1e222d;
  padding: 8px 12px;
  border-radius: 6px;
  margin-bottom: 4px;
  font-size: 12px;
}
.alert-config-row .lbl { color: #787b86; }
.alert-config-row .val { color: #d1d4dc; font-family: 'JetBrains Mono', monospace; }

/* RSI settings rows — match the reference dialog layout */
.rsi-setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
  border: 1px solid #2a2e39;
  background: #1e222d;
  padding: 8px 12px;
  border-radius: 6px;
  margin-bottom: 6px;
  font-size: 12px;
}
/* Same contract as .ind-label: the row name gives up width before the control
   does, because the control is the part that has to stay reachable. */
.rsi-setting-row .lbl {
  color: #787b86;
  font-size: 12px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.rsi-input {
  width: 90px;
  max-width: 90px;
  flex: 0 0 auto;
  background: transparent;
  border: none;
  color: #d1d4dc;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
  outline: none;
  text-align: right;
  font-weight: 600;
}
.rsi-select {
  background: transparent;
  border: none;
  color: #d1d4dc;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
  outline: none;
  cursor: pointer;
  font-weight: 600;
  text-align: right;
  padding-right: 4px;
  flex: 0 1 auto;
  max-width: 150px;
}
.rsi-select option {
  background: #1e222d;
  color: #d1d4dc;
}

.notify-channels {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.notify-chip {
  background: #2a2e39;
  color: #787b86;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 500;
}
.notify-chip.active { background: #2962ff; color: white; }
.notify-chip:hover { color: #d1d4dc; }

.modal-footer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 16px;
}
.btn-outline {
  border: 1px solid #2a2e39;
  background: #1e222d;
  color: #787b86;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 500;
}
.btn-outline:hover { background: #2a2e39; color: #d1d4dc; }
.btn-primary {
  background: #2962ff;
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 6px;
}
.btn-primary:hover { background: #1e4bd8; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
/* An outline button that is switched off has to look switched off: the paper money actions in the
   profile dialog are disabled while a broker account is trading, and a row that only refuses on
   press reads as a broken button rather than as a deliberate no. */
.btn-outline:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary svg { width: 14px; height: 14px; }

/* ============================================================
   Toasts
   ============================================================ */
#toast-host {
  position: fixed;
  bottom: 40px;
  right: 16px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
.toast {
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-left: 3px solid #2962ff;
  padding: 10px 14px;
  border-radius: 4px;
  min-width: 240px;
  max-width: 360px;
  font-size: 12px;
  color: #d1d4dc;
  box-shadow: 0 10px 30px rgba(0,0,0,0.5);
  animation: toastIn 0.25s ease-out;
  pointer-events: auto;
}
@keyframes toastIn {
  from { transform: translateY(8px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* ============================================================
   Chart watermark + live indicator
   ============================================================ */
.chart-watermark {
  position: absolute;
  bottom: 34px; left: 14px;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 6px;
  /* A watermark is read underneath the data, not as a label on top of it: big,
     low contrast, and out of the way of the price scale. */
  opacity: 0.09;
  pointer-events: none;
  user-select: none;
}
.chart-watermark .label {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #d1d4dc;
}

/* The way out of a zoomed-in or pinned chart, in the corner the price scale is
   in. Small on purpose: it sits over the chart, and the candles matter more. */
.chart-fit-btn {
  position: absolute;
  right: 3px;
  bottom: 30px;
  z-index: 11;
  background: rgba(19, 23, 34, 0.78);
  border: 1px solid #2a2e39;
  border-radius: 3px;
  color: #787b86;
  font-family: Inter, sans-serif;
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
  padding: 4px 7px;
  cursor: pointer;
}
.chart-fit-btn:hover { color: #d1d4dc; border-color: #363a45; background: #1e222d; }
.chart-fit-btn:active { background: #2a2e39; }

.chart-live-indicator {
  position: absolute;
  top: 8px; right: 12px;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(30,34,45,0.8);
  backdrop-filter: blur(4px);
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 500;
  color: #26a69a;
}

/* The Copilot's three votes, drawn on the chart. It sits low-left, clear of the
   position panel at the top and the price scale on the right, and its body never
   takes the pointer: a meter you cannot drag the chart through is furniture.
   What does take the pointer is the head row of it — the bar that reads as the
   panel's title, which is where a hand goes looking for a handle. The dots inside
   it are the sign, not the whole grip: eight pixels of them is a handle nobody
   finds, and a handle nobody finds is a panel that cannot be moved. */
.signal-strength {
  position: absolute;
  left: 8px;
  bottom: 28px;
  z-index: 24;
  width: 204px;
  padding: 7px 9px 8px;
  background: rgba(19, 23, 34, 0.86);
  border: 1px solid #2a2e39;
  border-radius: 6px;
  backdrop-filter: blur(3px);
  font-size: 10px;
  color: #d1d4dc;
  pointer-events: none;
}
.signal-strength.dragging {
  border-color: rgba(41, 98, 255, 0.6);
}
.signal-strength .ss-head {
  display: flex;
  align-items: baseline;
  justify-content: flex-start;
  gap: 5px;
  /* The padding is the hit area and the negative margin cancels it, so the head
     is grabbable across its whole width without moving the reading or the rows. */
  margin: -2px -3px 5px;
  padding: 2px 3px;
  border-radius: 4px;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.signal-strength .ss-head:hover { background: rgba(41, 98, 255, 0.12); }
.signal-strength .ss-head.dragging {
  cursor: grabbing;
  background: rgba(41, 98, 255, 0.18);
}
.signal-strength .ss-grip {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
  color: #8b93a3;
  font-size: 12px;
  line-height: 1;
  /* The dots are the sign that the head is a handle; they should not widen the
     meter or push its reading along when the hand arrives. */
  transition: color 0.12s;
}
.signal-strength .ss-grip:hover,
.signal-strength .ss-grip.dragging { color: #d1d4dc; }
.signal-strength .ss-grip.dragging { cursor: grabbing; }
.signal-strength .ss-direction {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.signal-strength .ss-confidence {
  font-family: 'JetBrains Mono', monospace;
  color: #787b86;
  margin-left: auto;
}
.signal-strength .ss-rows {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.signal-strength .ss-row {
  display: grid;
  /* label · bar · the number the bar was drawn from. The label column is as wide as
     the widest of the three votes ("Bar Trend (10)") so no row reads as
     "Bar Trend (1…": a meter whose own rows are cut off cannot be trusted to have
     counted them either. */
  grid-template-columns: 74px 1fr 26px;
  align-items: center;
  gap: 6px;
}
.signal-strength .ss-label {
  color: #787b86;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.signal-strength .ss-track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: #1e222d;
  overflow: hidden;
}
.signal-strength .ss-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 3px;
}
/* The figure beside each bar, in that bar's own colour: a row at 8% and a row at
   92% are the same length of ink apart, and a trader reading the meter should not
   have to measure them. */
.signal-strength .ss-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-align: right;
}
.signal-strength .ss-pending { color: #787b86; }

/* The gap readings, laid out beside the bars they were computed from. Same plate,
   same head-as-handle, same pointer-transparent body as the strength meter: a second
   style of floating panel would be a second thing for the trader to learn, and the
   reason the meter's rows take no mouse is the reason these rows take none either.
   Its first home is under the open-position strip, not beside it: that strip is above
   this panel in the stack and it takes the pointer, so a head parked in its corner is a
   handle the trader cannot find once a position is open — which is when they need it. */
.fvg-dashboard {
  position: absolute;
  left: 8px;
  top: 78px;
  z-index: 24;
  width: 248px;
  padding: 7px 9px 8px;
  background: rgba(19, 23, 34, 0.86);
  border: 1px solid #2a2e39;
  border-radius: 6px;
  backdrop-filter: blur(3px);
  font-size: 10px;
  color: #d1d4dc;
  pointer-events: none;
}
.fvg-dashboard.dragging { border-color: rgba(41, 98, 255, 0.6); }
.fvg-dashboard .fd-head {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin: -2px -3px 5px;
  padding: 2px 3px;
  border-radius: 4px;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.fvg-dashboard .fd-head:hover { background: rgba(41, 98, 255, 0.12); }
.fvg-dashboard .fd-head.dragging {
  cursor: grabbing;
  background: rgba(41, 98, 255, 0.18);
}
.fvg-dashboard .fd-grip {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
  color: #8b93a3;
  font-size: 12px;
  line-height: 1;
  transition: color 0.12s;
}
.fvg-dashboard .fd-grip:hover,
.fvg-dashboard .fd-grip.dragging { color: #d1d4dc; }
.fvg-dashboard .fd-grip.dragging { cursor: grabbing; }
.fvg-dashboard .fd-title {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.fvg-dashboard .fd-count {
  font-family: 'JetBrains Mono', monospace;
  color: #787b86;
  margin-left: auto;
}
.fvg-dashboard .fd-rows {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.fvg-dashboard .fd-row {
  display: grid;
  grid-template-columns: 58px 1fr;
  align-items: baseline;
  gap: 6px;
}
.fvg-dashboard .fd-label {
  color: #787b86;
  white-space: nowrap;
}
/* The answer in the column beside its question, in the tape's own face: these are
   numbers a trader reads against the price scale, not sentences. */
.fvg-dashboard .fd-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The stack's verdict, above the rows about one zone: the word is the answer and the track
   beside it is the evidence, so a 51/49 stack cannot read like a 100/0 one. The same 6px
   plate as the strength meter's rows — a second style of meter would be a second thing for
   the trader to learn — with its two halves side by side rather than overlaid, because the
   place they meet is the whole point. */
.fvg-dashboard .fd-bias {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
}
.fvg-dashboard .fd-bias-word {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.fvg-dashboard .fd-bias-track {
  display: flex;
  height: 6px;
  border-radius: 3px;
  background: #1e222d;
  overflow: hidden;
}
.fvg-dashboard .fd-bias-bull,
.fvg-dashboard .fd-bias-bear { height: 100%; }
.fvg-dashboard .fd-bias-share {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  text-align: right;
}
/* How many zones the verdict was worked over, beside the verdict: the counts and the widths
   are two yardsticks on the same stack, and a trader who wants the other one should not
   have to take the panel's word for which it used. */
.fvg-dashboard .fd-bias-note {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: #787b86;
  margin-bottom: 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid #232838;
}
/* The ranked stack, one line per open gap, each with a bar of its own so the order is read
   before any figure is. The fill widths are written inline, from the same shares the verdict
   above was worked out of, so the ladder and the word cannot describe two different tapes. */
.fvg-dashboard .fd-ladder {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 4px;
  padding-top: 5px;
  border-top: 1px solid #232838;
}
.fvg-dashboard .fd-gap {
  display: grid;
  grid-template-columns: 11px 1fr 42px;
  align-items: center;
  gap: 5px;
}
.fvg-dashboard .fd-gap-side,
.fvg-dashboard .fd-gap-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
}
.fvg-dashboard .fd-gap-pct { text-align: right; }
.fvg-dashboard .fd-gap-track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: #1e222d;
  overflow: hidden;
}
.fvg-dashboard .fd-gap-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 3px;
}
.fvg-dashboard .fd-gap-more {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: #787b86;
}
.fvg-dashboard .fd-pending { color: #787b86; }

/* Bandizer dashboard — the six newest support and resistance boxes, which side of them the
   tape is weighing in on, and what it means that price has or has not crossed the mid. It is
   a third floating panel, so it is built out of the same two shapes the trader has already
   learned: this panel's box and the strength meter's track. Nothing new is taught to read it.

   Its first home is to the right of the gap panel rather than under it. Both panels are
   draggable and the trader's chosen spot is remembered, but a fresh one that lands on top of
   the panel they already had open looks like a bug in the second panel, not like bad luck in
   the first. */
.bandizer-dashboard {
  position: absolute;
  left: 264px;
  top: 78px;
  z-index: 24;
  width: 268px;
  padding: 7px 9px 8px;
  background: rgba(19, 23, 34, 0.86);
  border: 1px solid #2a2e39;
  border-radius: 6px;
  backdrop-filter: blur(3px);
  font-size: 10px;
  color: #d1d4dc;
  pointer-events: none;
}
.bandizer-dashboard.dragging { border-color: rgba(41, 98, 255, 0.6); }
/* Folded: the head keeps the verdict and how many boxes stand behind it, and the rows close.
   The head's own bottom margin was spacing from the rows, so it goes with them. */
.bandizer-dashboard.folded .bz-rows { display: none; }
.bandizer-dashboard.folded .bz-head { margin-bottom: 0; }
/* Parked: the panel shares its edge with the price axis and hangs under the price tag. It is
   attached to the scale the boxes are priced on, so it takes that scale's emphasis rather than
   the drag border. */
.bandizer-dashboard.docked {
  border-color: rgba(139, 147, 163, 0.45);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45);
}
.bandizer-dashboard .bz-head {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin: -2px -3px 5px;
  padding: 2px 3px;
  border-radius: 4px;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.bandizer-dashboard .bz-head:hover { background: rgba(41, 98, 255, 0.12); }
.bandizer-dashboard .bz-head.dragging {
  cursor: grabbing;
  background: rgba(41, 98, 255, 0.18);
}
.bandizer-dashboard .bz-grip {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
  color: #8b93a3;
  font-size: 12px;
  line-height: 1;
  transition: color 0.12s;
}
.bandizer-dashboard .bz-grip:hover,
.bandizer-dashboard .bz-grip.dragging { color: #d1d4dc; }
.bandizer-dashboard .bz-grip.dragging { cursor: grabbing; }
.bandizer-dashboard .bz-title {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.bandizer-dashboard .bz-count {
  font-family: 'JetBrains Mono', monospace;
  color: #787b86;
  margin-left: auto;
}
/* The head's two controls sit at its right hand, past the count. They are the only part of the
   panel's body that takes the pointer besides the grip, and a button the drag treats as a handle
   would move the panel instead of folding it — so they stop the grab, not the head. */
.bandizer-dashboard .bz-tools {
  display: flex;
  gap: 3px;
  pointer-events: auto;
}
.bandizer-dashboard .bz-btn {
  pointer-events: auto;
  cursor: pointer;
  padding: 0 3px;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: #8b93a3;
  font-family: inherit;
  font-size: 10px;
  line-height: 1.2;
  transition: color 0.12s, border-color 0.12s;
}
.bandizer-dashboard .bz-btn:hover {
  color: #d1d4dc;
  border-color: #3a4050;
}
.bandizer-dashboard .bz-btn.on {
  color: #2962ff;
  border-color: rgba(41, 98, 255, 0.5);
}
.bandizer-dashboard .bz-rows {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bandizer-dashboard .bz-row {
  display: grid;
  grid-template-columns: 58px 1fr;
  align-items: baseline;
  gap: 6px;
}
.bandizer-dashboard .bz-label {
  color: #787b86;
  white-space: nowrap;
}
/* The answer in the column beside its question, in the tape's own face. Unlike the gap panel's
   values these are sentences rather than figures, and a row that says the crossing was thirty
   bars ago at 18:42 is worth the second line it takes — an ellipsis on a trading panel hides the
   one thing the trader came to read. */
.bandizer-dashboard .bz-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  white-space: normal;
}
/* The verdict first and alone on its own line: it is the word the trader came for, and the
   meter and rows under it are the evidence for it, so it gets no label column to share. */
.bandizer-dashboard .bz-verdict {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  margin-bottom: 2px;
}
/* The sentence under the word. It is what is happening, in plain language, on the face of the card
   rather than one hover away, and it is the one line here that wraps: a trader who has to mouse
   over the panel to learn that the floors all broke is not reading a dashboard. */
.bandizer-dashboard .bz-plain {
  font-size: 10px;
  line-height: 1.35;
  color: #a9b0be;
  margin-bottom: 4px;
}
.bandizer-dashboard .bz-bias {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
}
/* Both bars carry words, not bare figures: the number on the left of the strength bar is nothing
   until the word on its right says which way it points, and the sides bar is unreadable without
   knowing that green is floors and red is ceilings. */
.bandizer-dashboard .bz-bias-word {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.bandizer-dashboard .bz-bias-track {
  display: flex;
  height: 6px;
  border-radius: 3px;
  background: #1e222d;
  overflow: hidden;
}
.bandizer-dashboard .bz-bias-bull,
.bandizer-dashboard .bz-bias-bear { height: 100%; }
.bandizer-dashboard .bz-bias-note {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: #787b86;
  margin-bottom: 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid #232838;
}
.bandizer-dashboard .bz-ladder {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 3px;
  padding-top: 4px;
  border-top: 1px solid #232838;
}
.bandizer-dashboard .bz-box {
  display: grid;
  grid-template-columns: 11px 1fr auto;
  align-items: center;
  gap: 6px;
}
.bandizer-dashboard .bz-box-side,
.bandizer-dashboard .bz-box-range,
.bandizer-dashboard .bz-box-held {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
}
.bandizer-dashboard .bz-box-range { color: #d1d4dc; }
.bandizer-dashboard .bz-box-held { text-align: right; }
.bandizer-dashboard .bz-box-more {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: #787b86;
}
.bandizer-dashboard .bz-pending { color: #787b86; }

/* The Stood card: the same card as the three readings around it, parked to the right of the levels
   panel rather than under it. The two are read together — one weighs the boxes, the other counts how
   long they have been there — and the levels panel changes height when it folds or when the ladder
   fills, so a card underneath it would be moved by a fold it has nothing to do with. */
.stood-dashboard {
  position: absolute;
  left: 548px;
  top: 78px;
  z-index: 24;
  width: 268px;
  padding: 7px 9px 8px;
  background: rgba(19, 23, 34, 0.86);
  border: 1px solid #2a2e39;
  border-radius: 6px;
  backdrop-filter: blur(3px);
  font-size: 10px;
  color: #d1d4dc;
  pointer-events: none;
}
.stood-dashboard.dragging { border-color: rgba(41, 98, 255, 0.6); }
.stood-dashboard .sd-head {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin: -2px -3px 5px;
  padding: 2px 3px;
  border-radius: 4px;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.stood-dashboard .sd-head:hover { background: rgba(41, 98, 255, 0.12); }
.stood-dashboard .sd-head.dragging {
  background: rgba(41, 98, 255, 0.16);
  cursor: grabbing;
}
.stood-dashboard .sd-grip {
  color: #454a54;
  font-size: 11px;
  cursor: grab;
  pointer-events: auto;
  touch-action: none;
}
.stood-dashboard .sd-grip:hover,
.stood-dashboard .sd-grip.dragging { color: #d1d4dc; }
.stood-dashboard .sd-grip.dragging { cursor: grabbing; }
.stood-dashboard .sd-title {
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stood-dashboard .sd-count {
  margin-left: auto;
  color: #787b86;
  font-size: 9.5px;
  white-space: nowrap;
}
.stood-dashboard .sd-rows {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.stood-dashboard .sd-row {
  display: grid;
  grid-template-columns: 66px 1fr;
  align-items: baseline;
  gap: 6px;
}
.stood-dashboard .sd-label {
  color: #787b86;
  white-space: nowrap;
}
/* The level a total is made of, not the total: a price range beside the bars it has stood. These
   wrap rather than ellipsis, because the one figure the trader came to check is the price. */
.stood-dashboard .sd-value {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  white-space: normal;
}
.stood-dashboard .sd-bias {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
}
.stood-dashboard .sd-bias-word {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.stood-dashboard .sd-bias-track {
  display: flex;
  height: 6px;
  border-radius: 3px;
  background: #1e222d;
  overflow: hidden;
}
.stood-dashboard .sd-bias-bull,
.stood-dashboard .sd-bias-bear { height: 100%; }
.stood-dashboard .sd-bias-note {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: #787b86;
  margin: 2px 0 4px;
  padding-bottom: 4px;
  border-bottom: 1px solid #232838;
  white-space: normal;
}
.stood-dashboard .sd-pending { color: #787b86; }

/* The entries panel: the same card as the two readings above it, parked bottom-left where
   neither of them sits, because it is about the book rather than the tape and a trader who
   wants both on screen at once should not have to move either. */
.entries-dashboard {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 24;
  /* Wide enough that its head — "ENTRIES · 1H" plus the tally — is one line at the longest the
     tally gets, because the alternative is a second line of small grey type sitting over the
     first entry. */
  width: 300px;
  padding: 7px 9px 8px;
  background: rgba(19, 23, 34, 0.86);
  border: 1px solid #2a2e39;
  border-radius: 6px;
  backdrop-filter: blur(3px);
  font-size: 10px;
  color: #d1d4dc;
  pointer-events: none;
}
.entries-dashboard.dragging { border-color: rgba(41, 98, 255, 0.6); }
/* Folded: the head keeps the tally of what is open on this width and the trend line under it keeps
   the direction, which are the two a trader glances at while the tape runs; the rows close, because
   those five lines are the part the Positions tab and the Strategy report already own. Unlike the
   Bandizer card the head's own bottom margin stays — the line it spaces from is still there. */
.entries-dashboard.folded .en-rows { display: none; }
/* The head's control sits at its right hand, past the tally. It is the only part of the head that
   takes the pointer besides the grip, and a button the drag treats as a handle would move the panel
   instead of folding it — so it stops the grab, not the head. */
.entries-dashboard .en-tools {
  display: flex;
  gap: 3px;
  pointer-events: auto;
}
.entries-dashboard .en-btn {
  pointer-events: auto;
  cursor: pointer;
  padding: 0 3px;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: #8b93a3;
  font-family: inherit;
  font-size: 10px;
  line-height: 1.2;
  transition: color 0.12s, border-color 0.12s;
}
.entries-dashboard .en-btn:hover {
  color: #d1d4dc;
  border-color: #3a4050;
}
.entries-dashboard .en-btn.on {
  color: #2962ff;
  border-color: rgba(41, 98, 255, 0.5);
}
.entries-dashboard .en-head {
  display: flex;
  align-items: baseline;
  gap: 5px;
  /* One line, whatever the tally says. A count that wraps puts a second line of small grey
     type directly over the top entry, and the card reads as two panels colliding rather than
     as a head and its rows. */
  white-space: nowrap;
  margin: -2px -3px 5px;
  padding: 2px 3px;
  border-radius: 4px;
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.entries-dashboard .en-head:hover { background: rgba(41, 98, 255, 0.12); }
.entries-dashboard .en-head.dragging {
  cursor: grabbing;
  background: rgba(41, 98, 255, 0.18);
}
.entries-dashboard .en-grip {
  pointer-events: auto;
  cursor: grab;
  touch-action: none;
  user-select: none;
  color: #8b93a3;
  font-size: 12px;
  line-height: 1;
  transition: color 0.12s;
}
.entries-dashboard .en-grip:hover,
.entries-dashboard .en-grip.dragging { color: #d1d4dc; }
.entries-dashboard .en-grip.dragging { cursor: grabbing; }
.entries-dashboard .en-title {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex: 0 0 auto;
}
.entries-dashboard .en-count {
  font-family: 'JetBrains Mono', monospace;
  color: #787b86;
  margin-left: auto;
  /* The head never wraps, so the tally is the part that gives: it loses its tail to an
     ellipsis before it loses the card its one-line shape. */
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The direction the three longest-standing levels point, on its own line under the head rather
   than inside it: the head counts what is open on this width, and this is a reading of the tape,
   which keeps its answer whether or not the account holds anything. Mono because the counts
   beside the arrow change width between visits, and a line that reflows is a line the trader
   cannot glance at twice. */
.entries-dashboard .en-trend {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  letter-spacing: 0.04em;
  margin: 0 0 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The card's own rows read against the tape, hung on the end of the direction line. It is heavier
   than the line it sits on because it is the one figure there that asks for a decision: the
   direction is a property of the levels and can be glanced at, while a reversal or a move is about
   entries that have not been run out yet — and the verdict carries its own source with it, because
   one walk judging itself deserves a second look before it is leaned on. */
.entries-dashboard .en-verdict {
  font-weight: 700;
  letter-spacing: 0.08em;
}
.entries-dashboard .en-rows {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.entries-dashboard .en-item { display: flex; flex-direction: column; gap: 1px; }
/* A row the walk took on these bars and the account never opened. Same shape as a booked
   entry, because it is the same kind of fact about the same tape, and one shade back because
   the figure beside it is a mark at the last bar rather than money on a balance. */
.entries-dashboard .en-item.walked { opacity: .68; }
.entries-dashboard .en-item.walked .en-state { color: #a8b0bf; }
/* Four columns, and the price is the one that gives: it is the longest figure on the row and
   the one the trader came for, so the reason line — not the money — is what ellipsises. The
   first column is sized for eleven mono characters because a walk entry taken a day back
   carries its date ("23/10 02:00"), not a bare time; at 34px the stamp ran across the
   gap and printed into the symbol. */
.entries-dashboard .en-row {
  display: grid;
  grid-template-columns: 64px 68px 1fr 42px;
  align-items: baseline;
  gap: 5px;
}
.entries-dashboard .en-when,
.entries-dashboard .en-price,
.entries-dashboard .en-out {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9.5px;
  white-space: nowrap;
}
/* A stamp is the one cell on the row that must never be allowed past its column: the next
   cell is the symbol, and the two printed as one word. */
.entries-dashboard .en-when {
  color: #787b86;
  overflow: hidden;
  text-overflow: ellipsis;
}
.entries-dashboard .en-side { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.entries-dashboard .en-price { text-align: right; }
.entries-dashboard .en-out { text-align: right; }
.entries-dashboard .en-why {
  display: flex;
  align-items: baseline;
  gap: 5px;
  font-size: 9px;
  color: #787b86;
}
/* The reason is the payload of the row — why a source named this bar — and it is longer than the
   card, so it is the one text here that is never cut. It takes the width left beside the state and
   breaks inside itself onto a second line; the state stays at the right of the first line, because
   baseline alignment reads the first baseline of a wrapped item. `anywhere` is for a level price,
   which is one unbreakable token and would otherwise hold the line open past the edge. */
.entries-dashboard .en-reason {
  flex: 1 1 auto;
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}
.entries-dashboard .en-state {
  font-family: 'JetBrains Mono', monospace;
  flex: 0 0 auto;
  color: #8b93a3;
  /* "walk out 22/10 18:00" is the longest thing this column says, and a state that breaks
     onto a second line lands on top of the row underneath it. */
  white-space: nowrap;
}
.entries-dashboard .en-pending { color: #787b86; }

/* The handle over a chip that is painted rather than laid out. A canvas cannot
   hold a pointer, so a meter drawn onto it is stuck where the painter put it
   unless something invisible takes its rectangle's shape — this does, and it is
   under #drawing-overlay (z-index 5) so an armed drawing tool still gets the
   cursor it asked for. It shows itself on hover and while carried, because a
   thing that can be moved but never says so will never be moved. */
.overlay-grip {
  position: absolute;
  display: none;
  z-index: 4;
  cursor: grab;
  touch-action: none;
  user-select: none;
  border: 1px dashed transparent;
  border-radius: 4px;
}
.overlay-grip:hover { border-color: rgba(120, 123, 134, 0.55); }
.overlay-grip.dragging {
  cursor: grabbing;
  border-color: rgba(41, 98, 255, 0.7);
  background: rgba(41, 98, 255, 0.08);
}

/* Price label with countdown timer — tracks the current price line position.
   The `top` property is set dynamically via JS to match the Y coordinate of
   the current price on the chart's price scale. The label moves up/down
   with the dotted price line as the price changes. */
.price-timer-label {
  position: absolute;
  right: 60px; /* offset from the right edge to sit next to the price axis */
  z-index: 20;
  background: #26a69a;
  color: #ffffff;
  padding: 3px 8px;
  border-radius: 3px 0 0 3px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  text-align: left;
  min-width: 70px;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
  line-height: 1.35;
  transition: top 0.15s ease-out, background-color 0.3s ease;
  transform: translateY(-50%); /* center vertically on the price line */
}
.price-timer-label.bearish {
  background: #ef5350;
}
.price-timer-label .ptl-price {
  color: #ffffff;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.price-timer-label .ptl-timer {
  color: #131722;
  font-size: 11px;
  font-weight: 600;
  margin-top: 1px;
  white-space: nowrap;
}

/* Pane control widget — positioned inside the RSI indicator panel (bottom-right).
   Matches TradingView reference: "Open panel" button + collapse + fullscreen icons. */
.pane-controls {
  position: absolute;
  bottom: 4px;
  right: 60px;
  z-index: 15;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  pointer-events: auto;
}
.pane-open-panel {
  display: flex;
  align-items: center;
  gap: 4px;
  background: #1e222d;
  border: 1px solid #2a2e39;
  color: #787b86;
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.pane-open-panel:hover {
  background: #2a2e39;
  color: #d1d4dc;
}
.pane-control-buttons {
  display: flex;
  gap: 4px;
}
.pane-icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 4px;
  color: #787b86;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.pane-icon-btn:hover {
  background: #2a2e39;
  color: #d1d4dc;
}
.pane-icon-btn.active {
  background: #2962ff;
  color: white;
  border-color: #2962ff;
}

/* Indicator settings dialog rows */
.ind-setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
  padding: 8px 0;
  border-bottom: 1px solid #1e222d;
  font-size: 12px;
}
/* The label gives width to the control, never the other way round. Without this
   a long row name ("Smoothing Length", "Plot price candles with RSI color") pushes
   its number box past the panel's right edge, and the box the trader has to type
   in is the part that disappears. */
.ind-label {
  color: #d1d4dc;
  font-size: 12px;
  flex: 1 1 auto;
  min-width: 0;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.ind-input {
  width: 80px;
  max-width: 80px;
  flex: 0 0 auto;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 3px;
  color: #d1d4dc;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
  padding: 4px 8px;
  outline: none;
  text-align: right;
}
.ind-select {
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 3px;
  color: #d1d4dc;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
  padding: 4px 8px;
  outline: none;
  cursor: pointer;
  min-width: 80px;
  flex: 0 1 auto;
  max-width: 150px;
}
.ind-select option { background: #1e222d; color: #d1d4dc; }

/* Section captions and the sentence under them, in the indicator dialog. They are
   classes rather than inline styles because a caption that wraps mid-phrase is the
   difference between a labelled group and a stray word on the line above it. */
.ind-caption {
  font-size: 10px;
  color: #4f5562;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 16px 0 8px;
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
/* A tab's first caption has the tab's own padding above it already. */
.ind-tab-content > .ind-caption:first-child { margin-top: 0; }
.ind-hint {
  font-size: 10px;
  color: #4f5562;
  margin: 6px 0 0;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

/* Floating position panel — appears on chart when a position is open.
   Shows: Side | Size | SL | TP | Trail | PnL | Close — in a horizontal pill. */
.floating-position-panel {
  position: absolute;
  top: 40px;
  left: 8px;
  z-index: 25;
  display: flex;
  align-items: center;
  gap: 0;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 600;
  pointer-events: auto;
}
.fpp-side {
  padding: 6px 10px;
  font-weight: 700;
  font-size: 11px;
}
.fpp-side.buy { background: #26a69a; color: white; }
.fpp-side.sell { background: #ef5350; color: white; }
.fpp-size {
  padding: 6px 10px;
  color: #d1d4dc;
  background: #131722;
}
.fpp-sl {
  padding: 6px 10px;
  color: #ef5350;
  background: rgba(239,83,80,0.1);
  border-left: 1px solid #2a2e39;
}
.fpp-tp {
  padding: 6px 10px;
  color: #26a69a;
  background: rgba(38,166,154,0.1);
  border-left: 1px solid #2a2e39;
}
.fpp-trail {
  padding: 6px 10px;
  color: #ffc107;
  background: rgba(255,193,7,0.1);
  border-left: 1px solid #2a2e39;
  font-size: 10px;
}
.fpp-pnl {
  padding: 6px 12px;
  font-weight: 700;
  font-size: 12px;
  border-left: 1px solid #2a2e39;
}
.fpp-pnl.positive { color: #26a69a; background: rgba(38,166,154,0.15); }
.fpp-pnl.negative { color: #ef5350; background: rgba(239,83,80,0.15); }
.fpp-close {
  padding: 6px 10px;
  color: #ef5350;
  cursor: pointer;
  font-size: 14px;
  border-left: 1px solid #2a2e39;
  transition: background 0.15s;
}
.fpp-close:hover { background: rgba(239,83,80,0.2); }

/* ============================================================
   Price Scale Context Menu
   ============================================================ */
.price-scale-menu {
  position: fixed;
  z-index: 500;
  min-width: 220px;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.5);
  padding: 4px 0;
  font-size: 12px;
}
.psm-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  cursor: pointer;
  color: #d1d4dc;
  transition: background 0.1s;
}
.psm-item:hover { background: #2a2e39; }
.psm-item .psm-check {
  width: 14px;
  text-align: center;
  color: #2962ff;
  font-size: 11px;
}
.psm-item span:nth-child(2) { flex: 1; }
.psm-shortcut {
  color: #787b86;
  font-size: 10px;
}
.psm-sep {
  height: 1px;
  background: #2a2e39;
  margin: 4px 0;
}

/* Settings modal sidebar navigation */
.settings-nav-item {
  padding: 8px 16px;
  font-size: 12px;
  color: #787b86;
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}
.settings-nav-item:hover { background: #1e222d; color: #d1d4dc; }
.settings-nav-item.active {
  background: #2962ff;
  color: white;
}

/* ============================================================
   Responsive — the terminal on a tablet and on a phone.

   The desktop shell is three columns side by side. A phone has one
   column, so below 1024px the panels stack instead of vanishing:
   hiding the right-hand panel on a small screen, which an earlier
   build did, quietly removed the open positions, the resting orders
   and the trade history from the only place a trader holding a
   phone could read them.
   ============================================================ */

/* A phone's browser bar makes 100vh taller than the space actually shown,
   which pushed the bottom bar under the edge of the screen. dvh follows the
   bar as it hides; the declaration is ignored where the unit is unknown. */
@supports (height: 100dvh) {
  .terminal { height: 100dvh; }
  .sheet { height: 100dvh; }
}

@media (max-width: 1024px) {
  .terminal-body { flex-direction: column; }
  .terminal-main { min-height: 0; }

  /* The drawing rail becomes a strip above the chart, scrollable sideways. */
  .left-toolbar {
    flex-direction: row;
    align-items: center;
    width: auto;
    height: 40px;
    padding: 0 6px;
    border-right: none;
    border-bottom: 1px solid #2a2e39;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }
  .left-toolbar::-webkit-scrollbar { display: none; }

  /* On a strip the divider stands up: the same hair that separated rows now
     separates columns, and the group's chevron moves to the bottom-right corner
     of its square where it stays reachable by thumb. */
  .tool-divider { width: 1px; height: 20px; margin: 0 5px; flex-shrink: 0; }

  /* Nothing to drag when the panels are above and below each other. */
  .resize-handle { display: none; }

  /* Stacked, the ledger is a drawer and this is its only edge: a strip wide enough to
     catch a thumb, with the hair it sits on lighting up while it is held. */
  .panel-height-handle {
    display: block;
    position: relative;
    flex-shrink: 0;
    height: 9px;
    margin-top: -1px;
    cursor: row-resize;
    z-index: 3;
  }
  .panel-height-handle::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 4px;
    height: 1px;
    background: #2a2e39;
  }
  .panel-height-handle:hover::after,
  .panel-height-handle.dragging::after { background: #2962ff; height: 2px; top: 3px; }

  .right-panel {
    display: flex;
    /* The width is an inline style on the panel from the desktop split, and
       only !important outranks it here. The height is the drawer the trader
       dragged, or the sheet's own share when they never did. */
    width: 100% !important;
    min-width: 0 !important;
    height: var(--ledger-height, 42vh);
    border-top: 1px solid #2a2e39;
  }

  /* Stacked, the strip is the panel: collapse takes the height back from the
     ledger rather than the width, and the tabs stay put — picking one opens it. */
  body.panel-collapsed .right-panel { width: 100% !important; height: auto !important; }
  body.panel-collapsed .right-tabs { flex-direction: row; justify-content: space-between; padding: 0 8px; }
  body.panel-collapsed .right-tabs .tabs { display: flex; }
  body.panel-collapsed #right-create-alert { display: flex; }
  #right-collapse svg { transform: rotate(90deg); }
  body.panel-collapsed #right-collapse svg { transform: rotate(270deg); }

  .chart-header .indicator-pills { display: none; }
}

@media (max-width: 768px) {
  html, body { font-size: 12px; }

  /* Two rows rather than a scrollable strip: the symbol and indicator menus
     hang out of this bar, and an overflow that clips them would clip those. */
  .topbar {
    height: auto;
    flex-wrap: wrap;
    align-content: flex-start;
    padding: 4px 6px;
    gap: 2px 4px;
  }
  .topbar .spacer { display: none; }
  .topbar .divider-v { display: none; }
  .topbar .last-pill { display: none; }
  .topbar .profile-name { display: none; }
  /* Replay, snapshot, undo, redo and mute are keyboard-and-mouse habits; on a
     phone they only pushed the symbol selector off the screen. */
  #replay-btn, #snapshot-btn, #undo-btn, #redo-btn, #sound-btn { display: none; }

  .tf-group { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .tf-group::-webkit-scrollbar { display: none; }
  .tf-btn { padding: 8px 10px; font-size: 13px; }
  .tf-btn.tf-caret { padding: 8px 6px 8px 3px; }

  .icon-btn { height: 34px; width: 34px; }
  .icon-btn svg { width: 18px; height: 18px; }

  .chart-header { gap: 6px 10px; padding: 4px 8px; font-size: 11px; }

  /* The chart is the shorter half of this pairing, so the ledger gets less of
     the screen and keeps its own scroll. */
  .right-panel { height: var(--ledger-height, 38vh); }
  /* The strip scrolls sideways at every width now, so a phone only needs a smaller
     gutter and a taller touch target — the overflow itself is not a second decision. */
  .right-tabs { padding: 0 6px; }
  .right-tab { padding: 11px 10px; }

  .sheet { max-width: 100%; }
  .sheet-header, .sheet-body { padding-left: 12px; padding-right: 12px; }
  .sheet-body { padding-bottom: calc(16px + env(safe-area-inset-bottom)); }

  /* Three of the dialogs carry their own wider max-width as an inline style,
     which only !important outranks; without it the Pine editor would hang off
     the side of a phone with no way to scroll to its Ok button. */
  .modal { max-width: calc(100vw - 20px) !important; max-height: 86vh; padding: 16px; }
  @supports (max-height: 86dvh) { .modal { max-height: 86dvh; } }

  /* iOS Safari zooms the whole page in when a focused control sets its text
     smaller than 16px, so anything a phone can type into is that size. */
  .sheet input, .sheet select, .modal input, .modal select,
  .input-field, .ind-input { font-size: 16px; }

  .submit-btn { padding: 14px; font-size: 14px; }

  /* The settings dialog is a sidebar beside a pane, and asks for 400px of
     height it does not have here. The tabs become a strip you swipe, the pane
     whatever is left, and both inline sizes are beaten rather than moved: the
     markup still carries the desktop defaults. */
  .settings-body { flex-direction: column !important; height: auto !important; }
  .settings-nav {
    width: 100% !important;
    display: flex;
    gap: 4px;
    overflow-x: auto;
    scrollbar-width: none;
    border-right: none !important;
    border-bottom: 1px solid #2a2e39;
    padding: 6px 8px !important;
  }
  .settings-nav::-webkit-scrollbar { display: none; }
  .settings-nav .settings-nav-item { white-space: nowrap; padding: 9px 12px; }
  #settings-content { max-height: 48vh; }

  #toast-host {
    left: 10px;
    right: 10px;
    bottom: calc(34px + env(safe-area-inset-bottom));
  }
  .toast { min-width: 0; max-width: none; }

  .bottombar { padding: 0 8px; }
  .bottombar .group { gap: 6px; }

  button, a { -webkit-tap-highlight-color: transparent; }
}

/* An iPhone in a tall notch: the bottom bar is the only thing that touches the
   edge, and it is where the equity read-out lives. */
@supports (padding: env(safe-area-inset-bottom)) {
  @media (max-width: 768px) {
    .bottombar { padding-bottom: env(safe-area-inset-bottom); height: auto; min-height: 28px; }
  }
}

/* Landscape on a phone: the rows are worth more than the columns. */
@media (max-height: 520px) and (orientation: landscape) {
  .topbar { height: auto; }
  .left-toolbar { display: none; }
  .right-panel { height: 46vh; }
}

/* ============================================================
   Pine editor
   ============================================================ */
.pine-toolbar {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  margin-bottom: 6px;
}
.pine-toolbar .field-label { flex: 1; margin-bottom: 0; }
.pine-toolbar .input-field { width: auto; min-width: 150px; }
.pine-toolbar .btn-outline { flex: none; padding: 7px 12px; }

/* The script body, its number column, and the line the engine blamed.
   The highlight is a band behind transparent text, not a copy of the code: a
   mirrored string drifts the moment font, zoom or a scrollbar disagree with it,
   and a drifted copy would put the mark on the wrong line. One source line is
   one row — the textarea never soft-wraps — so a row number and a pixel say the
   same thing. The textarea's own metrics (12px / 1.55 / 10px padding) are what
   app.js reads to place the bands, so changing them here moves the paint with
   the text rather than against it. */
.pine-editor-shell {
  display: flex;
  align-items: stretch;
  height: 320px;
  min-height: 120px;
  box-sizing: border-box;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  background: #0d1117;
  overflow: hidden;
  resize: vertical;
}
.pine-editor-shell:focus-within { border-color: #2962ff; }

.pine-gutter {
  flex: none;
  width: 44px;
  overflow: hidden;
  padding: 0 6px 0 4px;
  text-align: right;
  background: #0d1117;
  border-right: 1px solid #1e222d;
  color: #4f5562;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  user-select: none;
}
.pine-gutter-row.bad {
  color: #ef5350;
  font-weight: 700;
  background: rgba(239, 83, 80, 0.12);
}

.pine-editor-stage { position: relative; flex: 1; min-width: 0; overflow: hidden; }

.pine-bad-lines {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}
.pine-bad-line {
  position: absolute;
  left: 0;
  right: 0;
  background: rgba(239, 83, 80, 0.16);
  border-left: 2px solid #ef5350;
  border-bottom: 1px solid rgba(239, 83, 80, 0.6);
  box-sizing: border-box;
}

.pine-editor {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  resize: none;
  padding: 10px 12px;
  border: none;
  border-radius: 0;
  background: transparent;
  color: #d1d4dc;
  caret-color: #2962ff;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.55;
  tab-size: 4;
  white-space: pre;
  overflow: auto;
}
.pine-editor:focus { outline: none; }

/* The line the engine blamed, listed so a failure names a line rather than
   quietly leaving an empty chart. Each row is a pointer: it carries the line it
   blames and puts the caret there when clicked. */
.pine-report {
  margin-top: 8px;
  max-height: 132px;
  overflow-y: auto;
  border: 1px solid #2a2e39;
  border-left: 3px solid #ef5350;
  border-radius: 4px;
  background: #131722;
  padding: 8px 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  line-height: 1.6;
  color: #ef5350;
  white-space: pre-wrap;
  word-break: break-word;
}
.pine-report-row { cursor: pointer; }
.pine-report-row:hover { text-decoration: underline; color: #ff8a80; }
.pine-report.clean { border-left-color: #26a69a; color: #26a69a; }

/* table.cell() output, floated over the candles. */
.pine-table-overlay {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  background: rgba(19, 23, 34, 0.86);
  border: 1px solid #2a2e39;
  border-radius: 4px;
  padding: 2px;
  font-size: 10px;
  color: #d1d4dc;
  max-width: 60%;
  overflow: hidden;
}
.pine-table-overlay table { border-collapse: collapse; }
.pine-table-overlay td {
  padding: 2px 6px;
  border: 1px solid rgba(120, 123, 134, 0.35);
  white-space: nowrap;
}
.pine-top_left     { top: 8px; left: 8px; }
.pine-top_center   { top: 8px; left: 50%; transform: translateX(-50%); }
.pine-top_right    { top: 8px; right: 8px; }
.pine-middle_left  { top: 50%; left: 8px; transform: translateY(-50%); }
.pine-middle_center{ top: 50%; left: 50%; transform: translate(-50%, -50%); }
.pine-middle_right { top: 50%; right: 8px; transform: translateY(-50%); }
.pine-bottom_left  { bottom: 8px; left: 8px; }
.pine-bottom_center{ bottom: 8px; left: 50%; transform: translateX(-50%); }
.pine-bottom_right { bottom: 8px; right: 8px; }

/* ── Strategy report ───────────────────────────────────────────────────────
   The dialog is wider than the others and reads as a document rather than a
   form: a head line that says what was walked, four key figures, one chart
   with its own series toggles, then the analysis groups. Everything shares the
   terminal's palette; nothing here invents a colour a chart does not already use. */
.rp-pad { padding: 0 20px 20px; }
.rp-head {
  font-size: 11px;
  color: #787b86;
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 4px;
  line-height: 1.5;
}
.rp-head b { color: #d1d4dc; font-weight: 600; }
.rp-head .empty { color: #f0b90b; }
.rp-sub {
  font-size: 11px;
  color: #787b86;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 16px 0 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.rp-toggles { margin-left: auto; display: flex; gap: 4px; flex-wrap: wrap; text-transform: none; letter-spacing: 0; }
.rp-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.rp-chip {
  border: 1px solid #2a2e39;
  background: #1e222d;
  color: #787b86;
  font-size: 11px;
  padding: 3px 9px;
  border-radius: 12px;
  cursor: pointer;
  font-family: inherit;
}
.rp-chip:hover { color: #d1d4dc; background: #262b38; }
.rp-chip.on { border-color: #2962ff; color: #d1d4dc; background: rgba(41, 98, 255, 0.14); }
.rp-chip[disabled] { cursor: not-allowed; opacity: 0.55; }
/* The chip that is waiting on a tape that has not landed yet keeps the colour the rest of the
   terminal uses for "not yet", and the row it sits in is switched off beside it — one press at
   a time. */
.rp-chip.wait { color: #f0b90b; border-color: #f0b90b; opacity: 1; }
/* A source's switch and the gear that opens its settings are two presses of one row, so they are
   two buttons — but they belong together, and the gear takes the room an icon needs rather than the
   room a word would. */
.rp-src { display: inline-flex; align-items: center; gap: 3px; }
.rp-chip.rp-gear { width: 24px; height: 22px; padding: 0; display: inline-flex;
  align-items: center; justify-content: center; }
.rp-chip.rp-gear svg { width: 13px; height: 13px; display: block; }
.rp-sub .rp-toggles + .rp-toggles { margin-left: 8px; }
.rp-keys { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.rp-key {
  background: #1e222d;
  border: 1px solid #2a2e39;
  border-radius: 6px;
  padding: 10px;
}
.rp-key .k { font-size: 10px; color: #787b86; text-transform: uppercase; letter-spacing: 0.04em; }
.rp-key .v { font-size: 17px; font-weight: 600; color: #d1d4dc; margin-top: 3px; font-variant-numeric: tabular-nums; }
.rp-key .s { font-size: 11px; color: #787b86; margin-top: 2px; font-variant-numeric: tabular-nums; }
.rp-key .v.up, .rp-up { color: #26a69a; }
.rp-key .v.down, .rp-down { color: #ef5350; }
.rp-chart { margin-top: 2px; position: relative; }
.rp-chart svg, .rp-body svg { display: block; width: 100%; height: auto; overflow: visible; }
/* A window narrower than the whole tape can be slid along it, and the plot says so before the
   trader tries: a grab for a window that will move, a grip once the hand has hold of it, and no
   caption dragged into the selection along with the tape. At the whole tape there is nothing left
   to slide, so the cursor stays plain and the wheel belongs to the dialog underneath. */
.rp-chart.scrollable { cursor: grab; }
.rp-chart.scrollable.dragging { cursor: grabbing; user-select: none; }
/* Every other chart in the report is a viewBox-only plot that wants the pane's width. The
   win/loss donut is a square mark beside its legend, so it names its own size — and takes it
   from the row it sits in rather than the column, which is what made it fill the pane. */
.rp-body svg.rp-donut { width: 120px; height: 120px; flex: 0 0 120px; }
.rp-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 8px; }
.rp-tab {
  border: 1px solid #2a2e39;
  background: #1e222d;
  color: #787b86;
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
}
.rp-tab:hover { color: #d1d4dc; }
.rp-tab.on { color: #d1d4dc; border-color: #2962ff; background: rgba(41, 98, 255, 0.14); }
.rp-body { font-size: 12px; color: #d1d4dc; }
.rp-rows { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 16px; margin-bottom: 10px; }
.rp-row { display: flex; justify-content: space-between; gap: 10px; border-bottom: 1px solid #1b1f2a; padding: 3px 0; }
.rp-row .l { color: #787b86; }
.rp-row .n { font-variant-numeric: tabular-nums; }
.rp-note {
  font-size: 11px;
  color: #787b86;
  background: #1e222d;
  border-left: 2px solid #434651;
  padding: 6px 9px;
  border-radius: 0 4px 4px 0;
  margin: 8px 0;
  line-height: 1.5;
}
.rp-table { width: 100%; border-collapse: collapse; font-size: 11px; }
.rp-table th {
  text-align: left;
  color: #787b86;
  font-weight: 500;
  border-bottom: 1px solid #2a2e39;
  padding: 4px 6px;
  white-space: nowrap;
}
.rp-table td { border-bottom: 1px solid #1b1f2a; padding: 4px 6px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rp-table th.r, .rp-table td.r { text-align: right; }
.rp-scroll { max-height: 220px; overflow-y: auto; }
@media (max-width: 768px) {
  .rp-keys { grid-template-columns: 1fr 1fr; }
  .rp-rows { grid-template-columns: 1fr; }
  .rp-toggles { width: 100%; margin-left: 0; }
}

/* The three markets the bot trades, across the top of the chart while it trades
   them. The strip is the only new furniture on the canvas, so it is the one that
   has to stay out of the candles: it lives in the chart's own top margin, the
   price scale keeps its corner, and the container ignores the pointer so a drag
   started between two cells still pans the chart. The cells alone take a press,
   because a cell is the way onto that market's chart. */
.market-ribbon {
  position: absolute;
  left: 8px;
  top: 6px;
  right: 68px;
  z-index: 12;
  display: flex;
  align-items: flex-start;
  gap: 6px;
  pointer-events: none;
  font-size: 10px;
  color: #d1d4dc;
  user-select: none;
}
.market-ribbon .mr-tag {
  /* Set the strip apart from a watch list without a heading: three dull words,
     level with the top of the cells, that only ever appear with the cells.
     It takes the pointer because it is the only place the strip's own tooltip
     can live — the container has to stay press-through for the chart. */
  padding: 3px 0 2px;
  color: #5a5f6a;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  pointer-events: auto;
  cursor: help;
}
.market-ribbon .mr-cells { display: flex; gap: 6px; }
.market-ribbon .mr-cell {
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding: 2px 6px 3px;
  background: rgba(19, 23, 34, 0.82);
  border: 1px solid #2a2e39;
  border-radius: 4px;
  cursor: pointer;
  pointer-events: auto;
  white-space: nowrap;
}
.market-ribbon .mr-cell:hover { border-color: #363a45; background: rgba(30, 34, 45, 0.9); }
/* The market on the chart is the one the trader is already looking at, so it is
   edged rather than filled: only a held market gets the fill. */
.market-ribbon .mr-cell.on-chart { border-color: rgba(41, 98, 255, 0.55); }
.market-ribbon .mr-cell.held {
  background: rgba(41, 98, 255, 0.18);
  border-color: rgba(41, 98, 255, 0.5);
}
.market-ribbon .mr-ticker { font-weight: 600; letter-spacing: 0.01em; }
.market-ribbon .mr-price { font-variant-numeric: tabular-nums; color: #b7bdc9; }
.market-ribbon .mr-change { font-variant-numeric: tabular-nums; color: #787b86; }
.market-ribbon .mr-change.up { color: #26a69a; }
.market-ribbon .mr-change.down { color: #ef5350; }
.market-ribbon .mr-spark { display: block; align-self: center; opacity: 0.75; }
.market-ribbon .mr-spark polyline { fill: none; stroke: #787b86; stroke-width: 1; }
.market-ribbon .mr-cell.held .mr-spark polyline { stroke: #91a9ff; }
@media (max-width: 900px) {
  /* Two of the three cells would sit over the candles on a narrow chart, so the
     strip loses the sparkline first and the change second — the ticker and the
     price are what a cell is for. */
  .market-ribbon .mr-spark { display: none; }
  .market-ribbon .mr-change { display: none; }
}
