/* css-version: 58 */
/* ============================================================================
   Called The Trade — design system ported from the v3-2 prototype (ThesisDesk.jsx).
   Mobile-first single column (560px), warm paper, IBM Plex Sans/Mono.
   No build step: semantic classes, not utility classes.
   ========================================================================== */

:root {
  --paper:   #FAFAF6;
  --card:    #FFFFFF;
  --ink:     #16213A;
  --slate:   #5B6880;
  --faint:   #8B94A8;
  --line:    #E4E2D9;
  --line-soft:#EFEDE5;
  --up:      #1B6B4A;  --up-soft:  #E7F2EC;
  --down:    #B3382C;  --down-soft:#F8EAE8;
  --you:     #B8860B;  --you-soft: #F7EFDA;   /* gold — the user's own view */
  --navy:    #1F3A6E;  --navy-soft:#E9EEF7;
  --amber-soft:#FBF6E9;

  /* theme-stable accent surfaces: text ON a dark accent stays light in BOTH themes,
     and the primary-button surface has its own token so it doesn't invert with --ink */
  --on-accent:     #FAFAF6;
  --accent-strong: #16213A;

  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --shadow: 0 1px 3px rgba(20,33,58,.08);
}

/* Dark theme — remaps the tokens; components built on var() follow automatically.
   Set on <html> by the bootstrap script in base.html (stored choice or OS preference). */
:root[data-theme="dark"] {
  --paper:   #0F131C;
  --card:    #1A2130;
  --ink:     #E7EAF0;
  --slate:   #A6B0C4;
  --faint:   #6E7A92;
  --line:    #2C3648;
  --line-soft:#232C3B;
  --up:      #43C282;  --up-soft:  #14311F;
  --down:    #E9776B;  --down-soft:#3A1A16;
  --you:     #D9AC4E;  --you-soft: #332912;
  --navy:    #3E5EA0;  --navy-soft:#1D2A44;
  --amber-soft:#2A2411;
  --on-accent:     #F2F5FA;
  --accent-strong: #34406A;
  --shadow: 0 1px 3px rgba(0,0,0,.45);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 15px/1.5 var(--sans);
}
[x-cloak] { display: none !important; }
/* full-width sliders everywhere (mobile-safe) — the UA default width made them span only a
   fraction of their section, so precision suffered. block + 100% fills the container. */
input[type=range] { display: block; width: 100%; height: 4px; accent-color: var(--navy); margin: 0; }
/* Buttons don't inherit text colour by default — bare <button> wrappers (e.g. the instrument
   picker) would fall back to UA black and go unreadable on dark surfaces. Inherit instead;
   explicitly-coloured buttons (.btn, .btn-link, …) still win by specificity. */
button { cursor: pointer; font-family: inherit; color: inherit; }
a { color: var(--navy); }

/* ---- shell ---------------------------------------------------------------- */
/* Mobile-first: the 560px column IS the base, so phones are unaffected by the widths
   below. Desktop gets more of the window (the comparison table and the recap fact row
   are the parts that actually need it); prose is capped separately so line length stays
   readable rather than stretching to the full column. */
.app { --col: 560px; max-width: var(--col); margin: 0 auto; padding: 20px 16px; }
#screen { display: block; }
.app-disclaimer {
  max-width: 560px; margin: 0 auto 40px; padding: 8px 16px 0;
  color: var(--faint); font-size: 11px; line-height: 1.5;
}
/* The column grows with the window instead of stopping at a fixed width: `50vw + half the old
   fixed width` leaves exactly half the gutter the fixed values did, at every viewport, and the
   min() stops it running away on ultrawide. */
@media (min-width: 800px) {
  .app { --col: min(calc(50vw + 360px), 1200px); padding: 28px 24px; }
  .app-disclaimer { max-width: min(calc(50vw + 360px), 1200px); padding-inline: 24px; }
}
@media (min-width: 1150px) {
  .app { --col: min(calc(50vw + 490px), 1500px); padding: 32px 28px; }
  .app-disclaimer { max-width: min(calc(50vw + 490px), 1500px); padding-inline: 28px; }
  /* keep reading measure sane once the column is wide */
  .lead, .verdict, .belief, .mech, .small-note, .card-note, .decay-note,
  .notrade, .budget-alert, .wide-quote, .mc-note, .fine { max-width: 78ch; }
}
/* ---- busy feedback -------------------------------------------------------- */
/* Several screens do multi-second work (a belief goes to an LLM, an analysis prices a chain).
   Without a visible signal that reads as "working", a frozen-looking page is indistinguishable
   from a broken one — so there are two: a bar at the top edge and a named pill. */
/* Centred overlay, not a pill at the foot of the page: anchored to the bottom it sat below the
   fold on a short screen, so a multi-second wait read as a frozen app. The scrim also stops a
   second click landing on a control whose request is already in flight. */
.screen-spin {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10, 15, 25, .38); backdrop-filter: blur(1.5px);
}
.screen-spin .spin-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--navy); color: var(--on-accent); font-family: var(--mono);
  font-size: 13px; padding: 16px 26px; border-radius: 999px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .4);
}
.screen-spin .dot-spin {
  width: 17px; height: 17px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid rgba(250, 250, 246, .3); border-top-color: var(--on-accent);
  animation: spin .7s linear infinite;
}
/* the overlay must actually catch clicks while it is up */
.screen-spin.htmx-request, .htmx-request .screen-spin { pointer-events: auto; }

.top-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 61;
  background: linear-gradient(90deg, transparent, var(--navy), transparent);
  background-size: 40% 100%; background-repeat: no-repeat;
  animation: top-progress 1.1s ease-in-out infinite;
}
@keyframes top-progress {
  0%   { background-position: -40% 0; }
  100% { background-position: 140% 0; }
}
.htmx-indicator { opacity: 0; pointer-events: none; transition: opacity .15s; }
.htmx-request .htmx-indicator, .htmx-indicator.htmx-request { opacity: 1; }
/* the control you actually clicked also shows it, so the feedback is where you're looking */
.btn.htmx-request {
  position: relative; color: transparent !important; pointer-events: none;
}
.btn.htmx-request::after {
  content: ''; position: absolute; top: 50%; left: 50%; width: 15px; height: 15px;
  margin: -7.5px 0 0 -7.5px; border-radius: 50%;
  border: 2px solid rgba(250,250,246,.4); border-top-color: var(--on-accent);
  animation: spin .7s linear infinite;
}
.btn.ghost.htmx-request::after {
  border-color: var(--line); border-top-color: var(--navy);
}
@media (prefers-reduced-motion: reduce) {
  .dot-spin, .top-progress, .btn.htmx-request::after { animation: none; }
  .top-progress { background: var(--navy); }
}

/* ---- persistent top nav ----------------------------------------------------
   Lives outside #screen so it is painted once and survives every swap. Sticky rather than fixed:
   fixed would need the page to reserve height for it and every screen already manages its own
   top spacing. Sits above the working overlay's scrim in z-order but below the error banner,
   which has to be readable over everything. */
