/* The live chart page (ADR-0040): the Run parameters bar (the only controls), then the chart with a
   trades list on its right. Every colour is a
   `var(--…)` from shell.css's palette, so the page re-themes with the rest of
   the app. */
#chart-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

/* Chart on the left, trades list on the right. */
#chart-main {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}
#chart-plot {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow: hidden;  /* the Plotly SVG never spills over the trades panel */
}

/* Draggable vertical divider between the chart and the trades panel. The dotted
   grip in the middle signals "drag me"; hover widens/brightens it. */
#chart-splitter {
  flex: 0 0 7px;
  cursor: col-resize;
  background: var(--border);
  position: relative;
  z-index: 5;
}
#chart-splitter::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 40px;
  border-radius: 3px;
  background: repeating-linear-gradient(
    to bottom, var(--text-dim) 0 2px, transparent 2px 5px
  );
}
#chart-splitter:hover,
#chart-splitter:focus-visible {
  background: var(--selected);
  outline: none;
}

/* TradingView-style legend: the loaded strategy's totals as one plain line in
   the plot's top margin. No fill, no border; it never takes the pointer. */
#chart-legend {
  position: absolute;
  top: 3px;
  left: 56px;
  z-index: 5;
  font-size: 12px;
  color: var(--text-dim);
  pointer-events: none;
}
/* The line never runs under the trades panel: `fitLegend` bounds it to the
   plot's width, and the per-source breakdown drops to a second line whole. */
#chart-legend .legend-mix { display: inline-block; white-space: nowrap; }
#chart-legend[hidden] {
  display: none;
}
#chart-legend-name {
  color: var(--text);
  font-weight: 600;
}
#chart-legend .pnl-up { color: var(--up); }
#chart-legend .pnl-down { color: var(--down); }

/* Floating "Clear TP/SL" control — appears over the chart while a trade is
   selected. Reliable HTML, not a Plotly annotation. A small neutral button, not
   a red alert (desk owner, 2026-10-07); sits under the legend, never over it. */
#remove-tpsl {
  position: absolute;
  top: 28px;
  left: 12px;
  z-index: 6;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 8px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}
#remove-tpsl[hidden] {
  display: none;
}
#remove-tpsl:hover {
  border-color: var(--text-dim);
}

/* "‹ Load more" — pinned by chart.js to the plot area's left edge, vertically
   centred; shown only while the view sits at the earliest loaded candle. */
#load-more {
  position: absolute;
  top: 50%;
  left: 12px;
  transform: translateY(-50%);
  z-index: 6;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
}
#load-more[hidden] {
  display: none;
}
#load-more:hover:not(:disabled) {
  background: var(--subtle);
}
#load-more:disabled {
  color: var(--text-dim);
  cursor: default;
}

#trades-panel {
  flex: 0 0 500px;
  width: 500px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-left: 1px solid var(--border);
  background: var(--panel);
}
/* The list scrolls on its own (header sticky) so the detail keeps its height. */
#trades-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Last resort only: the table is sized to fit the narrowest panel (420 px),
     so a sideways scroll appears only if a larger font makes it overflow. */
  overflow-x: auto;
  scrollbar-gutter: stable;
  /* Room under the last row so it scrolls clear of the page's floating
     bottom-right button (its Result would sit under it otherwise). */
  padding-bottom: 48px;
}

/* Horizontal divider above the detail: drag it UP to make the detail taller.
   `touch-action: none` lets a finger drag it instead of scrolling the page. */
#trade-detail-splitter {
  flex: 0 0 7px;
  cursor: row-resize;
  touch-action: none;
  background: var(--border);
  position: relative;
}
#trade-detail-splitter[hidden] { display: none; }
#trade-detail-splitter::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 3px;
  border-radius: 3px;
  background: repeating-linear-gradient(
    to right, var(--text-dim) 0 2px, transparent 2px 5px
  );
}
#trade-detail-splitter:hover,
#trade-detail-splitter:focus-visible,
#trade-detail-splitter.dragging {
  background: var(--selected);
  outline: none;
}

/* A clicked trade's Live | Backtest detail: a bottom panel whose height the
   divider sets (chart.js writes flex-basis; 40% of the column by default). */
