/* PropZilla — single hand-written stylesheet. Light theme, mobile-first.
   Styling mirrors the Daily Report Card (font, palette, surfaces, shadows). */

/* Anton (SIL OFL 1.1, see fonts/Anton-OFL.txt) — the logo wordmark only.
   Self-hosted like Inter rather than pulled from the Google CDN: one less
   third-party request, and it cannot go missing on us. Single weight by
   design, so never ask it for bold — that only triggers faux-bolding. */
@font-face {
  font-family: 'Anton';
  src: url('fonts/Anton-latin-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter Variable';
  src: url('fonts/InterVariable.woff2') format('woff2-variations'),
       url('fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #fafafa;
  --surface: #ffffff;
  --surface-2: #f4f5f7;
  --border: #e5e7eb;
  --border-strong: #cbd1d9;
  --text: #15171c;
  --muted: #6b7280;
  --accent: #1f6feb;
  --accent-weak: #e8f0fe;
  --pos: #15803d;
  --pos-weak: #dcfce7;
  --neg: #dc2626;
  --neg-weak: #fdecec;
  --warn: #f97316;
  --shadow: 0 1px 2px rgba(15,17,28,0.04), 0 1px 1px rgba(15,17,28,0.03);
  --radius: 10px;
  /* Two radii, and only two. --radius is the container tier (cards, panels,
     popovers); --radius-token is EVERY inline token — chip, badge, pill, flag,
     tag, segmented control — and the small blocks they sit in. Before v4.114 the
     EXECUTE cell alone shipped four (999/4/6/8). Data bars, 50% circles and
     micro-decorations (.pip, .dot, .sw, the hamburger) are neither tier and keep
     their own values: a 5px-tall meter is not a pill. */
  --radius-token: 8px;
  --sans: 'Google Sans', 'Inter Variable', 'Inter', ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--sans);
  font-feature-settings: 'cv11', 'ss01';
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
}
h1 { font-size: 22px; margin: 0; }
h2 { font-size: 17px; margin: 0 0 12px; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: var(--muted); }
.mono { font-variant-numeric: tabular-nums; }
.pos { color: var(--pos); }
.neg { color: var(--neg); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 16px;
  height: 56px; padding: 0 24px;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 10px; color: var(--text); font-weight: 600; }
.brand:hover { text-decoration: none; }
/* PropZilla mascot (v4.107). Mobile keeps the topbar at 56px and the logo small;
   the >=768px rule grows both, so the logo uses the empty room on the left that
   the nav never occupies. Sized by height — width follows the viewBox. */
.brand-mark { display: block; height: 30px; width: auto; }
/* The wordmark alone opts out of --sans, for Anton: a heavy condensed display
   face with one weight only, so it stays at 400 — asking for bold would just
   faux-embolden an already-black face. Anton's cap height runs much larger than
   Inter's, hence the bigger font-size here than the old stack wanted, and a
   little tracking because condensed caps need air (v4.110). */
.brand-text { font-family: 'Anton', var(--sans); font-weight: 400;
  font-size: 22px; text-transform: uppercase; letter-spacing: 0.04em; }
/* Mobile: nav is a dropdown panel toggled by the hamburger (.navtoggle).
   Desktop (>=768px): it becomes the inline tab row — see the desktop block. */
.navtabs {
  display: none; flex-direction: column; gap: 2px;
  position: absolute; top: 56px; left: 0; right: 0; z-index: 19;
  padding: 8px; background: var(--surface); border-bottom: 1px solid var(--border);
  box-shadow: 0 8px 24px rgba(15,17,28,.10);
}
.navtabs.open { display: flex; }
.navtabs a, .navtabs summary {
  padding: 11px 12px; border-radius: var(--radius-token); color: var(--muted); font-weight: 500;
}
.navtabs a:hover, .navtabs summary:hover { background: var(--bg); text-decoration: none; }
.navtabs a.active, .navtabs summary.active { color: var(--text); background: var(--surface-2); }
.nav-more-panel a { padding-left: 24px; }         /* mobile: indent under "More" */
.nav-sep { display: none; }                      /* mobile dropdown: no separators */
.nav-gear-icon { display: none; }                /* mobile: show the word */

/* "More" — groups the less-checked money/reporting pages behind one disclosure
   (v4.36). Native <details>/<summary>: no JS, works nested inside the mobile
   dropdown panel too. */
.nav-more summary { list-style: none; cursor: pointer; user-select: none; }
.nav-more summary::-webkit-details-marker { display: none; }
.nav-more summary::after { content: '▾'; font-size: 10px; margin-left: 5px; opacity: .6; }
.nav-more[open] summary::after { content: '▴'; }
.nav-more-panel { display: flex; flex-direction: column; gap: 2px; }
.nav-account {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 6px; padding: 10px 12px 2px; border-top: 1px solid var(--border);
}

/* Hamburger toggle — mobile only (hidden on desktop). */
.navtoggle {
  margin-left: auto; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0; border-radius: var(--radius-token);
  background: none; border: 1px solid var(--border); color: var(--text); cursor: pointer;
}
.navtoggle:hover { background: var(--surface-2); }
.navtoggle-bars { display: inline-flex; flex-direction: column; gap: 4px; width: 18px; }
.navtoggle-bars span { height: 2px; border-radius: 2px; background: currentColor; transition: transform .15s, opacity .15s; }
.navtoggle[aria-expanded="true"] .navtoggle-bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.navtoggle[aria-expanded="true"] .navtoggle-bars span:nth-child(2) { opacity: 0; }
.navtoggle[aria-expanded="true"] .navtoggle-bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.topbar-right { display: none; margin-left: auto; align-items: center; gap: 12px; }
.whoami { font-size: 13px; color: var(--muted); max-width: 40vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.logout-form { margin: 0; }
.linkish { background: none; border: 0; color: var(--accent); cursor: pointer; font: inherit; padding: 0; }

/* ---------- layout ---------- */
/* ONE container for EVERY page, FLUID (v4.25, owner directive after the
   1360px cap of v4.16): content uses the full viewport like a dashboard,
   with only an even gutter at the edges — same gutter as the topbar, so
   every edge lines up. Still no exceptions between tabs; reading-width
   content (journal forms) centers a narrower column INSIDE the fluid page.
   `.dashboard`, `.wide` and `.journal` stay as no-op classes. */
.page { margin: 0; padding: 16px 24px; }
/* A single stacked form doesn't want 1320px of input, so the form column stays
   readable inside the wide page. Multi-column grids (.plan-grid, .two-col) are
   unaffected and use the room. */
.form-page .form-main > label > input:not([type=checkbox]),
.form-page .form-main > label > select,
.form-page .form-main > label > textarea { max-width: 620px; }
/* v4.26 (owner rule: center ALL forms): every standalone form column sits in
   the same centered 760px band the journal uses — one form voice everywhere.
   Inline/filter forms (no .stack/.form-main) are untouched. */
form.stack, form.form-main, form.danger-form,
.card > .filters { max-width: 760px; margin-left: auto; margin-right: auto; }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.footer {
  margin: 24px 0 0; padding: 16px 24px;
  display: flex; flex-wrap: wrap; justify-content: center; text-align: center;
  gap: 6px 16px; font-size: 12px; color: var(--muted);
  border-top: 1px solid var(--border);
}

/* ---------- cards / sections ---------- */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; margin-bottom: 16px;
  box-shadow: var(--shadow);
}
/* ONE heading voice (v4.16): every card's title speaks in the same quiet
   small-caps the Book's sections use — no more shouting boxes. */
.card > h2, .jcard-head h2 {
  font-size: 12px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 600; margin: 0 0 12px;
}

/* ---------- buttons ---------- */
.btn-primary, .btn-secondary, .btn-danger, .btn-sm {
  display: inline-block; font: inherit; font-weight: 600; cursor: pointer;
  border-radius: var(--radius-token); padding: 11px 16px; border: 1px solid transparent; text-align: center;
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { text-decoration: none; filter: brightness(1.05); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn-secondary:hover { text-decoration: none; background: var(--bg); }
.btn-danger { background: var(--neg-weak); color: var(--neg); }
.btn-sm { padding: 7px 12px; font-size: 14px; background: var(--surface); border-color: var(--border); color: var(--text); }
.btn-link { color: var(--accent); font-weight: 500; }

/* ---------- forms ---------- */
label { display: block; font-size: 14px; color: var(--muted); margin-bottom: 12px; }
.stack > label, .form-main > label { margin-bottom: 14px; }
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], input[type=search], select, textarea {
  display: block; width: 100%; margin-top: 4px;
  font: inherit; font-size: 16px; color: var(--text);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-token);
  padding: 11px 12px; min-height: 44px;
}
textarea { min-height: 64px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
.or-new { margin-top: 6px; }
.check { display: flex; align-items: center; gap: 8px; color: var(--text); }
.check input { width: auto; min-height: 0; margin: 0; }
.check.inline { display: inline-flex; margin: 0; }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.form-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.form-actions .btn-primary, .form-actions .btn-secondary { flex: 1; min-width: 140px; }
.danger-form { margin-top: 24px; }

/* segmented type control */
.seg { border: 0; padding: 0; margin: 0 0 14px; }
.seg legend { font-size: 14px; color: var(--muted); padding: 0; margin-bottom: 6px; }
.seg { display: flex; flex-wrap: wrap; gap: 8px; }
.seg legend { flex-basis: 100%; }
.seg-opt { position: relative; margin: 0; }
.seg-opt input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.seg-opt span {
  display: inline-block; padding: 9px 14px; border: 1px solid var(--border);
  /* 8px, not a 999px lozenge: the pills sit next to buttons and inputs that are
     all 8px, and a fully-rounded chip next to them reads as a different system. */
  border-radius: var(--radius-token); background: var(--surface); color: var(--text); font-size: 14px;
  line-height: 1.5;
}
.seg-opt input:checked + span { background: var(--accent); color: #fff; border-color: var(--accent); }
.seg-opt input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.fx-line { margin: -6px 0 14px; font-size: 13px; }
.flag-row { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.flag-row input[type=date] { width: auto; margin-top: 0; }
.more summary { cursor: pointer; font-weight: 600; color: var(--accent); margin-bottom: 12px; }
.payout-chain label { margin-bottom: 10px; }

/* row-edit (firms/methods/setups) */
.row-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 0; border-top: 1px solid var(--border); }
.row-edit input { margin-top: 0; }
/* A list row READS as its record and opens its editor on click — the same
   <details> disclosure as .riskset on the Book, so a settings list is a list of
   names, not a column of form boxes. The editor underneath is the .row-edit
   form unchanged; it drops its own rule so the row shows one, not two. */
.rowset { border-top: 1px solid var(--border); }
.rowset > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; padding: 11px 0;
}
.rowset > summary::-webkit-details-marker { display: none; }
.rowset > summary strong { border-bottom: 1px dashed var(--border); }
.rowset > summary:hover strong { border-bottom-color: currentColor; }
.rowset[open] > summary strong { border-bottom-color: var(--accent); }
.rowset > summary .muted { font-size: 13px; }
.rowset > .row-edit { border-top: 0; padding-top: 0; }
.ed-name { flex: 2 1 140px; }
.ed-split { flex: 0 1 90px; }
.ed-notes { flex: 3 1 160px; }
.ed-name.static { padding: 8px 0; }
.is-archived { opacity: .55; }

/* plan catalog: edit/delete pair in a table row, and the register-form picker */
.rowacts { display: flex; gap: 10px; align-items: center; white-space: nowrap; }
.planpick { padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-token); }

/* Plans is a bulk data-entry screen used at a desk: let the form flow into
   columns as width allows instead of one tall stack of pairs. Labels stretch to
   equal row height and the control is pinned to the bottom, so inputs stay on a
   line even when a hint wraps to two lines. */
.plan-grid { display: grid; grid-template-columns: 1fr; gap: 0 16px; }
.plan-grid > label { display: flex; flex-direction: column; }
.plan-grid > label > input, .plan-grid > label > select { margin-top: auto; }
.plan-grid > label > .or-new { margin-top: 6px; }
@media (min-width: 700px)  { .plan-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1040px) { .plan-grid { grid-template-columns: repeat(3, 1fr); } }
/* The catalog table earns its width — keep cells on one line and let the
   existing .table-wrap scroll handle anything narrower. */
.plans-page table.data { min-width: 900px; }
.plans-page table.data th, .plans-page table.data td { white-space: nowrap; }

/* risk plan: the ladder of days to pass, and the ATM sizing table */
.ladder-step {
  display: inline-block; margin: 0 4px 4px 0; padding: 2px 9px; border-radius: var(--radius-token);
  background: var(--accent-weak); color: var(--accent); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.risk-stop { align-items: center; margin: 14px 0 4px; }
.risk-stop .inline-lbl { display: flex; align-items: center; gap: 8px; margin: 0; }
.risk-stop .inline-lbl input { margin-top: 0; width: 100px; }
.risk-last { margin: 0 0 14px; display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); }
/* how much drawdown is left, and where the reserve line sits */
.buffer { margin-bottom: 16px; }
.buffer-head { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; margin-bottom: 6px; }
.buffer-bar {
  position: relative; height: 10px; border-radius: 999px;
  background: var(--surface-2); overflow: hidden;
}
.buffer-fill { position: absolute; inset: 0 auto 0 0; background: var(--pos); border-radius: 999px; }
.buffer-fill.low { background: var(--neg); }
.buffer-reserve { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--text); opacity: .55; }
.buffer-note { margin: 6px 0 0; font-size: 13px; }
.risk-grid { margin-bottom: 4px; }
.risk-take {
  margin: 12px 0 0; padding: 12px 14px; border-radius: var(--radius-token);
  background: var(--pos-weak); border: 1px solid transparent; font-size: 15px;
}
.risk-take.stop { background: var(--neg-weak); color: var(--neg); }
.risk-take strong.mono { font-size: 17px; }
.risk-foot { margin-top: 12px; font-size: 13px; }