.topnav {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topnav-in {
  max-width: 560px; margin: 0 auto; padding: 10px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
@media (min-width: 800px) { .topnav-in { max-width: min(calc(50vw + 360px), 1200px); padding: 12px 24px; } }
@media (min-width: 1150px) { .topnav-in { max-width: min(calc(50vw + 490px), 1500px); padding: 12px 28px; } }

.topnav-brand {
  display: inline-flex; align-items: center; gap: 10px; min-width: 0;
  background: none; border: 0; padding: 4px 0; color: var(--ink);
}
.topnav-brand img { display: block; border-radius: 6px; flex: 0 0 auto; }
.topnav-brand span {
  font-family: var(--mono); font-size: 12.5px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; white-space: nowrap;
}
/* the name is the first thing to go when the bar gets tight — the mark still says where you are
   and still goes home, which is the part that has to survive */
@media (max-width: 439px) { .topnav-brand span { display: none; } }
.topnav-brand:hover span { color: var(--navy); }

.topnav-acts { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.topnav-link {
  background: none; border: 0; padding: 7px 4px; color: var(--slate);
  font-size: 13px; font-weight: 600; white-space: nowrap;
}
.topnav-link:hover { color: var(--ink); }
.btn.sm { padding: 7px 12px; font-size: 13px; }

/* ---- the first thing anyone sees: the intro on `/` -------------------------
   Restrained on purpose. This app's whole argument is that it doesn't oversell what it knows,
   and a gradient hero on the front of it would contradict the copy underneath. The wordmark
   borrows the mono/letterspaced treatment the eyebrows already use, sized up so it reads as
   the name of a company rather than a section label. */
.intro { margin: 4px 0 0; }
.wordmark {
  font-family: var(--mono); font-size: clamp(17px, 2.1vw, 21px); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--navy);
  margin-bottom: 20px; line-height: 1.1;
}
.intro-head {
  font-size: clamp(26px, 4.4vw, 38px); font-weight: 700; letter-spacing: -.025em;
  line-height: 1.16; text-wrap: balance; margin: 0 0 16px; max-width: 18ch;
}
.intro p { font-size: 15px; line-height: 1.65; color: var(--slate); margin: 0 0 13px; max-width: 62ch; }
.intro p:last-child { margin-bottom: 0; }
.intro p i { color: var(--ink); font-style: italic; }
.intro-fine { font-size: 12.5px !important; color: var(--faint) !important; margin-top: 16px !important; }
.intro-rule { border: 0; border-top: 1px solid var(--line); margin: 28px 0 26px; }

/* Wide: headline and copy side by side. Same words, roughly half the height, and the setup form
   stays on the fold instead of being pushed under a column of prose. Below this the grid simply
   does not apply and everything stacks in source order, which is already the right order. */
@media (min-width: 820px) {
  .intro {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    column-gap: clamp(36px, 5vw, 72px); align-items: start;
  }
  .wordmark { grid-column: 1 / -1; }
  .intro-head { grid-column: 1; margin-bottom: 0; }
  .intro-body { grid-column: 2; }
  .intro-head { max-width: 14ch; }
}

/* ---- typography helpers --------------------------------------------------- */
h1.screen-title { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 2px; }
h2.screen-title { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 2px; }
.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  color: var(--faint); text-transform: uppercase;
}
.lead { font-size: 14px; color: var(--slate); margin: 4px 0 18px; line-height: 1.5; }
.muted { color: var(--faint); }
.mono  { font-family: var(--mono); }
.section-label {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  color: var(--faint); text-transform: uppercase; margin: 0 0 8px;
}
.fine { font-size: 12px; color: var(--faint); line-height: 1.5; }

/* ---- cards ---------------------------------------------------------------- */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 16px; margin-bottom: 12px;
}
.card.tight { padding: 14px; }
.card-note {
  background: var(--amber-soft); border-left: 3px solid var(--you);
  border-radius: 0 6px 6px 0; padding: 12px 14px; margin-bottom: 12px;
  font-size: 13px; line-height: 1.5;
}

/* ---- buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 0; border-radius: 4px; padding: 11px 16px; font-size: 14px; font-weight: 600;
  background: var(--accent-strong); color: var(--on-accent); text-decoration: none; line-height: 1.2;
}
.btn:hover { filter: brightness(1.12); }
.btn.full { width: 100%; }
.btn.big { font-size: 15px; padding: 13px 18px; font-weight: 700; }
.btn.navy { background: var(--navy); }
.btn.danger { background: var(--down); }
.btn.ghost {
  background: var(--card); color: var(--ink); border: 1px solid var(--line); font-weight: 600;
}
.btn.ghost:hover { filter: none; background: var(--line-soft); }
/* DISABLED COMES LAST, AND IT HAS TO. `.btn:disabled` and `.btn.ghost` are both (0,2,0), so
   whichever is written later wins — and ghost was. A disabled ghost button therefore rendered
   with its full normal styling and looked completely live: reported as "greyed out and not
   clickable", which is precisely half right. It was not greyed out, and that was the bug.
   Every variant below it is covered, and `:hover` is neutralised so the pointer confirms it. */
.btn:disabled,
.btn.ghost:disabled {
  background: var(--line-soft); color: var(--faint); border-color: var(--line-soft);
  cursor: not-allowed; filter: none; opacity: .65;
}
.btn:disabled:hover, .btn.ghost:disabled:hover { background: var(--line-soft); filter: none; }
.btn-link { background: none; border: 0; padding: 6px 0; color: var(--slate); font-size: 14px; }
.btn-link.navy { color: var(--navy); font-weight: 600; }
.btn-link.faint { color: var(--faint); }
.btn-row { display: flex; gap: 8px; }
.btn-row .btn { flex: 1; }
.btn-row .btn.wide { flex: 2; }

/* ---- chips ---------------------------------------------------------------- */
.chip {
  display: inline-block; font-family: var(--mono); font-size: 11px; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 3px; background: var(--line-soft); color: var(--slate);
  vertical-align: middle; white-space: nowrap;
}
.chip.live { background: var(--up-soft); color: var(--up); }
.chip.draft{ background: var(--line-soft); color: var(--slate); }
.chip.win  { background: var(--navy-soft); color: var(--navy); }
.chip.warn { background: var(--down-soft); color: var(--down); }
.chip.you  { background: var(--you-soft); color: var(--you); }

/* selectable pill buttons (help level, moves, horizons, instruments) */
.pillset { display: flex; gap: 6px; flex-wrap: wrap; }
.pill-btn {
  font-family: var(--mono); font-size: 13px; padding: 7px 13px; border-radius: 4px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
}
.pill-btn.on { border-color: var(--accent-strong); background: var(--accent-strong); color: var(--on-accent); }
.pill-btn.navy.on { border-color: var(--navy); background: var(--navy-soft); color: var(--navy); }

/* ---- forms / sliders ------------------------------------------------------ */
.field { margin-bottom: 14px; }
.field > label, .field > .field-label {
  display: block; font-weight: 600; font-size: 14px; margin-bottom: 6px;
}
/* An allowlist of types, so every new input type has to be added here deliberately — `password`
   and `email` were missing and rendered as bare UA controls: white-on-white in dark mode, and
   half the width of the field above them. */
textarea, select,
input[type=text], input[type=number], input[type=date], input[type=time],
input[type=password], input[type=email], input[type=search], input[type=tel], input[type=url] {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 6px;
  font: inherit; color: var(--ink); background: var(--card); outline: none;
}
textarea:focus, input:focus, select:focus { border-color: var(--navy); }
textarea { resize: vertical; }
/* color must be explicit: these inputs carry no `type` attr, so the input[type=text] rule
   above doesn't match them and they'd fall back to UA black (black-on-dark in dark mode). */
.input-mono { font-family: var(--mono); background: var(--paper); color: var(--ink); }
.slider-box {
  background: var(--card); border: 1px solid var(--line); border-radius: 6px; padding: 12px;
}
.slider-box .slider-val { font-family: var(--mono); font-size: 24px; font-weight: 700; }
.slider-box .slider-val.navy { color: var(--navy); }
.slider-box .slider-val.gold { color: var(--you); }
/* A percentage with no referent is not a number anyone can act on — "2%" of what? The unit rides
   at the value's baseline, small and slate, so the figure stays the thing you read while the
   thing it measures is never more than a glance away. */
