/* Equyx console — the SPA shell: frozen header, tab strip, analyst sidebar. */

/* ---- the frozen header ------------------------------------------------
   The header does not scroll because it is OUTSIDE the scrolling area, not
   because three bars each carry a hand-computed sticky offset. Those offsets
   were 0 / 40px / 74px, and the moment the tab strip grew a scrollbar or the
   pill rail wrapped, every number below it was wrong — which is where the gap
   beside the analyst panel came from. A column that owns the viewport and
   scrolls its own body cannot drift. */
.console { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.chead { flex: 0 0 auto; z-index: 40; background: var(--panel, #0d0b08); }
.ctop, .tabstrip { background: var(--panel, #0d0b08); border-bottom: 1px solid var(--border, #2a2318); }
.ctop { display: flex; align-items: center; gap: 14px; padding: 7px 12px; }
.tabstrip { display: flex; align-items: stretch; gap: 2px; padding: 0 8px; overflow-x: auto; }
/* the tab strip scrolls sideways; a visible bar under it looks broken */
.tabstrip::-webkit-scrollbar { height: 0; }

.ctop .brand { display: flex; align-items: center; gap: 8px; cursor: pointer; flex: 0 0 auto; }
.cuser { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.cuser .who { font-size: 11px; color: var(--muted); max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- query bar ---- */
.qbar { position: relative; flex: 1 1 auto; display: flex; align-items: center; gap: 6px; max-width: 780px; }
.qbar-icon { color: var(--amber, #ffa028); font-weight: 700; }
.qbar-in {
  flex: 1; background: var(--chip, #12100c); border: 1px solid var(--border-strong, #3a3020);
  color: var(--text, #e8e2d6); font-family: var(--mono, monospace); font-size: 12.5px;
  padding: 6px 10px; border-radius: 3px;
}
.qbar-in:focus { border-color: var(--amber, #ffa028); outline: none; }
.qbar-x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 12px; }
.qbar-go {
  font: inherit; font-size: 11px; padding: 6px 12px; cursor: pointer;
  background: var(--amber, #ffa028); border: 1px solid var(--amber, #ffa028); color: var(--on-accent, #000);
  font-weight: 700; border-radius: 3px;
}
.qbar-go:disabled { opacity: .4; cursor: not-allowed; }
.qbar-hits {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 60;
  background: var(--chip); border: 1px solid var(--border-strong, #3a3020);
  border-radius: 4px; box-shadow: 0 10px 34px rgba(0,0,0,.6); overflow: hidden;
}
.qhit {
  display: grid; grid-template-columns: 92px 1fr auto; gap: 10px; align-items: baseline;
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: 7px 11px; color: var(--text); font: inherit; font-size: 12px;
}
.qhit:hover { background: rgba(255,160,40,.12); }
.qhit b { color: var(--amber, #ffa028); }
.qhit span { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qhit i { color: var(--muted); font-style: normal; font-size: 10.5px; }
.qhit-foot { padding: 6px 11px; font-size: 10.5px; color: var(--muted); border-top: 1px solid var(--border); }

/* ---- tabs ---- */
.ctab {
  display: flex; align-items: center; gap: 7px; padding: 6px 10px; cursor: pointer;
  border: 1px solid transparent; border-bottom: none; font-size: 11.5px;
  color: var(--muted); white-space: nowrap; border-radius: 3px 3px 0 0;
}
.ctab:hover { color: var(--text); background: rgba(255,255,255,.03); }
.ctab.on { color: var(--on-accent, #000); background: var(--amber, #ffa028); font-weight: 600; }
.ctab-kind { font-size: 8.5px; letter-spacing: .09em; opacity: .75; }
.ctab-label { max-width: 190px; overflow: hidden; text-overflow: ellipsis; }
.ctab-x { background: none; border: none; cursor: pointer; color: inherit; opacity: .55; font-size: 10px; padding: 0 2px; }
.ctab-x:hover { opacity: 1; }
/* THE PIN SITS QUIET UNTIL IT MATTERS. Faint on every tab so the option is
   discoverable without eleven pins shouting at once; solid once the tab is
   pinned, because then it is state and not an offer. */
/* 15x18 MEASURED - under the 22px pointer minimum, and mine. The icon
   stays 11px; the box around it grows. */
.ctab-pin { background: none; border: none; cursor: pointer; color: inherit; opacity: .35;
  padding: 0 4px; display: inline-flex; align-items: center; justify-content: center;
  min-height: 22px; min-width: 22px; }
.ctab-pin .ico, .ctab-pin svg { width: 11px; height: 11px; }
.ctab-pin:hover { opacity: .9; }
.ctab-pin.on { opacity: 1; color: var(--accent, var(--amber)); }
.ctab:hover .ctab-pin { opacity: .7; }
.ctab:hover .ctab-pin.on { opacity: 1; }
.tabstrip-spacer { flex: 1; }
.tabadd {
  font: inherit; font-size: 10.5px; padding: 5px 10px; margin: 3px 0; cursor: pointer;
  background: transparent; color: var(--muted); border: 1px solid var(--border); border-radius: 3px;
  white-space: nowrap;
}
.tabadd:hover { color: var(--amber, #ffa028); border-color: var(--amber, #ffa028); }

/* ---- suggestion rail ---- */
.pill {
  flex: 0 0 auto; font: inherit; font-size: 11px; padding: 5px 11px; cursor: pointer;
  background: var(--chip, #12100c); color: var(--amber-dim, #c8912f); border: 1px solid var(--border-strong, #3a3020);
  border-radius: 12px; white-space: nowrap;
}
.pill:hover { background: var(--amber, #ffa028); color: var(--on-accent, #000); border-color: var(--amber, #ffa028); }
.pill.own { border-color: var(--good); color: var(--good); }
.pill.own:hover { background: var(--good); color: var(--on-accent, #000); }

/* ---- market select (top bar) ---- */
.mkt-sel { position: relative; display: inline-flex; align-items: center; color: var(--muted); font-size: 11px; margin: 0 8px; }
.mkt-sel .ico { width: 14px; height: 14px; color: var(--amber, #ffa028); }
.mkt-btn { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 11px; padding: 5px 9px; background: var(--panel, #0d0b08); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm, 3px); cursor: pointer; }
.mkt-btn:hover { border-color: var(--amber, #ffa028); }
.mkt-btn .ico:last-child { width: 12px; height: 12px; color: var(--muted); }
.mkt-menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; min-width: 268px; padding: 6px; background: var(--panel, #0d0b08); border: 1px solid var(--border-strong, #3a3020); border-radius: var(--radius-sm, 3px); box-shadow: 0 12px 30px rgba(0,0,0,.55); }
.mkt-head { display: flex; align-items: center; gap: 6px; font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); padding: 4px 6px 7px; }
.mkt-head .spacer { flex: 1 1 auto; }
.mkt-opt { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; font: inherit; font-size: 11.5px; padding: 6px 7px; background: none; border: 0; border-radius: 3px; color: var(--text-2); cursor: pointer; }
.mkt-opt:hover { background: var(--hover, #17130c); color: var(--text); }
.mkt-opt.on { color: var(--text); }
.mkt-box { width: 14px; height: 14px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; border: 1px solid var(--border-strong, #3a3020); border-radius: 2px; color: var(--amber, #ffa028); }
.mkt-opt.on .mkt-box { border-color: var(--amber, #ffa028); }
.mkt-name { flex: 1 1 auto; }
.mkt-n { color: var(--faint); font-size: 10px; }
.mkt-foot { font-size: 10px; color: var(--muted); line-height: 1.5; padding: 7px 7px 3px; border-top: 1px solid var(--border); margin-top: 4px; }
.mk-tick { color: var(--amber, #ffa028); margin-right: 4px; }
.who .ico { margin-right: 5px; width: 13px; height: 13px; }

/* ---- body + panes ---- */
/* The body owns the remaining height and scrolls INSIDE, so opening the
   analyst shifts the content rather than leaving a strip of background. */
.cbody { flex: 1 1 auto; display: grid; grid-template-columns: minmax(0, 1fr) var(--side-w, 420px);
  min-height: 0; overflow: hidden; }
.cbody.side-closed { grid-template-columns: minmax(0, 1fr) 36px; }
/* Full screen hands the whole body to the answer. The pane is not unmounted -
   collapsing back must not cost a refetch or lose the scroll position. */
:root[data-analyst-full="1"] .cbody { grid-template-columns: 0 minmax(0, 1fr); }
/* The pane keeps its place in the grid at zero width. `display: none` here
   removed it as a grid ITEM, which left the analyst as the only child and
   auto-placement dropped it into the 0px column - a 2px analyst on a
   full-screen button. It stays mounted either way, so coming back costs no
   refetch and keeps the scroll position. */
:root[data-analyst-full="1"] .cbody > .cpane { overflow: hidden; }
.cpane { min-width: 0; overflow-y: auto; overflow-x: hidden; height: 100%; }
.cpane.hidden { display: none; }

.pane { padding: 16px 18px 40px; }
.pane-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; }
.pane-head h2 { font-size: 15px; margin: 0; letter-spacing: .02em; }
.pane-empty { padding: 60px 24px; max-width: 560px; margin: 0 auto; text-align: center; }
.pane-empty h2 { font-size: 16px; margin: 0 0 10px; }
.pane-empty p { color: var(--muted); font-size: 12.5px; line-height: 1.6; }

/* ---- watchlist ---- */
.wl-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.wl-table th {
  text-align: left; font-size: 9.5px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); padding: 5px 8px; border-bottom: 1px solid var(--border);
}
.wl-table td { padding: 7px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.wl-row { cursor: pointer; }
.wl-row:hover td { background: rgba(255,255,255,.03); }
.wl-sym b { color: var(--amber, #ffa028); }
.wl-name { font-size: 10.5px; color: var(--muted); }
.wl-px, .wl-chg { text-align: right; font-variant-numeric: tabular-nums; }
.wl-spark { width: 110px; }
.spark { width: 100px; height: 24px; }
.spark path { fill: none; stroke-width: 1.3; vector-effect: non-scaling-stroke; }
.spark path.up { stroke: var(--good, #4ec97e); }
.spark path.down { stroke: var(--bad, #e5484d); }

/* ---- saved ---- */
.saved-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.saved-card { border: 1px solid var(--border); border-radius: 4px; padding: 12px; }
.sv-top { display: flex; justify-content: space-between; align-items: baseline; }
.sv-top b { color: var(--amber, #ffa028); }
.sv-label { font-size: 12.5px; margin: 6px 0 4px; }
.sv-bits { font-size: 10.5px; color: var(--muted); margin-bottom: 10px; }
.sv-act { display: flex; gap: 8px; align-items: center; }

/* ---- alerts ---- */
.alert-truth {
  border: 1px solid var(--border); border-left: 3px solid var(--amber, #ffa028);
  padding: 10px 14px; margin-bottom: 14px; font-size: 12px;
}
.alert-truth ul { margin: 8px 0 0; padding-left: 18px; }
.alert-truth li { margin-bottom: 5px; line-height: 1.5; }
.alert-truth .ok { color: var(--good, #4ec97e); }
.alert-truth .bad { color: var(--amber, #ffa028); }
.alert-form { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; margin-bottom: 14px; }
.alert-form input, .alert-form select {
  background: var(--chip, #12100c); border: 1px solid var(--border-strong, #3a3020); color: var(--text);
  font: inherit; font-size: 11.5px; padding: 5px 8px; border-radius: 3px;
}
/* THE BASE RULE IN app.css GIVES EVERY `select` width:100%, so each of these
   took the whole flex line and the one-line form became four. Sized to their
   own content instead. Not folded into `.alert-form input, .alert-form
   select` above: that selector is (0,1,1) and would beat `.af-sym` (0,1,0)
   below, resizing the two boxes that were never wrong. */
.alert-form select { width: auto; max-width: 100%; }
.af-sym { width: 100px; }
.af-val { width: 90px; }
.af-help { flex-basis: 100%; font-size: 10.5px; color: var(--muted); }
.al-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.al-table th {
  text-align: left; font-size: 9.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); padding: 5px 8px; border-bottom: 1px solid var(--border);
}
.al-table td { padding: 7px 8px; border-bottom: 1px solid var(--border); }
.al-journal { list-style: none; margin: 0; padding: 0; font-size: 11.5px; }
.al-journal li { display: flex; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.aj-when { color: var(--muted); flex: 0 0 150px; }
.aj-what { flex: 1; }
.aj-del { flex: 0 0 90px; text-align: right; color: var(--muted); }
.aj-del.ok { color: var(--good, #4ec97e); }

/* ---- the analyst sidebar ---- */
.side {
  border-left: 1px solid var(--border); display: flex; flex-direction: column;
  min-width: 0; height: 100%; overflow: hidden; position: relative;
}
/* The grip sits ON the border, half in the panel and half over the pane beside
   it, because a 1px border is not a pointer target. */
.side-grip {
  position: absolute; left: -3px; top: 0; bottom: 0; width: 7px; z-index: 5;
  cursor: col-resize; background: transparent; touch-action: none;
}
.side-grip:hover, .side-grip:focus-visible { background: var(--amber, #ffa028); opacity: .55; outline: none; }
/* While dragging, nothing else may take the pointer or highlight text. */
body.side-dragging { cursor: col-resize; user-select: none; }
body.side-dragging iframe, body.side-dragging canvas { pointer-events: none; }
.side.collapsed { align-items: center; }
.side-head {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px;
  border-bottom: 1px solid var(--border); background: var(--amber, #ffa028); color: var(--on-accent, #000);
}
.side.collapsed .side-head {
  writing-mode: vertical-rl; height: 100%; background: transparent;
  color: var(--muted); border: none;
}
.side-head b { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; }
/* .8 ON THE ACCENT BAND MEASURED 4.21:1 AT 10.5px - under AA, and this is
   the line that says how many results are on screen. It is already the
   secondary half of the pair by being 10.5px beside the title; the fade was
   spending the contrast that made it readable to repeat what size already
   said. */
.side-sub { font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-x { background: none; border: none; cursor: pointer; color: inherit; font-size: 15px; }
.side-body { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.side-empty { padding: 20px 14px; font-size: 12px; color: var(--text); }
.side-empty p { line-height: 1.6; margin: 0 0 10px; }
.side-sheet {
  max-height: 240px; overflow: auto; font-size: 10px; line-height: 1.45;
  background: var(--panel-3); border-bottom: 1px solid var(--border); margin: 0; padding: 8px 10px; white-space: pre;
}
.side-log { flex: 1; overflow-y: auto; padding: 10px; min-height: 0; }
.side-pills { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 10px 0; }
.side-pills button {
  font: inherit; font-size: 10.5px; padding: 4px 9px; cursor: pointer; border-radius: 11px;
  background: var(--chip, #12100c); color: var(--amber-dim, #c8912f); border: 1px solid var(--border-strong, #3a3020);
}
.side-pills button:hover:not(:disabled) { background: var(--amber, #ffa028); color: var(--on-accent, #000); }
.side-pills button:disabled { opacity: .4; cursor: not-allowed; }
/* ---------------------------------------------------------- the composer
   Everything the reader can press lives INSIDE the field. The wrapper owns the
   border and the focus ring; the textarea is transparent and borderless inside
   it, so the whole thing reads as one control rather than a field with a
   toolbar stacked on top of it. */
.side-input { display: block; padding: 8px 10px; }
.composer {
  display: flex; flex-direction: column;
  background: var(--chip, #12100c); border: 1px solid var(--border-strong, #3a3020);
  border-radius: var(--radius-sm, 4px); padding: 6px 6px 4px; cursor: text;
}
.composer.on { border-color: var(--amber, #ffa028); }
.composer-text {
  background: none; border: none; outline: none; resize: none;
  color: var(--text); font: inherit; font-size: 12px; line-height: 1.5;
  padding: 2px 4px; max-height: 160px; min-height: 38px; width: 100%;
}
.composer-text::placeholder { color: var(--faint); }
.composer-bar { display: flex; align-items: center; gap: 4px; padding-top: 2px; }
.composer-tools { display: flex; gap: 1px; flex: 1; }
.composer-tools .tool {
  background: none; border: 1px solid transparent; color: var(--faint);
  cursor: pointer; padding: 4px 6px; line-height: 1; display: inline-flex;
  border-radius: var(--radius-sm, 4px);
}
.composer-tools .tool:hover { color: var(--amber, #ffa028); background: var(--hover, rgba(255,255,255,.05)); }
/* a listening microphone must be unmistakable — a page quietly recording is
   the one state a reader must never be unsure about */
.composer-tools .tool.on { color: var(--on-accent, #000); background: var(--bad, #ff4f4f); border-color: var(--bad, #ff4f4f); }
.composer-send {
  font: inherit; font-size: 11.5px; padding: 4px 14px; cursor: pointer;
  background: var(--amber, #ffa028); color: var(--on-accent, #000);
  border: 1px solid var(--amber, #ffa028); border-radius: var(--radius-sm, 4px);
}
.composer-send:disabled { background: transparent; color: var(--faint); border-color: var(--border); cursor: default; }
@media (pointer: coarse) {
  .composer-tools .tool { min-height: 34px; min-width: 34px; }
  .composer-send { min-height: 34px; }
  .composer-text { font-size: 16px; }   /* 16px or iOS zooms the page on focus */
}

/* ---- horizon bar ---- */
.hzbar { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin: 10px 0 4px; }
.hz-lab { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-right: 4px; }
.hz-btn {
  font: inherit; font-size: 11px; padding: 4px 10px; cursor: pointer; border-radius: 3px;
  background: transparent; color: var(--muted); border: 1px solid var(--border);
}
.hz-btn:hover { color: var(--text); border-color: var(--amber, #ffa028); }
.hz-btn.on { background: var(--amber, #ffa028); border-color: var(--amber, #ffa028); color: var(--on-accent, #000); font-weight: 600; }
.hz-note { font-size: 10.5px; color: var(--muted); margin-left: 6px; }

/* ---- the plan banner ---- */
.askbar {
  border: 1px solid var(--border); border-left: 3px solid var(--amber, #ffa028);
  padding: 9px 13px; margin: 8px 0; font-size: 12px; border-radius: 0 3px 3px 0;
}
.askbar.bad { border-left-color: var(--bad, #e5484d); }
.askbar.working { color: var(--muted); }
.ab-title { font-weight: 600; font-size: 13px; margin-bottom: 3px; }
.ab-note { color: var(--muted); line-height: 1.5; }
.ab-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 10.5px; color: var(--amber-dim, #c8912f); margin-top: 6px; }
.ab-dropped { font-size: 10.5px; color: var(--bad, #e5484d); margin-top: 5px; }
.ab-act { display: flex; gap: 10px; margin-top: 8px; }

/* ---- ask button on every row ---- */
.c-ask { width: 58px; text-align: right; }
.askbtn {
  font: inherit; font-size: 10px; padding: 3px 9px; cursor: pointer; border-radius: 10px;
  background: transparent; color: var(--amber-dim, #c8912f); border: 1px solid var(--border-strong, #3a3020);
}
.askbtn:hover { background: var(--amber, #ffa028); color: var(--on-accent, #000); border-color: var(--amber, #ffa028); }
.scr-table col.w-ask { width: 58px; }

/* ---- provenance ---- */
.sources { border: 1px solid var(--border); padding: 11px 14px; margin: 16px 0; font-size: 11.5px; border-radius: 3px; }
.sources ul { margin: 7px 0 0; padding-left: 18px; }
.sources li { margin-bottom: 4px; line-height: 1.5; color: var(--muted); }
.sources li b { color: var(--text); }
.src-stamp { margin-top: 8px; font-size: 10.5px; color: var(--amber-dim, #c8912f); }

/* ---- toast ---- */
.toast, .ask-toast {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 90;
  background: var(--chip); border: 1px solid var(--amber, #ffa028); border-radius: 4px;
  padding: 10px 16px; font-size: 12px; max-width: 620px; box-shadow: 0 10px 34px rgba(0,0,0,.6);
  cursor: pointer;
}
.spinner.sm { width: 10px; height: 10px; border-width: 1.5px; }
.mini {
  font: inherit; font-size: 10.5px; padding: 2px 8px; cursor: pointer; border-radius: 3px;
  background: transparent; color: var(--muted); border: 1px solid var(--border);
}
.mini:hover { color: var(--amber, #ffa028); border-color: var(--amber, #ffa028); }
/* every "Ask" chip in the product, measured at 36x20 on a desktop pointer.
   The coarse-pointer rules further down raise these again; this is the
   floor that applies to everyone. */
.ir-ask, .askbtn, .mk-ask, .nw-ask {
  display: inline-flex; align-items: center; justify-content: center; min-height: 22px;
}

@media (max-width: 1100px) {
  .console { height: auto; overflow: visible; }
  .cbody, .cbody.side-closed { grid-template-columns: minmax(0, 1fr); overflow: visible; }
  .cpane { height: auto; overflow: visible; }
  .side { height: auto; max-height: 60vh; border-left: none; border-top: 1px solid var(--border); }
}

/* ---- the model pane ---- */
.model-pane { padding-top: 4px; }
.mp-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; flex-wrap: wrap; margin-bottom: 14px; }
.mp-head h3 { margin: 0 0 4px; font-size: 14px; }
.mp-sub { font-size: 11.5px; color: var(--muted); max-width: 640px; line-height: 1.5; }
.mp-hz { display: flex; gap: 4px; flex-wrap: wrap; }
.mp-verdict { border: 1px solid var(--border); border-left: 4px solid var(--muted); padding: 12px 16px; margin-bottom: 14px; }
.mp-verdict.good { border-left-color: var(--good, #4ec97e); }
.mp-verdict.flat { border-left-color: var(--amber, #ffa028); }
.mp-verdict.bad { border-left-color: var(--bad, #e5484d); }
.mp-verdict.unknown { border-left-color: var(--muted); }
.mv-word { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.mp-verdict.good .mv-word { color: var(--good, #4ec97e); }
.mp-verdict.flat .mv-word { color: var(--amber, #ffa028); }
.mp-verdict.bad .mv-word { color: var(--bad, #e5484d); }
.mv-why { font-size: 12.5px; line-height: 1.6; color: var(--text); max-width: 780px; }
.mp-point { border: 1px solid var(--border); padding: 12px 16px; margin: 14px 0; }
.mpp-head { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-bottom: 9px; }
.mpp-row { display: flex; flex-wrap: wrap; gap: 12px 32px; }
.mpp-row div { display: flex; flex-direction: column; gap: 2px; }
.mpp-row span { font-size: 10.5px; color: var(--muted); }
.mpp-row b { font-size: 16px; font-variant-numeric: tabular-nums; }
.mpp-warn { margin-top: 10px; font-size: 11.5px; color: var(--amber, #ffa028); line-height: 1.5; }
.mp-weights { margin-top: 14px; }
.mpw-head { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin-bottom: 7px; }

/* ---- asked-question output: written read + chart ---- */
.askout { margin: 10px 0 18px; }
.askinsight { border: 1px solid var(--border); border-left: 3px solid var(--good, #4ec97e);
  padding: 12px 16px; margin-bottom: 14px; font-size: 12.5px; line-height: 1.65; }
.askinsight.busy, .askinsight.err { color: var(--muted); border-left-color: var(--muted); }
.askinsight.err { border-left-color: var(--bad, #e5484d); }
.ai-badge { font-size: 9.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--good, #4ec97e); margin-bottom: 8px; }
.askinsight .ai-out p { margin: 0 0 9px; }
.askinsight .ai-out strong { color: var(--amber, #ffa028); }
.ai-foot { margin-top: 9px; font-size: 10.5px; color: var(--muted); }
.askchart { border: 1px solid var(--border); padding: 12px 14px 8px; }
.ac-head { font-size: 11px; text-transform: uppercase; letter-spacing: .07em; margin-bottom: 8px; }
.ac-sub { text-transform: none; letter-spacing: 0; color: var(--muted); margin-left: 10px; font-size: 10.5px; }
/* THE CSS HEIGHT IS WHAT THE READER GETS, NOT THE viewBox. Trimming the
   viewBox to 200 changed nothing on screen because this fixed 260px overrode
   it - a reminder that an SVG has two heights and only one of them is
   visible. Both are 200 now, so the bars keep their size and the table moves
   sixty pixels up. */
.ac-svg { width: 100%; height: 200px; display: block; }
.ac-axis { stroke: var(--border-strong, #3a3020); stroke-width: 1; }
.ac-tick, .ac-xlab, .ac-axlab { fill: var(--muted); font-size: 9.5px; font-family: var(--mono, monospace); }
.ac-axlab { fill: var(--text); font-size: 10.5px; }
.ac-bar { fill: var(--amber, #ffa028); opacity: .75; }
.ac-bar.down { fill: var(--bad, #e5484d); opacity: .7; }
.ac-bargroup, .ac-dotgroup { cursor: pointer; }
.ac-bargroup:hover .ac-bar, .ac-dotgroup:hover .ac-dot { opacity: 1; }
.ac-dot { fill: var(--amber, #ffa028); opacity: .8; }
.ac-dotlab { fill: var(--muted); font-size: 9px; font-family: var(--mono, monospace); }
.ac-foot { font-size: 10.5px; color: var(--muted); margin-top: 4px; }

/* A pane inside the console has no brand and no navigation — the console owns
   both. What is left is the state that belongs to this security alone. */
.pane-bar { display: flex; align-items: center; gap: 10px; padding: 5px 10px; }
.pb-sym { font-size: 12px; font-weight: 700; color: var(--amber, #ffa028); letter-spacing: .06em; }

.side-ready { padding: 12px 14px; font-size: 11.5px; color: var(--muted); border-bottom: 1px solid var(--border); }
.side-ready b { color: var(--amber, #ffa028); }
/* The same chips as the disclosure below, laid out where the sentence that
   names them can be read at the same time. */
.sr-pills { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.sr-pills .pill { font-size: 10.5px; padding: 5px 10px; }

/* Ready-made questions live with the chat, under the box you would type in.
   They were a third band of chrome across the top, which pushed the actual
   results down on every screen and read as navigation rather than as things
   you can ask. Here they are what they are: prompts. */
.side-asks { border-top: 1px solid var(--border); padding: 4px 10px 6px; flex: 0 0 auto; }
.sa-toggle { width: 100%; text-align: left; font: inherit; font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); background: none; border: none;
  padding: 4px 0; cursor: pointer; }
.sa-toggle:hover { color: var(--amber, #ffa028); }
.sa-toggle i { font-style: normal; font-size: 9px; }
.sa-rail { display: flex; flex-wrap: wrap; gap: 4px; max-height: 168px; overflow-y: auto;
  padding: 6px 0 2px; }
.sa-rail .pill { font-size: 10.5px; padding: 4px 9px; }

/* ---- wide tables must scroll, not be cut off ------------------------
   A grid/flex child sizes to its content unless told otherwise, so an
   overflow-x rule on an inner wrapper does nothing while every ancestor is
   happy to grow. The chain below is what makes the wrapper actually narrower
   than its table, which is what makes it scroll. Without it the final column
   sits under the analyst panel and cannot be clicked at all. */
.cpane, .cpane > *, .scr-shell, .scr-body, .results { min-width: 0; }
.scr-body, .results { max-width: 100%; }
.tablewrap {
  max-width: 100%; overflow-x: auto; overflow-y: visible;
  scrollbar-width: thin; -webkit-overflow-scrolling: touch;
}
.tablewrap::-webkit-scrollbar { height: 9px; }
.tablewrap::-webkit-scrollbar-thumb { background: var(--border-strong, #3a3020); border-radius: 5px; }
.tablewrap::-webkit-scrollbar-thumb:hover { background: var(--amber-dim, #c8912f); }

/* Identity and the action stay put while the numbers scroll under them —
   losing the ticker is what makes a wide table unreadable. */
/* A PINNED CELL MUST BE OPAQUE. --panel is a translucent tint over the page in
   every theme — white at 1.6% in the terminal look — so a pinned column
   painted with it lets the columns sliding underneath show straight through,
   and the ticker ends up overprinted by whatever numbers scroll past. The base
   colour is painted first and the tint layered over it, which keeps each
   theme's shade while making the cell solid. */
.scr-table th.c-rank, .scr-table td.c-rank,
.scr-table th.c-stock, .scr-table td.c-stock,
.scr-table th.c-ask, .scr-table td.c-ask {
  background-color: var(--bg, #000);
  background-image: linear-gradient(var(--panel, transparent), var(--panel, transparent));
}
.scr-table th.c-rank, .scr-table td.c-rank { position: sticky; left: 0; z-index: 3; }
.scr-table th.c-stock, .scr-table td.c-stock { position: sticky; left: 34px; z-index: 3; }
.scr-table thead th.c-rank, .scr-table thead th.c-stock { z-index: 5; background-color: var(--amber, #ffa028); background-image: none; }
.scr-row:hover td.c-rank, .scr-row:hover td.c-stock { background-image: linear-gradient(var(--hover, #17130c), var(--hover, #17130c)); }

/* NO FADE ON A 9.5px NUMBER. Even in the right colour the .9 left it at
   3.48:1; there is nothing to spare at this size. */
.ctab-chg { font-size: 9.5px; font-variant-numeric: tabular-nums; }
.ctab-chg.up { color: var(--good, #4ec97e); }
.ctab-chg.down { color: var(--bad, #e5484d); }
/* WHITE ON A PALE TINT. This dates from when `.ctab.on` was a solid
   accent block and `--on-accent` was the right answer; the active tab is
   `background: var(--accent-soft)` now, and the change figure on the tab
   you are actually looking at measured 1.24:1. Weight still marks it as
   active; the colour goes back to meaning up or down. */
.ctab.on .ctab-chg.up { color: var(--good-ink, var(--good)); font-weight: 700; }
.ctab.on .ctab-chg.down { color: var(--bad-ink, var(--bad)); font-weight: 700; }
.pe-act { display: flex; gap: 8px; justify-content: center; margin-top: 16px; flex-wrap: wrap; }

/* The action pins to the right for the same reason identity pins to the left:
   a wide table scrolls, and a button you have to go looking for is a button
   most people never press. */
.scr-table th.c-ask, .scr-table td.c-ask {
  position: sticky; right: 0; z-index: 3;
  box-shadow: -6px 0 8px -6px rgba(0,0,0,.75);
}
.scr-table thead th.c-ask { z-index: 5; background-color: var(--amber, #ffa028); background-image: none; }
.scr-row:hover td.c-ask { background-image: linear-gradient(var(--hover, #17130c), var(--hover, #17130c)); }

/* A screen that covered less than it asked for has to say so — "12 matches"
   means something different when a fifth of the universe never answered. */
.cov-warn { color: var(--amber, #ffa028); }
.none-bad { display: block; color: var(--bad, #e5484d); line-height: 1.6; }
.nb-why { display: block; color: var(--muted); font-size: 11px; margin-top: 6px; }
.nb-retry { margin-top: 10px; }

/* ---- breadcrumbs ---- */
.crumbs { display: flex; align-items: center; gap: 2px; padding: 5px 12px; font-size: 11px;
  background: var(--panel, #0d0b08); border-bottom: 1px solid var(--border, #2a2318); overflow-x: auto; }
.crumbs::-webkit-scrollbar { height: 0; }
.crumb { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; }
.cr-sep { font-style: normal; color: var(--muted); margin: 0 5px; opacity: .6; }
.cr-link { font: inherit; font-size: 11px; background: none; border: none; padding: 0; cursor: pointer;
  color: var(--amber-dim, #c8912f); }
.cr-link:hover { color: var(--amber, #ffa028); text-decoration: underline; }
.cr-txt { color: var(--muted); }
.cr-txt.here { color: var(--text); font-weight: 600; }
.cr-map { font: inherit; font-size: 10.5px; padding: 2px 9px; cursor: pointer; border-radius: 3px;
  background: transparent; color: var(--muted); border: 1px solid var(--border); }
.cr-map:hover { color: var(--amber, #ffa028); border-color: var(--amber, #ffa028); }
.auto-note { color: var(--good, #4ec97e); }

/* ---- site map ---- */
.sitemap { max-width: 1000px; }
.sm-note { font-size: 11.5px; color: var(--muted); margin-bottom: 18px; line-height: 1.6; }
.sm-sec { border: 1px solid var(--border); border-radius: 4px; padding: 14px 16px; margin-bottom: 14px; }
.sm-top { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }
.sm-top h3 { margin: 0; font-size: 14px; color: var(--amber, #ffa028); }
.sm-path { font-size: 10.5px; color: var(--muted); background: var(--chip, #12100c); padding: 2px 7px; border-radius: 3px; }
.sm-what { font-size: 12.5px; line-height: 1.6; margin: 0 0 10px; }
.sm-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.sm-table th { text-align: left; vertical-align: top; width: 190px; padding: 5px 12px 5px 0;
  color: var(--amber-dim, #c8912f); font-weight: 600; border-top: 1px solid var(--border); }
.sm-table td { padding: 5px 0; line-height: 1.55; color: var(--muted); border-top: 1px solid var(--border); }

/* ---- one tab bar, at the top, chart included ---- */
.tabs.top { display: flex; gap: 2px; padding: 4px 8px 0; border-bottom: 1px solid var(--border);
  overflow-x: auto; flex-wrap: nowrap; }
.tabs.top::-webkit-scrollbar { height: 0; }
.tabs.top button { display: flex; align-items: center; gap: 6px; white-space: nowrap;
  font: inherit; font-size: 11.5px; padding: 7px 13px; cursor: pointer; border-radius: 3px 3px 0 0;
  background: transparent; color: var(--muted); border: 1px solid transparent; border-bottom: none; }
.tabs.top button:hover { color: var(--text); background: rgba(255,255,255,.03); }
.tabs.top button.on { background: var(--amber, #ffa028); color: var(--on-accent, #000); font-weight: 600; }
.tab-key { font-style: normal; font-size: 8.5px; opacity: .55; letter-spacing: .05em; }

/* ---- collapsible rail ---- */
.fold { border-bottom: 1px solid var(--border); }
.fold-head { display: flex; align-items: center; gap: 7px; width: 100%; text-align: left;
  font: inherit; font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  padding: 7px 10px; cursor: pointer; background: transparent; color: var(--muted); border: none; }
.fold-head:hover { color: var(--amber, #ffa028); background: rgba(255,255,255,.03); }
.fold.open .fold-head { color: var(--on-accent, #000); background: var(--amber, #ffa028); font-weight: 700; }
.fold-caret { font-style: normal; font-size: 9px; }
.fold-title { flex: 1; }
.fold-count { opacity: .75; }

/* ---- brief ---- */
.cr-brief { font: inherit; font-size: 10.5px; padding: 2px 11px; cursor: pointer; border-radius: 3px;
  background: var(--amber, #ffa028); color: var(--on-accent, #000); border: 1px solid var(--amber, #ffa028);
  font-weight: 700; margin-right: 6px; }
.cr-brief:hover { filter: brightness(1.12); }

.cr-share { font: inherit; font-size: 10.5px; padding: 2px 10px; cursor: pointer; border-radius: 3px;
  background: transparent; color: var(--amber-dim, #c8912f); border: 1px solid var(--border-strong, #3a3020);
  margin-right: 6px; }
.cr-share:hover { color: var(--amber, #ffa028); border-color: var(--amber, #ffa028); }

/* ---- the screen description, editable in place --------------------
   This paragraph is the criteria written out, so it is the natural place to
   reach when you want something slightly different. It behaves like a field
   because it is one. */
.explain { position: relative; cursor: text; transition: border-color .12s; }
.explain:not(.editing):hover { border-left-color: var(--good, #4ec97e); }
.explain .ex-text { display: block; padding-right: 210px; }
.explain.custom { border-left-color: var(--good, #4ec97e); }
.ex-edit, .ex-reset {
  position: absolute; top: 8px; font: inherit; font-size: 10px; padding: 3px 9px;
  cursor: pointer; border-radius: 10px; background: var(--chip, #12100c);
  color: var(--amber-dim, #c8912f); border: 1px solid var(--border-strong, #3a3020);
}
.ex-edit { right: 10px; }
.ex-reset { right: 108px; color: var(--muted); }
.explain:hover .ex-edit { background: var(--amber, #ffa028); color: var(--on-accent, #000); border-color: var(--amber, #ffa028); }
.explain.editing { cursor: default; }
.ex-box {
  width: 100%; background: var(--chip, #12100c); border: 1px solid var(--amber, #ffa028);
  color: var(--text); font: inherit; font-size: 12.5px; line-height: 1.6;
  padding: 8px 10px; border-radius: 3px; resize: vertical; min-height: 68px;
}
.ex-box:focus { outline: none; box-shadow: 0 0 0 2px rgba(255,160,40,.18); }
.ex-act { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.ex-hint { font-size: 10.5px; color: var(--muted); }
.ex-note { font-size: 10.5px; color: var(--muted); margin-top: 8px; line-height: 1.5; }

/* ---- readable, hittable chrome -------------------------------------
   Measured, not guessed: the header buttons were 22px tall and the breadcrumb
   links 17px, under the 24px a pointer target needs; the table's column
   headings and the tab-kind label sat at 8.5-9.5px, under a readable floor.
   Small text in a dense table is where a tool stops being usable at a glance. */
.cr-share, .cr-brief, .cr-map { min-height: 26px; padding-top: 4px; padding-bottom: 4px; }
.cr-link { min-height: 24px; padding: 3px 4px; display: inline-flex; align-items: center; }
.cr-txt { line-height: 24px; }
.ctab-kind { font-size: 10px; }
.scr-table thead th { font-size: 10.5px; }
.wl-table th, .al-table th { font-size: 10.5px; }
.sa-toggle { min-height: 26px; font-size: 10.5px; }
.mini { min-height: 24px; font-size: 11px; }
.askbtn { min-height: 24px; font-size: 10.5px; }
.ex-edit, .ex-reset { min-height: 24px; font-size: 10.5px; }

/* Keyboard users must be able to see where they are. */
:focus-visible {
  outline: 2px solid var(--amber, #ffa028);
  outline-offset: 1px;
  border-radius: 2px;
}

/* The last of the sub-10px text: the odds under each projection cell and the
   headings inside an expanded row. Both carry meaning, so neither can be the
   size you use for a footnote. */
.wk-odds { font-size: 10.5px; }
.d-h, .dp-top, .dp-plain { font-size: 10.5px; }
.sp-plain, .sp-top { font-size: 10.5px; }

/* The last five, all measured:
   - the gate's text links were 13-14px tall, well under a pointer target
   - the breadcrumb chevron was matched as a control at 20x20; it is decoration
     and should never have been focusable or clickable
   - "see exact data" sat at 1.91:1 — amber-dim on the amber header bar, which
     is the one place that colour has almost nothing to sit against */
.gate-email .linkish.sm, .gate-guest .linkish {
  min-height: 26px; padding: 5px 2px; display: inline-flex; align-items: center;
}
.cr-sep { pointer-events: none; user-select: none; }
/* ONLY WHILE THE HEADER IS ACTUALLY ON THE ACCENT. `--on-accent` is white
   here because `.side-head` is painted `var(--amber)` - but
   `.side.collapsed .side-head` sets `background: transparent`, and this rule
   kept the white text over whatever the page is. Measured at 1.31:1, white
   on rgb(225,225,225). Collapse the panel on any light theme and its one
   button disappears. */
/* INHERIT, DO NOT ENUMERATE. `.side-head` has three states - open (amber),
   collapsed above 900px (transparent, muted text) and collapsed below 900px
   (amber again, a bar). Hardcoding `--on-accent` was unreadable in the
   second at 1.31:1; scoping it to `:not(.collapsed)` was unreadable in the
   third at 2.59:1. The header already works out the right colour for each;
   the button takes it. */
.side-head .mini {
  color: inherit; border-color: rgba(0, 0, 0, .38); background: rgba(0, 0, 0, .10);
}
.side-head .mini:hover { background: rgba(0, 0, 0, .22); border-color: rgba(0, 0, 0, .6); color: inherit; }

/* The analyst's collapse control was 20x20 — the one button on screen you
   reach for when the panel is in your way, and the hardest to hit. */
.side-x {
  min-width: 28px; min-height: 28px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 3px;
}
.side-x:hover { background: rgba(0, 0, 0, .18); }

/* ---- the model bench ---- */
.bench { margin-bottom: 18px; }
.bn-head { font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); margin: 16px 0 8px; }
.bn-tag { text-transform: none; letter-spacing: 0; color: var(--amber-dim, #c8912f); margin-left: 8px; }
.bn-card { border: 1px solid var(--border); border-left: 4px solid var(--muted);
  padding: 12px 16px; margin-bottom: 12px; }
.bn-card.good { border-left-color: var(--good, #4ec97e); }
.bn-card.flat { border-left-color: var(--amber, #ffa028); }
.bn-top { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.bn-top b { font-size: 15px; }
.bn-grid { display: flex; flex-wrap: wrap; gap: 14px 34px; }
.bn-grid > div { display: flex; flex-direction: column; gap: 2px; }
.bn-grid span { font-size: 10.5px; color: var(--muted); }
.bn-grid b { font-size: 19px; font-variant-numeric: tabular-nums; }
.bn-grid i { font-style: normal; font-size: 10.5px; color: var(--muted); }
.bn-why { font-size: 11.5px; line-height: 1.6; color: var(--text); margin-top: 11px; max-width: 800px; }
.bn-cal { border-collapse: collapse; font-size: 11px; margin-top: 11px; }
.bn-cal th { text-align: left; padding: 3px 16px 3px 0; color: var(--muted); font-weight: 600; font-size: 10.5px; }
.bn-cal td { padding: 3px 16px 3px 0; font-variant-numeric: tabular-nums; }

/* ---- controls beside the chart they drive ---------------------------
   The dials were above and the chart below the fold, so moving a slider
   produced a change you could not see without scrolling. A control whose
   effect is off screen may as well not update. */
.fc-split { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 16px; align-items: start; }
.fc-controls { position: sticky; top: 0; }
.fc-controls .scen { margin-bottom: 0; }
.fc-controls .scen-grid { grid-template-columns: 1fr; gap: 12px; padding-top: 10px; }
.fc-controls .scen-presets { gap: 4px; }
.fc-controls .scen-btn { font-size: 10.5px; padding: 4px 9px; }
.fc-view { min-width: 0; }
.fc-view .scen-flag { margin-bottom: 10px; }

/* A change should announce itself. One short pulse on the numbers that moved
   is enough to say "that did something" without becoming noise. */
@keyframes fc-pulse {
  0% { background: rgba(255, 160, 40, .22); }
  100% { background: transparent; }
}
.fc-view .rangemeter, .fc-view .oshape, .fc-view .scen-delta { animation: fc-pulse .5s ease-out; }

@media (max-width: 1180px) {
  .fc-split { grid-template-columns: minmax(0, 1fr); }
  .fc-controls { position: static; }
  .fc-controls .scen-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
}

/* Visible to a screen reader, not to the eye. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
h1.brand { margin: 0; font-size: inherit; font-weight: inherit; display: flex; align-items: center; gap: 8px; }
.qbar-note {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 61;
  background: var(--bad-soft); border: 1px solid var(--bad, #e5484d); border-radius: 4px;
  padding: 8px 11px; font-size: 11.5px; color: var(--text);
  display: flex; align-items: center; gap: 10px; justify-content: space-between;
}

/* ---- phone: a finger is not a mouse pointer -------------------------
   25 controls measured under 40px on a 390px screen. Apple and Google both
   put the floor at 44 and 48; under that people miss, and missing in a list
   of stocks means opening the wrong one. */
/* ---- phone: the top bar has to WRAP, not run off the side ------------
   Measured on a 390px screen: header.ctop is flex-wrap:nowrap, so its five
   children — brand 82px, search 274px, market 124px, theme 108px, account
   246px — laid out to 918px and the whole page scrolled sideways behind them.
   A console that scrolls horizontally is one where the account menu is simply
   not reachable. Let the bar wrap, give the search its own row, and let the
   account block shrink instead of setting the page's width. */
@media (max-width: 700px), (pointer: coarse) {
  header.ctop { flex-wrap: wrap; row-gap: 6px; }
  header.ctop > * { min-width: 0; }
  header.ctop form.qbar { flex: 1 1 100%; order: 3; }
  header.ctop h1.brand { flex: 0 1 auto; }
  header.ctop .cuser { flex: 1 1 auto; justify-content: flex-end; overflow: hidden; }
  header.ctop .cuser > * { min-width: 0; }
  /* an email is the widest thing in the bar and the least useful at this size */
  header.ctop .cuser .cu-email, header.ctop .cuser .cu-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 42vw; }
  header.ctop .mkt-sel { margin: 0 4px; }

  /* .crumbs already says overflow-x:auto and still pushed the page to 494px on
     a 390px screen. A flex item defaults to min-width:auto, which means "never
     smaller than my content" — so the box never became narrow enough to have
     anything to scroll, and the row set the width of the page instead. This is
     the flexbox min-content trap and it needs min-width:0 on the item AND on
     the column above it, or the constraint never reaches down. */
  .console, .chead, .cbody, .cpane { min-width: 0; }
  /* min-width:0 only helps if it reaches every box in the chain, and guessing
     those class names did not: the row still measured 494px in a 390px view.
     Wrapping needs no knowledge of the ancestors, and on a phone a second line
     of buttons reads better than a scroll strip nobody notices is there. */
  .crumbs { flex-wrap: wrap; overflow-x: visible; row-gap: 4px; max-width: 100%; }
  .tabstrip { flex-wrap: wrap; overflow-x: visible; row-gap: 4px; max-width: 100%; }
  .tabstrip-spacer { display: none; }
  .ctab { max-width: 100%; }
  .ctab-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 38vw; }
}

@media (max-width: 700px), (pointer: coarse) {
  .tabadd, .cr-share, .cr-brief, .cr-map, .mini, .askbtn,
  .hz-btn, .mkt-btn, .scen-btn, .col-btn, .ex-edit, .ex-reset,
  .sa-toggle, .side-x, .qbar-go, .qbar-x, .pill {
    min-height: 44px; min-width: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    padding-left: 12px; padding-right: 12px;
  }
  .ctab { min-height: 44px; }
  .cr-link { min-height: 44px; }
  .side-input textarea { min-height: 44px; font-size: 16px; }  /* 16px stops iOS zooming on focus */
  .qbar-in { min-height: 44px; font-size: 16px; }
  .alert-form input, .alert-form select { min-height: 44px; font-size: 16px; }
  .ex-box { font-size: 16px; }
  /* nothing under 11px where a finger and a phone screen are involved */
  .c-sub, .st-name, .ctab-kind, .wk-odds, .sm-table, .ac-foot, .os-note { font-size: 11.5px; }
  .scr-table thead th, .wl-table th, .al-table th { font-size: 11px; }
}

/* A floor, not a list. Naming individual classes meant the next small thing
   added slipped under it again; on a phone nothing goes below 11.5px. */
@media (max-width: 700px), (pointer: coarse) {
  .console, .console * { font-size: max(11.5px, 1em); }
  .qbar-in, .side-input textarea, .ex-box,
  .alert-form input, .alert-form select { font-size: 16px; }
}

.bookmark.on { background: var(--amber, #ffa028); color: var(--on-accent, #000); border-color: var(--amber, #ffa028); font-weight: 700; }

/* Ask, on the card itself. Quiet until you go looking for it — a number you
   understand should not be shouting a button at you. */
.mcard { position: relative; }
.mc-ask {
  position: absolute; top: 6px; right: 6px;
  font: inherit; font-size: 10px; padding: 2px 8px; cursor: pointer; border-radius: 10px;
  background: transparent; color: var(--amber-dim, #c8912f);
  border: 1px solid var(--border-strong, #3a3020);
  opacity: 0; transition: opacity .12s;
}
.mcard:hover .mc-ask, .mc-ask:focus-visible { opacity: 1; }
.mc-ask:hover { background: var(--amber, #ffa028); color: var(--on-accent, #000); border-color: var(--amber, #ffa028); }
/* no hover on a touch screen, so it is always there */
@media (pointer: coarse) { .mc-ask { opacity: 1; min-height: 32px; } }

.hz-n { font-style: normal; font-size: 9.5px; opacity: .7; margin-left: 3px; }
.mkt-sel.research select { border-color: var(--amber-dim, #c8912f); }
.mkt-sel optgroup { font-style: normal; color: var(--muted); background: var(--panel, #0d0b08); }

/* --------------------------------------------------------- responsive
   THESE LIVE HERE BECAUSE THIS FILE OWNS `.cbody` AND LOADS LAST.
   The same rules sat in terminal.css first and did nothing at all: console.css
   comes after it in index.html and redefines `.cbody` at equal specificity, so
   the later file won every time. A media query does not outrank source order. */

/* THE PANELS MUST NOT OUT-VOTE THE THING YOU OPENED.
   On a 1280 laptop the rail at 228 and the analyst at 420 left the security
   itself 51% of the screen: the content people came for was the minority of
   their own window. Context shrinks first; the chart is the subject. */
@media (max-width: 1440px) {
  .cbody { grid-template-columns: minmax(0, 1fr) var(--side-w, 356px); }
}
@media (max-width: 1180px) {
  .cbody { grid-template-columns: minmax(0, 1fr) var(--side-w, 312px); }
}

/* ONE COLUMN, AND THE ANALYST BECOMES A SHEET.
   312px of chat beside 380px of chart is two unusable panes instead of one
   usable one. Below this width the analyst stops being a column and slides up
   over the content, the way every phone app that has to do both handles it. */
@media (max-width: 900px) {
  .cbody, .cbody.side-closed { grid-template-columns: minmax(0, 1fr); }
  .side {
    position: fixed; inset: auto 0 0 0; height: 70vh; z-index: 60;
    border-left: none; border-top: 1px solid var(--border-strong);
    box-shadow: 0 -10px 30px rgba(0, 0, 0, .55);
  }
  .side.collapsed { height: auto; }
  .side.collapsed .side-body { display: none; }
  .side-grip { display: none; }
  :root[data-analyst-full="1"] .side { height: 100%; top: 0; }
  .fc-split { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------- tab context menu */
.tabmenu-veil { position: fixed; inset: 0; z-index: 90; }
.tabmenu {
  position: fixed; z-index: 91; min-width: 200px;
  background: var(--bg-2); border: 1px solid var(--border-strong);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .6); padding: 4px;
}
.tabmenu-head {
  font-size: 10px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--faint); padding: 5px 8px 6px; border-bottom: 1px solid var(--border);
  margin-bottom: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tabmenu button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  color: var(--text); font: inherit; font-size: 12px; padding: 6px 9px; cursor: pointer;
}
.tabmenu button:hover:not(:disabled) { background: var(--amber, #ffa028); color: var(--on-accent, #000); }
.tabmenu button:disabled { color: var(--faint); cursor: default; }
.tabmenu-sep { height: 1px; background: var(--border); margin: 3px 0; }


/* ------------------------------------------------------- phone chrome
   MEASURED, NOT GUESSED: on a 390x844 phone the header alone was 446px -
   53% of the screen gone before a single figure. ctop 179 (brand, market,
   theme, sign-in and the ask box each taking a full row), crumbs 83, and a
   tabstrip that wrapped onto three rows at 184. A terminal that shows half a
   screen of chrome and no content is not a terminal on a phone.
   Everything below either shrinks, sheds a label it can live without, or
   scrolls sideways INSIDE itself rather than pushing the page. */
@media (max-width: 700px) {
  .chead { position: sticky; top: 0; z-index: 30; background: var(--bg); }

  .ctop { gap: 6px; padding: 5px 8px; flex-wrap: wrap; row-gap: 5px; }
  .ctop .brand-sub { display: none; }          /* "- market screener and AI terminal" */
  .ctop .who { display: none; }                /* "guest - nothing is saved" */
  .ctop .theme-btn span, .ctop .mkt-btn .mkt-label { display: none; }
  .ctop .theme-btn, .ctop .mkt-btn { padding-left: 8px; padding-right: 8px; }
  .cask { flex: 1 1 100%; order: 9; }          /* the ask box gets its own row, full width */
  .cask input { font-size: 16px; }             /* 16px or iOS zooms the page on focus */

  /* the trail matters least and costs a whole row; the last step is the one
     you are on, and that is already in the tab */
  .crumbs { display: none; }

  /* one row that scrolls, never three that stack */
  .tabstrip { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .tabstrip::-webkit-scrollbar { display: none; }
  .tabstrip .ctab, .tabstrip .tabadd { flex: 0 0 auto; }
  .tabstrip .tabadd span, .tabstrip .tabadd-label { display: none; }   /* icon only */
  .tabstrip-spacer { display: none; }

  /* the pane bar carries the symbol and the actions; the actions wrap */
  .pane-bar { flex-wrap: wrap; row-gap: 4px; }
}

/* ---- the analyst is a sheet, and a shut sheet is a bar ----
   70vh of chat with nothing in it was the single worst thing on the phone. */
@media (max-width: 900px) {
  .side.collapsed {
    height: auto; max-height: 46px;
  }
  /* NO RESERVED STRIP HERE, AND THAT IS DELIBERATE. I added
     `.cbody { padding-bottom: 52px }` believing the collapsed bar left the
     last row unreachable. Measured: at maximum scroll 0 of 193 controls are
     covered, and removing the padding changed neither that nor the document
     height (2620 both ways) - `.cbody`, `.console`, `body`, `.cpane` and
     `.scr-shell` were each tried and none of them extends it. The bar
     overlaps content at intermediate scroll positions, which is what a
     fixed bar does, and one scroll clears it. */
  .side.collapsed .side-head {
    writing-mode: horizontal-tb; height: auto; background: var(--amber, #ffa028);
    color: var(--on-accent, #000); border: none; justify-content: space-between;
  }
  .side:not(.collapsed) { height: 62vh; }
  .side .side-head { position: sticky; top: 0; z-index: 2; }
}

/* ---------------------------------------------------- the composer tools */
.side-tools { display: flex; gap: 2px; align-items: flex-end; padding-bottom: 2px; }
.side-tools .tool {
  background: none; border: 1px solid transparent; color: var(--muted);
  cursor: pointer; padding: 5px 6px; line-height: 1; display: inline-flex;
}
.side-tools .tool:hover { color: var(--amber, #ffa028); border-color: var(--border-strong); }
/* a listening microphone must be unmistakable - a page quietly recording is
   the one state a user must never be unsure about */
.side-tools .tool.on { color: var(--on-accent, #000); background: var(--bad, #ff4f4f); border-color: var(--bad, #ff4f4f); }

.att-tray { display: flex; flex-direction: column; gap: 4px; padding: 6px 10px 0; }
.att {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px;
  background: var(--chip, #12100c); border: 1px solid var(--border); font-size: 11.5px;
}
.att-thumb { width: 34px; height: 26px; object-fit: cover; border: 1px solid var(--border); }
.att-name { color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; }
.att-how { color: var(--faint); font-size: 10.5px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-x { background: none; border: none; color: var(--faint); cursor: pointer; font-size: 13px; }
.att-x:hover { color: var(--bad, #ff4f4f); }
.att-busy, .att-err { font-size: 11.5px; padding: 5px 10px 0; line-height: 1.5; }
.att-busy { color: var(--muted); }
.att-err { color: var(--bad, #ff4f4f); }



/* what a question was asked ABOUT, shown with the question */
.msg-att { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.msg-shot {
  max-width: 100%; max-height: 190px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm, 4px); display: block; cursor: zoom-in;
}
.msg-file {
  font-size: 11px; padding: 2px 7px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm, 4px); color: var(--muted);
}
.ab-theme { font-size: 11px; color: var(--muted); margin-top: 5px; line-height: 1.5; }

/* ---- phone, measured 16 Sep: header 135px over the content, analyst half-open ----
   One row of chrome and one ask box. The brand is its mark; the market picker
   keeps its icon and as much of its label as fits; the theme picker is an icon. */
@media (max-width: 700px) {
  header.ctop { flex-wrap: wrap; column-gap: 6px; row-gap: 6px; padding: 6px 8px; align-items: center; }
  header.ctop h1.brand .brand-name { display: none; }
  header.ctop h1.brand { flex: 0 0 auto; }
  /* basis 0: the market label shrinks to fit instead of pushing the rest onto new rows */
  header.ctop .mkt-sel { flex: 1 1 0; min-width: 0; margin: 0; }
  header.ctop .mkt-btn { width: 100%; max-width: 100%; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; justify-content: flex-start; }
  header.ctop .theme-wrap { flex: 0 0 auto; }
  header.ctop .theme-btn { width: 44px; max-width: 44px; overflow: hidden; white-space: nowrap; padding-left: 12px; padding-right: 0; justify-content: flex-start; }
  header.ctop .cuser { flex: 0 0 auto; }
  header.ctop .cuser .btn { padding-left: 10px; padding-right: 10px; }
  header.ctop .cuser .who { display: none; }
  header.ctop form.qbar { flex: 1 1 100%; order: 9; }
}

/* ---- the analyst on a phone: shut = a bar; open = the whole screen ---- */
@media (max-width: 900px) {
  .side:not(.collapsed) { top: 0; bottom: 0; height: 100vh; height: 100dvh; max-height: none; }
  .side:not(.collapsed) .side-body { height: calc(100% - 46px); overflow-y: auto; }
  /* !important: body.term.scr { overflow: auto } is more specific and won otherwise */
  html.analyst-open, html.analyst-open body { overflow: hidden !important; }
}
@media (max-width: 700px) {
  /* the screener's market row: one line that scrolls inside itself, not two rows of buttons */
  .mkt-bar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .mkt-bar::-webkit-scrollbar { display: none; }
  .mkt-bar .mkt-btn { flex: 0 0 auto; }
  /* the theme picker is its icon: no half-cut label */
  header.ctop .theme-btn { font-size: 0 !important; justify-content: center; padding-left: 0; }
  header.ctop .theme-btn svg { width: 18px; height: 18px; }
}
@media (max-width: 900px) {
  /* already the whole screen on a phone: "full screen" has nothing left to do */
  .side [data-side-full] { display: none; }
}
/* ---- the stock page's toolbar on a phone: one row ----
   Measured: 83px over two rows (symbol, live dot, rf, Bookmark, Save analysis,
   Refresh). The symbol is already in the quote header right below it and the
   risk-free rate is a setting, not something a phone reader changes. */
@media (max-width: 700px) {
  .pane-bar { flex-wrap: nowrap !important; overflow-x: auto; scrollbar-width: none; gap: 6px; padding-top: 4px; padding-bottom: 4px; }
  .pane-bar::-webkit-scrollbar { display: none; }
  .pane-bar .pb-sym, .pane-bar .rf-label, .pane-bar .spacer { display: none; }
  .pane-bar > * { flex: 0 0 auto; }
}

/* ================= the left rail =================================
   One vertical bar carrying every screen: the ones that are open, then the
   ones you can open. It replaces a horizontal tab strip that ran out of room
   after about five securities AND a second row of launcher buttons beside it.

   It is fixed rather than a grid track because `.cbody` redefines its columns
   in six places; a seventh definition that had to agree with all of them is a
   bug waiting to happen. Fixed costs one padding rule on `.console` and can
   never reflow a pane. Hover widens it OVER the content, so nothing shifts
   under the pointer - the thing that made an earlier peek-out unusable was
   that the page moved while you were reaching for it. */
/* NOT `--rail-w`: terminal.css already owns that name for the market rail
   inside a security, and declaring it here shrank that rail from 228px to
   52px on every terminal screen. Two rails, two names. */
:root { --crail-w: 52px; --crail-open: 216px; }

.crail {
  position: fixed; left: 0; top: var(--crail-top, 82px); bottom: 0; z-index: 60;
  width: var(--crail-w); overflow: hidden auto; overscroll-behavior: contain;
  background: var(--panel-2); border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 1px; padding: 6px 0 14px;
}
/* NO WIDTH TRANSITION. Animating the width means every item in the rail is a
   MOVING TARGET for the 130ms after the pointer arrives: you aim at Market,
   the bar widens, the row grows under you and the click lands on whatever is
   there when it settles. A headless click failed on exactly that, retrying
   for 30 seconds against an element that would not hold still, and a person
   with an unsteady hand hits the same thing. The labels still fade, because
   opacity costs no layout. */
/* ---- THE BAR OPENS FOR A KEYBOARD, NOT FOR A CLICK ----
   `:focus-within` matches focus however it arrived, so clicking a rail item
   left the bar open OVER the content until something else was focused: the
   screener's "Keep this screen" sat under the Alerts label and could not be
   pressed. The code worked around it by blurring the button after a mouse
   click, which is a hack with a cost - a real keyboard user who ARROWS into
   the bar lost it again. `:focus-visible` is the browser's own answer to the
   same question and needs no javascript. It is in its own rule, never in a
   selector list with :hover: a browser that does not understand :has() throws
   away the WHOLE rule it appears in, which would have taken hover with it. */
.crail:hover, .crail.pinned { width: var(--crail-open); box-shadow: 6px 0 22px rgba(0,0,0,.14); }
.crail:has(:focus-visible) { width: var(--crail-open); box-shadow: 6px 0 22px rgba(0,0,0,.14); }
.console { padding-left: var(--crail-w); }
/* THE BAR TAKES THE SPACE, IT DOES NOT SIT ON THE PAGE.
   It used to widen OVER the content on hover, on the theory that nothing
   should move under the pointer. What that actually did was cover the thing
   you were reading: the security's own name, the pane tabs and the left edge
   of the chart all disappeared behind it. The page moves aside instead, and
   the 180ms hover-intent delay below means a pointer passing through on its
   way somewhere else never moves anything at all. */
/* ONE VALUE, NOT THREE RULES TO KEEP IN STEP. `:has()` cannot be grouped -
   a browser that does not understand one selector throws away the whole rule
   - so the push needs a rule per trigger. When the phone breakpoint below
   had to switch the push off it overrode one of the three, and a tap on a
   rail item (which is `:focus-visible`, not `:hover` and not `.pinned`)
   pushed a 412px phone 216px to the right: measured as 480px of content in a
   412px window, on three screens. The triggers read a variable now, and the
   breakpoint sets that variable once - so a fourth trigger written later is
   correct on a phone without anyone remembering. */
/* the fallback is not decoration: `var()` with neither a value nor a
   fallback resolves to nothing and takes the whole declaration with it, and
   a push that cannot be resolved should be zero. `varcheck` flags any
   unfallbacked var, in all thirteen themes, for exactly this reason. */
.console { --crail-push: var(--crail-open, 216px); }
.console:has(.crail.pinned) { padding-left: var(--crail-push, 0px); }
.console:has(.crail:hover) { padding-left: var(--crail-push, 0px); }
.console:has(.crail:has(:focus-visible)) { padding-left: var(--crail-push, 0px); }

.crail-sec {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
  padding: 10px 0 4px 17px; white-space: nowrap; opacity: 0;
}
.crail:hover .crail-sec, .crail.pinned .crail-sec { opacity: 1; }
.crail:has(:focus-visible) .crail-sec { opacity: 1; }

.crail-item, .crail-pin {
  display: flex; align-items: center; gap: 11px; width: 100%;
  border: 0; background: transparent; color: var(--text-2); cursor: pointer;
  padding: 0 12px; min-height: 38px; text-align: left; position: relative;
}
.crail-item:hover, .crail-pin:hover { background: var(--hover); color: var(--text); }
.crail-item.on { background: var(--accent-soft); color: var(--accent); box-shadow: inset 2px 0 0 var(--accent); }
.crail-ico { width: 20px; height: 20px; flex: 0 0 20px; display: grid; place-items: center; }
.crail-item .logo { flex: 0 0 20px; }
/* the label exists at every width; only its visibility changes, so the icon
   never jumps sideways when the bar opens */
.crail-txt {
  flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 12.5px; opacity: 0; transition: opacity .1s ease;
}
.crail:hover .crail-txt, .crail.pinned .crail-txt { opacity: 1; }
.crail:has(:focus-visible) .crail-txt { opacity: 1; }
.crail-chg { font-size: 11px; font-variant-numeric: tabular-nums; opacity: 0; }
.crail:hover .crail-chg, .crail.pinned .crail-chg { opacity: 1; }
.crail-chg.up { color: var(--good); }
.crail-chg.down { color: var(--bad); }
.crail-x { font-size: 11px; color: var(--faint); padding: 2px 4px; border-radius: 3px; opacity: 0; }
.crail-item:hover .crail-x { opacity: 1; }
.crail-x:hover { background: var(--bad-soft); color: var(--bad); }
.crail-pin { color: var(--faint); min-height: 34px; }
.crail-pin[data-crail-pin="on"] { color: var(--accent); }


@media (max-width: 900px) {
  /* SAME LIST, LAID ON ITS SIDE. A 52px column is a quarter of a phone, so on
     a phone the same rail becomes one scrolling row under the header - same
     items, same order, same click. Labels are always visible here because
     there is no hover on a touch screen to reveal them. */
  :root { --crail-w: 0px; }
  /* THE ONE PLACE THE PUSH IS SWITCHED OFF. Every `.console:has(.crail...)`
     rule reads `--crail-push`, so this covers all of them - the three that
     exist and any added later. It is NOT `--crail-open`: that is also the
     rail's own open width, and zeroing it would collapse the rail itself. */
  .console { --crail-push: 0px; padding-left: 0; }
  .crail {
    position: static; width: auto; flex-direction: row; gap: 6px;
    border-right: 0; border-bottom: 1px solid var(--border);
    overflow-x: auto; overflow-y: hidden; padding: 6px 10px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .crail::-webkit-scrollbar { display: none; }
  .crail:hover, .crail.pinned { width: auto; box-shadow: none; }
  .crail-sec { display: none; }
  .crail-pin { display: none; }
  .crail-item {
    width: auto; flex: 0 0 auto; min-height: 40px; padding: 0 13px;
    border: 1px solid var(--border); border-radius: 9999px; gap: 8px;
  }
  .crail-item.on { box-shadow: none; border-color: var(--accent); }
  .crail-txt, .crail-chg { opacity: 1; }
  .crail-txt { max-width: 132px; }
}

/* ================= the Market screen ================= */
.mk-tabs { display: flex; gap: 8px; margin: 0 0 14px; flex-wrap: wrap; }
.mk-tab {
  border: 1px solid var(--border); background: var(--chip); color: var(--text-2);
  border-radius: 9999px; padding: 7px 16px; font-size: 12.5px; cursor: pointer; min-height: 34px;
}
.mk-tab:hover { border-color: var(--border-strong); color: var(--text); }
.mk-tab.on { background: var(--text); color: var(--bg); border-color: var(--text); }

.mk-wait { padding: 18px 2px; color: var(--muted); font-size: 12.5px; }
.mk-wait.bad { color: var(--bad); }

.mk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); gap: 14px; }
.mk-card { border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.mk-card-head { display: flex; align-items: baseline; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--border); }
.mk-card-head h3 { margin: 0; font-size: 13px; }
.mk-by { font-size: 11px; color: var(--faint); }

.mk-rows { list-style: none; margin: 0; padding: 0; }
.mk-row {
  display: grid; align-items: center; gap: 10px;
  /* EIGHT CHILDREN ON A VOLUME LIST, NOT SEVEN: `mk-move2` is rendered only
     when the list carries share volume, and without a track for it the Ask
     button wrapped to a second row. An unused final track is zero wide, so
     the seven-child lists are unaffected. */
  grid-template-columns: 18px 22px auto minmax(0, 1fr) auto auto auto auto;
  padding: 8px 14px; border-top: 1px solid var(--border);
}
.mk-row:first-child { border-top: 0; }
.mk-row:hover { background: var(--hover); }
.mk-rank { font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums; }
.mk-sym { border: 0; background: transparent; padding: 0; cursor: pointer; font-weight: 700; font-size: 12.5px; color: var(--accent); }
.mk-sym:hover { text-decoration: underline; }
/* a listing the price source will not accept: still ranked, still priced,
   but not pretending to be a link to a page that cannot load */
.mk-sym.flat { color: var(--text-2); cursor: default; font-weight: 700; }
.mk-sym.flat:hover { text-decoration: none; }
.mk-name { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mk-price { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text); }
.mk-move, .mk-move2 { font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mk-move.up, .mk-move2.up { color: var(--good); }
.mk-move.down, .mk-move2.down { color: var(--bad); }
.mk-move2 { font-size: 11px; opacity: .8; }
.mk-ask {
  font-size: 10.5px; padding: 2px 9px; border-radius: 9999px; cursor: pointer;
  border: 1px solid var(--border-strong); background: transparent; color: var(--muted);
}
.mk-ask:hover { border-color: var(--accent); color: var(--accent); }
.mk-foot { margin: 16px 2px 0; font-size: 11.5px; line-height: 1.55; color: var(--muted); }

@media (max-width: 720px) {
  .mk-grid { grid-template-columns: 1fr; }
  /* a seven-column row does not fit a phone; the name and the rank go, which
     are the two the ticker and the price already imply */
  /* same count, two fewer tracks because rank and name are display:none */
  .mk-row { grid-template-columns: 22px auto minmax(0, 1fr) auto auto auto; gap: 8px; padding: 10px 12px; }
  .mk-rank, .mk-name { display: none; }
  .mk-ask { min-height: 32px; padding: 4px 11px; }
}

/* ================= the Newswire ================= */
.nw-tabs { display: flex; gap: 8px; margin: 0 0 14px; flex-wrap: wrap; }
.nw-tab {
  border: 1px solid var(--border); background: var(--chip); color: var(--text-2);
  border-radius: 9999px; padding: 7px 16px; font-size: 12.5px; cursor: pointer; min-height: 34px;
}
.nw-tab:hover { border-color: var(--border-strong); color: var(--text); }
.nw-tab.on { background: var(--text); color: var(--bg); border-color: var(--text); }
.nw-wait { padding: 18px 2px; color: var(--muted); font-size: 12.5px; }
.nw-wait.bad { color: var(--bad); }

.nw-list { list-style: none; margin: 0; padding: 0; max-width: 940px; }
.nw-item {
  display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 14px;
  padding: 12px 0; border-top: 1px solid var(--border); align-items: start;
}
.nw-item:first-child { border-top: 0; }
.nw-thumb {
  width: 104px; height: 68px; object-fit: cover; border-radius: var(--radius-sm);
  background: var(--surface); display: block;
}
/* a missing image leaves a placeholder rather than collapsing the grid, so the
   headlines stay on one left edge however many carry a picture - and the
   placeholder now SAYS something, the source's initial, instead of being an
   empty rectangle that reads as a failure. The real picture is laid over it,
   so one that fails to load falls back here by itself. */
.nw-thumb-none { position: relative; border: 1px solid var(--border);
  display: grid; place-items: center; color: var(--faint);
  font-size: 22px; font-weight: 700; overflow: hidden; }
.nw-thumb-img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; }
/* `a.nw-title` too: `body.term a { color: var(--cyan) }` is (0,1,1) and this is
   (0,1,0), so every news headline has been painting the generic link colour
   rather than body text. Found by listing the classes the app puts on an <a>
   whose colour rule cannot win - `.pc-sym` was the same fault on the cards. */
a.nw-title, .nw-title {
  display: block; font-size: 14px; line-height: 1.45; color: var(--text);
  text-decoration: none; font-weight: 600;
}
.nw-title:hover { color: var(--accent); text-decoration: underline; }
.nw-meta { display: flex; align-items: center; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.nw-src { font-size: 11.5px; color: var(--muted); }
.nw-when { font-size: 11.5px; color: var(--faint); }
.nw-ask {
  font-size: 10.5px; padding: 2px 9px; border-radius: 9999px; cursor: pointer;
  border: 1px solid var(--border-strong); background: transparent; color: var(--muted);
}
.nw-ask:hover { border-color: var(--accent); color: var(--accent); }
.nw-foot { margin: 18px 2px 0; max-width: 940px; font-size: 11.5px; line-height: 1.6; color: var(--muted); }

@media (max-width: 720px) {
  .nw-item { grid-template-columns: 72px minmax(0, 1fr); gap: 10px; }
  .nw-thumb { width: 72px; height: 54px; }
  .nw-title { font-size: 13.5px; }
  .nw-ask { min-height: 32px; padding: 4px 11px; }
}

/* ---- a thumb is about 40px, and the header was built for a mouse ----
   Measured on a 390px screen: 19 controls under 40px tall — Go at 45x35, the
   market picker at 198x35, Research at 44x34. They are all fine with a cursor
   and all a near-miss with a thumb, which is why nobody notices until they
   are standing up on a train. Height only: widths are already generous, and
   forcing a min-width would wrap the header. */
@media (max-width: 900px) and (pointer: coarse) {
  .chead button,
  .chead select,
  .chead input,
  .chead .btn,
  .chead .mini,
  .chead .pill,
  .chead a[role="button"] {
    min-height: 40px;
    padding-top: 0; padding-bottom: 0;
  }
  /* the search field and its Go button sit on one line, so they have to agree */
  .chead .askline-go, .chead .qgo { min-height: 40px; }
}
/* the saved card's ticker line now leads with a logo, like every other place
   a ticker appears */
.sv-top { display: flex; align-items: center; gap: 7px; }
.sv-top .logo { flex: 0 0 auto; }
.sv-top .muted { margin-left: auto; }

/* ================= touch, everywhere =================
   The earlier pass raised the HEADER's controls and stopped there, so a sweep
   of three phones across four screens still found 30 controls under 40px and
   text down to 9.5px — the Expert toggle at 34px, every mode pill at 34px,
   every topic tab at 34px, every Ask at 34px, the depth counts at 9.5px.
   Fixing them one component at a time is how the next new screen arrives with
   the same problem, so this is stated once for coarse pointers and inherited
   by anything added later.

   `min-height` and not `height`: a control with two lines of text must still
   be allowed to grow. */
@media (pointer: coarse) {
  button,
  select,
  [role="button"],
  .btn, .mini, .pill, .qpill, .hz-btn, .mkt-btn, .tabadd,
  .mk-tab, .nw-tab, .mk-ask, .nw-ask, .ir-ask, .askbtn,
  .aime-mode, .aime-toggle, .aime-expert, .aime-send,
  .crail-item, .crail-pin,
  .watch-btn, .range-sel button, .tabs button {
    min-height: 44px;
  }
  /* an input a thumb has to land in is a control too */
  input[type="text"], input[type="search"], input:not([type]), textarea, .askline-in {
    min-height: 44px;
  }
  /* 9.5px and 10.5px are readable on a desk and not on a moving train */
  .mk-ask, .nw-ask, .ir-ask, .askbtn,
  .hz-n, .sea-thin, .ctab-kind, .crail-sec, .qpill,
  .mk-move2, .mk-name, .nw-src, .nw-when, .ir-why {
    font-size: 11.5px;
  }
  /* the tiny superscript count inside a depth button */
  .hz-n { font-size: 11px; }
}

/* A one-line headline is a 39px tap target — six pixels of padding is the
   difference between "the link is small" and "the link is fine", and it costs
   nothing on a list that already scrolls. */
@media (pointer: coarse) {
  .nw-title { display: block; padding: 4px 0; }
}

/* ---- THE RAIL IS OPAQUE, AND CANNOT BECOME TRANSPARENT AGAIN ----
   It painted `var(--panel-2)`, which the terminal theme did not define, so it
   had no background at all: the chart and the signals card showed straight
   through it and every label sat on top of another label. A var() that is not
   defined is not a colour, it is nothing. The fallback chain ends in a literal
   so this element can never again depend on a variable existing. */
.crail {
  background: var(--panel-2, var(--bg-2, var(--bg, #0b0906)));
  /* the rail floats over the page when it widens, so it needs to read as a
     layer: a solid fill plus an edge, not a tint */
  backdrop-filter: none;
}
.crail:hover, .crail.pinned {
  background: var(--panel-2, var(--bg-2, var(--bg, #0b0906)));
}
.crail:has(:focus-visible) {
  background: var(--panel-2, var(--bg-2, var(--bg, #0b0906)));
}

/* ---- the securities row ---- */
.tabstrip {
  background: var(--panel-3, var(--bg-2, #0a0805));
  border-bottom: 1px solid var(--border);
  padding: 4px 10px;
  gap: 4px;
}
.ctab {
  display: flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 5px 10px; border: 1px solid var(--border); border-radius: var(--radius-sm, 4px);
  background: var(--chip, var(--surface, #12100c)); color: var(--text-2);
  font-size: 12px; white-space: nowrap; flex: 0 0 auto; position: relative;
}
.ctab:hover { border-color: var(--border-strong); color: var(--text); }
/* THE LABEL WAS 4.49:1 ON ITS OWN TINT - a hundredth under AA, which is
   still under it. The border and the tint already say which tab is active,
   so the text does not also have to be the accent on a wash of itself. */
.ctab.on { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.ctab .logo { flex: 0 0 auto; }
.ctab-label { font-weight: 600; }
.ctab-chg { font-size: 11px; font-variant-numeric: tabular-nums; }
/* THE INK, NOT THE PRICE COLOUR. `--good` and `--bad` are right on a price
   and too light for an 11px figure on a pale tab - measured 3.67 to 4.34:1
   on the four light themes. The fallback substitutes at the element, so the
   nine dark themes, which have no `--good-ink`, keep `--good`. */
.ctab-chg.up { color: var(--good-ink, var(--good)); }
.ctab-chg.down { color: var(--bad-ink, var(--bad)); }
.ctab-x {
  border: 0; background: transparent; color: var(--faint); cursor: pointer;
  font-size: 11px; padding: 0 4px; line-height: 1; opacity: 0;
  /* 13x11 measured: the glyph is small on purpose, the target need not be */
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 22px; min-width: 22px;
}
.ctab:hover .ctab-x, .ctab.on .ctab-x { opacity: 1; }
.ctab-x:hover { color: var(--bad); }

@media (pointer: coarse) {
  .ctab { min-height: 40px; padding: 6px 12px; }
  .ctab-x { opacity: 1; min-width: 28px; }
}

/* ---- a wide table must scroll itself, not the page ----
   Measured on a 390px phone: a table on /learning came out 396px and the whole
   PAGE scrolled sideways by six pixels. Six pixels is enough: once the document
   is wider than the window every tap lands slightly off and the app feels
   broken in a way nobody can point at. The table scrolls inside its own box
   now, which is what a table that does not fit should always do. */
@media (max-width: 760px) {
  .pane table, .ln-table, .fin-table, .wl-table, .sea-table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* `display: block` on a table drops the implicit row sizing, so the head and
     body have to be told to stay tables or the columns stop lining up */
  .pane table > thead, .pane table > tbody,
  .ln-table > thead, .ln-table > tbody,
  .fin-table > thead, .fin-table > tbody,
  .wl-table > thead, .wl-table > tbody,
  .sea-table > thead, .sea-table > tbody { display: table; width: 100%; }
}

/* ---- HOVER-INTENT ON THE RAIL ----
   The bar widens to 216px over the content, so anything between 52px and
   216px from the left edge can have the rail open on top of it while the
   pointer is still travelling. A headless click reported exactly that: the
   Learning row intercepted a click meant for the pane behind it. A person
   reaching for a control on the left hits the same thing.
   A short delay before opening fixes it without taking the hover away: a
   pointer passing THROUGH on its way somewhere else is gone before the delay
   elapses, while a pointer that stops on the bar opens it. Closing stays
   instant, because a bar that lingers over content is the original problem. */
.crail { transition: width 0s linear 0s; }
.crail:hover { transition-delay: 180ms; }
/* the page moves with the bar, on the same clock, or the content jumps a
   fifth of a second before the bar that pushed it */
.console { transition: padding-left 0s linear 0s; }
.console:has(.crail:hover) { transition-delay: 180ms; }
.crail.pinned { transition-delay: 0s; }
.crail:has(:focus-visible) { transition-delay: 0s; }

/* ---- A PINNED COLUMN MUST BE OPAQUE ----
   The sticky ticker and rank cells were painted at 2.4% alpha, so every row
   scrolling sideways underneath showed straight through the column that is
   supposed to be holding still. Same failure as the transparent rail: a
   layer that floats over content and does not fully paint. */
.scr-table td.c-rank, .scr-table td.c-stock, .scr-table td.c-ask {
  background-color: var(--bg, #000);
  background-image: linear-gradient(var(--panel-2, #0b0906), var(--panel-2, #0b0906));
}
.scr-table tr.scr-row:nth-child(4n+1) td.c-rank,
.scr-table tr.scr-row:nth-child(4n+1) td.c-stock,
.scr-table tr.scr-row:nth-child(4n+1) td.c-ask {
  /* the zebra tint has to be baked in, not layered over a transparent cell */
  background-image: linear-gradient(var(--surface, #0b0b0b), var(--surface, #0b0b0b));
}

/* ---- padding, not targets ----
   The chrome above a security measured 268px of an 844px phone. The controls
   themselves cannot shrink - 40px is a thumb and the sweep enforces it - so
   the space comes back from the boxes AROUND them: the rail and the securities
   row were each carrying a rim of padding sized for a mouse. */
@media (max-width: 760px) {
  .crail { padding: 3px 10px; gap: 5px; }
  .tabstrip { padding: 2px 8px; gap: 4px; }
  .ctab { padding-top: 0; padding-bottom: 0; }
}