/* the funded playbook block on the account page: the stage, then the trade it
   asks for. Framed rather than tinted — it sits under the preset, not instead of it. */
.playbook { margin-top: 16px; padding: 12px 14px; border: 1px dashed var(--border); border-radius: var(--radius-token); }
.playbook-head { margin: 0 0 6px; font-size: 14px; }
.playbook-head strong { text-transform: uppercase; letter-spacing: .04em; font-size: 12px; color: var(--pos); }
.playbook p { margin: 6px 0 0; }
.playbook .risk-take.play { background: var(--surface-2); }
/* the cash-out call to action: the gate is met, so the instruction is a button
   and not a sentence pointing at the bottom of the page. */
.playbook-cta { margin-top: 10px !important; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.playbook-cta .muted { font-size: 12px; }
.btn-inline { padding: 8px 14px; font-size: 14px; }

/* ---------- auth ---------- */
.auth { max-width: 380px; margin: 48px auto; padding: 24px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.auth h1 { margin-bottom: 4px; }
.error { background: var(--neg-weak); color: var(--neg); padding: 10px 12px; border-radius: var(--radius-token); margin-bottom: 14px; font-size: 14px; }
.flash { background: var(--pos-weak); color: var(--pos); padding: 10px 12px; border-radius: var(--radius-token); margin-bottom: 14px; font-size: 14px; }

/* ---------- lists ---------- */
.filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.filters select, .filters input { width: auto; flex: 1 1 120px; margin-top: 0; }
.month-head { display: flex; justify-content: space-between; align-items: baseline; margin: 18px 0 8px; font-weight: 600; }
.rows { list-style: none; margin: 0; padding: 0; }
.rows li { margin-bottom: 8px; }
.rowlink {
  display: block; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 14px; color: var(--text);
  box-shadow: var(--shadow);
}
.rowlink:hover { text-decoration: none; background: var(--surface-2); }
/* expense row + inline "register in book" action for costs not yet on an account */
.exprow { display: flex; align-items: stretch; gap: 8px; }
.exprow .rowlink { flex: 1 1 auto; min-width: 0; }
.exprow-add {
  flex: 0 0 auto; display: flex; align-items: center; padding: 0 14px;
  border: 1px dashed var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--muted);
  font-size: 13px; font-weight: 600; white-space: nowrap;
}
.exprow-add:hover { text-decoration: none; color: var(--accent); border-color: var(--accent); background: var(--surface-2); }
.row-main { display: flex; align-items: center; gap: 8px; }
.row-date { font-variant-numeric: tabular-nums; font-size: 13px; color: var(--muted); flex: 0 0 auto; }
.row-title { font-weight: 600; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 6px; font-size: 14px; }
.badge { font-size: 12px; padding: 2px 8px; border-radius: var(--radius-token); background: var(--bg); border: 1px solid var(--border); color: var(--muted); }
.chip { font-size: 12px; padding: 2px 8px; border-radius: var(--radius-token); background: var(--bg); border: 1px solid var(--border); }
.chip.ok { background: var(--pos-weak); color: var(--pos); border-color: transparent; }
.chip.bad { background: var(--neg-weak); color: var(--neg); border-color: transparent; }
.chip.appr { background: var(--accent-weak); color: var(--accent); border-color: transparent; }
.chip.book { background: var(--accent-weak); color: var(--accent); border-color: transparent; font-variant-numeric: tabular-nums; }
.empty { text-align: center; padding: 32px 16px; color: var(--muted); display: flex; flex-direction: column; gap: 12px; align-items: center; }
.plain { list-style: none; padding: 0; margin: 0; }
.plain li { padding: 6px 0; border-top: 1px solid var(--border); }

/* linked-cost rows (book account ↔ expenses) */
.linkrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.linkrow-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; color: var(--text); flex: 1 1 auto; min-width: 0; }
.linkrow-main .mono { color: var(--muted); font-size: 13px; }
.inline-form { margin: 0; flex: 0 0 auto; }
.inline-form .btn-link { background: none; border: 0; cursor: pointer; padding: 0; font: inherit; }
.seed-note { margin-bottom: 12px; }

/* reset trail (account lineage) */
.trailrail { list-style: none; margin: 8px 0 0; padding: 0; }
.trailrail li { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 0 8px 16px; border-left: 2px solid var(--border); position: relative; }
.trailrail li::before { content: ""; position: absolute; left: -5px; top: 14px; width: 8px; height: 8px; border-radius: 50%; background: var(--border); }
.trailrail li.here { font-weight: 600; }
.trailrail li.here::before { background: var(--accent); }
.trail-num { font-variant-numeric: tabular-nums; }
.trail-meta { font-size: 13px; font-weight: 400; }
.trail-tot { margin-top: 12px; font-size: 14px; }

/* ---------- dashboard ---------- */
.hero {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 24px 16px; text-align: center; margin-bottom: 16px; box-shadow: var(--shadow);
}
.hero.pos { background: var(--pos-weak); border-color: transparent; }
.hero.neg { background: var(--neg-weak); border-color: transparent; }
.hero-label { font-size: 12px; letter-spacing: .08em; color: var(--muted); }
.hero-num { font-variant-numeric: tabular-nums; font-size: 40px; font-weight: 700; line-height: 1.1; margin: 4px 0; }
.hero.pos .hero-num { color: var(--pos); }
.hero.neg .hero-num { color: var(--neg); }
.hero-sub { font-variant-numeric: tabular-nums; font-size: 18px; color: var(--muted); }
.hero-meta, .hero-foot { font-size: 13px; color: var(--muted); margin-top: 6px; }

.stat-grid, .stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 16px; }
.stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; box-shadow: var(--shadow); }
.stat-k { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.stat-v { font-variant-numeric: tabular-nums; font-size: 22px; font-weight: 700; margin: 2px 0; }
.stat-s, .stat-d { font-size: 12px; color: var(--muted); }
.stat-unit { font-size: 13px; font-weight: 400; color: var(--muted); }

.table-wrap { overflow-x: auto; }
table.data, table.metrics { width: 100%; border-collapse: collapse; font-size: 14px; }
table.data th, table.metrics th { text-align: left; font-size: 12px; color: var(--muted); font-weight: 600; padding: 6px 8px; border-bottom: 1px solid var(--border); }
table.data td, table.metrics td { padding: 8px; border-bottom: 1px solid var(--border); }
table .num, table.data th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
table tr:last-child td { border-bottom: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.typechip { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-token); padding: 6px 12px; font-size: 14px; }

.months { display: flex; flex-direction: column; gap: 8px; }
.mrow, .bar-row { display: grid; grid-template-columns: 56px 1fr 72px; align-items: center; gap: 10px; }
.mlabel, .bar-label { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.mbars { display: flex; flex-direction: column; gap: 3px; }
.mbars .bar, .bar-track { height: 9px; border-radius: 4px; }
.bar-track { position: relative; background: var(--bg); display: flex; flex-direction: column; gap: 3px; height: auto; }
.bar { height: 9px; border-radius: 4px; min-width: 2px; }
.bar.spend { background: var(--neg); }
.bar.payout { background: var(--pos); }
.mnet, .bar-net { text-align: right; font-variant-numeric: tabular-nums; font-size: 13px; }
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 2px; vertical-align: middle; }
.dot.spend { background: var(--neg); }
.dot.payout { background: var(--pos); }

/* ---------- eval funnel (bought -> passed -> paid) ---------- */
.funnel-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.funnel-head h2 { margin: 0; }
.funnel-head .chip.book { text-decoration: none; }
.funnel-note { font-size: 12.5px; color: var(--muted); line-height: 1.45; margin: 0 0 16px; }
.funnel-note strong { color: var(--text); font-weight: 600; }
.funnel { display: flex; flex-direction: column; gap: 2px; }
.fstage { display: grid; grid-template-columns: 72px 1fr 48px; align-items: center; gap: 10px; }
.flabel { font-size: 13px; color: var(--muted); }
.ftrack { background: var(--bg); border-radius: 4px; height: 16px; overflow: hidden; }
.fbar { height: 16px; border-radius: 4px; min-width: 3px; }
.fbar.bought { background: var(--accent); }
.fbar.passed { background: var(--accent); opacity: .7; }
.fbar.paid { background: var(--pos); }
.fval { text-align: right; font-variant-numeric: tabular-nums; font-size: 16px; font-weight: 700; }
.frate { padding: 3px 0 3px 82px; font-size: 13px; color: var(--muted); }
.frate .fpct { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.funnel-break { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 14px; }
.fbreak-label { font-size: 12px; color: var(--muted); margin-right: 2px; }
.funnel-break .chip { font-variant-numeric: tabular-nums; }
.funnel-foot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); font-size: 12px; }