.slider-lede { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.slider-lede .slider-unit { font-size: 12px; color: var(--slate); }
/* wraps rather than overflows once the unit shares the row with the dollar aside on a narrow screen */
.slider-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.slider-head .aside { font-family: var(--mono); font-size: 13px; color: var(--slate); }
.slider-scale { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 10px; color: var(--faint); margin-top: 2px; }
.inline-add { display: flex; gap: 8px; }
.inline-add input { flex: 1; }
.inline-add .btn { padding: 8px 14px; }

/* ---- home scoreboard ------------------------------------------------------ */
.home-head { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 16px; gap: 8px; }
.home-actions { display: flex; gap: 8px; align-items: center; }
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--navy); color: var(--on-accent);
  font-family: var(--mono); font-weight: 600; border: 0;
}
.avatar.sm { width: 38px; height: 38px; font-size: 15px; }
.avatar.lg { width: 56px; height: 56px; font-size: 22px; }
.icon-btn {
  width: 38px; height: 38px; border: 1px solid var(--line); background: var(--card);
  border-radius: 4px; font-size: 15px; color: var(--ink);
}
.stat-row { display: flex; gap: 8px; margin-bottom: 16px; }
.stat {
  flex: 1; background: var(--card); border: 1px solid var(--line); border-radius: 6px; padding: 12px;
}
.stat .k { font-family: var(--mono); font-size: 11px; color: var(--faint); letter-spacing: .06em; margin-bottom: 2px; }
.stat .v { font-family: var(--mono); font-size: 22px; font-weight: 700; }
.stat .v.up { color: var(--up); } .stat .v.down { color: var(--down); } .stat .v.faint { color: var(--faint); }

.thesis-list { display: flex; flex-direction: column; gap: 12px; }
.thesis-card {
  display: block; width: 100%; text-align: left; background: var(--card);
  border: 1px solid var(--line); border-left: 4px solid var(--line);
  border-radius: 6px; padding: 16px; color: var(--ink);
}
.thesis-card:hover { box-shadow: var(--shadow); }
.thesis-card .tc-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.thesis-card .tc-date { font-family: var(--mono); font-size: 11px; color: var(--faint); }
.thesis-card .tc-statement { font-size: 15px; font-weight: 600; margin-bottom: 6px; }
.thesis-card .tc-big { font-family: var(--mono); font-size: 24px; font-weight: 700; letter-spacing: -0.01em; }
.thesis-card .tc-sub { font-size: 12px; color: var(--slate); margin-top: 2px; }
.edge-up { border-left-color: var(--up); }  .edge-down { border-left-color: var(--down); }
.c-up { color: var(--up); } .c-down { color: var(--down); } .c-faint { color: var(--faint); } .c-slate { color: var(--slate); }

/* ---- setup / wizard step chrome ------------------------------------------ */
.step-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.step-tag { font-family: var(--mono); font-size: 11px; color: var(--faint); letter-spacing: .14em; }
.appearance-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.helpscale { display: flex; gap: 4px; margin-bottom: 6px; }
.helpscale button {
  flex: 1; padding: 10px 0; border: 0; border-radius: 4px; font-family: var(--mono);
  font-size: 13px; font-weight: 700; background: var(--line-soft); color: var(--slate);
}
.helpscale button.on { background: var(--navy); color: var(--on-accent); }
.helpscale-ends { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 10px; color: var(--faint); margin-bottom: 8px; }

/* instrument cards (onboarding) */
.inst-card { background: var(--card); border: 1px solid var(--line); border-radius: 6px; margin-bottom: 8px; }
.inst-card.on { border-color: var(--navy); }
.inst-row { display: flex; align-items: center; justify-content: space-between; padding: 14px; }
.inst-pick { display: flex; align-items: center; gap: 12px; background: none; border: 0; text-align: left; flex: 1; padding: 0; }
.checkbox {
  width: 22px; height: 22px; border-radius: 4px; border: 1.5px solid var(--faint);
  display: inline-flex; align-items: center; justify-content: center; color: var(--on-accent); font-size: 13px; flex: 0 0 auto;
}
.checkbox.on { background: var(--navy); border-color: var(--navy); }
.inst-title { font-weight: 700; font-size: 15px; display: block; }
.inst-sub { font-size: 12px; color: var(--slate); display: block; }
.inst-body { padding: 0 14px 14px; border-top: 1px solid var(--line-soft); }

/* ---- candidates screen ---------------------------------------------------- */
.cand {
  position: relative; display: block; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); border-radius: 6px;
  padding: 12px; margin-bottom: 8px;
}
.cand.flagged { border-color: var(--you); }
.cand.dropped { opacity: .6; }
/* at the pick cap: unticked rows go inert, ticked ones stay live so you can swap */
.cand.locked { opacity: .45; cursor: not-allowed; }
.cand.locked .cand-check { border-style: dashed; }
.cand-head-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.cand-head-row .section-label { margin: 0; }
.pickcount { font-family: var(--mono); font-size: 11px; color: var(--faint); white-space: nowrap; }
.pickcount.full { color: var(--you); font-weight: 600; }
.cand-row { display: flex; align-items: flex-start; gap: 12px; }
.cand-mark { flex: 0 0 auto; margin-top: 2px; font-family: var(--mono); font-size: 14px; }
.cand-check {
  width: 20px; height: 20px; border-radius: 4px; border: 1.5px solid var(--faint); background: var(--card);
  display: inline-flex; align-items: center; justify-content: center; color: var(--on-accent); font-size: 12px; flex: 0 0 auto;
}
.cand > input:checked ~ .cand-row .cand-check { background: var(--navy); border-color: var(--navy); }
.cand > input:checked ~ .cand-row .cand-check::after { content: '✓'; }
.cand-body { flex: 1; }
.cand-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cand-tk { font-family: var(--mono); font-weight: 700; font-size: 18px; }
.cand-name { font-size: 14px; color: var(--slate); }
.cand-dir { font-family: var(--mono); font-size: 13px; color: var(--up); font-weight: 600; }
.cand-dir.down { color: var(--down); }
.cand-reason { font-size: 14px; color: var(--slate); line-height: 1.5; margin-top: 4px; }
.cand-why { font-size: 13px; line-height: 1.5; margin-top: 6px; }
.cand-why.flagged { color: var(--you); } .cand-why.dropped { color: var(--faint); }
/* hidden real checkbox drives the styled box + downstream form post */
.cand input[type=checkbox] { position: absolute; opacity: 0; width: 0; height: 0; }

/* ---- thesis card ---------------------------------------------------------- */
.tc-title { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 2px; }
.tc-meta { font-family: var(--mono); font-size: 12px; color: var(--slate); margin-bottom: 14px; }
.lens-foot { display: flex; align-items: center; justify-content: space-between; font-family: var(--mono); font-size: 12px; margin-top: 8px; }
.lens-foot .gap { color: var(--slate); font-weight: 700; }
.verdict { border-top: 1px solid var(--line-soft); margin-top: 12px; padding-top: 12px; font-size: 14px; line-height: 1.55; }

/* Trade heads read on a paper surface, not white-on-navy: the navy is reduced to a rank badge
   and a left rail so the numbers keep full contrast in both themes. */