#trade-detail {
  flex: 0 0 40%;
  min-height: 0;
  overflow-y: auto;
  background: var(--panel);
  font-size: 12px;
}
#trade-detail[hidden] { display: none; }
#trade-detail-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--panel);
  font-weight: 600;
  color: var(--text);
}
#trade-detail-title .buy { color: var(--buy); }
#trade-detail-title .sell { color: var(--sell); }
#trade-detail-close {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1;
  padding: 3px 6px;
  cursor: pointer;
}
#trade-detail-close:hover { color: var(--text); background: var(--subtle); }
#trade-detail table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}
#trade-detail th,
#trade-detail td {
  padding: 2px 10px;
  text-align: right;
  white-space: nowrap;
}
#trade-detail th {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
}
#trade-detail td:first-child,
#trade-detail th:first-child {
  text-align: left;
  color: var(--text-dim);
}
#trade-detail-context {
  border-top: 1px solid var(--border);
}
#trade-detail .pnl-up { color: var(--up); }
#trade-detail .pnl-down { color: var(--down); }
#trade-detail .null { color: var(--abstain); }
/* A live/backtest disagreement that matters (signal, executed, exit reason),
   or a false `same input` check: a subtle accent stripe, never a glow. */
#trade-detail tr.mismatch td:first-child {
  box-shadow: inset 2px 0 0 var(--accent);
  color: var(--text);
}
#trade-detail tr.mismatch td.live { color: var(--accent); }
#trade-detail tr.flagged td:last-child { color: var(--accent); }
/* The column the list's row reads (backtest first, live for a live-only
   trade): its header says so and its values are a touch bolder. */
#trade-detail-table[data-from="live"] thead th:nth-child(2),
#trade-detail-table[data-from="backtest"] thead th:nth-child(3) { color: var(--text); }
#trade-detail-table[data-from="live"] thead th:nth-child(2)::after,
#trade-detail-table[data-from="backtest"] thead th:nth-child(3)::after {
  content: " \00b7  in list";
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-dim);
}
#trade-detail-table[data-from="live"] td.live,
#trade-detail-table[data-from="backtest"] td.backtest { font-weight: 600; }
#trades-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 8px 10px;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--panel);
}
#trades-count {
  color: var(--text);
}
/* The filter row between the TRADES header and the list (both pages): one
   chip per source, with counts; /process/trades adds "Ungraded" and its
   grading progress at the right end. */
#trades-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
  font-size: 11px;
}
#trade-filters { display: flex; flex-wrap: wrap; gap: 3px; }
#trade-filters .tf {
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel);
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1;
  padding: 4px;
  cursor: pointer;
  white-space: nowrap;
}
#trade-filters .tf:hover { background: var(--subtle); color: var(--text); }
#trade-filters .tf[aria-pressed="true"] {
  border-color: var(--selected);
  color: var(--selected);
  background: color-mix(in srgb, var(--selected) 8%, transparent);
}
#trade-filters .tf-n { color: var(--text-dim); font-variant-numeric: tabular-nums; margin-left: 2px; }
#trade-filters .tf[aria-pressed="true"] .tf-n { color: inherit; }
#trade-filter-empty {
  margin: 0;
  padding: 10px;
  font-size: 12px;
  color: var(--text-dim);
}
/* The SQL audit: a small neutral button by the count, and a centred dialog
   with the query in a selectable monospace block. */
.trades-head-right { display: inline-flex; align-items: center; gap: 8px; }
#audit-sql-open,
#audit-sql-copy,
#audit-sql-close {
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel);
  color: var(--text-dim);
  font-size: 10px;
  letter-spacing: 0.04em;
  line-height: 1;
  padding: 3px 6px;
  cursor: pointer;
}
#audit-sql-open:hover,
#audit-sql-copy:hover,
#audit-sql-close:hover { color: var(--text); background: var(--subtle); }
#audit-sql {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(19, 23, 34, 0.18);
  letter-spacing: 0;
}
#audit-sql[hidden] { display: none; }
.audit-sql-card {
  width: min(820px, calc(100vw - 48px));
  max-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 4px 16px rgba(19, 23, 34, 0.12);
}
.audit-sql-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
}
.audit-sql-actions { display: inline-flex; gap: 6px; }
.audit-sql-hint {
  margin: 0;
  padding: 6px 10px;
  font-size: 11px;
  color: var(--text-dim);
}
#audit-sql-text {
  margin: 0 10px 10px;
  padding: 8px 10px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--subtle);
  color: var(--text);
  font-family: var(--mono-font);
  font-size: 11px;
  line-height: 1.45;
  white-space: pre;
  user-select: text;
}
#trades-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
#trades-empty {
  padding: 12px 10px;
  color: var(--text-dim);
  font-size: 12px;
}