/* ---------- calendar ---------- */
.cal-nav { display: flex; align-items: center; gap: 10px; }
.cal-month { font-weight: 600; min-width: 7.5em; text-align: center; }
.nav-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--radius-token);
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
  font-size: 20px; line-height: 1;
}
.nav-arrow:hover { background: var(--surface-2); text-decoration: none; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { text-align: center; font-size: 12px; color: var(--muted); padding-bottom: 4px; }
.cal-cell {
  aspect-ratio: 1 / 1; position: relative; border-radius: var(--radius-token);
  background: var(--surface-2); color: var(--text);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  overflow: hidden; padding: 2px;
}
a.cal-cell:hover { text-decoration: none; filter: brightness(0.97); }
.cal-cell.out { background: transparent; pointer-events: none; }
.cal-cell.none { background: var(--surface-2); }
.cal-cell.pos { background: var(--pos-weak); }
.cal-cell.neg { background: var(--neg-weak); }
.cal-cell.flat { background: var(--surface-2); }
.cal-cell.today { outline: 2px solid var(--accent); outline-offset: -2px; }
.cal-day { position: absolute; top: 3px; left: 5px; font-size: 12px; font-weight: 600; color: var(--muted); }
/* Mobile: colour-only. A 7-col grid of square cells is too cramped to fit a
   readable number on phones and cover screens, so we lean on the cell tint +
   legend instead. The per-day net returns on desktop (>=768px) — see below. */
.cal-amt { display: none; }
.cal-cell.pos .cal-amt { color: var(--pos); }
.cal-cell.neg .cal-amt { color: var(--neg); }
.cal-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; font-size: 12px; color: var(--muted); }
.cal-legend .legend-label { font-weight: 600; }
.cal-legend .sw { width: 14px; height: 14px; border-radius: 4px; display: inline-block; vertical-align: middle; }
.cal-legend .sw.pos { background: var(--pos-weak); }
.cal-legend .sw.neg { background: var(--neg-weak); }
.cal-legend .sw.none { background: var(--surface-2); }
/* Grid stretches the three columns to equal height; each is a flex column with
   the value pushed to the bottom, so the values stay aligned even when a label
   like "Payouts (paid)" wraps to two lines. The <br> in the markup is the
   no-CSS fallback (keeps label-over-value if this rule ever fails to load);
   it's hidden once flex is doing the stacking. */
.cal-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; text-align: center; }
.cal-summary > div { display: flex; flex-direction: column; gap: 4px; }
.cal-summary > div br { display: none; }
.cal-summary strong { font-size: 18px; margin-top: auto; }
.cal-pop {
  position: absolute; z-index: 50; min-width: 168px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(15,17,28,.16); padding: 6px;
  display: flex; flex-direction: column; gap: 2px;
}
.cal-pop-title { font-size: 12px; color: var(--muted); padding: 4px 8px 2px; }
.cal-pop a { display: block; padding: 9px 10px; border-radius: var(--radius-token); color: var(--text); font-size: 14px; }
.cal-pop a:hover { background: var(--surface-2); text-decoration: none; }