.bet-head {
  display: block; width: 100%; text-align: left; background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-left: 4px solid var(--navy);
  border-radius: 6px; padding: 14px 16px; cursor: pointer;
}
.bet-head:hover { border-color: var(--navy); border-left-color: var(--navy); }
.bet-head.top { background: var(--navy-soft); border-color: var(--navy); }
.bet-head .bet-top { display: flex; align-items: center; gap: 8px; }
.bet-head .bet-rank {
  font-family: var(--mono); font-size: 12px; font-weight: 700; line-height: 1.5;
  background: var(--navy); color: var(--on-accent); border-radius: 3px; padding: 1px 7px;
}
.bet-head .bet-eyebrow { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; color: var(--slate); }
.bet-head .bet-toggle { margin-left: auto; font-family: var(--mono); font-size: 11px; font-weight: 600; color: var(--navy); }
.bet-head .bet-name { font-size: 16px; font-weight: 700; margin-top: 8px; }
.bet-head .bet-line {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: 6px;
  font-family: var(--mono); font-size: 13px; color: var(--slate);
}
.bet-head .bet-line b { font-size: 15px; }
.bet-head .bet-risk b { color: var(--down); }
.bet-head .bet-reward b { color: var(--up); }
.bet-head .bet-arrow { color: var(--faint); }
.bet-head .bet-fit {
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line-soft);
  font-family: var(--mono); font-size: 11px; color: var(--faint);
}
.bet-body {
  background: var(--card); border: 1px solid var(--line); border-left: 4px solid var(--navy);
  border-top: 0; border-radius: 0 0 6px 6px; padding: 16px;
}
.bet-body .bet-trade { font-family: var(--mono); font-size: 13px; color: var(--navy); margin-bottom: 4px; }

/* loss-budget box */
.budget-box { background: var(--you-soft); border-radius: 4px; padding: 10px 12px; margin-top: 12px; }
.budget-box .bk { font-family: var(--mono); font-size: 11px; color: var(--you); font-weight: 700; letter-spacing: .04em; }
.budget-box .bv { font-size: 12px; color: var(--slate); line-height: 1.45; margin-top: 2px; }

/* outcomes table */
.outcomes { margin: 8px 0 12px; }
.outcomes .oc-label { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; color: var(--faint); margin-bottom: 4px; }
.outcomes .oc-row { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; }
.outcomes .oc-row .k { color: var(--slate); line-height: 1.35; }
.outcomes .oc-row .v { flex: 0 0 auto; text-align: right; font-family: var(--mono); font-size: 12px; font-weight: 600; }
.v.up { color: var(--up); } .v.down { color: var(--down); } .v.slate { color: var(--slate); }
.breakeven-line { font-family: var(--mono); font-size: 12px; margin-bottom: 12px; }

/* market-context chip toggles */
.togglechips { display: flex; gap: 6px; flex-wrap: wrap; }
.togglechips button {
  display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: 12px;
  padding: 6px 10px; border-radius: 4px; background: var(--line-soft); color: var(--ink);
  font-weight: 600; border: 1.5px solid transparent;
}
.togglechips button.on { border-color: var(--navy); }
.togglechips .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--navy); display: inline-block; }

/* A refused column: present, readable, and clearly not competing. Dimmed rather than greyed to
   illegibility — the numbers are the reason it is still here. */
table.compare th.refused { opacity: .72; }
table.compare th.refused .refused-tag {
  display: block; margin-top: 3px; font-family: var(--mono); font-size: 10px;
  color: var(--you); text-transform: none; letter-spacing: 0;
}
.chip-detail { margin-top: 8px; padding: 10px; background: var(--paper); border-radius: 4px; font-size: 13px; color: var(--slate); line-height: 1.5; }

/* taken / open position banner */
.taken-banner { display: flex; align-items: center; justify-content: space-between; padding: 16px; border-radius: 6px; margin-bottom: 12px; }
.taken-banner.up { background: var(--up-soft); border-left: 4px solid var(--up); }
.taken-banner.down { background: var(--down-soft); border-left: 4px solid var(--down); }
.taken-banner .tb-pnl { font-family: var(--mono); font-size: 24px; font-weight: 700; }

.card-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.card-actions .btn { flex: 1; min-width: 96px; }