/* Empty result: the likely culprit + a way straight to the form. */
#trades-why {
  margin: 0 10px 12px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--warn);
  border-radius: 4px;
  font-size: 12px;
  color: var(--text);
}
#trades-why[hidden] { display: none; }
#trades-why p { margin: 0 0 8px; line-height: 1.4; overflow-wrap: anywhere; }
#trades-why button,
#e2e-params button {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
}
#trades-why button:hover,
#e2e-params button:hover { background: var(--subtle); }
#e2e-params button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
  font-weight: 600;
}
#e2e-params button.primary:disabled { opacity: 0.6; cursor: progress; }

/* Run parameters: the end-to-end function's arguments — the page's only
   controls. One row of label:value chips (what decides the trades), the
   context-only ones under "More", and a form behind "Edit". */
#e2e-params {
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}
#e2e-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  min-width: 0;
}
.e2e-title {
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
}
.e2e-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}
#e2e-chips { flex: 0 1 auto; }
.e2e-context {
  padding: 0 12px 6px;
}
.e2e-context[hidden] { display: none; }
.e2e-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  max-width: 320px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  white-space: nowrap;
}
.e2e-chip-label {
  color: var(--text-dim);
  font-size: 11px;
}
.e2e-chip-value {
  color: var(--text);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
}
#e2e-params button.e2e-link {
  border-color: transparent;
  background: transparent;
  color: var(--accent);
  padding: 4px 6px;
}
#e2e-params button.e2e-link:hover { background: var(--subtle); }
#e2e-bar .live-status { margin-left: auto; }
.e2e-custom {
  font-size: 10px;
  padding: 1px 6px;
  border: 1px solid var(--accent);
  border-radius: 4px;
  color: var(--accent);
}
.e2e-custom[hidden] { display: none; }
#e2e-form {
  padding: 4px 12px 10px;
  border-top: 1px solid var(--border);
}
#e2e-form[hidden] { display: none; }
#e2e-form fieldset {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 8px 14px;
  margin: 0 0 8px;
  padding: 6px 10px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
}
#e2e-form legend {
  padding: 0 4px;
  font-weight: 600;
  color: var(--text);
}
.e2e-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.e2e-wide { grid-column: span 2; }
.e2e-label { color: var(--text); font-weight: 600; font-size: 11px; }
.e2e-hint { color: var(--text-dim); font-size: 11px; font-weight: 400; }
.e2e-hint.warn { color: var(--down); }
.e2e-pair { display: flex; gap: 6px; }
.e2e-pair input { flex: 1; min-width: 0; }
.e2e-pair input.e2e-short { flex: 0 0 64px; }
#e2e-form input {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 6px;
  font-size: 12px;
  min-width: 0;
}
#e2e-form input:focus-visible {
  outline: none;
  border-color: var(--selected);
}
.e2e-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.e2e-status { color: var(--text-dim); }
.e2e-status.err { color: var(--down); }

/* One row per trade, TradingView "List of trades" density (~24px rows):
   numbers right-aligned in tabular figures, the header sticks while it scrolls. */
#trades-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
#trades-table[hidden] { display: none; }
#trades-table th,
#trades-table td {
  height: 24px;
  padding: 0 3px;
  text-align: right;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
/* Breathing room at both edges so neither # nor the last column touches the panel
   border (nor the scrollbar). */
#trades-table th:first-child,
#trades-table td:first-child { padding-left: 8px; }
#trades-table th:last-child,
#trades-table td:last-child { padding-right: 10px; }
#trades-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--panel);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-dim);
}
/* Sortable headers: click cycles ascending → descending → newest first. The
   ▲/▼ shows on the active one only (from its aria-sort). */
