/* ============================================================
   CONSOLE — the office's data surface.
   Same design language as the site: Neue Haas → Helvetica,
   black on white, hairline structure, tabular numerics,
   dim-to-full states, monument-scale figures, restraint.
   ============================================================ */

:root {
  --paper:    #fff;                      /* the page and every surface  */
  --ink:      #0a0a0a;
  /* Three tiers, kept — the editorial character comes from the ratio
     between them, not from any of them being unreadable. The old --dim
     measured 2.27:1 and carried roughly half the text in the app,
     including every table header. Alphas solved for the ratio each
     tier actually needs against white. */
  --dim:      rgba(10, 10, 10, 0.557);   /* 4.5:1 — body text minimum   */
  --dim-2:    rgba(10, 10, 10, 0.677);   /* 7:1   — the stronger tier   */
  --dim-3:    rgba(10, 10, 10, 0.42);    /* decorative only, never text */
  --line:     rgba(10, 10, 10, 0.12);    /* hairlines — decoration      */
  --line-2:   rgba(10, 10, 10, 0.07);
  /* Borders that carry meaning — the edge of an input, a focusable
     control — are not decoration and need 3:1. */
  --line-int: rgba(10, 10, 10, 0.433);
  --fill:     #0a0a0a;
  --track:    rgba(10, 10, 10, 0.09);
  --gutter:   28px;
  --easing:   cubic-bezier(0.4, 0, 0.2, 1);
  --dur:      0.3s;
  color-scheme: light;
}

/* ---------- dark theme ----------
   The same tiers, inverted: paper goes to near-black, ink to near-white,
   and every dim/line alpha is rebuilt on white instead of black so the
   ratios hold. `--ink` doubles as the "strong fill" (primary buttons,
   the active pill) with `--paper` as the text on it, so filled controls
   flip automatically. The command palette and the search pill are dark
   chrome in both themes and keep their own colours.

   The console is light by default. Dark is entered only on demand —
   the topbar icon or the "Toggle theme" command — never from the OS
   preference, so the plan and the console always agree. */
:root[data-theme="dark"],
:root[data-theme="dark"] body {
  color-scheme: dark;
}
:root[data-theme="dark"] {
  --paper:    #101112;
  --ink:      #ececec;
  --dim:      rgba(255, 255, 255, 0.60);
  --dim-2:    rgba(255, 255, 255, 0.74);
  --dim-3:    rgba(255, 255, 255, 0.40);
  --line:     rgba(255, 255, 255, 0.14);
  --line-2:   rgba(255, 255, 255, 0.08);
  --line-int: rgba(255, 255, 255, 0.46);
  --fill:     #ececec;
  --track:    rgba(255, 255, 255, 0.11);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* `height: 100%` on html and body caps the scroll container at the
   viewport, so `position: sticky` on the header has nothing left to
   stick within and it detaches once the content runs past ~786px.
   Every long screen — the cost plan, the calendar, any project — lost
   its back control, nav, search and Checks button on the way down.
   min-height gives the page a floor without capping it. */
html, body { min-height: 100%; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: "Neue Haas Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.25;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.num { font-variant-numeric: tabular-nums; }
/* There was no global rule for this — only four scoped ones — so every
   .muted element outside a .tr, .ticket-foot or .alloc-row printed at
   full ink. On Markets that was 46 of 46: secondary text set louder than
   the headers above it, in a design where tone is the only thing
   carrying hierarchy. */
.muted { color: var(--dim); }

/* ---------- header ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: baseline;
  gap: 40px;
  padding: 18px var(--gutter);
  background: var(--paper);
  /* No line at rest — the nav floats clean on the white. The separator
     only appears once content has scrolled up behind the nav, where it
     is actually doing something. */
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--easing);
}
.topbar.scrolled { border-bottom-color: var(--line); }/* The brand at the foot: the home link, quietly placed. */
.foot-brand { font-weight: 500; white-space: nowrap; color: var(--ink); transition: opacity var(--dur) var(--easing); }
.foot-brand:hover { opacity: 0.6; }.foot-rights { color: var(--ink); }
/* position:relative + z-index:3 so .nav forms one stacking context
   above the backdrop; the dropdown panel sits below the buttons within
   it. See the grouped-navigation block for the full stacking contract. */
.nav { display: flex; gap: 18px; flex: 1 1 auto; position: relative; z-index: 3; }
.nav a {
  color: var(--dim);
  transition: color var(--dur) var(--easing);
}
.nav a:hover { color: var(--ink); }
.nav a.active { color: var(--ink); }
.search-btn { position: relative; z-index: 3; }   /* clickable above the backdrop */

/* The search pill is the only control on the right. The Checks indicator
   that used to sit beside it is gone: two objects of different grammar in
   one corner, one of which changed width as the book changed, is what
   made the bar feel unbalanced. */

/* ---------- layout ---------- */

.view { padding: 0 var(--gutter) 120px; max-width: 1400px; }
/* Every block of every screen runs this on every navigation, so its
   duration IS the app's perceived speed. At 0.5s the console felt
   sluggish even though routes render in under 8ms — the wait was
   entirely this. 0.24s still reads as a settle rather than a snap.
   Compositor-only properties (opacity, transform), so it never
   triggers layout. */