/* ---- chat ----------------------------------------------------------------- */
.chat { display: flex; flex-direction: column; min-height: 60vh; }
.chat-head { display: flex; align-items: center; gap: 8px; padding-bottom: 12px; margin-bottom: 8px; border-bottom: 1px solid var(--line); }
.chat-head .title { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-log { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; padding-bottom: 12px; }
.bubble { max-width: 88%; padding: 10px 14px; font-size: 14px; line-height: 1.55; border-radius: 10px; }
.bubble.ai { align-self: flex-start; background: var(--card); border: 1px solid var(--line); }
.bubble.user { align-self: flex-end; background: var(--accent-strong); color: var(--on-accent); }
.bubble.typing { align-self: flex-start; color: var(--faint); font-family: var(--mono); font-size: 12px; }
.chat-chips { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 8px; }
.chat-chips button { flex: 0 0 auto; white-space: nowrap; font-size: 12px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 99px; background: var(--card); color: var(--navy); }
.chat-input { display: flex; gap: 8px; padding-top: 4px; }
.chat-input input { flex: 1; }

/* ---- profile / resolved --------------------------------------------------- */
.profile-id { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.profile-id .name { font-size: 20px; font-weight: 700; }
.profile-id .email { font-family: var(--mono); font-size: 12px; color: var(--slate); }
.kv { display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap; padding: 8px 0; border-bottom: 1px solid var(--line-soft); font-family: var(--mono); font-size: 12px; }
.kv .k { color: var(--faint); } .kv .v { font-weight: 600; text-align: right; }
.result-banner { display: flex; align-items: center; justify-content: space-between; padding: 16px; border-radius: 6px; margin-bottom: 12px; }
.result-banner.won { background: var(--up-soft); border-left: 4px solid var(--up); }
.result-banner.lost { background: var(--down-soft); border-left: 4px solid var(--down); }
.result-banner .rb-big { font-family: var(--mono); font-size: 26px; font-weight: 700; }
.scorecard { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 16px; font-family: var(--mono); font-size: 12px; }
.timeline-row { display: flex; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.timeline-row .d { flex: 0 0 52px; font-family: var(--mono); font-size: 11px; color: var(--faint); }
.timeline-row .e { font-size: 13px; line-height: 1.45; }

/* ---- SVG chart helpers ---------------------------------------------------- */
.chart { width: 100%; display: block; }
.chart-legend { display: flex; gap: 16px; margin-top: 4px; font-family: var(--mono); font-size: 10px; }

/* ============================================================================
   Real-data detail (ranked trade candidate) — restyled into the token system.
   These render the genuine backend fields (legs, move-compare, timing, score).
   ========================================================================== */
.ticket { border: 1px solid var(--line); border-radius: 6px; padding: 12px; margin: 8px 0; background: var(--paper); }
.ticket-head { font-family: var(--mono); font-size: 13px; margin-bottom: 6px; }
.ticket-head .muted { text-transform: uppercase; letter-spacing: .05em; font-size: 10px; margin-left: 6px; }
table.legs { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 12px; }
table.legs td { padding: 4px 6px; border-bottom: 1px solid var(--line-soft); white-space: nowrap; }
table.legs .act { font-weight: 700; }
table.legs tr.buy .act { color: var(--up); } table.legs tr.sell .act { color: var(--down); }
table.legs .qty { color: var(--faint); }
table.legs .exp { color: var(--faint); }
table.legs .mny { width: 100%; text-align: right; }
table.legs em { font-style: normal; font-weight: 700; font-size: 10px; padding: 1px 5px; border-radius: 4px; }
table.legs em.itm { background: var(--up-soft); color: var(--up); }
table.legs em.otm { background: var(--line-soft); color: var(--faint); }
.ticket-net { font-family: var(--mono); font-size: 12px; margin-top: 8px; color: var(--navy); }
.ticket-net .muted { color: var(--faint); margin-left: 6px; }
.ticket-net .limit { display: block; margin-top: 4px; color: var(--up); }
.ticket-net .limit small { color: var(--faint); margin-left: 6px; }

table.move-compare, table.scen, table.breakdown { width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0; font-variant-numeric: tabular-nums; }
table.move-compare th, table.scen th { text-align: left; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--faint); text-transform: uppercase; padding: 6px; border-bottom: 1px solid var(--line); }
table.move-compare td, table.scen td { padding: 8px 6px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.move-compare small, table.scen small { display: block; color: var(--faint); font-size: 11px; margin-top: 2px; }
table.move-compare tr.your-case td { background: var(--you-soft); }
table.move-compare tr.flat-case td { background: var(--paper); }
td.pos, small.pos { color: var(--up); } td.neg, small.neg { color: var(--down); }

ul.math { list-style: none; padding: 12px; margin: 8px 0; display: grid; grid-template-columns: 1fr 1fr; gap: 2px 16px; font-family: var(--mono); font-size: 12px; background: var(--paper); border-radius: 6px; }
ul.math li { display: flex; justify-content: space-between; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--line-soft); }
ul.math li span { color: var(--faint); }
ul.math li small { color: var(--faint); font-size: 11px; }
ul.math li small.warn { color: var(--down); }

.winrate { font-size: 13px; line-height: 1.5; background: var(--navy-soft); border-radius: 6px; padding: 10px 12px; margin: 8px 0; }
.wr-how { background: none; border: 0; color: var(--navy); text-decoration: underline dotted; padding: 0 4px; font: inherit; font-size: 12px; cursor: pointer; }
.wr-detail { display: block; margin-top: 5px; padding-top: 5px; border-top: 1px solid var(--line-soft); color: var(--slate); font-size: 12px; line-height: 1.45; }
.budget-alert { background: var(--down-soft); border-left: 3px solid var(--down); border-radius: 0 6px 6px 0; padding: 10px 12px; font-size: 13px; line-height: 1.5; margin: 8px 0; }
.wide-quote { background: var(--amber-soft); border-left: 3px solid var(--you); border-radius: 0 6px 6px 0; padding: 10px 12px; font-size: 12px; line-height: 1.5; margin: 8px 0; }
.decay-note { font-size: 12px; color: var(--slate); line-height: 1.5; }
.flags { color: var(--down); font-size: 12px; }
.small-note { font-size: 12px; color: var(--slate); line-height: 1.5; }
.warn { color: var(--you); }

/* score popover */
.score-wrap { position: relative; display: inline-block; margin-left: auto; font-family: var(--mono); }
button.score { background: var(--line-soft); border: 0; border-radius: 4px; padding: 4px 10px; font-family: var(--mono); font-size: 12px; color: var(--ink); font-weight: 700; }
button.score em { color: var(--down); font-style: normal; font-weight: 600; }
button.score .caret { font-style: normal; font-size: 9px; margin-left: 3px; opacity: .7; }
.score-pop { position: absolute; z-index: 30; top: calc(100% + 4px); right: 0; width: 300px; background: var(--card); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 10px 28px rgba(16,24,40,.16); padding: 4px 14px 12px; text-align: left; }
.pop-head { font-family: var(--mono); font-size: 11px; letter-spacing: .06em; color: var(--faint); text-transform: uppercase; padding: 9px 0 7px; border-bottom: 1px solid var(--line); }
table.breakdown td { padding: 5px 4px; border-bottom: 1px solid var(--line-soft); white-space: nowrap; }
table.breakdown td:nth-child(2) { text-align: right; font-weight: 600; }
table.breakdown td:nth-child(3) { color: var(--faint); font-size: 11px; }
table.breakdown tr.subtotal td { border-top: 1px solid var(--line); }
table.breakdown tr.total td { border-top: 2px solid var(--navy); font-size: 14px; }
table.breakdown tr.pen td:nth-child(2) { color: var(--down); }

/* details / summary / alternatives */
details.more-info, details.prov, details.alt { margin-top: 8px; font-size: 13px; }
.how-scored { margin-top: 14px; border-top: 1px solid var(--line-soft); padding-top: 10px; }
details > summary { cursor: pointer; font-size: 13px; color: var(--navy); font-weight: 600; }
.more-info > p, .prov > p { font-size: 12px; color: var(--slate); line-height: 1.5; margin: 8px 0; }
table.picks td:first-child { width: 26px; }
table.picks input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--navy); }
.dirbadge { font-family: var(--mono); font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 3px; text-transform: uppercase; }
.dirbadge.up { background: var(--up-soft); color: var(--up); }
.dirbadge.down { background: var(--down-soft); color: var(--down); }
.alts { margin-top: 12px; }
.alts-head { font-family: var(--mono); font-size: 11px; color: var(--faint); margin-bottom: 8px; }
details.alt { border: 1px solid var(--line); border-radius: 6px; margin-bottom: 8px; background: var(--card); overflow: hidden; }
details.alt summary { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; padding: 10px 12px; list-style: none; font-family: var(--mono); font-size: 12px; }
details.alt summary::-webkit-details-marker { display: none; }
.alt-struct { font-weight: 700; color: var(--navy); }
.alt-contract { color: var(--slate); }
.alt-n i { font-style: normal; color: var(--faint); margin-right: 3px; }
.alt-score { margin-left: auto; font-weight: 700; color: var(--navy); }
.alt-body { padding: 0 12px 12px; }
.notrade { background: var(--down-soft); border-left: 3px solid var(--down); border-radius: 0 6px 6px 0; padding: 12px 14px; font-size: 13px; line-height: 1.5; margin-bottom: 12px; }
.reason-list { margin: 6px 0 0; padding-left: 18px; }
.trade { border-top: 1px solid var(--line); padding-top: 14px; margin-top: 14px; }
.trade h3 { font-size: 16px; margin: 0 0 8px; display: flex; align-items: center; gap: 8px; }
.trade h3 .rank { font-family: var(--mono); color: var(--navy); }
/* thesis recap — the top line of the analysis screen (belief + what it was priced against) */
.card.recap { border-left: 3px solid var(--navy); }
.recap-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 10px;
}
.recap-actions { display: inline-flex; gap: 14px; align-items: baseline; }
.linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--sans); font-size: 14px; font-weight: 600; color: var(--navy);
}
.linkish.faint { color: var(--slate); }
.linkish:hover { text-decoration: underline; }
.belief { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.35; margin: 0 0 14px; }
.recap-facts { list-style: none; padding: 0; margin: 0 0 12px; display: flex; flex-wrap: wrap; gap: 20px; }
.recap-facts li span { display: block; font-family: var(--mono); font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 2px; }
.recap-facts li b { font-size: 15px; }
.recap-facts li small { display: block; font-size: 10px; color: var(--faint); }
.mech { font-size: 13px; line-height: 1.5; margin: 8px 0 0; }
.mech > span { font-family: var(--mono); font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: .05em; display: block; margin-bottom: 2px; }
.mech > span i { font-style: normal; text-transform: none; letter-spacing: 0; }
.mech code { background: var(--navy-soft); color: var(--navy); padding: 1px 6px; border-radius: 4px; font-size: 12px; }
/* selected-candidate pills: ticker + its directness, with the meaning stated once in the label.
   Flex + a generated separator so a "·" can never wrap onto a line of its own. */