/* ---------- book ---------- */
.warnbox { background: #fff7ed; color: #9a3412; border: 1px solid #fed7aa; padding: 10px 12px; border-radius: var(--radius-token); margin-bottom: 14px; font-size: 14px; }
.book-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.seg-links { display: inline-flex; gap: 2px; background: var(--surface-2); border-radius: var(--radius-token); padding: 3px; }
.seg-links a { padding: 5px 14px; border-radius: var(--radius-token); color: var(--muted); font-size: 14px; font-weight: 500; }
.seg-links a:hover { text-decoration: none; }
.seg-links a.on { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }

.book-list .book-acct { display: block; }
.book-acct .row-sub { gap: 8px; }
.row-spacer { flex: 1 1 auto; }
.idle { font-size: 12px; }
.badge.bad { background: var(--neg-weak); color: var(--neg); border-color: transparent; }
.ochip {
  display: inline-flex; align-items: center; justify-content: center; min-width: 22px;
  padding: 1px 6px; border-radius: var(--radius-token); font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ochip.w    { background: var(--pos-weak); color: var(--pos); }
.ochip.l    { background: var(--neg-weak); color: var(--neg); }
.ochip.be   { background: #fff7ed; color: var(--warn); }
.ochip.none { background: var(--surface-2); color: var(--muted); }

.book-state .bs-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 12px; }
.bs-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.bs-grid > div { display: flex; flex-direction: column; gap: 2px; }
.bs-grid .stat-k { font-size: 11px; }
.bs-grid .stat-v { font-size: 18px; font-weight: 700; }
.bs-grid .manual { font-size: 11px; font-weight: 500; color: var(--accent); }
/* v4.78: the floor figure IS the editor — same <details> disclosure as the
   History balances. Inside a stat tile the form reads left-to-right like the
   tile does, not right-aligned like a table cell. */
.bs-grid .floorset { display: inline-block; }
.bs-grid .floorset .riskset-form { justify-content: flex-start; margin: 4px 0 0; }
.bs-grid .floorset .riskset-form input[type="text"] { font-size: 15px; }
.bs-rules { margin: 14px 0 0; font-size: 13px; }

/* book grid: accounts (rows) × days (cols). Stretches to the card so a full month
   fits without horizontal scrolling on a desktop; the min-widths keep the cells
   readable and hand the row back to .table-wrap's scroll on a phone. */
table.book-grid {
  border-collapse: collapse; font-size: 12px;
  table-layout: fixed; width: 100%; min-width: 900px;   /* fixed: the day columns split the leftover evenly */
}
table.book-grid th.bg-day {
  text-align: center; font-size: 11px; color: var(--muted);
  font-weight: 600; padding: 2px 0; border-bottom: 1px solid var(--border);
}
table.book-grid th.bg-day.we { color: var(--border-strong); }
table.book-grid th.bg-day.today { color: var(--accent); }
table.book-grid th.bg-acct {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
  text-align: left; padding: 5px 12px 5px 0; width: 184px;
  border-bottom: 1px solid var(--border); font-weight: 600;
}
table.book-grid th.bg-acct a {
  color: var(--text); display: block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Rows are near-identical by label ("50k Flex" × 20), so the number leads. */
.bg-num { font-weight: 700; font-variant-numeric: tabular-nums; }
.bg-label { font-weight: 400; color: var(--muted); margin-left: 5px; }
.bg-sub { display: flex; align-items: center; gap: 6px; margin-top: 1px; }
.bg-firm {
  font-size: 11px; font-weight: 400; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bg-phase {
  flex: 0 0 auto; font-size: 10px; font-weight: 600; letter-spacing: .03em;
  padding: 1px 6px; border-radius: var(--radius-token); background: var(--surface-2); color: var(--muted);
}
.bg-phase.funded { background: var(--accent-weak); color: var(--accent); }
/* Block break between "last traded on" groups; labelled in front of the idle tail. */
table.book-grid tr.bg-break td {
  height: 9px; padding: 0; border-bottom: 1px solid var(--border); background: none;
}
table.book-grid tr.bg-break.labelled td {
  height: auto; padding: 16px 0 5px; border-bottom: 0;
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted);
}
.bcell {
  width: 26px; min-width: 26px; height: 26px; text-align: center; vertical-align: middle;
  border-radius: var(--radius-token); font-size: 11px; font-weight: 700; color: var(--muted);
  border: 2px solid var(--bg);
}
.bcell.none   { background: var(--surface-2); color: transparent; }
.bcell.seed   { background: var(--surface-2); color: var(--muted); }
.bcell.up     { background: var(--pos-weak); color: var(--pos); }
.bcell.down   { background: var(--neg-weak); color: var(--neg); }
.bcell.be     { background: #fff7ed; color: var(--warn); }
.bcell.passed { background: var(--accent-weak); color: var(--accent); }
.bcell.blown  { background: var(--neg); color: #fff; }
.cal-legend .legend-note { margin-left: auto; font-style: italic; }
.cal-legend .sw.up     { background: var(--pos-weak); }
.cal-legend .sw.be     { background: #fff7ed; }
.cal-legend .sw.down   { background: var(--neg-weak); }
.cal-legend .sw.passed { background: var(--accent-weak); }
.cal-legend .sw.blown  { background: var(--neg); }

/* ---- History: the DAY calendar (v4.27) ---- */
/* The view switch and the month arrows share one line above whichever month
   view is showing, so switching Calendar <-> By account never moves the arrows. */
.hist-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 14px;
}
/* Cells are NOT square here: a day carries a record, a bar and a net, so height
   is content-driven and the extra width of the fluid page is welcome (nothing is
   capped — see the layout note at the top). Mobile is seven columns with the
   record only; the week-total column and the bar/net join at >=768px. */
.cal-grid.bcal { grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow.wk { display: none; color: var(--border-strong); }
.bcal-cell {
  aspect-ratio: auto; min-height: 66px;
  align-items: center; justify-content: center; gap: 3px;
  padding: 17px 3px 15px; text-decoration: none;
}
.bcal-cell.none     { background: var(--surface-2); }
.bcal-cell.pay-only { background: var(--surface-2); }
.bcal-cell.w        { background: var(--pos-weak); }
.bcal-cell.l        { background: var(--neg-weak); }
.bcal-cell.e        { background: #fff7ed; }
/* pass/blow/payout counts: centred under the record on a phone (a 45px cell has
   no free corner), in the top-right corner opposite the day number on desktop */
.bcal-tags {
  position: absolute; bottom: 2px; left: 0; right: 0;
  display: flex; justify-content: center; gap: 3px;
}
.bcal-tag {
  display: inline-flex; align-items: center; border-radius: var(--radius-token);
  padding: 0 4px; font-size: 10px; font-weight: 700; line-height: 16px;
  font-variant-numeric: tabular-nums;
}
.bcal-tag.pass { background: var(--accent-weak); color: var(--accent); }
.bcal-tag.blow { background: var(--neg); color: #fff; }
/* The payout tag carries the AMOUNT withdrawn, in full — it's cash out of the
   book, not a count worth a glyph. A phone cell can't hold "$1,200.00", so it
   keeps the bare $ and the amount joins at >=768px (the day's net does the same). */
.bcal-tag.pay  {
  background: var(--surface); color: var(--muted); white-space: nowrap;
  border: 1px solid var(--border); line-height: 14px;   /* reads on a grey cell */
}
.bcal-tag.pay .pay-lg { display: none; }
/* The day's record IS the headline — one W/L per account, wrapping on a phone. */
.bcal-rec {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center;
  gap: 0 5px; font-size: 12px; font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.bcal-rec .bc-w  { color: var(--pos); }
.bcal-rec .bc-l  { color: var(--neg); }
.bcal-rec .bc-be { color: var(--warn); }
.bcal-bar { display: none; }
.bcal-net { display: none; }
/* week totals column (desktop only — see the media query) */
.bcal-wk {
  display: none; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; border-radius: var(--radius-token); background: var(--surface-2);
  padding: 6px 4px; font-size: 11px; text-align: center;
}
.bcal-wk.empty { background: transparent; }
.bcal-wk-rec { font-weight: 700; font-variant-numeric: tabular-nums; }
.bcal-wk-rec .bc-w { color: var(--pos); }
.bcal-wk-rec .bc-l { color: var(--neg); }
.bcal-wk-net { font-weight: 700; }
.bcal-wk-sub { font-size: 10px; }
.bcal-card .cal-legend .bcal-tag { line-height: 15px; }

/* ---- PropBook v2 screen ---- */
.book .page-head { margin-bottom: 12px; }
.num { font-variant-numeric: tabular-nums; }
.chip.eval { background: var(--surface-2); color: var(--muted); border-color: transparent; }

/* 1. reminder bar */
.reminder {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 18px 20px; margin-bottom: 14px; box-shadow: var(--shadow);
}
.reminder-line { margin: 0; font-size: 17px; font-weight: 600; }
.bullets { display: flex; align-items: center; gap: 10px; }
.pips { display: inline-flex; gap: 4px; }
.pip { width: 12px; height: 18px; border-radius: 3px; background: var(--surface-2); }
.pip.live { background: var(--accent); }
.pip.spent { background: var(--border); }
.pip.none { background: var(--surface-2); }
.bullets-txt { font-size: 13px; color: var(--muted); }
.bullets-txt strong { color: var(--text); }

/* 2. operational strip */
.opstrip { display: flex; flex-wrap: wrap; gap: 28px; padding: 4px 4px 14px; }
.opstrip > div { display: flex; flex-direction: column; gap: 2px; }
.op-k { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.op-v { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* v4.77: the farm tiles carry a second line — the split behind a count, the
   account count behind a capital figure. Muted and small: it qualifies the
   headline number, it never competes with it. (.pos/.neg are the global
   figure colours — nothing extra needed here.) */
.op-sub { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

.book-alert { margin-bottom: 14px; }
.book-tabs { margin-bottom: 16px; }

/* --- the tab row carries today's red-folder USD releases (v4.104) ---
   The strip rides the tab line rather than taking a band of its own: the
   account table is the page, and a news bar that pushes it down costs more
   than it tells you. Static text — the times are printed once, server-side,
   in New York time. No countdown, no interval, nothing to keep alive.
   Below 900px it drops onto its own line under the tabs (see the media
   block at the bottom of this section) because 3 tabs + 3 events do not
   share a phone width. */
.book-tabrow {
  display: flex; align-items: center; gap: 12px 16px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.book-tabrow .book-tabs { margin-bottom: 0; }
.newsbar {
  display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap;
  min-width: 0; margin-left: auto;
  font-size: 13px; line-height: 1.35; color: var(--text);
}
.news-ev { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
/* Flat fills, like every other indicator in this sheet (.pip, .cal-legend .sw).
   These were 🔴/🟢/⚪ until v4.113 — the emoji glyphs are drawn with a gradient
   by the system font, and this app has no gradient anywhere else. */
.news-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.news-dot.red { background: var(--neg); }
.news-dot.clear { background: var(--pos); }
.news-dot.unknown { background: transparent; box-shadow: inset 0 0 0 1.5px var(--border-strong); }
.news-time { font-weight: 600; color: var(--text); }
.news-title { color: var(--muted); }
/* Truncation is a tooltip away, never a lost event: the title on .newsbar
   always lists the full day. */
.news-more {
  padding: 1px 7px; border-radius: var(--radius-token);
  background: var(--surface-2); color: var(--muted);
  font-size: 12px; font-weight: 600;
}
.newsbar.clear .news-txt, .newsbar.unavail .news-txt { color: var(--muted); }
.newsbar.unavail { cursor: help; }
.newsbar.is-stale .news-time { color: var(--muted); }
@media (max-width: 899px) {
  .newsbar { margin-left: 0; width: 100%; }
}

/* 3. ranked listing (Live status): the order to spend the day's bullets */
/* v4.16 (supersedes the v4.10 viewport bleed, which read as a jumping
   container): the ranked tables sit INSIDE the shared page column like every
   other surface — a calm bordered wrap, edge cells padded, internal scroll
   only when the window is genuinely narrower than the table. */
.rankt-bleed {
  overflow-x: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  margin-bottom: 16px;
}
table.rankt { border-collapse: collapse; width: 100%; min-width: 1080px; font-size: 13px; }
/* one uniform gutter for every column — 8px a side since v4.31 (10px before),
   the same on every tab, so the edge insets below still line up. The v4.17
   per-tab 8px 4px squeeze stays gone; it made the gutters uneven. */
table.rankt th, table.rankt td { padding: 9px 8px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
/* edge cells carry the inset the card's padding used to provide */
table.rankt th:first-child, table.rankt td:first-child { padding-left: 16px; }
table.rankt th:last-child, table.rankt td:last-child { padding-right: 12px; }
table.rankt thead th { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 600; white-space: nowrap; }
table.rankt tbody tr:last-child td { border-bottom: 0; }
table.rankt tr.traded { opacity: .55; }
table.rankt th.num, table.rankt td.num { text-align: right; }
.rt-rank { white-space: normal; }
.rt-rank strong { font-size: 17px; font-variant-numeric: tabular-nums; margin-right: 6px; }
/* v4.17: chips stack under the rank number — the row of chips was the widest
   thing in the column */
.rt-rank .rchip { display: block; width: max-content; margin-top: 3px; }
.rchip {
  display: inline-block; padding: 1px 8px; border-radius: var(--radius-token);
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
.rchip.finish  { background: var(--accent-weak); color: var(--accent); }
.rchip.healthy { background: var(--pos-weak); color: var(--pos); }
.rchip.thin    { background: #ffedd5; color: var(--warn); }
.rchip.last    { background: var(--neg-weak); color: var(--neg); }
.rchip.done    { background: var(--surface-2); color: var(--muted); }
.rt-acct a { font-weight: 600; color: var(--text); }
/* v4.31 (supersedes the v4.21 uniform width:1%): every column asking for the
   same 1% made the browser hand out the surplus in equal slices REGARDLESS of
   what each column needs — the money columns got squeezed under their content
   and the table pushed past the page, which is what put a horizontal scrollbar
   under the day's plan. Plain auto layout sizes each column to its content and
   spreads what's left in proportion, so the whole row fits the page column —
   no width declarations here at all.
   The account sub-line keeps a cap so Account can't balloon, but as a
   PREFERRED width: it shrinks when the window is tight instead of pushing the
   table past the page. */
.rt-acct .rt-sub { width: auto; max-width: 210px; }
.rt-acct .rt-sub { display: flex; align-items: center; gap: 1px 6px; font-size: 12px; color: var(--muted); margin-top: 2px; white-space: normal; flex-wrap: wrap; }
/* v4.9: the number's last 4 IS the identity mid-session — big, mono, first */
.rt-num { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.rt-num:hover { text-decoration: none; color: var(--accent); }
.rt-label { color: var(--text); font-weight: 500; }
/* the top-ranked pending row: where the eye starts — advice, not enforcement */
table.rankt tr.next td { background: var(--accent-weak); }
table.rankt tr.next td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
table.rankt tr.next.filled td { background: var(--accent-weak); }
.rchip.up-next { background: var(--accent); color: #fff; }
/* v4.31: the cell wraps rather than widening the table — the figure and its
   stop count stay glued, the close-drop chip drops to its own line. */
.rt-buf { white-space: normal; }
.rt-buf > strong, .rt-buf > .muted { white-space: nowrap; }
.rt-buf strong { font-variant-numeric: tabular-nums; }
.rt-buf > .chip { display: block; width: max-content; margin-top: 4px; }
.warn-t { color: var(--warn); }
/* The balance, under the buffer it is measured from (v4.102). Muted and small:
   it is context for the figure above, not a second instruction — the buffer is
   what decides the trade, the balance is only where it is counted from. */
.rt-bal-sub {
  display: block; margin-top: 5px;
  font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.bufbar { display: block; width: 120px; height: 5px; border-radius: 999px; background: var(--surface-2); margin-top: 5px; overflow: hidden; }
.bufbar-fill { display: block; height: 100%; border-radius: 999px; }
.bufbar-fill.good { background: var(--pos); }
.bufbar-fill.warn { background: var(--warn); }
.bufbar-fill.risk { background: var(--neg); }
/* v4.31: same deal — the headline figure never breaks, but the "→ balance",
   "or press", "or finish" and stage lines under it may. */
.rt-loss, .rt-win, .rt-pass { white-space: normal; }
.rt-loss strong, .rt-win strong, .rt-pass strong { white-space: nowrap; font-variant-numeric: tabular-nums; }
.rt-then { display: block; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* a payable account: the stage line doubles as the link that logs the cash-out. */
a.rt-cashout { color: var(--accent); font-weight: 600; }
a.rt-cashout:hover { text-decoration: underline; }
.wpips { display: inline-flex; gap: 3px; }
.wpip { width: 9px; height: 9px; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--border); }
.wpip.on { background: var(--accent); border-color: transparent; }
.rt-atm { font-size: 11.5px; color: var(--muted); }
.rt-atm-row { display: block; white-space: nowrap; }
.rt-atm-row strong { color: var(--text); }
/* v4.59: the loss figure doubles as the PREPLANNING knob — click it, type a
   dollar figure, and that account's whole plan (sizes included) re-derives.
   Native <details>, no JS; the dashed underline is the "this is editable" hint
   and turns accent when a planned figure (not policy) is in force. */
.riskset { display: inline-block; }
.riskset summary { list-style: none; cursor: pointer; user-select: none; }
.riskset summary::-webkit-details-marker { display: none; }
.riskset summary strong { border-bottom: 1px dashed var(--border); }
.riskset summary:hover strong { border-bottom-color: currentColor; }
.riskset.on summary strong { border-bottom: 1px solid var(--accent); }
.riskset-mark {
  display: block; font-size: 10px; font-weight: 700; color: var(--accent);
  text-transform: uppercase; letter-spacing: .04em; text-align: right;
}
.riskset-form {
  display: flex; gap: 6px; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; margin: 6px 0 2px;
}
.riskset-form input[type="text"] { width: 76px; padding: 6px 8px; font-size: 14px; text-align: right; }
/* A full balance (50973.50) needs more room than a risk figure (750.00), and the
   history's balance column reserves the open editor's width so correcting one
   row doesn't shuffle the whole table sideways. */
.riskset-form.wide input[type="text"] { width: 100px; }
.hist-bal { min-width: 192px; }
.riskset-form .btn-sm { white-space: nowrap; }
/* v4.75: settle by hand — the firm's verdict, one click. On the account's state
   card it's a row under the rules line; on every Book row it's the same <details>
   disclosure as the planned figures, kept small and muted so it never competes
   with the day's numbers. Pass reads green on hover, blow red — colour only on
   intent, so neither button shouts from a resting row. */
.settle-cta {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
  font-size: 13px;
}
.settle-cta input[type="date"] { padding: 5px 8px; font-size: 13px; width: auto; }
.settle-pass:hover { border-color: var(--pos); color: var(--pos); }
.settle-blow:hover { border-color: var(--neg); color: var(--neg); }
.settleset { margin-left: 6px; }
.settleset summary {
  font-size: 10px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.settleset summary:hover { color: var(--text); }
.settle-form { justify-content: flex-start; }
.settle-form input[type="date"] { padding: 4px 6px; font-size: 12px; width: auto; }
.rt-fin { display: block; font-size: 12px; font-weight: 600; color: var(--accent); }
.rt-atm-row.fin, .rt-atm-row.fin strong { color: var(--accent); }
.rt-atm-row.fin em {
  font-style: normal; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
}
/* the funded playbook's own rows (press / bank) — the same shape as the
   finisher, in the winning-day green so a funded row reads apart from an eval's. */
.rt-play { display: block; font-size: 12px; font-weight: 600; color: var(--pos); }
.rt-atm-row.play, .rt-atm-row.play strong { color: var(--pos); }
.rt-atm-row.play em, .rt-atm-row.fin em {
  font-style: normal; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
}
.rchip.press { background: var(--pos-weak); color: var(--pos); }
.rt-comm { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rt-comm .rt-atm-row { line-height: inherit; }
.rt-comm .rt-atm-row.fin { color: var(--accent); }
.rt-comm .rt-atm-row.play { color: var(--pos); }
.rankt-note { margin: 12px 4px 0; font-size: 12px; }
.rankt-note em { font-style: normal; font-weight: 700; color: var(--accent); font-size: 10px; text-transform: uppercase; }

/* the Update tab's variant: same ranked table, plus a balance-entry column.
   tr.urow keeps the class only for the preview JS hook — undo the flex-card look. */
table.rankt tr.urow {
  display: table-row; padding: 0; background: transparent;
  border: 0; box-shadow: none; border-radius: 0;
}
table.rankt tr.urow.filled { border: 0; box-shadow: none; }
table.rankt tr.urow.filled td { background: var(--accent-weak); }
table.rankt.update .bufbar { width: 84px; }
.rt-result { white-space: normal; }
.rt-result strong { white-space: nowrap; font-variant-numeric: tabular-nums; }
.rt-result .rt-then { display: block; }
.rt-entry { min-width: 100px; }
.rt-entry .urow-entry { display: block; }
.rt-entry .urow-entry input { width: 96px; padding: 8px 9px; font-size: 15px; }
.rt-entry .urow-preview { display: block; margin-top: 3px; min-width: 0; }

/* ---------- book: quick update (one balance per account, in a list) ---------- */
.update-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.upd-progress { display: flex; flex-direction: column; gap: 6px; flex: 1 1 200px; min-width: 160px; }
.upd-count { font-size: 15px; }
.upd-count strong { font-variant-numeric: tabular-nums; }
.upd-track { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.upd-fill { height: 100%; background: var(--pos); border-radius: 999px; transition: width .2s ease; }
.upd-date { margin: 0; font-size: 13px; display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
.upd-date input { width: auto; padding: 8px 10px; font-size: 15px; }

.usection { margin-bottom: 18px; }
.usection h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 600; margin: 0 0 8px; }

.ulist { display: flex; flex-direction: column; gap: 8px; }
.urow {
  display: flex; align-items: center; gap: 12px; padding: 11px 14px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); cursor: text;
}
.urow.filled { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.urow.done { background: var(--surface-2); box-shadow: none; cursor: default; color: var(--text); }
.urow.done:hover { text-decoration: none; background: var(--border); }

.urow-dot {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid var(--border-strong); display: inline-flex;
  align-items: center; justify-content: center; font-size: 12px; line-height: 1; color: #fff;
}
.urow.filled .urow-dot { border-color: var(--accent); background: var(--accent); }
.urow-dot.on { border-color: transparent; background: var(--pos); }

.urow-id { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* The name is a link (the only route to an untraded account's page) but must not
   read as one inside the row. */
a.urow-id { color: inherit; }
a.urow-id:hover { text-decoration: none; }
a.urow-id:hover .urow-name { text-decoration: underline; }
.urow-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.urow-meta { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.urow-meta .num { font-variant-numeric: tabular-nums; }
.urow-prev { font-variant-numeric: tabular-nums; white-space: nowrap; }

.urow-entry { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; }
.urow-entry input {
  width: 116px; min-width: 0; margin: 0; padding: 9px 11px; font-size: 16px;
  text-align: right; font-variant-numeric: tabular-nums;
}
.urow-preview { font-size: 13px; font-weight: 600; min-width: 92px; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.urow-preview.w  { color: var(--pos); }
.urow-preview.l  { color: var(--neg); }
.urow-preview.be { color: var(--warn); }

.urow-result { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 10px; font-size: 13px; font-variant-numeric: tabular-nums; }
.urow-result strong { white-space: nowrap; }
.urow-bal { font-weight: 600; white-space: nowrap; }

/* Passed/blown today: still on screen, visibly out of the pool. */
.usection.settled { margin-top: 22px; }
.urow.settled { opacity: .82; }
.urow.settled:hover { opacity: 1; }
.urow-dot.pass { border-color: transparent; background: var(--pos); }
.urow-dot.blow { border-color: transparent; background: var(--neg); }
.settled-actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 10px; font-size: 13px;
}

/* The day's scoreboard. Deliberately the last block on the tab, not the strip. */
.usection.daytally { margin-top: 24px; }
.dtally {
  display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap;
  padding: 12px 14px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); font-size: 13px; color: var(--muted);
}
.dt-item strong { font-size: 15px; color: var(--text); font-variant-numeric: tabular-nums; margin-right: 2px; }
.dt-item.w strong    { color: var(--pos); }
.dt-item.l strong    { color: var(--neg); }
.dt-item.be strong   { color: var(--warn); }
.dt-item.pass strong { color: var(--pos); }
.dt-item.blow strong { color: var(--neg); }
.dt-net { margin-left: auto; display: inline-flex; align-items: baseline; gap: 8px 12px; flex-wrap: wrap; }
.dt-net strong { font-size: 17px; color: var(--text); font-variant-numeric: tabular-nums; }
.dt-net strong.pos { color: var(--pos); }
.dt-net strong.neg { color: var(--neg); }
/* Funded vs eval P/L. Eval is deliberately grey and a size down — it is a
   scoreboard number, not money, and shouldn't read like a paid day. */
.dt-pl { display: inline-flex; align-items: baseline; gap: 5px; }
.dt-pl-k { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.dt-pl.ev strong { font-size: 14px; color: var(--muted); font-weight: 600; }

.update-actions {
  position: sticky; bottom: 0; z-index: 2; display: flex; gap: 10px;
  padding: 12px 0 14px; background: linear-gradient(to top, var(--bg) 72%, rgba(250,250,250,0));
}
.update-actions .btn-primary { flex: 1; }
.all-done { text-align: center; color: var(--pos); font-weight: 600; padding: 14px 0 4px; }

@media (max-width: 560px) {
  /* phones keep the tighter gutter */
  .page, .footer { padding-left: 16px; padding-right: 16px; }
  .topbar { padding: 0 16px; }
  .urow { flex-wrap: wrap; }
  .urow-entry { width: 100%; justify-content: flex-end; }
  .urow-entry input { flex: 1 1 auto; width: auto; }
  .update-head { align-items: stretch; }
  .upd-date { width: 100%; }
}

/* ---------- desktop ---------- */
@media (min-width: 768px) {
  .navtoggle { display: none; }
  /* The logo takes the vertical room next to the nav (v4.107). */
  .topbar { height: 92px; }
  .brand-mark { height: 64px; }
  .brand-text { font-size: 34px; }
  /* DRC-style: the menu sits on the right, clustered next to the user / sign out.
     margin-left:auto pushes it right; topbar-right then follows directly after. */
  .navtabs {
    display: flex; flex-direction: row; gap: 2px; position: static;
    margin-left: auto; padding: 0; background: none; border: 0; box-shadow: none;
  }
  .navtabs a, .navtabs summary { padding: 6px 12px; font-size: 14px; }
  .nav-sep { display: inline-block; width: 1px; height: 16px; background: var(--border); margin: 0 6px; align-self: center; }
  .nav-gear-icon { display: inline; font-size: 16px; line-height: 1; }
  .nav-gear-word { display: none; }              /* desktop: the gear says it */
  .nav-account { display: none; }
  .topbar-right { display: flex; margin-left: 0; }
  .nav-more { position: relative; }
  .nav-more-panel {
    position: absolute; top: 100%; right: 0; margin-top: 4px; z-index: 21;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-token);
    box-shadow: 0 8px 24px rgba(15,17,28,.10); padding: 6px; min-width: 150px;
  }
  .nav-more-panel a { padding: 8px 10px; display: block; }
  .cal-amt {
    display: block; margin-top: 12px; font-size: 13px; font-weight: 700; line-height: 1;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* History calendar: the phone shows tint + record only; the desktop cell has
     room for the W/BE/L proportion bar, the day's net and a week-total column. */
  .cal-grid.bcal { grid-template-columns: repeat(7, 1fr) minmax(84px, 0.8fr); gap: 5px; }
  .cal-dow.wk { display: block; }
  .bcal-wk { display: flex; }
  .bcal-tags { top: 3px; right: 4px; bottom: auto; left: auto; justify-content: flex-end; }
  .bcal-tag.pay .pay-sm { display: none; }
  .bcal-tag.pay .pay-lg { display: inline; }
  .bcal-cell { min-height: 104px; padding: 22px 10px 10px; }
  .bcal-rec { font-size: 15px; gap: 0 7px; }
  .bcal-bar {
    display: flex; width: 64%; max-width: 104px; height: 4px; margin-top: 3px;
    border-radius: 999px; overflow: hidden; background: rgba(15,17,28,.07);
  }
  .bcal-bar i { display: block; height: 100%; }
  .bcal-bar i.w  { background: var(--pos); }
  .bcal-bar i.be { background: var(--warn); }
  .bcal-bar i.l  { background: var(--neg); }
  .bcal-net { display: block; margin-top: 2px; font-size: 12px; font-weight: 700; line-height: 1; }
  .stat-grid, .stats { grid-template-columns: repeat(3, 1fr); }
  .tables { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
  .tables .card:first-child { grid-column: 1 / -1; }
  .bs-grid { grid-template-columns: repeat(3, 1fr); }
}
.risk-swap { margin: 6px 0 0; font-size: 13px; }

/* ---------- journal (the DRC's day layer, v4.0) ---------- */
/* Reminder bar doubles as the intent display: goal (or carried focus) + a sub line. */
.reminder-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 320px; }
.reminder-sub { margin: 0; font-size: 13px; }
.reminder-sub strong { color: var(--text); }

/* The journal's reading/writing content centers a 760px column INSIDE the
   shared page width (v4.16) — readable forms, no jumping page edges. */
.journal .jcard-head, .journal .jform, .journal .jtrades, .journal .jday-ctx,
.journal .jorph-h, .journal .jphase2, .journal .shot-grid, .journal .jtradeform,
.journal .error, .journal .warnbox {
  max-width: 760px; margin-left: auto; margin-right: auto;
}
.journal .carried { max-width: 760px; margin: 0 auto 16px; }
.journal .jcard-head { margin-bottom: 14px; }
.jcard-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.jcard-head h2 { margin: 0; }
.jcard-head .muted { font-size: 13px; }
.jcount {
  display: inline-flex; align-items: center; justify-content: center; min-width: 22px;
  padding: 1px 7px; margin-left: 4px; border-radius: var(--radius-token);
  background: var(--surface-2); color: var(--muted); font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Focus carried from the last EOD ("tomorrow's focus" actually read again). */
.carried {
  display: flex; flex-direction: column; gap: 2px;
  background: var(--accent-weak); border-radius: var(--radius-token);
  padding: 10px 14px; margin-bottom: 16px; font-weight: 600;
}
.carried-k { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--accent); }

/* 1–10 grade picker and tag chips — radio/checkbox pills (the .seg-opt pattern). */
.jgrade { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-bottom: 14px; }
.jgrade .seg-opt span {
  display: block; text-align: center; padding: 10px 0; border-radius: var(--radius-token);
  font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.jgrade-label { margin-bottom: 6px; }
.jgrade-note { margin-bottom: 14px; }
.jtags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; }
/* A free-text field living in a pill row (the stop-size "other" box) has to read
   as one more pill: the global input rule's 44px min-height, 16px text and 4px
   top margin would otherwise sit it a few pixels low and a few taller. */
.jtags input[type=text] {
  margin-top: 0; min-height: 0;
  padding: 9px 12px; font-size: 14px; line-height: 1.5; border-radius: var(--radius-token);
}
/* Specific enough to beat the base `width: 100%` and the rule just above. */
.jtags input[type=text].jstop-other { width: 5.5em; }   /* "12.5" is the widest preset */
/* The open-window hint is a caption for the toggle beside it, not body copy —
   at 16px it out-shouted the 13px pill it explains. */
.jwindow-row .muted { font-size: 13px; }
.jday-ctx { margin: -4px 0 14px; font-size: 13px; }
.jform-foot { display: flex; align-items: center; gap: 12px; }
.savestat { font-size: 13px; color: var(--muted); }
.savestat.err { color: var(--neg); font-weight: 600; }
.page-stat { text-align: right; }

/* The day's trades, read off the Book (per-trade journal cards come in phase 2). */
.jtrade { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.jtrade-id { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.jtrade-id > a { font-weight: 600; color: var(--text); }
.jtrade-meta { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.jtrade-result { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.jphase2 { margin: 12px 0 0; font-size: 12px; }

/* Inline morning intent on the Book's Update tab (collapsed until needed). */
.intent-inline summary { cursor: pointer; font-weight: 600; }
.intent-inline[open] summary { margin-bottom: 14px; }
/* centered like journal.php's day view — same column, same calm */
.intent-inline .jform, .eodsec .jform { max-width: 760px; margin-left: auto; margin-right: auto; }
.usection.eodsec { margin-top: 24px; }

/* ---- the trade card (v4.1) + journal links on Book rows ---- */
.rt-jlink { display: inline-block; font-size: 12px; font-weight: 600; white-space: nowrap; }
/* v4.2: the link sits right after the account name — the names are near-identical
   ("50k Flex" × 6), so the name column has the room and the eye is already there. */
.rt-jlink-name { margin-left: 8px; vertical-align: 1px; }
.rt-result .rt-jlink { display: block; margin-top: 3px; }

/* balance field inside the trade card: keep the .urow class purely as the
   live-preview JS hook — none of the Book row's card chrome */
.urow.jbal {
  display: block; border: 0; padding: 0; margin-top: 4px;
  background: none; box-shadow: none; cursor: auto;
}
.urow.jbal input { text-align: left; width: 100%; }
.urow.jbal .urow-preview { display: block; margin-top: 4px; text-align: left; }

/* 1–5 star rating: radios in reverse DOM order so earlier stars light up */
.jrate-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 16px; }
.jrate-row .jgrade-label { margin: 0; }
.jstars { display: inline-flex; flex-direction: row-reverse; }
.jstar { margin: 0; position: relative; }
.jstar input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.jstar span { font-size: 26px; line-height: 1; color: var(--border-strong); padding: 0 2px; cursor: pointer; }
.jstar:hover span, .jstar:hover ~ .jstar span { color: var(--warn); }
.jstar:has(input:checked) span, .jstar:has(input:checked) ~ .jstar span { color: var(--warn); }
.jstar input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.jflag span { font-size: 13px; }
/* the flag is a warning, not a choice: red when set, matching the ⚑ chip on Book rows */
.jflag input:checked + span { background: var(--neg); border-color: var(--neg); }
.jflag input:focus-visible + span { outline-color: var(--neg); }
.jstars-ro { color: var(--warn); font-size: 14px; letter-spacing: 1px; white-space: nowrap; }
.jstars-ro .dim { color: var(--border-strong); }

/* journal detail under a trade row on the day view */
.jtrade-journal {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  border-top: 0 !important; padding: 2px 0 8px !important;
  margin-top: -4px; font-size: 13px;
}
.jtrade-note { color: var(--muted); }
.jorph-h { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; margin: 16px 0 4px; }

/* ---- screenshots (v4.3) ---- */
.shot-add {
  display: inline-block; padding: 9px 14px; margin: 4px 0 14px;
  border: 1px dashed var(--border-strong); border-radius: var(--radius-token);
  color: var(--muted); font-size: 13px; cursor: pointer;
}
.shot-add:hover { color: var(--accent); border-color: var(--accent); }
.shot-add input[type=file] { display: none; }
.shot-previews { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: -6px 0 14px; font-size: 12px; }
.shot-preview { height: 52px; border-radius: var(--radius-token); border: 1px solid var(--border); display: block; }
/* a not-yet-saved paste/pick: same ✕ affordance as a stored shot, so a
   doubled paste is removable before the save */
.shot-pending { position: relative; margin: 0; line-height: 0; }
.shot-pending .shot-del { position: absolute; top: 2px; right: 2px; border: 0; cursor: pointer; font: inherit; line-height: 1; padding: 0; }
.shot-grid { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.shot-thumb { position: relative; margin: 0; }
.shot-thumb img { height: 110px; max-width: 220px; object-fit: cover; border-radius: var(--radius-token); border: 1px solid var(--border); display: block; }
.shot-thumb form { position: absolute; top: 4px; right: 4px; margin: 0; }
.shot-del {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(21,23,28,.65); color: #fff; font-size: 12px; text-decoration: none;
}
.shot-del:hover { background: var(--neg); }
.shot-strip { display: inline-flex; gap: 6px; }
.shot-mini img { height: 40px; border-radius: var(--radius-token); border: 1px solid var(--border); display: block; }
.jhead-right { display: inline-flex; align-items: center; gap: 14px; }
.jtabs { margin-bottom: 16px; }
.journal .page-head { flex-wrap: wrap; }

/* ---- grade calendar (v4.15): the DRC month view, grade as the focus ---- */
.cal-cell.jg { text-decoration: none; }
.cal-cell.jg.g-low  { background: var(--neg-weak); }
.cal-cell.jg.g-mid  { background: #fff7ed; }
.cal-cell.jg.g-good { background: var(--pos-weak); }
.cal-cell.jg.g-top  { background: var(--pos); }
.cal-cell.jg.g-top .jg-grade, .cal-cell.jg.g-top .jg-mind, .cal-cell.jg.g-top .cal-day { color: #fff; }
.cal-cell.jg.g-note { background: var(--surface-2); }
.jg-grade { font-size: 20px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.cal-cell.jg.g-low .jg-grade  { color: var(--neg); }
.cal-cell.jg.g-mid .jg-grade  { color: #b45309; }
.cal-cell.jg.g-good .jg-grade { color: var(--pos); }
.jg-mind { font-size: 10px; color: var(--muted); margin-top: 1px; }
.jg-dot { font-size: 18px; color: var(--muted); line-height: 1; }
.jg-tags { position: absolute; bottom: 3px; right: 4px; font-size: 11px; line-height: 1; letter-spacing: -1px; }
.jg-sw { background: var(--surface-2); }
.jg-sw.g-low { background: var(--neg-weak); } .jg-sw.g-mid { background: #fff7ed; }
.jg-sw.g-good { background: var(--pos-weak); } .jg-sw.g-top { background: var(--pos); }
/* open-trade badge (journaled at entry, balance pending) */
.chip.opent { background: #fff7ed; color: var(--warn); border-color: transparent; font-weight: 700; white-space: nowrap; }
a.chip.opent:hover { text-decoration: none; background: var(--warn); color: #fff; }
.jopen-hint { display: block; margin-top: 4px; font-size: 12px; }
/* journal column on the account page's history */
.jhist { white-space: nowrap; }
.jhist .jstars-ro { font-size: 12px; margin: 0 2px; }
.stats-note { margin-top: 10px; font-size: 12px; }
tr.stat-all td { border-top: 2px solid var(--border-strong); font-weight: 600; }

/* The fixed ATM column on the Book list: same preset every day, so it reads as a
   label, not a control. `.tight` = cushion is under one full stop of room. */
/* The account page's session table carries the same colour key, so the two screens
   read as one thing: a tinted left edge and the session name in the session colour. */
table.atm tr.atm-s0 td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
table.atm tr.atm-s1 td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
table.atm tr.atm-s0 .atm-sess { color: #b45309; }
table.atm tr.atm-s1 .atm-sess { color: var(--accent); }
table.atm tr.atm-s0 td { background: rgba(249, 115, 22, .06); }
table.atm tr.atm-s1 td { background: rgba(31, 111, 235, .05); }
table.atm .atm-sess { text-transform: uppercase; font-size: 11px; letter-spacing: .04em; }

/* --- v4.62: the BV flag. A per-row bookkeeping fact ("this one is invoiced to
   the company"), shown as a quiet purple chip so it reads as an annotation on a
   trading row, never as a status like passed/blown. --- */
.chip.biz { background: #f3e8ff; color: #7e22ce; border-color: transparent; font-weight: 600; letter-spacing: .03em; }
.biz-sub { color: #7e22ce; font-weight: 600; }
.exprow.is-biz .rowlink { box-shadow: inset 3px 0 0 #d8b4fe; }
.biz-check { margin: -4px 0 4px; }

/* Declare mode: the list turned into one form for the retrospective
   "which of these go to the BV" pass. */
.declare-bar { font-size: 13px; margin: 0 0 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.declare-tick { display: flex; align-items: center; padding: 0 4px 0 2px; }
.declare-tick input { width: 20px; height: 20px; }
.declare-actions { position: sticky; bottom: 0; padding: 12px 0; background: linear-gradient(to top, var(--bg) 70%, transparent); }

/* --- v4.63: Firm stats — spend/payouts per month per firm. A wide cross-tab,
   so the table keeps its own min-width and hands the overflow to .table-wrap's
   scroll on a phone; the TOTAL row is the sheet's bottom line and reads like
   one. The per-cell .sub lines carry the secondary figures (home currency, the
   buy/paid counts) without a column each. --- */
.firmstats table.firmtab { min-width: 780px; }
.firmstats table.firmtab th, .firmstats table.firmtab td { white-space: nowrap; }
.firmstats .firm-cell a { font-weight: 600; }
.firmstats .sub { display: block; font-size: 11px; font-weight: 400; line-height: 1.4; }
.firmstats tfoot .total-row td { font-weight: 700; border-top: 2px solid var(--border); border-bottom: none; background: var(--surface-2); }
.firmstats .crumbs { margin: 0 0 12px; font-size: 13px; }
.firmstats .chips a.chip { text-decoration: none; font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   The EV optimizer (v4.79) — regime sizing, survival odds, account pricing.
   Each regime gets its own colour so the state is readable at a glance down a
   column: brute is neutral (nothing to protect), reanimation red (the account
   is fighting for its life), transition amber (real profit, still exposed),
   harvest green (the capital is safe, collect).
--------------------------------------------------------------------------- */
.chip.rg-brute       { background: var(--surface-2);  color: var(--muted);  border-color: transparent; }
.chip.rg-survival    { background: #fdecec;           color: #b45309;       border-color: transparent; }
.chip.rg-reanimate   { background: var(--neg-weak);   color: var(--neg);    border-color: transparent; }
.chip.rg-transition  { background: #fff2e5;           color: var(--warn);   border-color: transparent; }
.chip.rg-harvest     { background: var(--pos-weak);   color: var(--pos);    border-color: transparent; }
.chip.warn           { background: #fff2e5;           color: var(--warn);   border-color: transparent; }

/* the Book listing's Optimizer column */
.rt-opt { white-space: nowrap; }
.rt-opt .chip { display: inline-block; margin-bottom: 3px; }
.rt-optmoney { display: block; font-variant-numeric: tabular-nums; }
.rt-optmoney.agrees { opacity: .62; }
.rt-optatm { display: block; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rt-optatm strong { color: var(--text); }

/* the account page's optimizer card */
.optimizer h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em;
                color: var(--muted); margin: 18px 0 8px; }
/* TODAY'S PLAN — the deterministic decision model on the account page, painted
   in the `color` it returned (same `--rgc` contract as the Book row's block).
   It sits ABOVE the survival DP because it is the one that gets traded. */
.todayplan { border: 1px solid var(--rgc); border-left-width: 3px;
             border-radius: var(--radius-token); padding: 12px 14px; margin-bottom: 14px;
             background: color-mix(in srgb, var(--rgc) 7%, var(--surface-2)); }
.todayplan-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 6px; }
.todayplan-chip { background: var(--rgc); color: #fff; font-weight: 800; letter-spacing: .06em; }
.todayplan-br { margin-left: auto; color: var(--muted); }
.todayplan em { font-style: italic; display: block; margin-top: 4px; }

.opt-regime { border: 1px solid var(--border); border-left-width: 3px; border-radius: var(--radius-token);
              padding: 12px 14px; background: var(--surface-2); }
.opt-regime.rg-brute      { border-left-color: var(--muted); }
.opt-regime.rg-survival   { border-left-color: #b45309; }
.opt-regime.rg-reanimate  { border-left-color: var(--neg); }
.opt-regime.rg-transition { border-left-color: var(--warn); }
.opt-regime.rg-harvest    { border-left-color: var(--pos); }
.opt-regime-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 6px; }
.opt-plan { display: flex; flex-wrap: wrap; gap: 22px; margin: 12px 0 4px; }
.opt-k { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.opt-v { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; }
.opt-atms { list-style: none; padding: 0; margin: 10px 0 0; font-variant-numeric: tabular-nums; }
.opt-atms li { padding: 4px 0; border-top: 1px solid var(--border); font-size: 13px; }
.opt-atm-name { display: inline-block; min-width: 82px; color: var(--muted); font-size: 12px; }
.opt-odds { margin-top: 16px; }
.opt-note { font-size: 12px; margin-top: 10px; }
.opt-warn { font-size: 12px; background: #fff2e5; border-left: 3px solid var(--warn);
            padding: 8px 12px; border-radius: var(--radius-token); margin: 10px 0 0; }

/* the Masterplan's calibration verdict */
.cal-line { padding: 10px 14px; border-radius: var(--radius-token); border-left: 3px solid var(--border);
            background: var(--surface-2); font-size: 13px; }
.cal-agrees      { border-left-color: var(--pos); background: var(--pos-weak); }
.cal-optimistic  { border-left-color: var(--warn); background: #fff2e5; }
.cal-pessimistic { border-left-color: var(--accent); background: var(--accent-weak); }
.optt td, .optt th { vertical-align: top; }
.optt .rt-then { font-size: 11px; }
.opt-exits { font-size: 12px; margin: 10px 0 0; color: var(--muted); }
.opt-exit { display: block; margin-top: 4px; }
.opt-exit.up   { color: var(--pos); }
.opt-exit.down { color: var(--neg); }

/* ===========================================================================
   EXECUTION UI (v4.81) — the Book's ranked tables read during live trading.
   The goal is match-to-NinjaTrader with no arithmetic and no searching: firm
   colour and account number identify the row, one block says what to load.
   =========================================================================== */

/* --- firm badges: colour IS the identifier ------------------------------- */
.firmb {
  display: inline-block; padding: 3px 9px; border-radius: var(--radius-token);
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  text-transform: uppercase; white-space: nowrap; line-height: 1.35;
}
.firmb-lucid        { background: #1d4ed8; color: #fff; }
.firmb-fundednext   { background: #6d28d9; color: #fff; }
.firmb-topstep      { background: #111827; color: #fb923c; }
.firmb-apex         { background: #9f1239; color: #fff; }
.firmb-tpt          { background: #0f766e; color: #fff; }
.firmb-mff          { background: #15803d; color: #fff; }
.firmb-tradeify     { background: #0e7490; color: #fff; }
.firmb-bulenox      { background: #4338ca; color: #fff; }
.firmb-earn2trade   { background: #b45309; color: #fff; }
.firmb-alpha        { background: #334155; color: #fff; }
.firmb-fundingpips  { background: #047857; color: #fff; }
.firmb-etf          { background: #be123c; color: #fff; }
.firmb-blueguardian { background: #0369a1; color: #fff; }
.firmb-leeloo       { background: #7c2d12; color: #fff; }
.firmb-none         { background: var(--surface-2); color: var(--muted); }
/* stable fallback hues for firms with no hand-picked colour */
.firmb-h0 { background: #b91c1c; color: #fff; }
.firmb-h1 { background: #a16207; color: #fff; }
.firmb-h2 { background: #166534; color: #fff; }
.firmb-h3 { background: #155e75; color: #fff; }
.firmb-h4 { background: #5b21b6; color: #fff; }
.firmb-h5 { background: #9d174d; color: #fff; }
.firmb-h6 { background: #1e40af; color: #fff; }
.firmb-h7 { background: #3f3f46; color: #fff; }

/* --- the NT8 match line: badge + the number as it reads in the dropdown --- */
.rt-idline { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.rt-acct .rt-num {
  font-size: 20px; font-weight: 800; letter-spacing: .01em;
  font-variant-numeric: tabular-nums; color: var(--text); text-decoration: none;
}
.rt-acct .rt-num:hover { text-decoration: underline; }

/* --- the execution block: regime pill + the sizes, and nothing else -------
   Everything that justifies the sizes (risk, target, R:R, breakeven win rate,
   the post-loss balance, the survival exits) is on the pill's tooltip. Printed
   in the row it gets read past forty times a session. Two exception flags stay
   visible — BLOWS and PLANNED — because those are states you must not have to
   hover to discover. */
.rt-exec { min-width: 210px; }
.xblock {
  border-left: 4px solid var(--border); border-radius: var(--radius-token);
  padding: 7px 10px; background: var(--surface-2);
}
.xhead { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.xpill {
  display: inline-block; padding: 3px 9px; border-radius: var(--radius-token);
  font-size: 11px; font-weight: 800; letter-spacing: .07em; cursor: pointer;
  background: var(--bg); border: 1px solid currentColor;
  /* the regime name plus its pencil is one token — wrapping it turns a pill into
     a two-line box and shoves the flags onto their own row */
  white-space: nowrap;
}
.xflag {
  font-size: 10px; font-weight: 800; letter-spacing: .06em;
  padding: 2px 6px; border-radius: var(--radius-token); cursor: help;
}
.xflag.bad  { background: var(--neg); color: #fff; }
.xflag.plan { background: var(--surface-2); color: var(--muted); border: 1px solid var(--border); }
.xflag.last { background: #7f1d1d; color: #fff; }

.xtags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.xtag {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 5px 10px; border-radius: var(--radius-token); white-space: nowrap;
  background: var(--bg); border: 1px solid var(--border);
  font-variant-numeric: tabular-nums; font-size: 14px;
}
.xtag em { font-style: normal; font-size: 10px; font-weight: 800; letter-spacing: .06em;
           text-transform: uppercase; color: var(--muted); }
.xtag-stop { font-weight: 700; color: var(--muted); }
.xtag-stop::after { content: ':'; font-weight: 400; }
.xtag-size { font-weight: 800; }
/* the dollar exposure, plainly: a middot, muted, normal weight. It is reference
   beside the instruction, not a second instruction — no border, no accent, no
   stress colour, and it must not compete with the contract count. */
.xtag-amt { color: var(--muted); font-weight: 400; }
.xtag-amt::before { content: '· '; }
.xtag.none { color: var(--muted); font-style: italic; font-size: 12px; }
.xalt { margin-top: 4px; opacity: .6; }
.xalt .xtag { font-size: 12px; padding: 2px 7px; }

/* the ACTION — the decision model's own instruction for this account today.
   Reads under the sizing pill because that is the order it is used in: what to
   put on, then what the trade is for. Muted and small: it is a sentence, and it
   must not compete with the contract count above it. */
.xact { margin-top: 6px; font-size: 11px; font-weight: 600; letter-spacing: .02em;
        color: var(--muted); cursor: help; }

/* **[KEY-CONCEPT]** REGIME COLOUR IS A FIELD, NOT A STYLESHEET. `--rgc` is the
   `color` hex that `calculateAccountRegime()` returned, set inline on the block,
   so the row is painted by the decision model rather than by a class the CSS and
   the engine both have to remember. Change a colour in lib/regime.php and the
   Book repaints with nothing here to keep in step.

   The classes below survive only as the FALLBACK — the shape (the dashed endgame
   border) and a colour for any block rendered without the property. */
.xblock.x-brute      { border-left-color: #dc2626; background: #fef2f2; }
.xblock.x-brute      .xpill { color: #b91c1c; }
.xblock.x-survival   { border-left-color: #d97706; background: #fffbeb; }
.xblock.x-survival   .xpill { color: #b45309; }
.xblock.x-transition { border-left-color: #2563eb; background: #eff6ff; }
.xblock.x-transition .xpill { color: #1d4ed8; }
.xblock.x-harvest    { border-left-color: #16a34a; background: #f0fdf4; }
.xblock.x-harvest    .xpill { color: #15803d; }
/* reanimation is the endgame — louder than the rest, and marked as a last shot.
   The dashed outline is SHAPE, so it stays with the class while the colour of it
   comes from the model. */
.xblock.x-reanimate  { border-left-color: #7f1d1d; background: #fef2f2;
                       border: 1px dashed #7f1d1d; border-left-width: 4px; border-left-style: solid; }
.xblock.x-reanimate  .xpill { color: #7f1d1d; }

/* Last, so the model's own colour beats every fallback above it — same
   specificity, so the cascade is the only thing deciding, and it must decide
   for `--rgc`. */
.xblock.x-regime           { border-left-color: var(--rgc);
                             background: color-mix(in srgb, var(--rgc) 7%, var(--surface-2)); }
.xblock.x-regime .xpill    { color: var(--rgc); }
.xblock.x-regime.x-reanimate { border-color: var(--rgc); border-left-color: var(--rgc); }

/* the planned-risk editor opens off the regime pill itself — and the pill has to
   LOOK editable. Elsewhere the app dashes-underlines an editable figure; a pill
   already has a border, so it carries a small pencil instead. */
.xhead .riskset { display: inline-block; }
.xhead .riskset summary { list-style: none; cursor: pointer; display: inline-flex;
                          align-items: center; gap: 6px; }
.xhead .riskset summary::-webkit-details-marker { display: none; }
.xhead .riskset .riskset-mark { display: none; }   /* the PLANNED flag says it */
.xpill-edit { font-style: normal; font-size: 10px; opacity: .5; margin-left: 5px;
              font-weight: 400; letter-spacing: 0; }
.xhead .riskset summary:hover .xpill { background: var(--surface-2); }
.xhead .riskset summary:hover .xpill-edit { opacity: 1; }
.xhead .riskset[open] .xpill { outline: 2px solid currentColor; outline-offset: 1px; }
.xhead .riskset[open] .xpill-edit { opacity: 1; }
.xhead .riskset-form { margin-top: 7px; }

/* --- FUNDED rows read as a different class of thing ----------------------
   A funded account is the income account; an eval is a lottery ticket. Scanning
   a mixed book, that distinction should land before any text is read — so funded
   rows take a soft emerald tint and a left edge, evals stay neutral. The tint is
   deliberately faint: it marks a whole row, and anything stronger would compete
   with the EXECUTE block's regime colour, which is the thing being read. */
.rankt tr.fundedrow > td { background: #f4fbf7; }
.rankt tr.fundedrow > td:first-child { box-shadow: inset 3px 0 0 #10b981; }
.rankt tr.fundedrow.traded > td { background: #f8fbf9; }

/* --- the account cell: one identity line, one meta tag ------------------- */
.rt-meta {
  display: inline-block; margin-top: 3px;
  font-size: 12px; color: var(--muted); font-weight: 600;
}
.rt-meta.m-paid  { color: var(--pos); }
.rt-meta.m-ready { color: #0f766e; }
.rt-meta.m-met   { color: var(--pos); }
/* THE FINISH LINE (v4.99). Under one preset day's target, so a single trade ends
   the eval — the moment oversizing is most tempting and most expensive. It gets
   the only pill treatment in this cell: amber, bordered, unmissable at a glance
   down the column. Bordered rather than solid so it never competes with the UP
   NEXT row banding, which owns solid amber on this page. */
.rt-meta.m-finish {
  color: var(--warn); background: #fff7ed; border: 1px solid var(--warn);
  border-radius: var(--radius-token); padding: 1px 7px;
}
/* The size ceiling, beside the badge — the second half of the answer, so the
   dollars and the biggest legal position are one glance apart instead of four
   columns. Dashed: it is a limit, not a quantity to type. */
.rt-cap {
  display: inline-block; margin-left: 6px; vertical-align: 1px;
  font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--warn); border: 1px dashed var(--warn); border-radius: var(--radius-token); padding: 1px 6px;
  white-space: nowrap; cursor: help;
}

/* An OPEN position is the one thing in this cell that is never hidden (v4.98).
   It is not a control you go looking for, it is a state you must be told: money
   is live in this account right now. So it sits in the flow on its own line,
   always — and ONLY when there is one, so a quiet row costs nothing. Every other
   row is exactly as tall as it was. */
.rt-open { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 5px; }

/* Controls and provenance — real functionality, just not first-glance material.
   Revealed on hover or keyboard focus, and ALWAYS shown where there is no hover
   to reveal them with: a touch device would otherwise lose them entirely.

   They are taken OUT OF FLOW rather than merely faded. Fading alone leaves the
   row exactly as tall as before — the clutter goes but none of the height does,
   which is half a fix. Absolute positioning gives back the space AND avoids the
   layout shift that display:none would cause on every hover, which in a table
   you are scanning down is worse than the clutter was.

   **[KEY-CONCEPT] It stays INSIDE the account cell** (v4.103). Two anchors were
   tried and both leaked. The cell's top-right corner sat on the account NUMBER,
   which is a link you click to open the account. `left: 100%` off the identity
   line (v4.100) cleared the number but spilled into the next column — and since
   v4.102 that column is EXECUTE, so it landed on the regime pill, which IS the
   click-to-plan risk control. A card that covers a control is worse than one
   that covers a figure, and out there every neighbour is a control.

   So: the cell's own bottom-right corner, and `right` keeps it inside the column
   whatever the row is doing. The bottom-LEFT belongs to the open chip and the
   card clears it horizontally; nothing else in the cell reaches that corner. */
.rankt .rt-acct { position: relative; }
.rt-tools {
  position: absolute; right: 8px; bottom: 6px; z-index: 2;
  display: flex; flex-wrap: nowrap; align-items: center; gap: 6px;
  padding: 3px 6px; border-radius: var(--radius-token);
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: 0 2px 8px rgba(0,0,0,.06);
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
}
.rankt tr:hover .rt-tools,
.rankt tr:focus-within .rt-tools { opacity: 1; pointer-events: auto; }
/* No hover to reveal with: back in the flow, always visible, last in the cell. */
@media (hover: none) {
  .rt-tools { position: static; margin-top: 5px; opacity: 1; pointer-events: auto;
              flex-wrap: wrap; background: none; border: 0; box-shadow: none; padding: 0; }
}

/* --- UP NEXT: the row the eye must land on ------------------------------- */
/* UP NEXT outranks the funded tint — one row at a time says "trade this now",
   and its amber has to beat every other row treatment on the page. */
.rankt tr.urow.next > td,
.rankt tr.urow.next.fundedrow > td { background: #fffdf5; border-top: 2px solid var(--warn); border-bottom: 2px solid var(--warn); }
.rankt tr.urow.next.fundedrow > td:first-child { box-shadow: none; }
.rankt tr.urow.next > td:first-child { border-left: 4px solid var(--warn); }
.rankt tr.urow.next > td:last-child  { border-right: 2px solid var(--warn); }
.rankt tr.urow.next .rt-num  { font-size: 26px; }
.rankt tr.urow.next .firmb   { font-size: 13px; padding: 4px 11px; }
.rankt tr.urow.next .xtag  { font-size: 16px; padding: 7px 12px; }
.rankt tr.urow.next .xpill { font-size: 12px; }
.rchip.up-next {
  background: var(--warn); color: #fff; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; padding: 3px 8px; border-radius: var(--radius-token); border-color: transparent;
}
/* a spent row recedes — its execution block is history, not an instruction */
.rankt tr.traded .xblock, .rankt .rt-result ~ .xblock { opacity: .55; }

/* the NT8 identifier must never wrap — it is matched character by character
   against the Chart Trader dropdown, and a broken line breaks that match */
.rt-idline { flex-wrap: nowrap; }
.rt-acct .rt-num { white-space: nowrap; }
.rankt .rt-acct { min-width: 250px; }
.rankt tr.urow.next .rt-num { font-size: 23px; }

/* ---------------------------------------------------------------------------
   The Audit page (v4.86) — the measured twin of the Masterplan's projection.
   The verdict leads, because it is the answer; everything below is the working.
--------------------------------------------------------------------------- */
.audit-form .audit-presets { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.btn-chip {
  display: inline-block; padding: 6px 12px; border-radius: var(--radius-token); font-size: 13px;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  text-decoration: none;
}
.btn-chip:hover { border-color: var(--accent); }
.btn-chip.on { background: var(--accent-weak); color: var(--accent); border-color: transparent; font-weight: 600; }
.audit-form .check { display: flex; gap: 9px; align-items: flex-start; margin: 10px 0; font-size: 13px; }
.audit-form .check input { margin-top: 3px; }
.audit-window { font-size: 12px; margin-top: 10px; }

.verdict { border-left: 4px solid var(--border); }
.verdict.bad  { border-left-color: var(--neg); background: #fffafa; }
.verdict.good { border-left-color: var(--pos); background: #fafffb; }
.verdict-big { font-size: 40px; font-weight: 800; font-variant-numeric: tabular-nums;
               margin: 4px 0 2px; line-height: 1.1; }
.verdict-sum { font-size: 14px; color: var(--muted); margin: 0 0 12px; }
.verdict-sum strong { color: var(--text); font-variant-numeric: tabular-nums; }
.verdict-band { font-size: 13px; background: var(--surface-2); border-radius: var(--radius-token);
                padding: 10px 12px; margin: 0 0 4px; }
.verdict-band.firm { background: var(--neg-weak); }
.verdict h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em;
              color: var(--muted); margin: 18px 0 8px; }
.bkt { width: 100%; }
.bkt th { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.bkt td, .bkt th { padding: 7px 10px; border-bottom: 1px solid var(--border); text-align: left; }
.bkt td.num, .bkt th.num { text-align: right; font-variant-numeric: tabular-nums; }
.stat-v.band { font-size: 16px; }
.quality-bad { border-left: 4px solid var(--warn); }

/* ---------------------------------------------------------------------------
   Equity comparison chart (v4.95, impact.php)
   Two series, one axis. "What happened" is the recessive reference — grey and
   dashed; the proposal carries the accent. The dash is deliberate secondary
   encoding: identity must survive a colourblind reader and a greyscale print,
   so it is never carried by hue alone.
--------------------------------------------------------------------------- */
.eqchart { position: relative; margin: 6px 0 2px; }
.eqchart svg { width: 100%; height: 320px; display: block; overflow: visible; }
.eq-line { fill: none; stroke-width: 2; vector-effect: non-scaling-stroke;
           stroke-linejoin: round; stroke-linecap: round; }
.eq-actual { stroke: var(--muted); stroke-dasharray: 5 4; }
.eq-cons   { stroke: var(--accent); }
.eq-zero   { stroke: var(--border-strong); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* `hidden` is an HTMLElement property — assigning el.hidden on an SVG child sets
   a JS expando and leaves the content attribute alone, so the crosshair drew a
   stray line down the left edge on every load. Visibility rides a class on the
   CONTAINER, which is real HTML, and both layers read it. */
.eq-cross  { stroke: var(--border-strong); stroke-width: 1; vector-effect: non-scaling-stroke;
             opacity: 0; transition: opacity .08s linear; }
.eqchart.eq-on .eq-cross { opacity: 1; }
.eq-legend { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 6px;
             font-size: .82rem; color: var(--muted); }
.eq-key { display: inline-flex; align-items: center; gap: 7px; }
.eq-key::before { content: ""; width: 18px; height: 0; border-top-width: 2px; }
.eq-key-actual::before { border-top: 2px dashed var(--muted); }
.eq-key-cons::before   { border-top: 2px solid var(--accent); }
.eq-axis { display: flex; justify-content: space-between; font-size: .76rem;
           color: var(--muted); margin-top: 2px; }
.eq-tip { display: none; position: absolute; pointer-events: none; z-index: 3; background: var(--surface);
          border: 1px solid var(--border); border-radius: var(--radius-token); box-shadow: var(--shadow);
          padding: 7px 10px; font-size: .8rem; line-height: 1.45; white-space: nowrap;
          transform: translate(-50%, -100%); }
.eqchart.eq-on .eq-tip { display: block; }
.eq-tip b { font-variant-numeric: tabular-nums; }
.eq-tip .k { color: var(--muted); }
.eq-grid { stroke: var(--border); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* Labels sit in HTML, not in the SVG: the plot uses preserveAspectRatio="none"
   to fill its box, which would stretch any text inside it. */
.eq-plot { position: relative; }
.eq-ylabels { position: absolute; inset: 0; pointer-events: none; }
.eq-ylabels span { position: absolute; left: 0; transform: translateY(-50%);
                   font-size: .72rem; color: var(--muted); background: var(--surface);
                   padding: 0 4px; font-variant-numeric: tabular-nums; }