.view > * { animation: rise 0.24s var(--easing) both; }
@keyframes rise { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.disclaimer { color: var(--dim); padding: 22px var(--gutter) 60px; border-top: 1px solid var(--line-2); }

/* ---------- monument ---------- */

/* Less air at the top now the header carries only the nav — content
   starts higher. */
.monument { padding: 36px 0 40px; }
.monument .label {
  color: var(--dim);
  letter-spacing: 0.01em;
  font-size: 12px;
  margin-bottom: 18px;
}
.monument .figure {
  font-size: clamp(3.5rem, 11vw, 8.5rem);
  line-height: 0.9;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  margin-left: -0.03em;
}
.monument .sub { color: var(--dim); margin-top: 20px; font-size: 15px; }

/* ---------- ledger (stat strip) ---------- */

.ledger {
  display: grid;
  /* minmax(0,…) not bare 1fr: a grid track's default min is min-content,
     so one long figure would push the strip past its container. */
  grid-template-columns: repeat(var(--led-cols, 6), minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.ledger .cell { padding: 20px 0; }
.ledger .cell + .cell { padding-left: 22px; }
.ledger .k {
  display: block;
  color: var(--dim);
  letter-spacing: 0.01em;
  font-size: 11px;
  margin-bottom: 8px;
}
.ledger .v { font-size: 21px; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
/* These set grid-template-columns directly rather than redefining
   --led-cols: an inline custom property would still win, so overriding
   the variable here would be a silent no-op. */
@media (max-width: 820px) { .ledger { grid-template-columns: repeat(3, minmax(0, 1fr)); } .ledger .cell { border-top: 1px solid var(--line-2); } }
@media (max-width: 520px) { .ledger { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- block / section heads ---------- */

.block { padding-top: 56px; }
.block-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding-bottom: 14px;
}
.block-head h2 {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.block-head .note { color: var(--dim); font-size: 12.5px; }

/* ---------- tables ---------- */

.tbl { width: 100%; }
.tr {
  display: grid;
  align-items: baseline;
  gap: 20px;
  padding: 14px 0;
  border-top: 1px solid var(--line-2);
}
.tr:first-child { border-top: 1px solid var(--line); }
.tr.head { border-top: 1px solid var(--line); padding: 10px 0; }
.tr.head p { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; }
.tr.foot { border-top: 1px solid var(--line); }
.tr .r { text-align: right; font-variant-numeric: tabular-nums; }
.tr .em { font-size: 15px; }

/* allocation: name | bar | held/target | drift | value */
.alloc .tr { grid-template-columns: 1.4fr 1.9fr 0.9fr 0.6fr 1fr; }
.prop .tr  { grid-template-columns: 2fr 0.9fr 1fr 0.9fr 1fr 0.7fr; }
.wal .tr   { grid-template-columns: 1.6fr 1fr 1.4fr 0.9fr 1fr; }
.exch .tr  { grid-template-columns: 1.2fr 1.7fr 1fr 0.8fr; }
.acct .tr  { grid-template-columns: 2fr 0.9fr 1fr 0.7fr 0.9fr 1fr; }
.flow .tr  { grid-template-columns: 1fr 0.7fr 2.4fr 1fr; }
.docs .tr  { grid-template-columns: 2.4fr 1fr 1fr 0.7fr 0.7fr 0.9fr; }
.attr .tr  { grid-template-columns: 1.4fr 0.8fr 0.8fr 1.6fr 1fr; }
.ddn .tr   { grid-template-columns: 1.2fr 0.8fr 0.9fr 2fr; }
.liq .tr   { grid-template-columns: 1fr 1.4fr 1.6fr 0.9fr; }

/* rows that navigate */
a.tr { transition: background var(--dur) var(--easing); }
a.tr:hover { background: rgba(10, 10, 10, 0.025); }
a.tr:hover .em { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.ven .tr { grid-template-columns: 2fr 1fr 1fr 1fr 0.7fr 0.9fr; }
/* .hide-sm is written 63 times across the views but was only ever honoured
   inside .ven .tr and .blotter — so on every other table the columns it
   marks as droppable stayed put and pushed the page sideways (Treasury ran
   417px wide in a 375px viewport). One global rule, as the name implies. */
@media (max-width: 720px) {
  .hide-sm { display: none; }
  .alloc .tr { grid-template-columns: 1.2fr 1fr 1fr; }
  .alloc .tr .bar-cell { display: none; }
  .ven .tr { grid-template-columns: 1.6fr 0.9fr 0.9fr 0.7fr; }
}

/* thin monochrome bar (deployed vs target) */
.bar { position: relative; height: 3px; background: var(--track); align-self: center; }
.bar .fill { position: absolute; inset: 0 auto 0 0; background: var(--fill); }
.bar .tick { position: absolute; top: -3px; bottom: -3px; width: 1px; background: var(--ink); }

/* ---------- feed (news / activity) ---------- */

.feed .item {
  display: grid;
  grid-template-columns: 130px 120px 1fr;
  gap: 20px;
  align-items: baseline;
  padding: 16px 0;
  border-top: 1px solid var(--line-2);
}
.feed .item:first-child { border-top: 1px solid var(--line); }
.feed .date { color: var(--dim); font-variant-numeric: tabular-nums; }
.feed .tag { color: var(--dim); letter-spacing: 0.01em; font-size: 11.5px; }
@media (max-width: 620px) { .feed .item { grid-template-columns: 1fr; gap: 3px; } }

/* ---------- property ---------- */

.holding { padding-top: 56px; }
.holding-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding-bottom: 16px; border-bottom: 1px solid var(--line);
}
.holding-head h2 { font-size: 26px; font-weight: 500; letter-spacing: -0.02em; }
.holding-head .status { color: var(--dim); }
.deflist .row {
  display: grid; grid-template-columns: 200px 1fr; gap: 20px;
  padding: 13px 0; border-top: 1px solid var(--line-2);
}
.deflist .row .dt { color: var(--dim); }

/* program stepper — editorial */
.program { display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px; padding: 26px 0 6px; }
.pstep .pbar { height: 2px; background: var(--track); position: relative; margin-bottom: 12px; }
.pstep .pbar .pf { position: absolute; inset: 0 auto 0 0; background: var(--fill); }
.pstep .pname { font-size: 14px; }
.pstep.next .pname { color: var(--dim); }
.pstep .pdetail { color: var(--dim); font-size: 12px; margin-top: 3px; }
@media (max-width: 620px) { .program { grid-template-columns: 1fr; } }

/* budget waterfall — monochrome stepped */
.budget { padding-top: 8px; }
.split-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; padding-top: 34px; }
@media (max-width: 720px) { .split-grid { grid-template-columns: 1fr; gap: 34px; } }
/* ---------- responsive header ----------
   Stays one row on small screens too — the nav scrolls horizontally
   rather than wrapping to its own line. */
@media (max-width: 720px) {
  .topbar { gap: 16px; }
  .nav { gap: 16px; }
}

/* ============================================================
   TRADING LAYER — charts, buttons, positions, ticket, blotter
   ============================================================ */

/* ---------- chart ---------- */

.chart-block { padding-bottom: 26px; }
.chart-read { display: flex; align-items: baseline; gap: 16px; padding: 4px 0 14px; }
.chart-read .cr-val { font-size: 21px; letter-spacing: -0.02em; }
.chart-read .cr-delta { color: var(--dim-2); }
.chart-read .cr-date { color: var(--dim); margin-left: auto; }
.chart-stage { position: relative; cursor: crosshair; }
.chart-svg { display: block; width: 100%; height: 100%; }
.chart-cross .cc-line { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(10,10,10,0.3); pointer-events: none; }
.chart-cross .cc-dot { position: absolute; width: 7px; height: 7px; border-radius: 50%; background: var(--ink); transform: translate(-3px, -3px); pointer-events: none; }
.chart-min, .chart-max { position: absolute; right: 0; color: var(--dim); font-size: 11.5px; pointer-events: none; }
.chart-max { top: -2px; }
.chart-min { bottom: -2px; }

/* ---------- buttons ---------- */

.btn {
  font-size: 13px;
  padding: 9px 18px;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  transition: background var(--dur) var(--easing), color var(--dur) var(--easing), opacity var(--dur) var(--easing);
}
.btn:hover { background: var(--ink); color: var(--paper); }
.btn.primary { background: var(--ink); color: var(--paper); }
.btn.primary:hover { opacity: 0.82; }
.btn:disabled { opacity: 0.3; pointer-events: none; }

.ranges { display: flex; gap: 4px; padding-top: 12px; }
.range-btn {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
  padding: 5px 11px;
  border: 1px solid transparent;
  transition: color var(--dur) var(--easing), border-color var(--dur) var(--easing);
}
.range-btn:hover { color: var(--ink); }
.range-btn.active { color: var(--ink); border-color: var(--ink); }

/* ---------- positions (ranked, skyscreamer-style, editorial) ---------- */

.pos-list { }
.pos-row {
  display: grid;
  grid-template-columns: 40px 1.9fr 88px 1.1fr 0.7fr 0.9fr 0.6fr;
  gap: 20px;
  align-items: center;
  padding: 16px 0;
  border-top: 1px solid var(--line-2);
  transition: opacity var(--dur) var(--easing);
}
.pos-row:first-child { border-top: 1px solid var(--line); }
.pos-row.head { padding: 10px 0; border-top: 1px solid var(--line); }
.pos-row.head p { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; }
a.pos-row:hover .em { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.pos-row .r { text-align: right; }
.pos-row .pr-w { font-size: 15px; }
.pos-row .pr-bar .bar { height: 3px; }
.chips { display: flex; gap: 6px; margin-top: 6px; }
.chip {
  font-size: 10.5px;
  letter-spacing: 0.01em;
  color: var(--dim-2);
  border: 1px solid var(--line);
  padding: 2px 7px;
}
@media (max-width: 720px) {
  .pos-row { grid-template-columns: 34px 1.6fr 0.9fr 0.7fr; gap: 12px; }
  .pos-row .pr-bar, .pos-row .pr-day, .pos-row .pr-spark { display: none; }
}

/* ---------- crumbs + holding actions ---------- */
.actions { display: flex; gap: 10px; }

/* ---------- ticket ---------- */

.ticket { border: 1px solid var(--ink); padding: 22px; margin-top: 30px; }
.ticket-head { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 18px; }
.ticket-head .t-title { font-size: 15px; }
.ticket-head .t-close { color: var(--dim); font-size: 13px; }
.ticket-head .t-close:hover { color: var(--ink); }
.ticket-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 26px; padding-bottom: 20px; }
@media (max-width: 640px) { .ticket-grid { grid-template-columns: 1fr; } }
.t-field .k { display: block; color: var(--dim); letter-spacing: 0.01em; font-size: 11px; margin-bottom: 8px; }
.t-input {
  font: inherit;
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  border: 0;
  border-bottom: 1px solid var(--ink);
  padding: 4px 0 6px;
  width: 100%;
  outline: none;
  background: transparent;
  border-radius: 0;
}
.t-input::placeholder { color: var(--dim); }
.t-est { font-size: 17px; display: block; padding-top: 4px; }
.t-field > span:not(.k) { display: block; padding-top: 4px; }
.ticket-foot { display: flex; justify-content: space-between; align-items: center; gap: 24px; border-top: 1px solid var(--line-2); padding-top: 18px; }
.ticket-foot .muted { max-width: 40em; }

/* ---------- blotter ---------- */

.blotter .b-row {
  display: grid;
  grid-template-columns: 58px 2fr 0.9fr 0.9fr 1fr 1.2fr;
  gap: 20px;
  align-items: baseline;
  padding: 15px 0;
  border-top: 1px solid var(--line-2);
}
.blotter .b-row:first-child { border-top: 1px solid var(--line); }
.blotter .b-row.session { background: rgba(10,10,10,0.025); }
.side {
  font-size: 11px;
  letter-spacing: 0.01em;
  text-align: center;
  padding: 3px 0;
  align-self: center;
}
.side.buy { background: var(--ink); color: var(--paper); }
.side.sell { border: 1px solid var(--ink); color: var(--ink); }
.b-what .muted { margin-top: 3px; font-size: 12.5px; }
.b-when { text-align: right; }
.b-when .b-status { color: var(--dim); font-size: 11.5px; letter-spacing: 0.01em; margin-top: 3px; }
.blotter .r { text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 720px) {
  .blotter .b-row { grid-template-columns: 52px 1.6fr 1fr; }
  .b-when { display: none; }
}

/* ============================================================
   THE MODULES — dashboard, exposure, property, analytics
   Same rules throughout: no radius, hairline structure, the
   grey ramp where a second colour would normally be reached for.
   ============================================================ */

/* ---------- small shared type ---------- */

.sub-line  { margin-top: 3px; font-size: 12.5px; }
.prose     { max-width: 46em; line-height: 1.45; }
.foot-note { margin-top: 18px; color: var(--dim); max-width: 52em; line-height: 1.45; }
.more      { color: var(--dim); transition: color var(--dur) var(--easing); }
.more:hover { color: var(--ink); }
.spark     { width: 100%; height: 28px; display: block; color: var(--ink); opacity: 0.55; }
.chip.flag { border-color: var(--ink); color: var(--ink); }

.search-btn {
  display: flex; align-items: center; gap: 10px;
  color: var(--dim); padding: 6px 12px;
  border: 1px solid var(--line);
  transition: border-color var(--dur) var(--easing), color var(--dur) var(--easing);
}
.search-btn:hover { border-color: var(--ink); color: var(--ink); }
.search-btn kbd {
  font: inherit; font-size: 11px; color: var(--dim);
  border: 1px solid var(--line); padding: 1px 5px;
}
.theme-btn {
  position: relative; z-index: 3;      /* clickable above the backdrop */
  margin-left: auto;                    /* pushes theme + search to the right together */
  display: inline-flex; align-items: center; justify-content: center;
  width: 33px; height: 33px; padding: 0;
  color: var(--dim);
  border: 0; background: none;
  transition: color var(--dur) var(--easing);
}
.theme-btn:hover { color: var(--ink); }
.theme-btn svg { display: block; }
/* the filled half of the disc rotates so the icon reads as the
   theme you would switch TO — a nod, not a literal state readout */
.theme-btn svg path { transition: transform var(--dur) var(--easing); transform-origin: 10px 10px; }
:root[data-theme="dark"] .theme-btn svg path { transform: rotate(180deg); }
.disclaimer { display: flex; justify-content: flex-start; align-items: baseline; gap: 0.4em; flex-wrap: wrap; }
/* ---------- treemap ---------- */

.treemap { display: flex; gap: 2px; height: 300px; }
.tm-left, .tm-right { display: flex; flex-direction: column; gap: 2px; }
.tm-cell {
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 16px; min-height: 0; overflow: hidden;
  transition: opacity var(--dur) var(--easing);
}
.tm-cell:hover { opacity: 0.82; }

/* Ramp steps for the treemap (and the geography bars). Light mode keeps the
   site's grey ramp with dark text on the pale tiles. Dark mode uses an
   ascending dark-grey ramp with white text throughout — the tiles stay
   distinguishable, but no figure ever sits on a white background. */
.tm-r0 { background: #0a0a0a; color: #fff; }
.tm-r1 { background: #8f8d8a; color: #fff; }
.tm-r2 { background: #b8b6b2; color: #0a0a0a; }
.tm-r3 { background: #e0deda; color: #0a0a0a; }
.tm-r4 { background: #f0efec; color: #0a0a0a; }
:root[data-theme="dark"] .tm-r0 { background: #000000; color: #fff; }
:root[data-theme="dark"] .tm-r1 { background: #1c1d1f; color: #fff; }
:root[data-theme="dark"] .tm-r2 { background: #26282a; color: #fff; }
:root[data-theme="dark"] .tm-r3 { background: #313335; color: #fff; }
:root[data-theme="dark"] .tm-r4 { background: #3c3e40; color: #fff; }

.tm-pct { font-size: 22px; letter-spacing: -0.02em; line-height: 1; }
.tm-name { margin-top: 6px; font-size: 13px; }
.tm-val { font-size: 12px; opacity: 0.62; margin-top: 2px; }
.tm-right .tm-cell { padding: 12px 14px; }
.tm-right .tm-pct { font-size: 16px; }
@media (max-width: 720px) {
  .treemap { height: 240px; }
  .tm-pct { font-size: 16px; } .tm-right .tm-pct { font-size: 13px; }
  .tm-name, .tm-val { font-size: 11px; }
}

/* ---------- horizontal proportion bars ---------- */

.hbars { padding-top: 4px; }
.hb-row {
  display: grid; grid-template-columns: 1.1fr 1.6fr auto;
  gap: 16px; align-items: center;
  padding: 11px 0; border-top: 1px solid var(--line-2);
}
.hb-row:first-child { border-top: 1px solid var(--line); }
.hb-track { height: 3px; background: var(--track); position: relative; }
.hb-fill { position: absolute; inset: 0 auto 0 0; }
.hb-val { font-variant-numeric: tabular-nums; text-align: right; }
.hb-sub { grid-column: 1 / -1; color: var(--dim); font-size: 12px; margin-top: -4px; }

/* ---------- diverging bars (monthly / annual) ---------- */

.bars-div {
  display: flex; gap: 6px; align-items: flex-end;
  position: relative; padding-bottom: 4px;
}
.bd-zero { position: absolute; left: 0; right: 0; height: 1px; background: var(--line); }
.bd-col { flex: 1; min-width: 0; text-align: center; }
.bd-stage { position: relative; }
.bd-bar { position: absolute; left: 15%; right: 15%; background: var(--ink); }
.bd-bar.down { background: var(--track); border-top: 1px solid var(--ink); }
.bd-col.partial .bd-bar { background: repeating-linear-gradient(45deg, var(--ink) 0 2px, var(--paper) 2px 4px); }
.bd-lab { color: var(--dim); font-size: 11px; margin-top: 8px; white-space: nowrap; }
.bd-val { font-size: 11.5px; margin-top: 2px; }
@media (max-width: 720px) { .bd-lab, .bd-val { font-size: 9.5px; } .bars-div { gap: 3px; } }

/* ---------- attention queue ---------- */

.att-row {
  display: grid; grid-template-columns: 10px 1fr auto auto;
  gap: 18px; align-items: baseline;
  padding: 17px 0; border-top: 1px solid var(--line-2);
  transition: background var(--dur) var(--easing);
}
.att-row:first-child { border-top: 1px solid var(--line); }
.att-row:hover { background: rgba(10, 10, 10, 0.025); }
.att-pri { width: 7px; height: 7px; align-self: center; background: var(--ink); }
.att-pri.med { background: var(--dim); }
.att-pri.low { background: none; border: 1px solid var(--dim); }
.att-title { font-size: 15px; }
.att-row:hover .att-title { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.att-detail { color: var(--dim); margin-top: 4px; max-width: 56em; line-height: 1.4; }
.att-tag { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; }
.att-due { color: var(--dim); white-space: nowrap; }
@media (max-width: 720px) {
  .att-row { grid-template-columns: 10px 1fr; gap: 12px; }
  .att-tag, .att-due { grid-column: 2; font-size: 11px; }
}

/* ---------- insights + events ---------- */

.ins { padding: 16px 0; border-top: 1px solid var(--line-2); }
.ins:first-child { border-top: 1px solid var(--line); }
.ins-kind { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; margin-bottom: 7px; }
.ins-text { line-height: 1.45; max-width: 48em; }

.ev-row {
  display: grid; grid-template-columns: 105px 100px 1fr; gap: 16px; align-items: baseline;
  padding: 13px 0; border-top: 1px solid var(--line-2);
}
.ev-row:first-child { border-top: 1px solid var(--line); }
.ev-date { color: var(--dim); }
.ev-tag { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; }
@media (max-width: 620px) { .ev-row { grid-template-columns: 1fr; gap: 2px; } }

/* ---------- private position notes ---------- */

.pn-row { display: grid; grid-template-columns: 200px 1fr; gap: 20px; padding: 14px 0; border-top: 1px solid var(--line-2); }
.pn-row:first-child { border-top: 1px solid var(--line); }
.pn-note { color: var(--dim); line-height: 1.45; max-width: 52em; }
@media (max-width: 620px) { .pn-row { grid-template-columns: 1fr; gap: 4px; } }

/* ---------- project cards ---------- */

.proj-grid { display: grid; grid-template-columns: 1fr; gap: 2px; }
.proj-card {
  border: 1px solid var(--line); padding: 24px;
  transition: border-color var(--dur) var(--easing), background var(--dur) var(--easing);
}
.proj-card:hover { border-color: var(--ink); background: rgba(10, 10, 10, 0.015); }
.pc-head { display: flex; justify-content: space-between; align-items: baseline; gap: 20px; }
.pc-name { font-size: 20px; letter-spacing: -0.02em; }
.pc-region { font-size: 12.5px; margin-top: 3px; }
.pc-summary { color: var(--dim-2); margin-top: 14px; max-width: 52em; line-height: 1.45; }
.pc-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--line-2); }
.pc-stats .k { display: block; color: var(--dim); letter-spacing: 0.01em; font-size: 11px; margin-bottom: 7px; }
.pc-stats .v { font-size: 19px; letter-spacing: -0.02em; }
.pc-prog { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; margin-top: 22px; }
@media (max-width: 720px) { .pc-stats { grid-template-columns: 1fr 1fr; } .pc-prog { grid-template-columns: 1fr 1fr; } }

/* ---------- feasibility: scenarios + inputs ---------- */

.scen-row { display: flex; gap: 2px; flex-wrap: wrap; padding-bottom: 26px; }
.scen-btn {
  text-align: left; padding: 13px 18px; border: 1px solid var(--line);
  transition: border-color var(--dur) var(--easing), background var(--dur) var(--easing);
}
.scen-btn:hover { border-color: var(--dim); }
.scen-btn.active { border-color: var(--ink); background: var(--ink); color: var(--paper); }
.sb-name { display: block; font-size: 14px; }
.sb-note { display: block; font-size: 12px; opacity: 0.55; margin-top: 3px; }

.feas-inputs { display: grid; grid-template-columns: repeat(5, 1fr); gap: 22px 26px; }
@media (max-width: 980px) { .feas-inputs { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .feas-inputs { grid-template-columns: 1fr 1fr; } }
.fi .k { display: block; color: var(--dim); letter-spacing: 0.01em; font-size: 11px; margin-bottom: 8px; }
.fi-input {
  font: inherit; font-size: 16px; font-variant-numeric: tabular-nums;
  border: 0; border-bottom: 1px solid var(--ink); border-radius: 0;
  padding: 4px 0 6px; width: 100%; outline: none; background: transparent;
  transition: border-color var(--dur) var(--easing);
}
.fi-input:focus { border-bottom-width: 2px; padding-bottom: 5px; }

/* ---------- budget check ---------- */

.bcheck {
  display: grid; grid-template-columns: 1.1fr 1.6fr auto; gap: 40px; align-items: center;
  border: 1px solid var(--ink); padding: 26px;
}
.bcheck.over { border-style: dashed; }
.bc-fig { font-size: 34px; letter-spacing: -0.03em; line-height: 1; }
.bc-sub { color: var(--dim); margin-top: 9px; font-size: 12.5px; }
.bcm-track { position: relative; height: 8px; background: var(--track); }
.bcm-fill { position: absolute; inset: 0 auto 0 0; background: var(--ink); }
.bcheck.over .bcm-fill { background: repeating-linear-gradient(45deg, var(--ink) 0 3px, var(--paper) 3px 6px); }
.bcm-cap { position: absolute; right: 0; top: -4px; bottom: -4px; width: 1px; background: var(--ink); }
.bcm-keys { display: flex; justify-content: space-between; margin-top: 9px; color: var(--dim); font-size: 12px; }
.bc-var { text-align: right; }
.bcv-k { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; }
.bcv-v { font-size: 21px; letter-spacing: -0.02em; margin-top: 7px; }
@media (max-width: 820px) { .bcheck { grid-template-columns: 1fr; gap: 22px; } .bc-var { text-align: left; } }

/* ---------- residual land value ---------- */

.rlv { display: grid; grid-template-columns: 1.2fr 1fr; gap: 48px; border-top: 1px solid var(--line); padding-top: 26px; }
.rlv-fig { font-size: clamp(2.4rem, 6vw, 4rem); letter-spacing: -0.04em; line-height: 0.95; }
.rlv-sub { color: var(--dim); margin-top: 14px; max-width: 26em; line-height: 1.4; }
.rlv-line { display: flex; justify-content: space-between; gap: 20px; padding: 12px 0; border-top: 1px solid var(--line-2); }
.rlv-line:first-child { border-top: none; }
.rlv-line.strong { border-top: 1px solid var(--ink); font-size: 17px; }
.rlv-line .fk { color: var(--dim); }
.rlv-verdict { margin-top: 16px; line-height: 1.45; }
.rlv-verdict.no { border-left: 2px solid var(--ink); padding-left: 12px; }
.rlv-verdict.ok { color: var(--dim-2); }
@media (max-width: 820px) { .rlv { grid-template-columns: 1fr; gap: 30px; } }

/* ---------- feasibility line items ---------- */

.flines { padding-top: 2px; }
.fr { display: flex; justify-content: space-between; gap: 20px; padding: 11px 0; border-top: 1px solid var(--line-2); }
.fr:first-child { border-top: 1px solid var(--line); }
.fr .fk { color: var(--dim-2); }
.fr.total { border-top: 1px solid var(--ink); font-size: 16px; }
.fr.total .fk { color: var(--ink); }

/* ---------- waterfall ---------- */

.wf { display: flex; gap: 6px; align-items: flex-start; padding-top: 8px; }
.wf-col { flex: 1; min-width: 0; text-align: center; }
.wf-stage { position: relative; }
.wf-bar { position: absolute; left: 12%; right: 12%; background: var(--ink); }
.wf-bar.neg { background: var(--track); border: 1px solid rgba(10, 10, 10, 0.28); }
.wf-bar.total { background: var(--ink); }
.wf-lab { color: var(--dim); font-size: 11px; margin-top: 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wf-val { font-size: 11.5px; margin-top: 2px; }
@media (max-width: 820px) { .wf-lab, .wf-val { font-size: 9px; } .wf { gap: 3px; } }

/* ---------- cash flow ---------- */

.cf-wrap { width: 100%; }
.cf-svg { display: block; width: 100%; height: 210px; }

/* ---------- sensitivity grid ---------- */

.sens-grid { display: flex; flex-direction: column; gap: 2px; }
.sg-row { display: grid; grid-template-columns: 120px repeat(var(--sg-cols), 1fr); gap: 2px; }
.sg-cell { padding: 14px 10px; text-align: center; font-size: 13px; }
.sg-corner, .sg-head, .sg-side {
  color: var(--dim); letter-spacing: 0.01em; font-size: 11px;
  display: flex; align-items: center; justify-content: center;
}
.sg-corner, .sg-side { justify-content: flex-start; }
.sg-val.base { outline: 2px solid var(--ink); outline-offset: -2px; }
@media (max-width: 720px) {
  .sg-row { grid-template-columns: 62px repeat(var(--sg-cols), 1fr); }
  .sg-cell { padding: 10px 2px; font-size: 11px; }
}

/* ---------- cash ladder ---------- */

.ladder { display: flex; gap: 2px; align-items: flex-end; }
.lad-seg { min-width: 0; }
.lad-bar { height: 46px; background: var(--ink); }
.lad-k { color: var(--dim); font-size: 11px; margin-top: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lad-v { font-size: 13px; margin-top: 3px; }

/* ---------- analytics ---------- */

.an-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; }
@media (max-width: 900px) { .an-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .an-grid { grid-template-columns: 1fr; } }
.an-card { border: 1px solid var(--line); padding: 22px; }
.an-k { color: var(--dim); letter-spacing: 0.01em; font-size: 11px; }
.an-v { font-size: 38px; letter-spacing: -0.03em; line-height: 1; margin-top: 14px; }
.an-d { color: var(--dim); font-size: 12px; margin-top: 9px; }
.an-detail { color: var(--dim-2); font-size: 12.5px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-2); line-height: 1.4; }

.risk-row {
  display: grid; grid-template-columns: 1.2fr 1.4fr auto; gap: 20px; align-items: center;
  padding: 15px 0; border-top: 1px solid var(--line-2);
}
.risk-row:first-child { border-top: 1px solid var(--line); }
.rbar { height: 3px; background: var(--track); position: relative; }
.rfill { position: absolute; inset: 0 auto 0 0; background: var(--ink); }
.rv { font-size: 17px; font-variant-numeric: tabular-nums; text-align: right; }
.rn { grid-column: 1 / -1; color: var(--dim); font-size: 12px; margin-top: -5px; }

/* ---------- filters ---------- */

.filters { display: flex; gap: 4px; flex-wrap: wrap; padding-top: 8px; }
.filter-btn {
  font-size: 12.5px; color: var(--dim); padding: 6px 13px;
  border: 1px solid transparent;
  transition: color var(--dur) var(--easing), border-color var(--dur) var(--easing);
}
.filter-btn:hover { color: var(--ink); }
.filter-btn.active { color: var(--ink); border-color: var(--ink); }

/* ============================================================
   COMMAND PALETTE + SHORTCUTS
   The site's "layer on top" language: a black panel, same
   easing and duration as the gate and the mobile menu.
   ============================================================ */

.palette, .sheet {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(10, 10, 10, 0.32);
  display: flex; justify-content: center;
  visibility: hidden; opacity: 0;
  transition: opacity var(--dur) var(--easing), visibility var(--dur);
}
.palette { align-items: flex-start; padding: 12vh 20px 20px; }
.sheet { align-items: center; padding: 20px; }
.palette.open, .sheet.open { visibility: visible; opacity: 1; }

.pal-panel, .sheet-panel {
  background: #0a0a0a; color: #fff;
  width: 100%; max-width: 640px;
  display: flex; flex-direction: column;
  max-height: 72vh;
  transform: translateY(-6px);
  transition: transform var(--dur) var(--easing);
}
.palette.open .pal-panel, .sheet.open .sheet-panel { transform: none; }

.pal-field { display: flex; align-items: center; gap: 12px; padding: 18px 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.14); }
.pal-caret { opacity: 0.4; }
.pal-input {
  font: inherit; font-size: 16px; flex: 1; min-width: 0;
  background: transparent; border: 0; outline: none; color: #fff; border-radius: 0;
}
.pal-input::placeholder { color: rgba(255, 255, 255, 0.38); }
.pal-esc { font-size: 11px; color: rgba(255, 255, 255, 0.38); border: 1px solid rgba(255, 255, 255, 0.2); padding: 2px 6px; }

.pal-results { overflow-y: auto; flex: 1; padding: 8px 0; scrollbar-width: none; }
.pal-results::-webkit-scrollbar { display: none; }
.pal-group {
  color: rgba(255, 255, 255, 0.36); letter-spacing: 0.01em;
  font-size: 10.5px; padding: 12px 20px 6px;
}
.pal-row {
  display: flex; align-items: baseline; gap: 14px; padding: 10px 20px;
  color: rgba(255, 255, 255, 0.62);
}
.pal-row:hover, .pal-row.on { background: rgba(255, 255, 255, 0.09); color: #fff; }
.pal-title { flex: 0 1 auto; }
.pal-sub { font-size: 12px; opacity: 0.5; margin-left: auto; text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pal-empty { padding: 26px 20px; color: rgba(255, 255, 255, 0.42); }
.pal-foot {
  display: flex; gap: 18px; align-items: center;
  padding: 12px 20px; border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: 11.5px; color: rgba(255, 255, 255, 0.38);
}
.pal-foot b { color: rgba(255, 255, 255, 0.7); font-weight: 500; }
.pal-count { margin-left: auto; }
@media (max-width: 620px) { .pal-sub { display: none; } .pal-foot span:nth-child(3) { display: none; } }

.sheet-panel { max-width: 460px; }
.sheet-head { display: flex; justify-content: space-between; align-items: baseline; padding: 18px 20px; border-bottom: 1px solid rgba(255, 255, 255, 0.14); }
.sheet-close { color: rgba(255, 255, 255, 0.5); font-size: 13px; }
.sheet-close:hover { color: #fff; }
.sheet-body { padding: 8px 0 14px; overflow-y: auto; }
.sc-row { display: flex; align-items: center; gap: 16px; padding: 9px 20px; }
.sc-keys { display: flex; gap: 4px; flex: 0 0 92px; }
.sc-keys kbd {
  font: inherit; font-size: 11px; min-width: 22px; text-align: center;
  border: 1px solid rgba(255, 255, 255, 0.22); padding: 2px 6px; color: #fff;
}
.sc-label { color: rgba(255, 255, 255, 0.62); }


/* The Checks drawer was deleted — the audit answers inside the Agent's
   thread now (see .chk-lead below), so there is no panel to open. */

/* ============================================================
   FEASIBILITY WORKSPACE — tabs, cost plan, land valuation
   ============================================================ */

.ftabs {
  display: flex; gap: 26px; margin-top: 56px;
  border-bottom: 1px solid var(--line);
}
.ftab {
  padding: 0 0 13px; color: var(--dim); position: relative;
  transition: color var(--dur) var(--easing);
}
.ftab:hover { color: var(--ink); }
.ftab.on { color: var(--ink); }
.ftab.on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 1px; background: var(--ink);
}
@media (max-width: 720px) {
  .ftabs { gap: 18px; overflow-x: auto; scrollbar-width: none; }
  .ftabs::-webkit-scrollbar { display: none; }
  .ftab { white-space: nowrap; font-size: 13px; }
}

/* ---------- cost plan ---------- */

.cost-plan { }
.cp-group { padding-top: 30px; }
.cp-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  padding-bottom: 10px; border-bottom: 1px solid var(--ink);
}
.cp-gname { font-size: 15px; }
.cp-gnote { color: var(--dim); font-size: 12px; margin-top: 3px; }
.cp-gsub { font-size: 17px; font-variant-numeric: tabular-nums; }
.cp-row {
  display: grid; grid-template-columns: 1.7fr 1.5fr 110px 1fr 62px;
  gap: 18px; align-items: baseline;
  padding: 11px 0; border-bottom: 1px solid var(--line-2);
}
.cp-name { }
.cp-basis { color: var(--dim); font-size: 12px; }
.cp-input {
  font: inherit; font-size: 13.5px; font-variant-numeric: tabular-nums;
  text-align: right; width: 100%; padding: 3px 0;
  background: transparent; color: var(--ink); border: 0; border-radius: 0;
  border-bottom: 1px solid var(--line); outline: none;
  transition: border-color var(--dur) var(--easing);
}
.cp-input:hover  { border-bottom-color: var(--dim); }
.cp-input:focus  { border-bottom-color: var(--ink); }
.cp-amt { text-align: right; font-variant-numeric: tabular-nums; }
.cp-pct { text-align: right; font-size: 12px; }
.cp-total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--ink);
  font-size: 21px; letter-spacing: -0.02em;
}
@media (max-width: 820px) {
  .cp-row { grid-template-columns: 1.4fr 92px 1fr; gap: 12px; }
  .cp-basis, .cp-pct { display: none; }
}

/* ---------- benchmark bar ---------- */

.bench { padding-top: 6px; }
.bench-track { position: relative; height: 8px; background: var(--track); }
.bench-band { position: absolute; top: 0; bottom: 0; background: rgba(10, 10, 10, 0.28); }
.bench-mark { position: absolute; top: -5px; bottom: -5px; width: 2px; background: var(--ink); }
.bench-keys { display: flex; justify-content: space-between; margin-top: 9px; color: var(--dim); font-size: 11.5px; }
.bench-verdict { margin-top: 16px; line-height: 1.45; max-width: 48em; }

/* ---------- land valuation ---------- */

.lv-row {
  display: grid; grid-template-columns: 1.5fr 1.6fr 1fr 54px;
  gap: 18px; align-items: center;
  padding: 15px 0; border-top: 1px solid var(--line-2);
}
.lv-row:first-child { border-top: 1px solid var(--line); }
.lv-track { height: 3px; background: var(--track); position: relative; }
.lv-fill { position: absolute; inset: 0 auto 0 0; background: var(--ink); }
.lv-val { text-align: right; font-size: 16px; font-variant-numeric: tabular-nums; }
.lv-wt { text-align: right; font-size: 12px; }
.lv-note { grid-column: 1 / -1; color: var(--dim); font-size: 12px; margin-top: -6px; }
@media (max-width: 720px) {
  .lv-row { grid-template-columns: 1.4fr 1fr 46px; }
  .lv-track { display: none; }
}

.comps .tr { grid-template-columns: 2fr 0.9fr 1fr 0.7fr 1fr 0.7fr 1fr; }
.adjm .tr  { grid-template-columns: 1.6fr repeat(6, 1fr); }
@media (max-width: 820px) {
  .comps .tr { grid-template-columns: 1.6fr 1fr 0.9fr 1fr; }
  .adjm .tr  { grid-template-columns: 1.2fr repeat(6, 1fr); font-size: 12px; }
}
/* ============================================================
   ASSISTANT — checks + ask
   ============================================================ */

.chk-head { display: flex; justify-content: space-between; align-items: baseline; padding-bottom: 14px; border-bottom: 1px solid var(--ink); }
.chk-scope { font-size: 15px; }
.chk-count { color: var(--dim); font-size: 12.5px; }
.chk-clean { color: var(--dim-2); line-height: 1.5; padding-top: 18px; }
.chk {
  display: grid; grid-template-columns: 10px 1fr; gap: 14px;
  padding: 16px 0; border-bottom: 1px solid var(--line-2);
}
.chk-sev { width: 7px; height: 7px; margin-top: 6px; background: var(--ink); }
.chk.med .chk-sev { background: var(--dim); }
.chk.low .chk-sev { background: none; border: 1px solid var(--dim); }
.chk-title { line-height: 1.35; }
.chk-detail { color: var(--dim); margin-top: 6px; line-height: 1.45; font-size: 13px; }

/* ---- could not be evaluated ----
   Ranked above "high", because a check that did not run is a worse
   condition than one that ran and failed. Monochrome, so the weight
   has to come from structure rather than colour: a solid rule down
   the edge and full-ink text where the other rows go dim. */
.chk.critical { border-left: 2px solid var(--ink); padding-left: 12px; margin-left: -14px; }
.chk.critical .chk-sev { background: var(--ink); box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px var(--ink); }
.chk.critical .chk-detail { color: var(--ink); }
.chk-count.incomplete { color: var(--ink); }
.chk-warn {
  border-left: 2px solid var(--ink); padding: 2px 0 2px 12px;
  margin: 18px 0 4px; line-height: 1.5; font-size: 13px; color: var(--ink);
}

/* ============================================================
   ASK — a conversation surface

   The interaction model of a chat client (centred column, turns,
   a docked composer that grows, attachments, streaming) rendered
   in this app's language: monochrome, hairlines, Helvetica 500.
   The one concession to chat convention is a soft radius on the
   composer and the operator's own turn — those two read as "a
   thing you type into" and "a thing you said", and squares do not.
   ============================================================ */
.ask-shell {
  max-width: 46em; margin: 0 auto;
  min-height: calc(100vh - 260px);
  display: flex; flex-direction: column;
}
/* The page carries no visible title — the nav says Agent and lights it.
   Kept for screen readers so the view still announces itself. */
.ask-vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.ask-head { display: flex; justify-content: flex-end; min-height: 0; }
.ask-new {
  background: none; border: 0; font: inherit; font-size: 13px; cursor: pointer;
  color: var(--dim); transition: color var(--dur) var(--easing);
}
.ask-new:hover { color: var(--ink); }
.ask-new[hidden] { display: none; }

/* the thread */
.ask-thread { flex: 1; padding: 18px 0 26px; }
.msg { display: flex; padding: 9px 0; }
.msg.user { justify-content: flex-end; }
.msg.user .msg-body {
  background: rgba(10, 10, 10, 0.055);
  padding: 12px 16px; border-radius: 14px;
  max-width: 84%; line-height: 1.5; white-space: pre-wrap;
}
.msg.bot .msg-body {
  color: var(--ink); line-height: 1.62; white-space: pre-wrap;
  /* Takes the whole row rather than shrink-wrapping: a shrink-wrapped
     flex item gives any grid inside it (the audit's .chk rows) no width
     to distribute, collapsing its 1fr column to min-content. */
  flex: 1 1 100%; min-width: 0; max-width: 100%;
  padding: 4px 0 10px;
}
.msg.bot.thinking .msg-body { color: var(--dim); }
/* The audit's own answer, rendered inside a turn as markup rather than
   streamed text — so it opts out of pre-wrap and reuses the .chk rows. */
.msg.bot.rich .msg-body { white-space: normal; }
.msg.bot .chk-lead { line-height: 1.6; }
.msg.bot .chk:first-of-type { border-top: 1px solid var(--line); margin-top: 14px; }
.msg.bot .chk-cov { padding-top: 14px; }
.msg.bot.err .msg-body { color: var(--ink); border-left: 2px solid var(--ink); padding-left: 13px; }

/* Empty posture: the greeting, the chips and the composer read as one
   centred group rather than a heading stranded at the top of the page
   with the input a screen away. */
.ask-shell.is-empty { justify-content: center; }
.ask-shell.is-empty .ask-thread { flex: 0 0 auto; padding-bottom: 20px; }
.ask-shell.is-empty .ask-dock { position: static; }

.ask-empty { padding: 0; }
.ask-greet { font-size: 24px; letter-spacing: -0.02em; padding-bottom: 22px; }
.ask-suggest { display: flex; flex-wrap: wrap; gap: 8px; }
.ask-suggest[hidden] { display: none; }
.ask-chip {
  text-align: left; padding: 10px 15px; border: 1px solid var(--line);
  font: inherit; font-size: 13.5px; color: var(--dim); background: none; cursor: pointer;
  border-radius: 999px;
  transition: border-color var(--dur) var(--easing), color var(--dur) var(--easing);
}
.ask-chip:hover { border-color: var(--ink); color: var(--ink); }

/* the dock: composer + attachments, pinned to the bottom of the view */
.ask-dock { position: sticky; bottom: 18px; background: var(--paper); padding-top: 10px; }
.ask-attached { display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 9px; }
.ask-attached[hidden] { display: none; }
.doc-chip {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 6px 5px 13px; font-size: 12.5px; color: var(--dim-2);
  max-width: 24em;
}
.doc-chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-x {
  background: none; border: 0; cursor: pointer; font: inherit; line-height: 1;
  color: var(--dim); padding: 0 4px; transition: color var(--dur) var(--easing);
}
.doc-x:hover { color: var(--ink); }

.ask-composer {
  border: 1px solid var(--line-int); border-radius: 16px;
  padding: 12px 14px 10px; background: var(--paper);
  transition: border-color var(--dur) var(--easing);
}
/* Nothing goes black while you type. Two things used to: this border
   turned full ink on focus-within, and the global 2px ink focus ring
   drew on the textarea inside it — a black box inside a black box.
   The border is now static and the caret is the affordance, which is
   what a text field's focus indicator should be anyway. */
.ask-field:focus-visible, .ask-field:focus { outline: none; }
/* Same for the picker's search field — the panel's own edge is enough. */
.doc-search:focus-visible, .doc-search:focus { outline: none; }
.ask-field {
  font: inherit; font-size: 15.5px; line-height: 1.5;
  width: 100%; border: 0; outline: none; resize: none; background: transparent;
  color: var(--ink); max-height: 200px; overflow-y: auto;
}
.ask-field::placeholder { color: var(--dim); }
.ask-bar { display: flex; align-items: center; gap: 8px; padding-top: 8px; }
.ask-attach {
  background: none; border: 1px solid var(--line); border-radius: 999px;
  font: inherit; font-size: 12.5px; color: var(--dim); cursor: pointer;
  padding: 5px 13px; transition: border-color var(--dur) var(--easing), color var(--dur) var(--easing);
}
.ask-attach:hover { border-color: var(--ink); color: var(--ink); }

/* Response-mode pill, styled like the attach pill. A small dot carries
   the state — hollow for General, filled once Analysis is on. */
.ask-mode {
  background: none; border: 1px solid var(--line); border-radius: 999px;
  font: inherit; font-size: 12.5px; color: var(--dim); cursor: pointer;
  padding: 5px 12px 5px 10px; display: inline-flex; align-items: center; gap: 7px;
  transition: border-color var(--dur) var(--easing), color var(--dur) var(--easing);
}
.ask-mode:hover { border-color: var(--ink); color: var(--ink); }
.ask-mode-dot {
  width: 7px; height: 7px; border-radius: 50%;
  border: 1.5px solid currentColor; box-sizing: border-box;
  transition: background var(--dur) var(--easing);
}
.ask-mode[data-mode="analysis"] { color: var(--ink); border-color: var(--ink); }
.ask-mode[data-mode="analysis"] .ask-mode-dot { background: var(--ink); }

.ask-send {
  margin-left: auto; flex: 0 0 auto;
  width: 34px; height: 34px; border-radius: 50%; border: 0;
  background: var(--ink); color: var(--paper); cursor: pointer;
  display: grid; place-items: center;
  transition: opacity var(--dur) var(--easing);
}
.ask-send svg { display: block; }
.ask-send:hover { opacity: 0.82; }

/* document picker, above the composer */
.doc-pop {
  border: 1px solid var(--line-int); background: var(--paper);
  margin-bottom: 10px; display: flex; flex-direction: column;
  max-height: 46vh; box-shadow: 0 -8px 32px rgba(10, 10, 10, 0.08);
}
.doc-pop[hidden] { display: none; }
.doc-pop-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.doc-search { font: inherit; font-size: 14px; flex: 1; min-width: 0; border: 0; outline: none; background: transparent; }
.doc-search::placeholder { color: var(--dim); }
.doc-pop-close { background: none; border: 0; font: inherit; font-size: 12.5px; color: var(--dim); cursor: pointer; }
.doc-pop-close:hover { color: var(--ink); }
.doc-list { overflow-y: auto; flex: 1; padding: 4px 0; }
.doc-row {
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  font: inherit; padding: 9px 16px;
  transition: background var(--dur) var(--easing);
}
.doc-row:hover { background: rgba(10, 10, 10, 0.03); }
.doc-row.on { background: rgba(10, 10, 10, 0.055); }
.doc-row.on .doc-name::after { content: " — attached"; color: var(--dim); font-size: 11.5px; }
.doc-name { font-size: 13.5px; color: var(--ink); }
.doc-meta { font-size: 11.5px; color: var(--dim); }
.doc-empty { padding: 20px 16px; color: var(--dim); font-size: 13px; }
.doc-pop-note { padding: 11px 16px; border-top: 1px solid var(--line); color: var(--dim); font-size: 11.5px; line-height: 1.45; }
.doc-pop-note a { color: var(--ink); border-bottom: 1px solid var(--line-int); }

@media (max-width: 620px) {
  .ask-shell { min-height: calc(100vh - 200px); }
  .msg.user .msg-body { max-width: 92%; }
}

@media (max-width: 720px) { .assist { width: 100%; } }

/* ---------- uploads ---------- */

.dropzone {
  border: 1px dashed var(--dim); padding: 34px 20px; text-align: center;
  cursor: pointer; outline: none;
  transition: border-color var(--dur) var(--easing), background var(--dur) var(--easing);
}
.dropzone:hover, .dropzone:focus-visible, .dropzone.over { border-color: var(--ink); background: rgba(10, 10, 10, 0.02); }
.dropzone.over { border-style: solid; }
.dz-lede { font-size: 15px; }
.dz-sub { color: var(--dim); font-size: 12.5px; margin-top: 7px; }
.dz-file { display: flex; align-items: flex-end; gap: 24px; padding-top: 16px; flex-wrap: wrap; }
.dz-entity .k { display: block; color: var(--dim); letter-spacing: 0.01em; font-size: 11px; margin-bottom: 7px; }
.dz-select {
  font: inherit; background: transparent; color: var(--ink);
  border: 0; border-bottom: 1px solid var(--ink); border-radius: 0;
  padding: 4px 0; outline: none; min-width: 12rem;
}
.dz-status { color: var(--dim); font-size: 12.5px; }
.dz-status.err { color: var(--ink); }

.lnk { color: var(--dim); font-size: 12.5px; transition: color var(--dur) var(--easing); }
.lnk:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.doc-acts { display: flex; gap: 12px; justify-content: flex-end; }

.cfl .tr  { grid-template-columns: 0.8fr 2.2fr 1fr 1fr; }
.scen .tr { grid-template-columns: 2fr 1fr 1fr 0.8fr 0.8fr 0.8fr; }
@media (max-width: 720px) {
  .scen .tr { grid-template-columns: 1.4fr 0.9fr 0.7fr 0.7fr; }
  .scen .tr > *:nth-child(3), .scen .tr > *:nth-child(5) { display: none; }
}

/* ============================================================
   REPORTS — screen-hidden, print-only document
   ============================================================ */

#report-root { display: none; }
body.printing > *:not(#report-root) { display: none !important; }
body.printing #report-root { display: block; }

#report-root { color: var(--ink); font-size: 11pt; line-height: 1.45; }
.rp-cover { padding: 0 0 34pt; border-bottom: 1pt solid var(--ink); margin-bottom: 26pt; }
.rp-mark { font-size: 10pt; letter-spacing: 0.01em; color: var(--dim); }
.rp-title { font-size: 30pt; font-weight: 500; letter-spacing: -0.02em; line-height: 1.05; margin-top: 40pt; }
.rp-sub { font-size: 14pt; color: var(--dim-2); margin-top: 8pt; }
.rp-meta { display: grid; grid-template-columns: 1fr 1fr; gap: 10pt 30pt; margin-top: 30pt; }
.rp-meta > div { display: flex; justify-content: space-between; gap: 16pt; padding-bottom: 6pt; border-bottom: 0.5pt solid var(--line); }
.rp-meta span:first-child { color: var(--dim); }
.rp-office { color: var(--dim); margin-top: 26pt; font-size: 10pt; }

.rp-sec { padding-bottom: 26pt; }
.rp-break { break-before: page; }
.rp-sec h2 {
  font-size: 11pt; font-weight: 500; letter-spacing: 0.01em;
  padding-bottom: 8pt; border-bottom: 1pt solid var(--ink); margin-bottom: 12pt;
}
.rp-sec h3 { font-size: 11pt; font-weight: 500; margin: 20pt 0 8pt; }
.rp-lede { margin-bottom: 14pt; max-width: 46em; }

.rp-table { width: 100%; border-collapse: collapse; margin-bottom: 10pt; }
.rp-table th {
  text-align: left; font-weight: 500; color: var(--dim); letter-spacing: 0.01em; font-size: 8.5pt;
  padding: 5pt 0; border-bottom: 0.5pt solid var(--ink);
}
.rp-table td { padding: 5pt 0; border-bottom: 0.5pt solid var(--line-2); vertical-align: top; }
.rp-table .r { text-align: right; }
.rp-table .num { font-variant-numeric: tabular-nums; }
.rp-table tr { break-inside: avoid; }

.rp-note { color: var(--dim); font-size: 9.5pt; line-height: 1.45; margin-top: 8pt; max-width: 46em; }
.rp-finding { padding: 10pt 0; border-bottom: 0.5pt solid var(--line-2); break-inside: avoid; }
.rp-fh { font-size: 9pt; letter-spacing: 0.01em; margin-bottom: 4pt; }
.rp-disc { color: var(--dim); font-size: 9pt; padding-top: 14pt; border-top: 0.5pt solid var(--line); }

@media print {
  @page { size: A4; margin: 18mm 16mm; }
  html, body { background: #fff; }
  .rp-sec, .rp-cover { page-break-inside: auto; }
  .rp-sec h2, .rp-sec h3 { break-after: avoid; }
}

/* ============================================================
   NAVIGATION — persistent back control
   The breadcrumb used to live in the scrolling body, which meant
   a long screen had no way out once you scrolled. It lives in the
   sticky header now.
   ============================================================ */

.back-link {
  display: inline-flex; align-items: baseline; gap: 8px;
  color: var(--dim); white-space: nowrap;
  padding: 5px 12px 5px 10px; margin-left: -4px;
  border: 1px solid var(--line);
  transition: color var(--dur) var(--easing), border-color var(--dur) var(--easing);
}
.back-link:hover { color: var(--ink); border-color: var(--ink); }
.back-link[hidden] { display: none; }

/* ============================================================
   FOLD — progressive disclosure
   ============================================================ */

.fold { border-top: 1px solid var(--line); }
.fold + .fold { border-top: 1px solid var(--line-2); }
.fold > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 0; color: var(--dim);
  transition: color var(--dur) var(--easing);
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary:hover { color: var(--ink); }
.fold[open] > summary { color: var(--ink); }
.fold-t { font-size: 14px; }
.fold-i { position: relative; width: 11px; height: 11px; flex: none; }
.fold-i::before, .fold-i::after {
  content: ""; position: absolute; background: currentColor;
  transition: transform var(--dur) var(--easing), opacity var(--dur) var(--easing);
}
.fold-i::before { left: 0; right: 0; top: 5px; height: 1px; }
.fold-i::after  { top: 0; bottom: 0; left: 5px; width: 1px; }
.fold[open] .fold-i::after { transform: scaleY(0); opacity: 0; }
.fold-body { padding: 4px 0 30px; }

/* ============================================================
   ASSET VALUATION
   ============================================================ */

.val-inputs {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px 26px;
}
@media (max-width: 980px) { .val-inputs { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .val-inputs { grid-template-columns: 1fr 1fr; } }

.dcf .tr { grid-template-columns: 0.6fr 1.2fr 1.2fr 1.2fr; }

/* ------------------------------------------------------------
   Header layout — one row. Navigation on the left, search on the
   right. It used to be two rows (identity + actions, then nav), but
   the brand and the Report/Checks buttons are gone, so row one had
   become just the search pill floating over empty space. One row
   brings everything up and puts search in the nav row.
   ------------------------------------------------------------ */

.topbar { flex-wrap: nowrap; align-items: center; gap: 24px; }
/* overflow:visible, not auto — auto forces overflow-y:auto too, which
   clips the dropdown panel. Five short top-level items fit without a
   scroll; on a phone they wrap (handled below). */
.topbar .nav {
  order: 0; flex: 1 1 auto; min-width: 0;
  gap: 22px; overflow: visible;
}
.topbar .nav a { white-space: nowrap; }
.topbar .search-btn { flex-shrink: 0; margin-left: auto; }

/* ============================================================
   APPRAISAL — fields, chips and inputs
   (shared by the guided conversation and by the result's
   assumption/adjust panels; the transcript styles follow below)
   ============================================================ */

.ap-fields {
  display: grid; grid-template-columns: 1fr 1fr; gap: 26px 34px;
  padding: 34px 0 6px; max-width: 52em;
}
@media (max-width: 620px) { .ap-fields { grid-template-columns: 1fr; } }
.ap-field { display: block; }
.ap-field .k {
  display: block; color: var(--dim);
  letter-spacing: 0.01em; font-size: 11px; margin-bottom: 9px;
}
.ap-input {
  font: inherit; font-size: 19px; font-variant-numeric: tabular-nums;
  border: 0; border-bottom: 1px solid var(--ink); border-radius: 0;
  padding: 5px 0 7px; width: 100%; outline: none; background: transparent;
  transition: border-color var(--dur) var(--easing);
}
.ap-input:focus { border-bottom-width: 2px; padding-bottom: 6px; }
.ap-choices { display: flex; flex-wrap: wrap; gap: 2px; }
.ap-choice {
  text-align: left; padding: 10px 15px; border: 1px solid var(--line);
  font-size: 13.5px;
  transition: border-color var(--dur) var(--easing), background var(--dur) var(--easing), color var(--dur) var(--easing);
}
.ap-choice:hover { border-color: var(--dim); }
.ap-choice.on { border-color: var(--ink); background: var(--ink); color: var(--paper); }
.ap-field:has(.ap-choices) { grid-column: 1 / -1; }

.ap-nav {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; padding-top: 36px; max-width: 52em;
}

.assum .tr { grid-template-columns: 1.3fr 1fr 2fr; }
@media (max-width: 720px) { .assum .tr { grid-template-columns: 1.4fr 1fr; } }

/* ============================================================
   APPRAISAL — GUIDED CONVERSATION
   A typographic transcript, not chat bubbles. Left-aligned,
   hairline-separated. Agent lines in ink; your answers in dim.
   ============================================================ */
.ap-convo { padding-top: 6px; }
.cx { max-width: 46em; }

.cx-turn { padding: 22px 0; border-top: 1px solid var(--line); }
.cx-turn:first-child { border-top: none; }

.cx-who {
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--dim-2); margin-bottom: 10px;
}
.cx-turn.live .cx-who { color: var(--ink); }

.cx-say {
  font-size: 18px; line-height: 1.5; letter-spacing: -0.01em;
  max-width: 40em;
}
/* inferred figures the agent reflects back: weight + tabular + a hairline underline, never colour */
.cx-say b {
  font-weight: 500; font-variant-numeric: tabular-nums;
  border-bottom: 1px solid var(--line); padding-bottom: 1px;
}

/* your answer, echoed quietly */
.cx-turn.you .cx-say { color: var(--dim); font-size: 16px; font-variant-numeric: tabular-nums; }

/* a settled turn you can reopen */
.cx-edit { cursor: pointer; }
.cx-edit:hover .cx-say { color: var(--ink); }
.cx-edit .cx-who::after {
  content: " · edit"; color: var(--dim-2);
  opacity: 0; transition: opacity var(--dur) var(--easing);
}
.cx-edit:hover .cx-who::after { opacity: 1; }

/* reply zone under the live agent line */
.cx-reply { margin-top: 18px; }
.cx-inline { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.cx-reply .ap-input { font-size: 22px; }
.cx-reply .ap-field { margin: 0; }

/* submit chevron for numeric / text answers */
.cx-send {
  border: 0; background: var(--ink); color: var(--paper);
  width: 42px; height: 42px; border-radius: 0; flex: 0 0 auto;
  font-size: 18px; line-height: 1; cursor: pointer;
  transition: opacity var(--dur) var(--easing);
}
.cx-send:hover { opacity: 0.82; }

.cx-actions { display: flex; align-items: center; gap: 14px; margin-top: 6px; }
.cx-skip { margin-top: 12px; }

/* adjust panel reuses .ap-fields grid, tightened */
.cx-adjfields { padding: 4px 0 20px; gap: 20px 28px; max-width: 40em; }

/* the result grows in below the transcript, separated by a full rule */
#ap-result:not(:empty) { border-top: 1px solid var(--ink); margin-top: 12px; padding-top: 4px; }

@media (max-width: 620px) {
  .cx-say { font-size: 16px; }
  .cx-adjfields { grid-template-columns: 1fr; }
}

/* ============================================================
   PLAIN BREAKDOWN — the cost plan, legible
   ============================================================ */

.pb-story { border-top: 1px solid var(--ink); max-width: 40em; }
.pb-line {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 20px; padding: 16px 0; border-bottom: 1px solid var(--line-2);
}
.pb-line.total { border-bottom: none; border-top: 1px solid var(--ink); }
.pb-lbl { color: var(--dim-2); }
.pb-line.total .pb-lbl { color: var(--ink); }
.pb-fig { font-size: 26px; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.pb-line.total .pb-fig { font-size: 34px; }

.pb-bar { display: flex; height: 46px; gap: 2px; margin-bottom: 26px; }
.pb-seg { min-width: 2px; }

.pb-row {
  display: grid; grid-template-columns: 10px 1fr 1fr 1fr 54px;
  gap: 18px; align-items: baseline;
  padding: 15px 0; border-top: 1px solid var(--line-2);
}
.pb-row:first-child { border-top: 1px solid var(--line); }
.pb-row.head { padding: 10px 0; }
.pb-row.head p {
  color: var(--dim);
  letter-spacing: 0.01em; font-size: 11px; text-align: right;
}
.pb-key { width: 10px; height: 10px; align-self: center; }
.pb-name { font-size: 15px; }
.pb-what { color: var(--dim); font-size: 12.5px; margin-top: 5px; line-height: 1.45; max-width: 34em; }
.pb-total, .pb-each, .pb-pct { text-align: right; font-variant-numeric: tabular-nums; }
.pb-each { color: var(--dim-2); }
@media (max-width: 720px) {
  .pb-row { grid-template-columns: 10px 1fr 1fr; }
  .pb-each, .pb-pct { display: none; }
  .pb-fig { font-size: 20px; }
  .pb-line.total .pb-fig { font-size: 26px; }
}
.chk-cov { color:rgba(10,10,10,.5); font-size:12.5px; padding-top:18px; line-height:1.5; }

/* ---------- structure (entities & facilities) ---------- */

.ent-tree { border-top: 1px solid var(--line); }
.ent { border-bottom: 1px solid var(--line-2); padding: 14px 0; }
.ent-row { display: grid; grid-template-columns: 2.4fr 1fr 1fr; gap: 20px; align-items: baseline; }
.ent-row .r { text-align: right; }
.ent-holds { color: var(--dim-2); font-size: 12.5px; padding-top: 8px; }
.ent-note { color: var(--dim-2); font-size: 12.5px; padding-top: 6px; line-height: 1.5; max-width: 62em; }
.ent-warn {
  border-left: 2px solid var(--ink); padding: 2px 0 2px 14px;
  margin-bottom: 16px; line-height: 1.55; max-width: 62em;
}
.fac .tr { grid-template-columns: 2.4fr 1.1fr 0.9fr 0.9fr 0.8fr; }
@media (max-width: 720px) {
  .ent-row { grid-template-columns: 1fr 0.8fr; }
  .fac .tr { grid-template-columns: 1.8fr 0.9fr 0.9fr; }
}
.ccy .tr { grid-template-columns: 2.4fr 1fr 1fr 0.7fr; }
.bul .tr { grid-template-columns: 2.4fr 1fr 0.9fr 1fr 0.9fr; }
@media (max-width: 720px) { .ccy .tr { grid-template-columns: 1.6fr 1fr 0.7fr; } .bul .tr { grid-template-columns: 1.8fr 1fr 0.9fr; } }

/* ---------- outside-click shield ----------
   Transparent (the white surface stays, nothing dims). Fixed to the
   viewport at z-index:0 inside the topbar's z:20 context — below .nav
   (z:3), so nav buttons and the open panel stay live above it while a
   press on any other pixel lands on the shield and closes the menu.
   display:none when [hidden] so it never interferes when closed. */
.nav-backdrop { position: fixed; inset: 0; z-index: 0; background: transparent; }
.nav-backdrop[hidden] { display: none; }

/* ---------- grouped navigation ---------- */
.nav-group { position: relative; display: inline-flex; align-items: center; }

/* The label is a real <button> so a tap is a click on touch. Full reset
   so it reads identically to the sibling <a> links. */
.nav-top {
  color: var(--dim);
  background: none; border: 0; margin: 0; padding: 0;
  font: inherit; line-height: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  transition: color var(--dur) var(--easing);
}
/* No chevron — the group opens on hover, so the arrow is just noise. */
.nav-top:hover,
.nav-group.open   .nav-top,
.nav-group.active .nav-top { color: var(--ink); }

/* ---------- the panel ----------
   THE GUARANTEE: z-index:-1 inside the .nav stacking context makes the
   panel paint BELOW every top-level button and direct link, whatever
   their DOM order — so a panel overlapping a neighbour's column can
   never intercept that neighbour's click. display:none when closed (so
   it can never catch a tap); display:flex only when .open. No :hover,
   no bridge, no pointer-events tricks — those are what broke it. */
.nav-drop {
  position: absolute; top: 100%; left: 0; z-index: -1;
  display: none; flex-direction: column; gap: 12px;
  margin-top: 10px;
  background: var(--paper); border: 1px solid var(--line);
  padding: 16px 20px; min-width: 168px;
  box-shadow: 0 6px 22px rgba(10, 10, 10, 0.10);   /* the pill's same lift */
}
/* The Search pill's sweep, on the panel. A wide low-alpha band twice the
   box width, animated across on the shared `sheen` loop. White over the dark
   panel in dark mode (as on Search); a fainter ink band in light, where a
   white one would vanish. Sits under the links (z-index) so text stays crisp,
   and never eats a click. */
.nav-drop::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(100deg,
    transparent 30%,
    rgba(10, 10, 10, 0.05) 47%,
    rgba(10, 10, 10, 0.09) 50%,
    rgba(10, 10, 10, 0.05) 53%,
    transparent 70%);
  background-size: 200% 100%;
  animation: sheen 3.6s linear infinite;
}
:root[data-theme="dark"] .nav-drop::after {
  background: linear-gradient(100deg,
    transparent 28%,
    rgba(255, 255, 255, 0.10) 46%,
    rgba(255, 255, 255, 0.20) 50%,
    rgba(255, 255, 255, 0.10) 54%,
    transparent 72%);
  background-size: 200% 100%;
}
.nav-drop > * { position: relative; z-index: 1; }   /* links above the sheen */
/* An invisible bridge across the 10px gap, so moving the pointer from the
   label down to the panel never crosses empty space and drops the hover. */
.nav-drop::before {
  content: ""; position: absolute; left: 0; right: 0;
  top: -12px; height: 12px;
}
.nav-group.open .nav-drop { display: flex; }
.nav-drop a { color: var(--dim); white-space: nowrap; transition: color var(--dur) var(--easing); }
.nav-drop a:hover, .nav-drop a.active { color: var(--ink); }

/* ---------- allocation: open in place ---------- */

.alloc-item { border-top: 1px solid var(--line-2); }
.alloc-item:first-child { border-top: 1px solid var(--line); }
.alloc-row {
  display: grid; width: 100%; text-align: left;
  grid-template-columns: 1.4fr 1.9fr 0.9fr 0.6fr 1fr;
  align-items: baseline; gap: 20px; padding: 14px 0;
  border: 0; background: none; cursor: pointer;
  transition: background var(--dur) var(--easing);
}
.alloc-row:hover { background: rgba(10, 10, 10, 0.025); }
.alloc-item.open .alloc-row { background: rgba(10, 10, 10, 0.025); }
.alloc-row .r { text-align: right; font-variant-numeric: tabular-nums; }

.alloc-panel { overflow: hidden; transition: height var(--dur) var(--easing); }
.alloc-inner { padding: 4px 0 26px; }
.alloc-cols {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  border-top: 1px solid var(--line-2); padding-top: 20px;
}
.alloc-cols .k {
  display: block; color: var(--dim);
  letter-spacing: 0.01em; font-size: 11px; margin-bottom: 9px;
}
.alloc-cols .v { font-size: 26px; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.alloc-cols .sub-line { padding-top: 7px; font-size: 12.5px; }
.alloc-note { color: var(--dim-2); padding-top: 18px; line-height: 1.5; max-width: 62em; }
.alloc-actions { display: flex; gap: 10px; padding-top: 22px; }

@media (max-width: 720px) {
  .alloc-row { grid-template-columns: 1.2fr 1fr 1fr; }
  .alloc-row .bar-cell { display: none; }
  .alloc-cols { grid-template-columns: 1fr; gap: 18px; }
}

/* ---------- calendar ---------- */

.cal-note { color: var(--dim-2); font-size: 12.5px; padding-top: 6px; line-height: 1.5; max-width: 60em; }
.cal-lead {
  border-left: 2px solid var(--ink); padding: 4px 0 4px 14px;
  margin-top: 34px; line-height: 1.55; max-width: 62em;
}

/* nav bar */
.cal-cal { margin-top: 8px; }
.cal-nav { display: flex; align-items: center; gap: 14px; padding-bottom: 16px; }
.cal-step {
  width: 30px; height: 30px; line-height: 1;
  border: 1px solid var(--line-int); background: var(--paper); color: var(--ink);
  font-size: 14px; cursor: pointer;
  transition: background var(--dur) var(--easing), color var(--dur) var(--easing);
}
.cal-step:hover { background: var(--ink); color: var(--paper); }
.cal-title { font-size: 15px; font-weight: 500; font-variant-numeric: tabular-nums; min-width: 96px; }
.cal-quick { margin-left: auto; display: flex; gap: 16px; }
.cal-quick button { background: none; border: 0; color: var(--dim); font-size: 12.5px; font-weight: 500; cursor: pointer; transition: color var(--dur) var(--easing); }
.cal-quick button:hover { color: var(--ink); }

/* weekday header — aligns to the grid columns */
.cal-dow { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-dow span { font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--dim); padding: 0 8px 8px; }

/* the grid — uniform hairlines, no cards, no radius. minmax(0,1fr) + min-width:0
   so a long event label can never push a column past its 1/7th share. */
.cal-grid {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  border-top: 1px solid var(--line); border-left: 1px solid var(--line);
}
.cal-cell {
  min-height: 96px; min-width: 0; padding: 8px 8px 10px;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  position: relative;
  transition: background var(--dur) var(--easing);
}
.cal-daynum { font-variant-numeric: tabular-nums; font-size: 13px; color: var(--dim-2); }
.cal-cell.out { background: rgba(10, 10, 10, 0.014); }          /* adjacent-month recess */
.cal-cell.out .cal-daynum { color: var(--dim-3); }
.cal-cell.today .cal-daynum {
  color: var(--ink); border-bottom: 2px solid var(--ink); padding-bottom: 1px;   /* today: ink underline, not colour */
}
.cal-cell.has { cursor: pointer; }
.cal-cell.has:hover { background: rgba(10, 10, 10, 0.028); }
.cal-cell.sel { background: rgba(10, 10, 10, 0.05); }
.cal-cell.crit { box-shadow: inset 2px 0 0 0 var(--ink); }       /* critical: inset ink left-rule */
.cal-cell:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

/* event labels (desktop) */
.cal-evs { display: flex; flex-direction: column; gap: 3px; margin-top: 6px; }
.cal-ev {
  font-size: 11px; line-height: 1.35; color: var(--dim-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-ev.crit { color: var(--ink); font-weight: 500; }
.cal-ev.appx::after { content: " ·"; color: var(--dim); }
.cal-more { font-size: 10.5px; color: var(--dim); }

/* event dots (mobile) */
.cal-dots { display: none; gap: 3px; margin-top: 6px; }
.cal-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--dim-2); display: inline-block; }
.cal-dot.crit { background: var(--ink); }

/* jump strip */
.cal-jump { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px; padding: 16px 0 2px; }
.cal-jump-l { font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--dim); }
.cal-jump button {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-size: 12px; font-variant-numeric: tabular-nums; color: var(--dim);
  transition: color var(--dur) var(--easing);
}
.cal-jump button:hover { color: var(--ink); }
.cal-jump button.on { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* detail panel */
.cal-detail { border-top: 1px solid var(--line); margin-top: 22px; padding-top: 18px; }
.cal-dhead { display: flex; justify-content: space-between; align-items: baseline; }
.cal-dtitle { font-size: 15px; font-weight: 500; font-variant-numeric: tabular-nums; }
.cal-dcount { color: var(--dim); font-size: 12.5px; }
.cal-devent { padding: 14px 0; border-bottom: 1px solid var(--line-2); }
.cal-devent.crit { border-left: 2px solid var(--ink); padding-left: 14px; margin-left: -16px; }
.cal-dmeta { color: var(--dim); font-size: 12.5px; padding-top: 4px; font-variant-numeric: tabular-nums; }
.cal-dempty { color: var(--dim); font-size: 13.5px; padding: 6px 0 4px; }

@media (max-width: 720px) {
  .cal-cell { min-height: 54px; padding: 6px; }
  .cal-daynum { font-size: 12px; }
  .cal-evs { display: none; }
  .cal-dots { display: flex; }
  .cal-quick { gap: 12px; }
  .cal-title { min-width: 76px; font-size: 14px; }
}

/* ============================================================
   FOCUS, HEADINGS, SEMANTICS

   There was exactly one :focus-visible rule in 1,194 lines, and
   eight selectors set `outline: none` unconditionally — including
   every one of the 31 cost-plan inputs. Keyboard users had no way
   to tell where they were.

   Element + pseudo-class (0,1,1) beats the bare class selectors
   (0,1,0) that killed the outline, so this restores focus without
   !important and without unpicking the rules that suppress the
   default ring for mouse users.
   ============================================================ */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 1px;
}

/* Inputs sit on a baseline rule rather than in a box, so an offset
   ring around them reads as detached. Thicken their own rule instead
   and keep the outline tight. */
input:focus-visible, textarea:focus-visible { outline-offset: 1px; }

/* Interactive borders carry meaning and need 3:1, unlike the
   decorative hairlines that give the app its structure. */
.cp-input, .fi-input, .ap-input { border-bottom-color: var(--line-int); }

/* Skip link — the first thing in the tab order, visible only when
   focused. Without it, reaching the content past the header and a
   ten-item nav is a long walk on every screen. */
/* Hidden in place, not off-screen. Parking it above the viewport meant a
   rubber-band overscroll at the top dragged it into view; clipping it to
   a 1px box leaves nothing above to reveal. A keyboard focus expands it. */
.skip {
  position: fixed; left: 8px; top: 8px; z-index: 100;
  width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  border: 0;
}
.skip:focus {
  width: auto; height: auto; padding: 10px 16px; overflow: visible;
  clip: auto; clip-path: none;
  background: var(--paper); color: var(--ink); border: 1px solid var(--ink);
}

/* The page heading. The only <h1> in the codebase was in the print
   stylesheet, so screen readers got a document with no title and the
   heading order started at <h2> on every view. Visually it is the
   label above the monument, which is where the page already announces
   itself — so this adds structure without adding furniture. */
.view-h1 {
  font-size: 12px; font-weight: 500;
  letter-spacing: 0.01em; color: var(--dim);
  padding: 0 0 0 0; margin: 0;
}

/* Tables are divs. Roles make them tables to assistive tech without
   touching the grid layout that gives them their look — WCAG 1.3.1 is
   a hard fail otherwise, and it is the kind of thing that ends an
   institutional procurement review before anyone sees the product. */
[role="table"] { display: block; }
[role="row"] { display: grid; }
/* The rounding convention, stated under the figure it applies to. A
   tool that says what precision it is claiming is making a smaller
   claim than one printing seven digits — and a more credible one. */
.prec { color: var(--dim-3); font-size: 11.5px; letter-spacing: 0.01em; }

/* ---- treemap: labels that fit the cell they are in ----
   Area equals share, so small holdings get small cells and that is
   the honest answer — a minimum height would fix the look by
   falsifying the chart. The label steps down instead. Padding
   tightens with each tier, because 16px of padding in a 24px cell is
   most of the cell. */

.tm-cell.tm-sm { padding: 9px 14px; justify-content: center; }
.tm-cell.tm-sm .tm-pct { font-size: 13px; }
.tm-cell.tm-sm .tm-name { margin-top: 2px; font-size: 12px; }
.tm-cell.tm-sm .tm-val { display: none; }          /* the row below states it */

/* Too short for two lines: name and share side by side on one. */
.tm-cell.tm-xs {
  padding: 0 14px; justify-content: center;
  flex-direction: row; align-items: baseline; gap: 8px;
}
.tm-cell.tm-xs .tm-pct { font-size: 12px; order: 2; opacity: 0.72; }
.tm-cell.tm-xs .tm-name {
  margin-top: 0; font-size: 12px; order: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tm-cell.tm-xs .tm-val { display: none; }

/* ---- the header on a phone ----
   Three labelled action buttons, a brand with a subtitle and a
   nav do not fit in 375px, so they were wrapping onto three rows and
   pushing the content off the first screen. Order of sacrifice:
   the brand subtitle (the office knows whose office it is), then the
   ⌘K hint (there is no ⌘ key on a phone), then the clock. */
@media (max-width: 620px) {
  .topbar { padding: 14px var(--gutter); row-gap: 12px; }  /* Below 860px an existing rule drops the "Search" label and leaves
     the ⌘K badge as the button. On a phone that is backwards — there
     is no ⌘ key — and hiding the badge without restoring the label
     left an empty box. Put the word back. */
  .topbar .search-btn kbd { display: none; }
  .topbar .search-btn span { display: inline; font-size: 13px; }
  .search-btn { padding: 6px 11px; font-size: 13px; }
  /* Nav wraps on a phone. overflow:visible so the panel is not clipped. */
  .topbar .nav { gap: 14px 16px; overflow: visible; flex-wrap: wrap; }
  /* On a phone the absolute panel would drop over the wrapped row below
     it — and z-index:-1 would put it BEHIND those items, so its own
     links get eaten. So here the panel flows in-line instead: the open
     group takes a full row and the panel sits below it as its own row,
     pushing the following items down. No overlap, nothing to invert. */
  .nav-group.open { flex-basis: 100%; }
  .nav-drop {
    position: static; z-index: auto;
    width: 100%; min-width: 0;
    margin-top: 8px; border: 0; padding: 4px 0 2px;
  }
}
@media (max-width: 400px) {
  /* Last resort: Report is the least used of the three in a hurry. */}
@media (max-width: 620px) {
  /* The controls were being flex-shrunk to nothing — the search button
     collapsed to a 24px empty box with its label clipped inside. The
     nav is the only thing here that should absorb the slack, because
     it is the only thing that can scroll. */
  .topbar .search-btn { flex-shrink: 0; }
  .topbar .search-btn span { white-space: nowrap; }
}

/* ============================================================
   THE SEARCH CONTROL — glass

   Report and Checks left the header for the command palette, so one
   control does the work of three. It sits where the clock was.

   Glass is a departure from the flat monochrome elsewhere, so it is
   kept honest: the blur only reads when content scrolls beneath the
   sticky header, which is exactly when a floating control should
   look like it is floating. Everything else — weight, letterform,
   the ⌘K badge — stays in the existing language.
   ============================================================ */

.search-btn.glass {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 15px; margin-left: auto;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 999px;
  /* Black rather than clear. On a white page a light glass pill is
     nearly invisible against the header it sits in — this is the one
     control left up there, so it should read as a control. Ink is
     already the app's only strong value, so it belongs to the same
     palette rather than introducing an accent colour. */
  background: rgba(10, 10, 10, 0.88);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  backdrop-filter: blur(14px) saturate(180%);
  box-shadow:
    0 1px 2px rgba(10, 10, 10, 0.10),
    0 6px 20px rgba(10, 10, 10, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.72);
  transition: background var(--dur) var(--easing), color var(--dur) var(--easing),
              box-shadow var(--dur) var(--easing), transform var(--dur) var(--easing);
}
.search-btn.glass:hover {
  background: rgba(10, 10, 10, 0.96);
  color: #fff;
  box-shadow:
    0 1px 2px rgba(10, 10, 10, 0.12),
    0 10px 28px rgba(10, 10, 10, 0.20),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.search-btn.glass:active { transform: translateY(0.5px); }
.search-btn.glass .sb-label { font-size: 13.5px; }

/* Sheen — the same technique as the shimmer in the Claude app: a wide
   gradient band twice the width of its box, swept by animating
   background-position from 200% to -200% on a linear loop. Monochrome
   here: white at low alpha over the ink pill, so it reads as light
   moving across a dark surface rather than as colour. The band is a
   pseudo-element so it passes over the label and the ⌘K key too, and
   the pill clips it to its own radius. */
.search-btn.glass { position: relative; overflow: hidden; }
.search-btn.glass::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 25%,
    rgba(255, 255, 255, 0.10) 42%,
    rgba(255, 255, 255, 0.20) 50%,
    rgba(255, 255, 255, 0.10) 58%,
    transparent 75%
  );
  background-size: 200% 100%;
  animation: sheen 3.6s linear infinite;
}
@keyframes sheen {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.search-btn.glass kbd {
  font: inherit; font-size: 10.5px; letter-spacing: 0.01em;
  padding: 2px 6px; border-radius: 5px;
  background: rgba(255, 255, 255, 0.13);
  border: 1px solid rgba(255, 255, 255, 0.10);
  color: rgba(255, 255, 255, 0.72);
}
/* The focus ring is an outline on the element itself, and on a black
   pill the default ink ring disappears — offset it in white instead. */
.search-btn.glass:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px #fff, 0 6px 20px rgba(10, 10, 10, 0.14);
}
@supports not (backdrop-filter: blur(2px)) {
  .search-btn.glass { background: var(--ink); }
}

/* Dark mode keeps the pill dark, but a near-black pill sinks into the near-
   black page. Lift it a touch — a faint frosted fill over the page, a stronger
   hairline, a deeper shadow — so the trigger stays findable without turning
   light. (The menu it opens is the light surface; this is just the handle.) */
:root[data-theme="dark"] .search-btn.glass {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.40),
    0 8px 22px rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
:root[data-theme="dark"] .search-btn.glass:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.22);
  color: #fff;
}

/* ---- the treemap gets its height back ----
   The right column stacks four cells in whatever height the container
   has, so the container height *is* the label budget. At 300px the two
   smallest cells could not show their names. 420px gets Private
   markets to a full three-line label; Digital assets at 3% of the book
   still gets the one-line treatment, because area is share and 3% of
   the height is genuinely small. */
.treemap { height: 420px; }
@media (max-width: 720px) { .treemap { height: 320px; } }

/* The small-holdings band: side by side rather than stacked, so a 3%
   cell is narrow-and-tall instead of wide-and-invisible. Same area,
   usable shape. */
.tm-band { display: flex; gap: 2px; }
.tm-band .tm-cell { justify-content: flex-end; }

/* ============================================================
   REDUCED MOTION — one rule, not six allowlists

   This was maintained as six hand-written lists of selectors, and they
   had already fallen behind: the nav chevron, the skip link and the
   search-pill sheen were all still animating. A blanket rule cannot
   fall behind. Durations go to ~0 rather than `none` so that
   transitionend/animationend still fire and nothing waits forever on a
   callback that never arrives.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ============================================================
   ARRIVAL SLIDE

   Coming from the plan (pasternak.cv), the plan lifts up and away; the
   Console then slides up into place and fades in, so the jump between the
   two apps reads as one continuous move rather than a hard reload.
   ============================================================ */
@keyframes console-enter { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
body { animation: console-enter 0.34s cubic-bezier(0.4, 0, 0.2, 1) both; }

@media (prefers-reduced-motion: reduce) {
  body { animation: none; }
}