.mech.picks .picklist { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
.mech.picks .pick { white-space: nowrap; cursor: help; }
.mech.picks .pick + .pick::before { content: '·'; color: var(--faint); margin-right: 8px; }
.mech.picks .pick small { font-family: var(--mono); font-size: 11px; color: var(--slate); margin-left: 4px; }

/* an opt-out with its cost stated — the checkbox is checked, so the label has to say what
   turning it off saves as well as what leaving it on does */
.optrow {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 16px;
  padding: 12px; border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.optrow input[type=checkbox] { margin-top: 2px; width: 16px; height: 16px; accent-color: var(--navy); flex: 0 0 auto; }
.optrow b { display: block; font-size: 14px; }
.optrow small { display: block; margin-top: 2px; font-size: 12px; color: var(--slate); line-height: 1.5; }

/* ---- the event lens: live Polymarket / Kalshi quotes ----------------------- */
.eo-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; }
.eo {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 13px 0; border-top: 1px solid var(--line-soft);
}
/* a market adjacent to the belief rather than a reading of it — muted so it can't be mistaken
   for the direct one at a glance */
.eo.related .eo-odds { color: var(--slate); }
/* the second leg of the SAME question: indented and ruled, so it reads as a counterweight to the
   row above rather than as an independent second confirmation */
.eo.eo-pair { margin-left: 20px; padding-left: 12px; border-left: 2px solid var(--line); }

.eo-num { min-width: 74px; text-align: right; flex: 0 0 auto; }
.eo-odds { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
           font-size: 25px; font-weight: 700; letter-spacing: -.02em; line-height: 1.05; }
.eo-lab { display: block; font-size: 10.5px; color: var(--faint); margin-top: 2px; }

.eo-body { flex: 1; min-width: 0; }
.eo-q { display: block; font-weight: 600; font-size: 14px; line-height: 1.4; color: var(--ink); text-decoration: none; }
.eo-q:hover { color: var(--navy); text-decoration: underline; }
.eo-mean { font-size: 13px; line-height: 1.5; color: var(--slate); margin: 3px 0 0; }
.eo-mean b { color: var(--ink); }
.eo-other { color: var(--faint); }
.eo-pairnote { font-size: 12px; line-height: 1.5; color: var(--faint); margin: 3px 0 0; }
.eo-meta {
  display: flex; flex-wrap: wrap; gap: 3px 12px; margin-top: 5px;
  font-family: var(--mono); font-size: 11px; color: var(--faint);
}
.eo-meta b { color: var(--slate); font-weight: 500; }
/* resolving after the horizon is information, not a warning — stated, never enforced */
.eo-late { font-size: 12px; line-height: 1.5; color: var(--you); margin: 5px 0 0; }

/* ---- what's been moving the market (shared panel) -------------------------- */
.mc-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mc-head .section-label { margin: 0; }
.mc-detail { margin-top: 12px; padding: 12px; background: var(--paper); border-radius: 6px; }
.mc-note { font-size: 13px; line-height: 1.55; color: var(--slate); margin: 0; }
.mc-points { list-style: none; padding: 0; margin: 12px 0 0; display: flex; flex-direction: column; gap: 8px; }
.mc-points li { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.mc-points li b {
  font-family: var(--mono); font-size: 13px; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: 3px; padding: 1px 7px;
}
.mc-points li span { color: var(--slate); }
.mc-points li small { color: var(--faint); font-size: 11px; font-family: var(--mono); }
.mc-arts { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.mc-arts-label { font-family: var(--mono); font-size: 10px; letter-spacing: .12em; color: var(--faint); text-transform: uppercase; margin-bottom: 8px; }
.mc-art { display: block; text-decoration: none; padding: 7px 0; border-bottom: 1px solid var(--line-soft); }
.mc-art:last-child { border-bottom: 0; padding-bottom: 0; }
.mc-art-title { display: block; font-size: 13px; line-height: 1.45; color: var(--navy); font-weight: 600; }
.mc-art-meta { display: block; font-family: var(--mono); font-size: 11px; color: var(--faint); margin-top: 2px; }
.mc-foot { margin: 10px 0 0; }
.mc-empty { font-size: 13px; line-height: 1.55; color: var(--slate); margin: 4px 0 0; }
.empty-state { border-style: dashed; text-align: left; }

/* loading state — a shimmer in the shape of the answer, so a 20-30s search reads as working */
.mc-loading .chip { color: var(--you); background: var(--you-soft); }
.mc-loading-line { font-size: 13px; line-height: 1.55; color: var(--slate); margin: 10px 0 14px; }
.sk {
  display: block; height: 12px; border-radius: 4px; background: var(--line-soft);
  animation: sk-pulse 1.4s ease-in-out infinite;
}
.sk-pill { display: inline-block; width: 104px; height: 26px; border-radius: 4px; }
.sk-pill.w2 { width: 132px; animation-delay: .15s; }
.sk-pill.w3 { width: 88px;  animation-delay: .3s; }
.sk-line { width: 100%; margin-bottom: 9px; }
.sk-line.w2 { width: 72%; animation-delay: .15s; }
.sk-line.w3 { width: 86%; animation-delay: .3s; }
.sk-line.sk-meta { width: 34%; height: 9px; margin-bottom: 14px; }
@keyframes sk-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }

/* ---- side-by-side trade comparison ---------------------------------------- */
/* Horizontal scroll only. The pinned header is out for now: it needed a max-height here to give
   the sticky rows a scroll container, and that second scroll region fought with page scrolling.
   With no height cap there is nothing to scroll vertically, so the page behaves normally. */
.compare-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* fixed layout so one long cell (the flags) can't stretch its column and blow the table out;
   the columns keep their share and the whole table scrolls horizontally when it must */
table.compare { border-collapse: collapse; table-layout: fixed; width: 100%; min-width: 500px; font-size: 13px; }
table.compare col.c-head { width: 150px; }
table.compare col.c-trade { width: 118px; }
table.compare th, table.compare td { padding: 9px 10px; text-align: right; vertical-align: top; border-bottom: 1px solid var(--line-soft); overflow-wrap: anywhere; }
table.compare thead th { border-bottom: 1px solid var(--line); }
table.compare thead th b { display: block; font-size: 14px; margin-top: 3px; }
table.compare thead th small {
  display: block; font-family: var(--mono); font-size: 10px; color: var(--faint); line-height: 1.3;
}
.cmp-rank {
  display: inline-block; font-family: var(--mono); font-size: 11px; font-weight: 700;
  background: var(--navy); color: var(--on-accent); border-radius: 3px; padding: 0 6px;
}
/* the measure column stays put while the trade columns scroll */
table.compare .rowhead {
  position: sticky; left: 0; z-index: 1; text-align: left; min-width: 150px;
  background: var(--card); font-weight: 600;
}
/* only the measure column pins, and only horizontally — no vertical sticky, no second scroll box */
table.compare thead th { background: var(--card); box-shadow: inset 0 -1px 0 var(--line); }
table.compare thead th.rowhead { left: 0; z-index: 3; }
table.compare tr.key-row td { box-shadow: inset 0 -1px 0 var(--line); }

/* the market's implied move — the anchor the input opens on, so it reads as a figure not a footnote */
.cmp-mkt td { background: var(--navy-soft); }
.cmp-mkt .rowhead { background: var(--navy-soft); }
.mkt-move { font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--ink); }

/* per-trade expected move */
.cmp-move .you-diff { color: var(--you); font-weight: 600; }
.cmp-move .movein { display: inline-flex; align-items: baseline; gap: 2px; font-family: var(--mono); font-size: 12px; color: var(--faint); }
/* 62px cut `124.9` to `124.` — a long-horizon move is four digits plus a decimal, and a
   silently truncated number is worse than a wrapped one */
.cmp-move .movein input {
  width: 82px; padding: 5px 6px; text-align: right;
  font-family: var(--mono); font-size: 14px; font-weight: 700; color: var(--you);
}
/* the loss budget restated as a share of capital — one spanning cell, so it is left-aligned
   under the row head rather than right-aligned like the per-column figures above it */
.cmp-risk .riskcell { text-align: left; padding: 10px 12px; }
.cmp-risk .movein { display: inline-flex; align-items: baseline; gap: 2px; font-family: var(--mono); font-size: 12px; color: var(--faint); }
.cmp-risk .movein input {
  width: 62px; padding: 5px 6px; text-align: right;
  font-family: var(--mono); font-size: 14px; font-weight: 700; color: var(--you);
}
.cmp-risk .riskcell > small { display: block; margin-top: 3px; font-size: 11px; }

/* a figure that no longer matches the move it was computed at — withheld, not recalculated */
/* the withheld figure doubles as the control that gets it back */
table.compare button.v.stale {
  font-family: var(--mono); font-size: 11px; font-weight: 600; color: var(--you);
  background: var(--you-soft); border: 1px solid var(--you); border-radius: 3px;
  padding: 3px 8px; cursor: pointer; white-space: nowrap;
}
table.compare button.v.stale:hover { background: var(--you); color: var(--on-accent); }
table.compare button.v.stale.htmx-request { color: transparent; }
table.compare button.v.stale.htmx-request::after {
  content: ''; position: absolute; width: 11px; height: 11px; margin: 1px 0 0 -22px;
  border-radius: 50%; border: 2px solid var(--you-soft); border-top-color: var(--you);
  animation: spin .7s linear infinite;
}
.reanalyze { margin-top: 12px; padding: 12px; background: var(--amber-soft); border-left: 3px solid var(--you); border-radius: 0 6px 6px 0; }
.reanalyze .fine { margin: 0 0 10px; }
.reanalyze-err {
  margin: 10px 0 0; padding: 10px 12px; border-radius: 4px;
  background: var(--down-soft); color: var(--down); font-size: 12px; line-height: 1.5;
}
.reanalyze-err .linkish { color: var(--down); font-size: 12px; text-decoration: underline; }

.btn.took.on { background: var(--up); color: var(--on-accent); }
.took-note { margin: 8px 0 0; }
.took-note .linkish { font-size: 12px; text-decoration: underline; }

.cmp-howto td { padding-top: 12px; padding-bottom: 12px; }
.btn.sm { padding: 6px 12px; font-size: 13px; }
.btn.ghost.on { background: var(--navy); color: var(--on-accent); border-color: var(--navy); }

/* ---- floating dock (fixed, always on screen while an analysis is open) --------- */
/* Icon-only so it stays out of the way of a wide table, with the label carried by the tooltip
   and aria-label rather than the button face. */
.dock {
  position: fixed; right: 16px; bottom: 16px; z-index: 60;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
.dock-bar {
  display: flex; gap: 4px; padding: 5px;
  background: var(--card); border: 1px solid var(--line); border-radius: 999px;
  box-shadow: 0 6px 22px rgba(20,33,58,.22);
}
.dockbtn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%; border: 0;
  background: transparent; color: var(--navy);
}
.dockbtn:hover { background: var(--navy-soft); }
.dockbtn:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.dockbtn.htmx-request { color: transparent; }
.dockbtn.htmx-request::after {
  content: ''; position: absolute; width: 15px; height: 15px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--navy);
  animation: spin .7s linear infinite;
}
.dock-tip {
  max-width: 280px; padding: 10px 12px; border-radius: 6px;
  background: var(--ink); color: var(--paper); box-shadow: var(--shadow);
  font-size: 12.5px; line-height: 1.5;
}
@media (max-width: 560px) {
  .dock { right: 10px; bottom: 10px; left: 10px; }
  .dock-tip { max-width: 100%; }
}

