:root {
  --bg: #0A0219;
  --panel: #120A26;
  --line: #2A2044;
  --text: #E6E6F0;
  --muted: #8A84A3;
  --accent: #00BCD4;
  --bad: #E81C64;
  /* Ship 7c-2: the ladder's width, ONE named constant. It was clamp(180px, 15vw, 280px), which on
     a wide display spent most of the column on nothing -- half of it per side, with no numbers in
     either half. 168px is the three bands the renderer draws (a depth bar, a ~46px size number, a
     34px cumulative silhouette) and no more; the chart keeps the rest. */
  --book-w: 168px;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text);
  font: 13px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
body { display: flex; flex-direction: column; }
header#bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 12px;
  border-bottom: 1px solid var(--line); background: var(--panel); }
.brand { font-weight: 700; letter-spacing: .04em; color: var(--accent); margin-right: 6px; }
.sep { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }
.muted { color: var(--muted); }
.badge { padding: 2px 8px; border-radius: 10px; background: var(--accent); color: #041018; font-weight: 700; }
label { display: inline-flex; align-items: center; gap: 4px; }
select, input, button { background: var(--bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 4px; padding: 3px 6px; font: inherit; }
button { cursor: pointer; }
button:hover { border-color: var(--accent); }
button.on { background: var(--accent); color: #041018; border-color: var(--accent); }
.notice { padding: 8px 12px; border-bottom: 1px solid var(--line); }
.notice a { color: var(--accent); }
.error { color: var(--bad); }
/* V-03 Beat 1b-2: the live-chain banner (paused / re-derived) and the pill beside the window label */
.notice.warn { color: #FFB74D; }
#tail-pill { cursor: help; }
main { flex: 1; display: flex; min-height: 0; }
/* V-01: the price chart and the PFO pane stack in a column; the panels float over them. */
#panes { flex: 1; min-width: 0; display: flex; flex-direction: column; }
#chart-wrap { flex: 1; position: relative; min-height: 360px; }
#chart { position: absolute; inset: 0; }
/* Ship 5: while the measurement ruler is armed. `user-select` is load-bearing rather than cosmetic
   -- there is no such rule anywhere else in this file, so without it a measuring drag selects the
   page's text and the browser shows a drag ghost over the chart. */
#chart-wrap.measuring { cursor: crosshair; user-select: none; }
#pfo-wrap { position: relative; border-top: 1px solid var(--line); }
#pfo { width: 100%; height: 220px; }
/* Ship LQ1: the Liquidity pane. Its header is collapsed with the pane (height 0 + overflow), never hidden. */
#liq-wrap { position: relative; border-top: 1px solid var(--line); overflow: hidden; }
#liq { width: 100%; height: 0; }
.liq-head { display: flex; gap: 8px; align-items: center; padding: 2px 8px; font-size: 12px; height: 0; overflow: hidden; }
#liq-wrap.on .liq-head { height: auto; }
/* Ship MV3: the CVD pane, the Liquidity pane's rules */
#flow-wrap { position: relative; border-top: 1px solid var(--line); overflow: hidden; }
#flow { width: 100%; height: 0; }
#flow-wrap.on .liq-head { height: auto; }
.liq-readout { color: var(--muted, #999); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Ship 4b-2 -- ZEN: the two panes, full window. THE FIRST `display: none` RULES IN THIS FILE.
 *
 * tests/test_seriesv_shell.py used to forbid that declaration by REGEX against selectors naming a
 * chart container, which a class rule like `.collapsed #chart { display: none }` would have walked
 * straight past while still handing Lightweight Charts' autoSize a 0x0 box. That pin is now an
 * enumerated ALLOWLIST instead: every `display: none` in this file must be declared there by a
 * human, and none of them may name a chart container in any form. These four rules are the reason
 * it was rewritten, and they are its first entries -- the hole is closed in the same change that
 * would otherwise have exploited it.
 *
 * Nothing here touches #panes, #chart-wrap, #chart, #pfo-wrap or #pfo. The panes are what zen is
 * FOR; only the chrome around them is removed, so no chart container is ever hidden or collapsed. */
body.zen nav#shell-nav { display: none; }
body.zen header#bar { display: none; }
body.zen footer { display: none; }
body.zen #inspector { display: none; }
/* The way out, and the reason zen is never persisted. It sits INSIDE #chart-wrap because the header
   is exactly what zen hides -- a control that hides its own way back is the stranded-operator shape
   this arc has met four times. z-index 6 clears the float panels (3) and the view panels (5). */
#zen-exit { position: absolute; z-index: 6; top: 8px; right: 94px; display: none;
  background: rgba(18, 10, 38, 0.88); border: 1px solid var(--line); border-radius: 4px;
  padding: 3px 8px; color: var(--text); cursor: pointer; font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace; }
body.zen #zen-exit { display: block; }
.float-panel { position: absolute; z-index: 3; background: rgba(18, 10, 38, 0.88); border: 1px solid var(--line);
  border-radius: 4px; padding: 4px 7px; font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace; cursor: pointer; }
#score-panel { left: 8px; top: 8px; min-width: 190px; }
/* Ship FG1: the regime badge, top right of the pane (right: 94px clears the price scale); below the fullscreen exit */
#grid-regime { right: 94px; top: 8px; font-size: 11px; padding: 3px 7px; white-space: nowrap; }
body.zen #grid-regime { top: 40px; }
#dash-panel { right: 94px; bottom: 34px; min-width: 170px; }
#pfo-info { right: 94px; top: 10px; }
/* Ship 4: the freshness panel -- newest stored row per layer and its age, so "nothing has
   happened" is distinguishable from "something is stuck". */
#freshness-panel { left: 8px; bottom: 34px; min-width: 215px; cursor: default; }
#freshness-panel .head { color: var(--text); margin-bottom: 3px; }
#freshness-panel .cell .v { color: var(--muted); }
#freshness-panel .cell .v.fresh { color: #26A69A; }
#freshness-panel .cell .v.quiet { color: var(--text); }
#freshness-panel .cell .v.none { color: var(--muted); font-style: italic; }
/* The head pill goes amber only PAST the measured ceiling (one bar + the 483.7 s worst landing
   + a poll), never during the normal sawtooth -- see state.js headWarnAfterS. */
.badge.late { background: #FFB74D; color: #041018; }
/* Ship 4c: the bar-close countdown and the spot feed's own pill. The countdown is monospaced so a
   digit changing every second does not reflow the header. The feed pill's colours mirror the head
   pill's: normal is unstyled, degraded is amber, gone is red -- and "gone" means the live price is
   REMOVED from the chart, never shown stale. */
#bar-countdown { font-variant-numeric: tabular-nums; font-family: ui-monospace, Menlo, Consolas, monospace;
  cursor: help; }
#feed-pill { cursor: help; }
.badge.feed-stale { background: #FFB74D; color: #041018; }
.badge.feed-dead { background: #EF5350; color: #FFFFFF; }
.float-panel .cell { display: flex; justify-content: space-between; gap: 12px; }
.float-panel .k { color: var(--muted); }
.tone-bull { color: #00BCD4; }
.tone-bear { color: #E81C64; }
.tone-good { color: #26A69A; }
.tone-bad { color: #EF5350; }
.tone-info { color: #42A5F5; }
.tone-neutral { color: var(--text); }
.score-title { margin-bottom: 3px; }
.score-row { display: grid; grid-template-columns: 76px 1fr 34px; align-items: center; gap: 6px; }
.score-row.total { grid-template-columns: 76px 1fr; border-top: 1px solid var(--line); margin-top: 3px; padding-top: 2px; }
.score-row .v { text-align: right; }
/* Ship 13: the by-design absence notes (a higher timeframe's reduced MTF ladder, a SetupScore that is not
   computed above 15m). One wrapped line of muted text, never a data row. */
.float-panel .cell.note, .score-row.note { display: block; max-width: 240px; white-space: normal;
  color: var(--muted); font-style: italic; font-size: 11px; margin-top: 3px; }
#tf-note { max-width: 420px; }
.score-track { display: block; height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; }
.score-fill { display: block; height: 100%; background: var(--accent); width: 0; }
/* Ship 4b: the panel used to be a hard 340px at EVERY viewport >= 901px, so its ~110-word prose
 * reflowed into a ~315px ribbon on a 2560px display and read as cut off. clamp() grows it with the
 * viewport without a media-query ladder, and the floor is today's width so nothing narrower
 * regresses. overflow-wrap (not word-break) is the robust half: it also lowers the element's
 * min-content size, which is what actually stops an unbreakable token overflowing inside a flex
 * item -- so the "clipped mid-word" reading is impossible whichever way the report is read.
 * #inspect-out keeps its own word-break: break-all, because stored JSON SHOULD break mid-token. */
/* Ship 7c: the live book ladder. A flex SIBLING of #panes and #inspector, so
   expanding it narrows the chart and collapsing it hands the width straight
   back -- the same mechanism as the inspector's, and the reason the price
   SCALE (the price -> y mapping) is unaffected either way: autoscale runs on
   the visible bar set, which a width change does not alter. */
#book { width: var(--book-w); flex: 0 0 auto; min-width: 0;
        display: flex; flex-direction: column; border-left: 1px solid var(--line);
        background: var(--panel); overflow: hidden; }
#book[hidden] { display: none; }
body.zen #book { display: none; }
#book .book-head { display: flex; justify-content: space-between; align-items: center;
                   gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--line);
                   font-size: 12px; }
/* The panel reads as part of the cockpit: the inspector's own heading treatment, and the header's
   badge for the age. Nothing here is a new visual language. */
#book #book-title { text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
                    font-size: 11px; }
#book #book-age { background: var(--line); color: var(--text); font-weight: 400;
                  font: 10px/1.4 ui-monospace, Menlo, Consolas, monospace; padding: 2px 6px; }
#book .book-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px;
                    padding: 4px 8px; border-bottom: 1px solid var(--line);
                    font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace; }
#book .book-tools button { padding: 2px 6px; font: inherit; }
#book .book-tools label { gap: 3px; color: var(--muted); }
#book #book-note { padding: 6px 8px; font-size: 11px; }
/* GX1 polish: the GEX view's header -- short fixed lines (layers.js GEX_HEADER_COLS), never wrapped */
#book #book-note.gex-head { white-space: normal; overflow: hidden; font: 11px/1.35 ui-monospace, Menlo, Consolas, monospace; }
#book #book-note.gex-head .gex-lines { display: block; white-space: pre; }
#book #book-note.gex-head .gex-why { display: block; white-space: normal; overflow-wrap: anywhere; margin-top: 3px;
  color: var(--muted); }
#book canvas { flex: 1; width: 100%; min-height: 0; display: block; }

#inspector { width: clamp(340px, 26vw, 560px); flex: 0 1 auto; min-width: 0; overflow-wrap: anywhere;
  border-left: 1px solid var(--line); background: var(--panel); padding: 8px 12px;
  overflow: auto; }
#inspector h2 { margin: 0 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); }
#inspect-out { white-space: pre-wrap; word-break: break-all; font: 11px/1.35 ui-monospace, Menlo, Consolas, monospace; }
footer { display: flex; justify-content: space-between; gap: 12px; padding: 6px 12px;
  border-top: 1px solid var(--line); background: var(--panel); }
footer a { color: var(--muted); }
/* V-00.1 shell: the top nav and the Parameters/Trades panels. */
nav#shell-nav { display: flex; flex-wrap: wrap; align-items: stretch; gap: 2px; padding: 0 12px;
  background: var(--bg); border-bottom: 1px solid var(--line); }
nav#shell-nav .brand { align-self: center; margin-right: 14px; }
nav#shell-nav .grow { flex: 1; }
nav#shell-nav a.tab { color: var(--muted); text-decoration: none; padding: 9px 14px;
  border-bottom: 2px solid transparent; }
nav#shell-nav a.tab:hover { color: var(--text); }
nav#shell-nav a.tab.on { color: var(--text); border-bottom-color: var(--accent); }
/* Ship TC2 train 3: Log out is a button (it POSTs), drawn like a tab */
nav#shell-nav button.tab { color: var(--muted); background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 9px 14px; font: inherit; cursor: pointer; }
nav#shell-nav button.tab:hover { color: var(--text); }
#view-login input[type=password] { min-width: 220px; }
body.view-other header#bar { visibility: hidden; }
main { position: relative; }
.panel { position: absolute; inset: 0; z-index: 5; overflow: auto; background: var(--bg); padding: 16px 20px; }
.panel h2 { margin: 0 0 6px; font-size: 15px; }
.panel h3 { margin: 16px 0 4px; font-size: 13px; color: var(--bad); }
.panel code { color: var(--accent); }
.badges { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.badge.good { background: var(--line); color: var(--text); }
.badge.warn { background: var(--bad); color: #FFFFFF; }
#params-table { border-collapse: collapse; min-width: 320px; max-width: 100%; }
#params-table th, #params-table td { text-align: left; padding: 4px 10px; border-bottom: 1px solid var(--line);
  font: 12px/1.4 ui-monospace, Menlo, Consolas, monospace; word-break: break-all; }
#params-table th { color: var(--muted); font-weight: 400; white-space: nowrap; }
/* V-02: Live / Paper and the Trades tab. */
#live-status { max-width: 70ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
button:disabled, input:disabled, select:disabled { opacity: .45; cursor: default; }
table.grid { border-collapse: collapse; width: 100%; margin: 6px 0 4px; }
table.grid th, table.grid td { text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--line);
  font: 12px/1.4 ui-monospace, Menlo, Consolas, monospace; }
table.grid th { color: var(--muted); font-weight: 400; white-space: nowrap; }
table.grid tbody tr { cursor: pointer; }
table.grid tbody tr:hover { background: var(--panel); }
.panel h3.plain { color: var(--muted); }
#trades-detail { white-space: pre-wrap; word-break: break-all; font: 11px/1.35 ui-monospace, Menlo, Consolas, monospace; }
@media (max-width: 900px) {
  main { flex-direction: column; }
  #inspector { width: auto; border-left: 0; border-top: 1px solid var(--line); max-height: 30vh; }
  /* Ship 7c: #book must be reset here too. `main` becomes a COLUMN at this
     width, so a fixed-width sibling stops being a column beside the chart and
     becomes a short band above the inspector; left as `flex: 0 0 <w>` it
     would keep a width that now means height and squeeze the chart's own
     min-height: 360px. */
  #book { width: auto; border-left: 0; border-top: 1px solid var(--line); max-height: 30vh; }
}

/* Renderer ship: the drawing surface. The count badge is a quiet chrome badge (the operator's own drawings are
   not engine data); it turns to the warn colour only for an unreadable stored value or a refused write. */
#shape-count { background: var(--line); color: var(--text); font-weight: 400; }
#shape-count.warn { background: var(--bad); color: #FFFFFF; }
/* The note input sits over the pane at the clicked point (app.js sets left/top through the CSSOM). Shown and
   hidden with the `hidden` attribute only -- never a display rule on anything inside #chart-wrap. */
#shape-text { position: absolute; z-index: 5; box-sizing: border-box; width: 200px; font: 11px system-ui, sans-serif; padding: 2px 4px;
  background: var(--panel, #0A0219); color: var(--text); border: 1px solid var(--accent); border-radius: 3px; }
#shape-controls { margin: 6px 0; }
/* Ship CT1: the position tool's inline edit strip and its settings dialog. Shown / hidden with the `hidden`
 * attribute only (no display rule), positioned through the CSSOM like #shape-text. */
.pos-edit { position: absolute; z-index: 5; display: flex; gap: 4px; align-items: center; padding: 3px 5px;
  background: var(--panel, #1e222d); border: 1px solid var(--line, #444); border-radius: 4px;
  font: 11px system-ui, sans-serif; }
.pos-edit[hidden] { visibility: hidden; }
.pos-edit button { font: inherit; padding: 1px 5px; }
.pos-edit input { font: inherit; width: 56px; }
.pos-edit .pos-grp { display: inline-flex; gap: 2px; align-items: center; }
.pos-dialog { position: absolute; z-index: 6; top: 40px; left: 40px; width: 420px; max-height: 80%; overflow: auto;
  padding: 8px; font: 12px system-ui, sans-serif; }
.pos-dialog label { display: block; margin: 3px 0; }
.pos-dialog pre { white-space: pre-wrap; font-size: 11px; margin: 4px 0; }
/* Ship CS1: the Colours panel (a pos-dialog, so it floats over the chart without resizing it) */
.colours-panel { width: 530px; left: auto; right: 40px; }
.colours-row { display: flex; align-items: center; gap: 6px; margin: 2px 0; }
.colours-name { flex: 1 1 auto; min-width: 150px; }
.colours-cell { display: inline-flex; align-items: center; gap: 3px; width: 112px; }
.colours-cell input[type=color] { width: 22px; height: 18px; padding: 0; border: 0; background: none; }
/* a whole "#RRGGBB" in a monospace field: 7 characters, never clipped (the 62 px field cut "#00BCD4" to "#00BCI") */
.colours-hex { width: 8ch; padding: 1px 3px; font: 12px/1.3 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.colours-head .colours-cell { color: var(--muted); }
.pos-dialog-head { font-weight: 600; margin-bottom: 6px; display: flex; justify-content: space-between; }

/* Ship 7b-2b: the heat cell under the cursor. Bottom-LEFT, clear of #dash-panel's top-right and of
   the heat layer's own 12 px hit strip along the bottom edge, so it never sits on the thing it is
   describing. */
#heat-readout { left: 8px; bottom: 26px; max-width: 320px; }
/* Barrett 2026-09-29: the status bar under the price pane (heat / volume-profile status) -- never on the plot,
   and a FIXED height so a layer toggling never resizes the chart. */
#status-bar { flex: 0 0 34px; overflow-y: auto; padding: 2px 8px; border-top: 1px solid var(--line);
              font: 11px/15px ui-monospace, monospace; color: var(--muted); }
#status-bar .cell { display: inline; margin-right: 14px; }
/* Ship TC2: the trading cockpit. The kill strip sits on every view (zen too: it is not the nav). */
#cockpit-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 3px 12px;
  background: #1A0B2E; border-bottom: 1px solid var(--line); font-size: 12px; }
.kill-state { font-weight: 700; padding: 1px 8px; border-radius: 3px; }
.kill-state.killed { background: #3A0D1A; color: #FF8A80; }
.kill-state.live { background: #0D3A1F; color: #69F0AE; }
.kill-state.unknown { color: var(--muted); }
button.kill { background: #B71C1C; color: #fff; border-color: #FF1744; font-weight: 700; }
button.kill:disabled { background: #3A0D1A; color: #FF8A80; cursor: default; }
.ap-lines { display: flex; flex-wrap: wrap; gap: 4px 10px; }
.ap-line { font-weight: 700; padding: 1px 6px; border-radius: 3px; }
.ap-line.real { background: #FF1744; color: #fff; }
.ap-line.paper { background: #283593; color: #E8EAF6; }
.ap-off { color: var(--muted); }
.ap-unknown { color: #FFB74D; }   /* TC2: an unread Autopilot state is unknown, never off (the .notice.warn colour) */
.tc-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tc-toolbar .grow { flex: 1; }
.tc-toast { min-height: 1.4em; }
.tc-slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 10px; }
.tc-card { border: 1px solid var(--line); border-radius: 6px; padding: 8px 10px; background: var(--panel); }
.tc-card.real { border: 2px solid #FF1744; }
.tc-card-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.mode-badge { font-weight: 800; letter-spacing: .06em; padding: 1px 8px; border-radius: 3px; color: #fff; }
.mode-badge.real { font-size: 14px; }
.chips { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0; }
.chip { border: 1px solid var(--line); border-radius: 10px; padding: 0 8px; color: var(--muted); }
.chip.on { color: var(--text); border-color: var(--accent); }
.chip.ap.on { background: var(--accent); color: #041018; font-weight: 700; }
.chip.warn { color: #FFB74D; border-color: #FFB74D; }
.chip.bad { color: #FF8A80; border-color: #FF1744; }
.tc-today { margin: 4px 0; }
.ap-banner { margin: 6px 0; padding: 6px 8px; border-radius: 4px; border: 1px solid var(--line); }
.ap-banner.on.paper { background: #1A237E; border-color: #5C6BC0; }
.ap-banner.on.real { background: #4A0012; border: 2px solid #FF1744; }
.ap-banner.off { color: var(--muted); }
.tc-check { margin: 4px 0; }
.tc-actions { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.tc-equity { height: 220px; position: relative; border: 1px solid var(--line); }
table.kv { border-collapse: collapse; font-size: 12px; }
table.kv th { text-align: left; color: var(--muted); font-weight: 400; padding: 0 8px 0 0; }
.tc-modal { position: fixed; inset: 0; z-index: 50; background: rgba(5, 1, 12, 0.72); display: flex;
  align-items: flex-start; justify-content: center; overflow: auto; padding: 40px 12px; }
.tc-modal[hidden] { visibility: hidden; pointer-events: none; }
.tc-modal-box { background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px;
  width: min(720px, 100%); }
.tc-modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.tc-form, .tc-ticket, .tc-settings { display: flex; flex-direction: column; gap: 4px; }
.tc-field { display: flex; justify-content: space-between; gap: 8px; }
.tc-field input, .tc-field select { min-width: 46%; }
.tc-confirm { margin-top: 8px; font-weight: 700; color: #FF8A80; }
.tc-version { margin: 6px 0; }
.tc-version.current b { color: var(--accent); }
button.send { background: var(--accent); color: #041018; font-weight: 700; }
/* Phone width (Barrett Q4): the kill strip and the slot cards stay usable; the tables scroll inside the panel. */
@media (max-width: 600px) {
  .tc-slots { grid-template-columns: 1fr; }
  #cockpit-strip { font-size: 13px; }
  button.kill { padding: 6px 16px; }
  table.grid { display: block; overflow-x: auto; }
}