#trades-table th[data-sort] { cursor: pointer; user-select: none; }
#trades-table th[data-sort]:hover { color: var(--text); }
#trades-table th[data-sort]:focus-visible { outline: 1px solid var(--selected); outline-offset: -1px; }
#trades-table th[aria-sort] { color: var(--selected); }
#trades-table th[aria-sort="ascending"]::after,
#trades-table th[aria-sort="descending"]::after {
  display: inline-block;
  width: 0;
  margin-left: 1px;
  font-size: 7px;
  vertical-align: 1px;
  overflow: visible;
}
#trades-table th[aria-sort="ascending"]::after { content: "▲"; }
#trades-table th[aria-sort="descending"]::after { content: "▼"; }
#trades-table .c-id,
#trades-table .c-when,
#trades-table .c-src,
#trades-table .c-side { text-align: left; }
/* Entry/TP/SL left the list (desk owner, 2026-10-08: they are in the detail and
   on the chart), so Time and Source get the freed width instead of hugging. */
#trades-table .c-when,
#trades-table .c-src { padding-right: 12px; }
#trades-table td.c-res { font-weight: 600; }

/* Where the trade traded: neutral when both sides agree, an outlined tone per
   single side, the accent when both traded in different directions. */
.src-badge {
  display: inline-block;
  padding: 0 4px;
  border: 1px solid transparent;
  border-radius: 3px;
  font-size: 10px;
  line-height: 14px;
  font-weight: 600;
  white-space: nowrap;
}
.src-badge.src-both { color: var(--text-dim); font-weight: 500; padding-left: 0; }
.src-badge.src-live { color: var(--warn); border-color: currentColor; }
.src-badge.src-backtest { color: var(--text-dim); border-color: var(--abstain); }
.src-badge.src-both_diff {
  color: var(--accent);
  border-color: currentColor;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
#trade-detail-title .src-badge { vertical-align: 1px; }

#trades-table td.c-id,
#trades-table td.c-when { color: var(--text-dim); }
#trades-table td.c-side { font-weight: 700; }
#trades-table td.buy { color: var(--up); }
#trades-table td.sell { color: var(--down); }
#trades-table td.pnl-up { color: var(--up); }
#trades-table td.pnl-down { color: var(--down); }
#trades-table td.null { color: var(--abstain); }
.trade-row { cursor: pointer; }
.trade-row:hover td { background: var(--subtle); }
/* Live and backtest disagree (one won, the other lost): a thin accent edge.
   Before `.is-sel` so the selection's edge wins on the selected row. */
.trade-row.pnl-split td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.trade-row.is-sel td { background: var(--border); }
.trade-row.is-sel td:first-child { box-shadow: inset 3px 0 0 var(--selected); }

/* The "miquito": a loading card centred over the chart. */
#loading-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--overlay);
  z-index: 5;
}
#loading-overlay[hidden] {
  display: none;
}
.loading-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-size: 14px;
}
.loading-card .monkey {
  font-size: 26px;
  animation: monkey-bounce 0.8s ease-in-out infinite;
}
@keyframes monkey-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

/* The small bouncing miquito while the price cache / strategies refresh —
   same look as /monitoring's column spinner. [hidden] must outrank the flex. */
.filter-loading {
  font-size: 12px;
  color: var(--text-dim);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.filter-loading[hidden] { display: none; }
.filter-monkey {
  display: inline-block;
  animation: filter-bounce 0.8s ease-in-out infinite;
}
@keyframes filter-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

/* ● Live — the chart updates itself on open / tab return; this says when. */
.live-status { display: inline-flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--text-dim); padding: 3px 10px; border: 1px solid var(--border); border-radius: 999px;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--up);
  box-shadow: 0 0 6px color-mix(in srgb, var(--up) 70%, transparent); }
.live-status.busy .live-dot { background: var(--warn); box-shadow: none; animation: live-pulse 1s ease-in-out infinite; }
.live-status.err { color: var(--down); border-color: color-mix(in srgb, var(--down) 45%, transparent); }
.live-status.err .live-dot { background: var(--down); box-shadow: none; }
@keyframes live-pulse { 50% { opacity: .3; } }