/* ---- expansions, rendered in a full-width row under the row that opened them ---- */
/* text-align:left is not cosmetic here — table.compare right-aligns every cell, and the panel
   inherits that, which threw the ticket's labels to the right edge */
table.compare tr.expand-row > td { padding: 0; background: var(--paper); text-align: left; }
.expand-panel { padding: 16px; border-top: 2px solid var(--navy); }
.expand-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.expand-head b { font-size: 15px; }
.expand-panel .card.mc { background: transparent; border: 0; padding: 0; margin: 0; }

/* icon controls in the line-up row */
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; margin-left: 6px; border-radius: 6px;
  border: 1px solid var(--line); background: var(--card); color: var(--slate);
}
.iconbtn:hover { border-color: var(--navy); color: var(--navy); background: var(--navy-soft); }
.iconbtn.danger:hover { border-color: var(--down); color: var(--down); background: var(--down-soft); }
.iconbtn:focus-visible { outline: 2px solid var(--navy); outline-offset: 1px; }
/* Open state mirrors "Show me → Hide": the trigger fills in and its glyph becomes a close ×.
   Both glyphs are always in the DOM and swapped by the `on` class, so the toggle rides on
   x-bind (synchronous) rather than x-show. */
.iconbtn.on { background: var(--navy); border-color: var(--navy); color: var(--on-accent); }
.iconbtn.danger.on { background: var(--down); border-color: var(--down); color: var(--on-accent); }
.iconbtn .ic-close { display: none; }
.iconbtn.on .ic-close { display: block; }
.iconbtn.on .ic-main { display: none; }

/* destructive variant of an inline expansion */
.expand-panel.danger { border-top-color: var(--down); }

/* the swap list — renders once the backend supplies the AI's full exposure set */
.swap-list { display: flex; flex-direction: column; gap: 8px; }
.swap-opt {
  display: grid; grid-template-columns: auto auto 1fr; gap: 4px 10px; align-items: baseline;
  text-align: left; width: 100%; padding: 11px 13px;
  background: var(--card); border: 1px solid var(--line); border-radius: 6px;
}
.swap-opt:hover { border-color: var(--navy); background: var(--navy-soft); }
.swap-tk { font-family: var(--mono); font-weight: 700; font-size: 14px; color: var(--navy); }
.swap-dir { font-family: var(--mono); font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 3px; text-transform: uppercase; }
.swap-dir.up { background: var(--up-soft); color: var(--up); }
.swap-dir.down { background: var(--down-soft); color: var(--down); }
.swap-direct { font-family: var(--mono); font-size: 11px; color: var(--faint); justify-self: end; }
.swap-why { grid-column: 1 / -1; font-size: 13px; line-height: 1.45; color: var(--slate); }

table.compare .rowhead small { display: block; font-weight: 400; font-size: 11px; color: var(--faint); line-height: 1.4; margin-top: 2px; }
table.compare td.num { font-family: var(--mono); }
table.compare td.num .v { white-space: nowrap; }
table.compare td.num small { display: block; font-size: 10px; font-weight: 400; }
table.compare td.num small.warn, table.compare .warn { color: var(--down); }
/* leading number on that row — marks the cell, never a row of its own */
table.compare .best { font-style: normal; color: var(--navy); font-size: 11px; margin-left: 4px; cursor: help; }
table.compare .flagcell { font-family: var(--sans); font-size: 11px; line-height: 1.4; }
table.compare .flagcell span { display: block; margin-bottom: 3px; }

/* generating spinner */
.gen { padding-top: 40px; display: flex; flex-direction: column; align-items: center; }
.spinner { width: 42px; height: 42px; border: 3px solid var(--line); border-top-color: var(--navy); border-radius: 50%; animation: spin .9s linear infinite; margin-bottom: 24px; }
.gen-steps { display: flex; flex-direction: column; gap: 8px; width: 100%; max-width: 320px; font-family: var(--mono); font-size: 12px; }
.gen-steps .s { display: flex; gap: 8px; color: var(--faint); }
@keyframes spin { to { transform: rotate(360deg); } }

.back-link { background: none; border: 0; color: var(--slate); font-size: 14px; padding: 0 0 12px; cursor: pointer; }

/* demo picker (stub-mode helper on the belief step) */
.demo-picker { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.demo-picker label { color: var(--faint); font-size: 12px; }
.demo-picker select { width: auto; min-width: 190px; font-family: var(--mono); font-size: 12px; color: var(--navy); padding: 6px 10px; }

/* ---- auth screens ---------------------------------------------------------- */
.auth-card { display: flex; flex-direction: column; gap: 14px; }
.field { display: block; }
.field .section-label { display: block; margin-bottom: 6px; }
.field .section-label i { font-style: normal; text-transform: none; letter-spacing: 0; opacity: .8; }
.field .fine { display: block; margin-top: 6px; }
.auth-or {
  display: flex; align-items: center; gap: 12px; margin: 16px 0;
  color: var(--faint); font-family: var(--mono); font-size: 11px; text-transform: uppercase;
}
.auth-or::before, .auth-or::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.auth-google { gap: 10px; }
.auth-google .gicon { flex: 0 0 auto; }
.auth-google:disabled .gicon { filter: grayscale(1); opacity: .5; }
.auth-note { margin-top: 8px; }
.auth-alt { margin-top: 18px; }
.auth-alt .linkish { font-size: 12px; text-decoration: underline; }
/* offline credentials — visible on purpose; guessing at them wastes time */
.demo-creds { margin-top: 22px; }
.demo-creds ul { list-style: none; padding: 0; margin: 8px 0; display: flex; flex-direction: column; gap: 4px; }
.demo-creds li { font-family: var(--mono); font-size: 12px; }
.demo-creds li span { color: var(--faint); margin: 0 4px; }
.demo-creds code { background: var(--card); border: 1px solid var(--line); border-radius: 3px; padding: 1px 6px; }
.demo-creds .fine { margin: 6px 0 0; }

/* guest state: an unfilled avatar reads as "not you" without saying it twice */
.avatar.guest { background: transparent; border: 1px dashed var(--faint); color: var(--faint); }

/* "keep this" prompts — the ask after real work, never a wall at the door */
.guest-bar, .keep-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.guest-bar .fine, .keep-bar .fine { display: block; margin-top: 2px; }
.keep-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
@media (max-width: 560px) {
  .guest-bar > *, .keep-bar > * { width: 100%; }
  .keep-actions { justify-content: space-between; }
}

/* ---- recorded ticket + optional fill ---------------------------------------- */
/* The fill is asked for AFTER the decision is recorded, so it has to read as a quiet
   follow-up rather than a form standing between the user and their trade. */
.fill-form { border-top: 1px solid var(--line-soft); padding-top: 10px; }
.fill-form label { display: block; line-height: 1.5; }
.fill-form .btn-row { align-items: stretch; }
.fill-form .inp {
  flex: 2; min-width: 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 6px;
  font-family: var(--mono); font-size: 14px; color: var(--ink); background: var(--card);
}
.fill-form .inp:focus { outline: none; border-color: var(--navy); }
.fill-form .btn { flex: 1; }

/* empty third column: a visible way back to three, not a table that quietly shrinks */
table.compare th.slot-add {
  text-align: center; vertical-align: middle;
  border-left: 1px dashed var(--line); background: transparent;
}
table.compare th.slot-add small {
  display: block; margin-top: 4px; font-family: var(--mono); font-size: 10px;
  color: var(--faint); font-weight: 400;
}
.iconbtn.add { margin: 0 auto; border-style: dashed; }
.iconbtn.add.on { border-style: solid; }

/* ---- error banner ---------------------------------------------------------- */
/* htmx 2 drops every 4xx body by default. These are rendered here rather than swapped into the
   control's own target, because most of those targets are the thing the user is reading — a
   128-byte sentence would replace the whole comparison table, or the whole screen. */
.hx-error {
  position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 95;
  width: min(560px, calc(100vw - 24px)); margin-top: 12px;
  background: var(--card); border: 1px solid var(--down); border-radius: 8px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .3);
  display: flex; align-items: flex-start; gap: 8px; padding: 12px 12px 12px 14px;
}
.hx-error[hidden] { display: none; }
.hx-error-body { flex: 1; min-width: 0; }
.hx-error-body > :first-child { margin-top: 0; }
.hx-error-body > :last-child { margin-bottom: 0; }
.hx-error-body .card { border: 0; padding: 0; margin: 0; background: transparent; }
.hx-error-body .notrade { margin: 0; }
.hx-error-x {
  flex: 0 0 auto; border: 0; background: none; color: var(--faint);
  font-size: 20px; line-height: 1; padding: 0 4px; cursor: pointer;
}
.hx-error-x:hover { color: var(--ink); }

/* ---- delete ----------------------------------------------------------------- */
/* Bottom of the page, visually separated, and never beside the analysis controls: this is the
   one irreversible action on the screen and a misclick has no undo. */
.danger-zone { margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--line); }
.btn.danger.pill { border-radius: 999px; padding: 10px 20px; font-size: 13px; }
.danger-confirm { border-color: var(--down); }

/* Home: the card and its delete are siblings — a <button> inside a <button> is invalid. */
.tc-wrap { position: relative; }
/* The delete button is absolutely positioned OVER the card, so the card's own top row has to be
   told to get out of its way — otherwise the date runs under the icon. 30px = the button's 28px
   box plus its 10px offset, less the 16px card padding the row already has, plus breathing room. */
.tc-wrap .thesis-card .tc-top { padding-right: 30px; }
.tc-del {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 6px;
  border: 1px solid transparent; background: transparent; color: var(--faint);
}
.tc-wrap:hover .tc-del { border-color: var(--line); }
.tc-del:hover { border-color: var(--down); color: var(--down); background: var(--down-soft); }
.tc-del:focus-visible { outline: 2px solid var(--down); outline-offset: 1px; }
.tc-confirm {
  background: var(--card); border: 1px solid var(--down); border-radius: 8px;
  padding: 14px; margin-bottom: 10px;
}
.tc-confirm .tc-statement { margin-bottom: 6px; }
/* Restore reuses the delete button's box but never its colour — red on the one control that puts
   something BACK would be the wrong promise in the one place it matters. */
.tc-restore:hover { border-color: var(--navy); color: var(--navy); background: var(--navy-soft); }
.tc-restore:focus-visible { outline-color: var(--navy); }
.tc-confirm.restore { border-color: var(--navy); }
/* an archived card is still a real idea — muted, not greyed out of legibility */
.thesis-card.archived { opacity: .92; }
.chip.archived { background: var(--line-soft); color: var(--slate); }
/* the way back to what was archived — quiet, but on Home, because Home is where it vanished from */
.home-foot { display: flex; justify-content: flex-end; margin-top: 18px; }
.home-foot .btn-link { font-size: 13px; }
.tc-confirm .fine { margin: 0 0 12px; }
