/* Aftertax — shared design system.
   Light, airy, Material structure (Roboto 900 display, rgba-black ink, white
   elevation cards, black pill CTAs, soft radial glows) with the Ledger's own
   warm palette: emerald + bronze + a brick-rose gradient — deliberately not
   ProjectionLab's purple/blue/teal. Chart palette (validated for CVD +
   contrast on white): emerald #059669 optimised · indigo #7C3AED generic ·
   #D97706 property · #0891B2 cash */

/* One :root. These were three separate blocks (palette, type scale,
   spacing + categorical palette) scattered down the file; no token was
   defined twice, so merging them changes nothing except findability. */
:root{
  /* Design pack — indigo on a light grey ground, generous radii, near-flat
     elevation. Ink is #0B0E14 at alpha. */
  --ink-87:rgba(11,14,20,.88);
  --ink-60:rgba(11,14,20,.62);
  --ink-56:rgba(11,14,20,.56);   /* 4.5:1 on white. Was named --ink-38 while holding .56 */
  --ink-38:var(--ink-56);        /* deprecated alias — remove once nothing references it */
  --line:rgba(11,14,20,.12);
  --line-soft:rgba(11,14,20,.08);

  --accent:#5B5BF6; --accent-deep:#4338CA;
  --accent-wash:rgba(91,91,246,.10);
  --accent-glow:rgba(91,91,246,.35);
  --green-ok:#0D9488;
  --brick:#BE123C;   /* was var(--brick) — self-referential, so every use fell back to inherit */
  --warn:#D97706;
  --warn-deep:#A85C06;   /* was var(--warn-deep) — self-referential, so it resolved to
                            nothing. Deeper than --warn: this is only ever text on a
                            pale amber wash, where #D97706 misses 4.5:1. */
  --warn-wash:rgba(217,119,6,.14);
  /* Flat since pass 4. Every consumer is overridden to flat ink or accent;
     this stays defined so anything missed degrades to indigo, not to nothing. */
  --grad:#5B5BF6;
  --ease:cubic-bezier(.25,.7,.3,1);
  --shadow-card:0 1px 2px rgba(11,14,20,.03);
  --shadow-lift:0 8px 28px rgba(11,14,20,.13);
  --radius-card:16px;
  --radius-pill:999px;
  --sans:'Inter',ui-sans-serif,system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --surface:#fff;
  --surface-sunk:#F6F7F9;
  --ground:#F6F7F9;
  --sidebar:#0B0E14;

  --fs-display:40px;
  --fs-hero:30px;
  --fs-h2:26px;
  --fs-figure:19px;
  --fs-h3:17px;
  --fs-lead:15px;
  --fs-body:14px;
  --fs-small:13px;
  --fs-micro:11.5px;

  /* ---- extended: spacing scale (new) ---- */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-5:24px; --space-6:32px; --space-7:48px; --space-8:64px;

  /* ---- extended: categorical data palette (new) ----
     Asset classes only — never UI chrome. Hue-separated, chroma kept
     below --accent's so a legend never outshouts the interface.
     Checked against a deuteranopia/protanopia simulation. */
  --cat-cash:oklch(0.74 0.08 227);
  --cat-isa:oklch(0.63 0.10 175);
  --cat-taxable:oklch(0.58 0.03 260);
  --cat-pension:oklch(0.55 0.11 322);
  --cat-property:oklch(0.66 0.12 58);
  --cat-equity:oklch(0.54 0.13 24);

  /* ---- extended: milestone-category palette (new, pass 2) ----
     Separate namespace from --cat-* above on purpose — .cat-cash (milestone
     category "money in and out") and --cat-cash (asset class) were the same
     name for two different things. This set is --tl-*, consumed via --tl-cat. */
  --tl-prop:oklch(0.62 0.10 40);
  --tl-family:oklch(0.60 0.11 150);
  --tl-money:oklch(0.62 0.11 205);
  --tl-work:oklch(0.58 0.12 300);

  /* ---- the positive / negative / warning trio ----
     Unchanged — --green-ok / --brick / --warn already do this job.
     Naming it here so it reads as a closed set of three, deliberately
     separate from the categorical ramp above. */

  /* ---- table-specific radius (new) ---- */
  --radius-input:10px;

  /* The --teal / --purple / --focus-blue aliases that used to live here are
     gone. They were left from an earlier rename and lied about themselves:
     teal resolved to indigo, purple to amber. All 94 usages now name the
     token they actually meant. */
}
*{box-sizing:border-box;}
[hidden]{display:none !important;}
html{scroll-behavior:smooth;}
body{margin:0;background:var(--ground);color:var(--ink-60);
  font-family:var(--sans);line-height:1.62;letter-spacing:-0.006em;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}
.wrap{max-width:1240px;margin:0 auto;padding:0 24px 48px;}

/* ---------- nav ---------- */
nav{display:flex;justify-content:space-between;align-items:center;padding:26px 0 0;}
/* Same lockup as .sn-brand in the tool — mark, 9px gap, wordmark — so the logo
   doesn't change shape depending which page you landed on. */
.wordmark{display:inline-flex;align-items:center;gap:9px;
  font-weight:800;font-size:var(--fs-h3);letter-spacing:-0.01em;color:var(--ink-87);text-decoration:none;
  transition:opacity .18s var(--ease);}
.wordmark::before{content:'';width:22px;height:22px;border-radius:7px;background:var(--grad);flex:none;}
.wordmark:hover{opacity:.75;}
nav .nav-link{font-size:var(--fs-body);font-weight:500;color:var(--ink-60);text-decoration:none;
  border-bottom:2px solid transparent;padding-bottom:2px;transition:color .18s var(--ease),border-color .18s var(--ease);}
nav .nav-link:hover{color:var(--ink-87);border-color:var(--accent);}

/* ---------- type ---------- */
.eyebrow{font-size:var(--fs-small);font-weight:700;letter-spacing:-0.005em;
  color:var(--accent);margin-bottom:18px;}
h1{font-weight:900;font-size:clamp(36px,5.4vw,58px);line-height:1.06;margin:0 0 22px;
  max-width:820px;letter-spacing:-0.02em;color:var(--ink-87);}
h2{font-weight:900;font-size:var(--fs-h2);margin:0 0 6px;letter-spacing:-0.01em;color:var(--ink-87);}
.sub{font-size:var(--fs-h3);color:var(--ink-60);max-width:640px;margin-bottom:20px;}
.sub b{color:var(--ink-87);font-weight:700;}
.section-divider{margin:72px 0 32px;padding-top:40px;border-top:1px solid var(--line-soft);}
.section-num{font-size:var(--fs-micro);font-weight:700;color:var(--accent);letter-spacing:-0.005em;
  margin-bottom:10px;}

/* ---------- focus (keyboard) ---------- */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:6px;}

/* ---------- layout ---------- */
.grid{display:grid;grid-template-columns:1.1fr 1fr;gap:22px;align-items:start;}
@media (max-width:860px){.grid{grid-template-columns:1fr;}}

/* ---------- cards ---------- */
.panel,.ledger-card,.why-panel,.gap-stamp,.signup-panel,.roadmap-panel{
  background:#fff;border:1px solid var(--line-soft);border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);}
.panel{padding:30px;}
.panel .hint{font-size:var(--fs-small);color:var(--ink-56);margin-bottom:26px;}

/* ---------- fields ---------- */
.field{margin-bottom:22px;}
.field label{display:block;font-size:var(--fs-body);font-weight:600;color:var(--ink-87);margin-bottom:4px;}
.field .caption{font-size:var(--fs-small);color:var(--ink-56);margin-bottom:9px;}
.num-input{display:flex;align-items:center;background:var(--surface-sunk);border:1px solid transparent;border-radius:11px;
  padding:0 12px;transition:background .18s var(--ease),border-color .18s var(--ease),box-shadow .18s var(--ease);}
.num-input:hover{background:#EFF3F1;}
.num-input:focus-within{background:#fff;border-color:var(--accent);box-shadow:0 0 0 3px rgba(91,91,246,.13);}
.num-input:focus-within:hover{border-color:var(--accent);}
.num-input span{color:var(--ink-56);font-size:var(--fs-lead);margin-right:5px;}
.num-input input[type=number]{background:transparent;border:none;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-h3);font-weight:500;padding:11px 0;width:100%;outline:none;
  font-variant-numeric:tabular-nums;}
/* The 16px thumb overhangs a full-width track, so inset the range slightly —
   otherwise every slider pushes its field 4px wider than the column. */
input[type=range]{-webkit-appearance:none;appearance:none;box-sizing:border-box;
  width:calc(100% - 4px);margin:8px 2px 0;height:4px;background:var(--line);
  border-radius:4px;cursor:pointer;}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;
  background:var(--accent);cursor:pointer;border:2.5px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.3);
  transition:transform .15s var(--ease);}
input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.25);}
input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:var(--accent);
  cursor:pointer;border:2.5px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.3);transition:transform .15s var(--ease);}
input[type=range]::-moz-range-thumb:hover{transform:scale(1.25);}
.range-val{color:var(--accent);font-size:var(--fs-body);font-weight:700;float:right;font-variant-numeric:tabular-nums;}
.checkbox-row{display:flex;align-items:center;gap:10px;font-size:var(--fs-body);color:var(--ink-60);margin:-6px 0 6px;}
.checkbox-row input{accent-color:var(--accent);width:16px;height:16px;}
.income-row{display:grid;grid-template-columns:1fr 100px 130px 28px;gap:8px;align-items:center;margin-bottom:8px;}
.income-row input[type=text],.income-row input[type=number]{background:#fff;border:1px solid var(--line);
  border-radius:10px;color:var(--ink-87);font-size:var(--fs-body);font-weight:500;padding:9px 10px;font-family:inherit;
  outline:none;width:100%;font-variant-numeric:tabular-nums;transition:border-color .18s var(--ease);}
.income-row input:hover{border-color:var(--ink-60);}
.income-row input:focus{border-color:var(--accent);}
.income-row select{background:#fff;border:1px solid var(--line);border-radius:10px;color:var(--ink-87);
  font-size:var(--fs-small);padding:9px 6px;font-family:inherit;outline:none;transition:border-color .18s var(--ease);}
.income-row select:hover{border-color:var(--ink-60);}
.income-row button{background:none;border:none;color:var(--ink-56);cursor:pointer;font-size:var(--fs-h3);
  transition:color .15s var(--ease),transform .15s var(--ease);}
.income-row button:hover{color:var(--brick);transform:scale(1.2);}
/* Holdings rows: the income-row pattern, one column wider. Same fields, same
   borders, same remove button — a holding is a line item exactly as an income
   source is. Value and cost are sterling unless the currency says otherwise,
   in which case the rate field appears beside them. */
.hold-list{margin-top:6px;}
.hold-row{display:grid;grid-template-columns:1fr 96px 132px 96px 96px 28px;gap:8px;
  align-items:center;margin-bottom:8px;}
.hold-row.has-fx{grid-template-columns:1fr 96px 132px 96px 96px 72px 28px;}
/* 132px for the wrapper: "SIPP / pension" is 126px of text in a select, which
   cannot wrap, so a narrower column clips the one word that says what the
   option means. One font size for every control in the row, and it is the
   grid's, so the row and the grid above it read as one table. */
.hold-row input[type=text],.hold-row input[type=number],.hold-row select{
  background:#fff;border:1px solid var(--line);border-radius:10px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-body);padding:8px 10px;width:100%;box-sizing:border-box;
  min-width:0;}
.hold-row input:hover,.hold-row select:hover{border-color:var(--ink-60);}
.hold-row input:focus,.hold-row select:focus{border-color:var(--accent);outline:none;}
.hold-row input[readonly]{background:var(--surface-sunk);color:var(--ink-56);}
.hold-row button{background:none;border:none;color:var(--ink-56);cursor:pointer;
  font-size:var(--fs-h3);line-height:1;padding:0;}
.hold-row button:hover{color:var(--brick);}
/* The second line under a row: who owns it and whether it is the employer.
   Two small controls, so they share one line rather than two more columns. */
.hold-meta{display:flex;flex-wrap:wrap;gap:6px 16px;align-items:center;
  grid-column:1/-1;margin:-4px 0 6px;font-size:var(--fs-micro);color:var(--ink-56);}
.hold-meta label{display:inline-flex;align-items:center;gap:6px;cursor:pointer;}
.hold-meta select{font-size:var(--fs-micro);padding:3px 6px;border-radius:6px;
  border:1px solid var(--line);background:#fff;color:var(--ink-87);font-family:inherit;}
.hold-head{display:grid;grid-template-columns:1fr 96px 132px 96px 96px 28px;gap:8px;
  font-size:var(--fs-micro);color:var(--ink-56);margin:10px 0 4px;}
.hold-head.has-fx{grid-template-columns:1fr 96px 132px 96px 96px 72px 28px;}
/* The grid's Company stock cells are derived once there are holdings */
.nwp-cell.is-derived{background:var(--surface-sunk);border-style:dashed;}
.nwp-cell.is-derived input{color:var(--ink-60);}
.nwp-label .nwp-recon{display:block;font-size:var(--fs-micro);color:var(--ink-56);
  font-weight:500;margin-top:1px;}
/* On a phone the row is two columns and the controls reflow by importance:
   the name and the wrapper get a full line each — the wrapper because its
   longest option is 142px at the 16px mobile floor and a half-width select
   clips it to "SIPP / pen" — then value beside cost, currency beside the rate,
   and the remove button on its own at the end. */
@media (max-width:640px){
  .hold-head{display:none;}
  .hold-row,.hold-row.has-fx{grid-template-columns:1fr 1fr;}
  .hold-row .hold-label,.hold-row .hold-wrap{grid-column:1/-1;}
  .hold-row .hold-label{order:1;} .hold-row .hold-wrap{order:2;}
  .hold-row .hold-value{order:3;} .hold-row .hold-cost{order:4;}
  .hold-row .hold-ccy{order:5;} .hold-row .hold-fx{order:6;}
  .hold-row > span:empty{display:none;}
  .hold-row button{order:7;grid-column:1/-1;justify-self:end;}
  .hold-meta{order:8;}
}
@media (pointer:coarse){
  .hold-meta{gap:6px 16px;}
  .hold-meta label{min-height:44px;}
  .hold-meta input[type=checkbox]{width:20px;height:20px;}
  /* The remove glyph is 17px tall; the thing under the finger is this box. */
  .hold-row button{min-width:44px;min-height:44px;}
}

/* The disposal modeller. Reuses the cash planner's control shape (.cg-ctl,
   .cg-unit) and the table treatment already used for comparisons — one figure
   size, weight for hierarchy, no highlighted column. Neutrality is the point:
   nothing here may read as the tool preferring one row. */
.disp-controls{display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center;margin-bottom:12px;}
.disp-controls select{background:#fff;border:1px solid var(--line);border-radius:8px;
  color:var(--ink-87);font-family:inherit;font-size:var(--fs-body);padding:7px 9px;max-width:100%;}
.disp-controls select:hover{border-color:var(--ink-60);}
.disp-controls select:focus{border-color:var(--accent);outline:none;}
.disp-note{font-size:var(--fs-small);line-height:1.6;color:var(--ink-60);
  padding:12px 14px;background:var(--surface-sunk);border-radius:8px;margin-bottom:12px;}
.disp-line{font-size:var(--fs-small);line-height:1.65;color:var(--ink-60);margin-bottom:10px;}
.disp-line b{color:var(--ink-87);font-weight:700;}
.disp-sub{font-size:var(--fs-micro);font-weight:700;letter-spacing:0.1em;color:var(--ink-56);
  text-transform:uppercase;margin:18px 0 8px;}
.disp-tab{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;
  margin-bottom:10px;}
.disp-tab th{text-align:left;font-size:var(--fs-micro);font-weight:600;color:var(--ink-56);
  padding:6px 10px 6px 0;border-bottom:1px solid var(--line);}
.disp-tab td{font-size:var(--fs-body);color:var(--ink-87);padding:9px 10px 9px 0;
  border-bottom:1px solid var(--line-soft);vertical-align:top;line-height:1.5;}
.disp-tab td:first-child{color:var(--ink-60);}
.disp-tab tr:last-child td{border-bottom:none;}
/* No row is emphasised, hovered or coloured. A highlighted row in a table of
   options is a recommendation drawn in CSS. */
.disp-cap{font-size:var(--fs-micro);line-height:1.6;color:var(--ink-56);margin-bottom:4px;}
@media (max-width:640px){
  /* "Sell £x of [holding]" is one line on a wide screen and two on a phone:
     the select carries a label, an owner and a value, which will not share
     285px with a number field. Each control takes a row and its select the
     full width, so nothing is clipped. */
  .disp-controls{display:block;}
  .disp-controls .cg-ctl{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
  .disp-controls select{flex:1;min-width:0;}
  .disp-tab,.disp-tab thead,.disp-tab tbody,.disp-tab tr,.disp-tab th,.disp-tab td{display:block;}
  .disp-tab thead{display:none;}
  .disp-tab tr{border-bottom:1px solid var(--line);padding:8px 0;}
  .disp-tab tr:last-child{border-bottom:none;}
  .disp-tab td{border:none;padding:2px 0;}
  .disp-tab td:first-child{font-weight:600;color:var(--ink-87);}
  .disp-tab td[data-l]::before{content:attr(data-l) ' ';color:var(--ink-56);font-size:var(--fs-micro);}
}

/* Monte Carlo card. Same figure size and weight hierarchy as the rest; the fan
   is the accent at two opacities, so it reads as one distribution rather than
   three separate bands. */
.mc-status{font-size:var(--fs-small);color:var(--ink-56);margin:10px 0;}
.mc-status:empty{display:none;margin:0;}
.mc-head{font-size:var(--fs-body);color:var(--ink-60);margin-top:12px;line-height:1.6;}
.mc-head b{color:var(--ink-87);font-weight:700;}
.mc-line{font-size:var(--fs-small);color:var(--ink-60);line-height:1.6;margin-top:6px;}
.mc-line b{color:var(--ink-87);font-weight:700;}
.mc-cap{font-size:var(--fs-micro);color:var(--ink-56);line-height:1.6;margin-top:12px;}
.mc-cap a{color:var(--accent-deep);}

.hold-fall{margin-top:14px;}
.hold-fall label{display:block;font-size:var(--fs-small);color:var(--ink-87);font-weight:500;}
.hold-fall .caption{margin-top:6px;}

.add-source{background:none;border:1px dashed var(--line);color:var(--accent-deep);font-family:inherit;
  font-size:var(--fs-small);font-weight:600;padding:10px 14px;border-radius:10px;cursor:pointer;width:100%;
  transition:border-color .18s var(--ease),background .18s var(--ease);}
.add-source:hover{border-color:var(--accent);background:var(--accent-wash);}

/* ---------- scenario bar ---------- */
.scenario-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;background:#fff;
  border:1px solid var(--line-soft);border-radius:var(--radius-card);padding:14px 18px;
  box-shadow:var(--shadow-card);margin-top:30px;}
.sc-label{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;
  color:var(--ink-56);margin-right:2px;}
#scenarioSelect{background:#fff;border:1px solid var(--line);border-radius:9px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-body);font-weight:600;padding:8px 10px;outline:none;min-width:170px;
  transition:border-color .18s var(--ease);}
#scenarioSelect:hover{border-color:var(--ink-60);}
#scenarioSelect:focus{border-color:var(--accent);}
.sc-btn{background:#fff;border:1px solid var(--line);border-radius:9px;font-family:inherit;font-size:var(--fs-small);
  font-weight:600;color:var(--ink-87);padding:8px 13px;cursor:pointer;
  transition:border-color .18s var(--ease),background .18s var(--ease),color .18s var(--ease);}
.sc-btn:hover{border-color:var(--accent);}
.sc-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff;}
.sc-btn.primary:hover{background:var(--accent-deep);border-color:var(--accent-deep);}
.sc-btn.danger:hover{border-color:var(--brick);color:var(--brick);}
.sc-btn:disabled{opacity:.4;cursor:not-allowed;}
.sc-btn:disabled:hover{border-color:var(--line);color:var(--ink-87);}
.sc-status{font-size:var(--fs-small);font-weight:600;color:var(--accent-deep);margin-left:auto;}
/* The unsaved state, stated rather than left as an empty-looking dropdown. A
   quiet chip with a hollow dot: present, clearly not a list, and clearly not
   yet saved. */
.sc-now{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;
  font-size:var(--fs-small);color:var(--ink-60);background:var(--surface-sunk);
  border:1px solid var(--line-soft);border-radius:9px;padding:7px 11px;}
.sc-now::before{content:'';flex:none;width:6px;height:6px;border-radius:50%;
  border:1.5px solid var(--ink-56);box-sizing:border-box;}

/* ---------- household summary strip ---------- */
.hh-strip{display:flex;flex-wrap:wrap;align-items:center;gap:24px;background:#fff;
  border:1px solid var(--line-soft);border-radius:var(--radius-card);padding:22px 26px;
  box-shadow:var(--shadow-card);margin-bottom:20px;}
.hh-main{min-width:210px;}
.hh-label{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;color:var(--ink-56);}
.hh-figure{font-size:clamp(30px,4vw,40px);font-weight:900;letter-spacing:-0.02em;color:var(--ink-87);
  font-variant-numeric:tabular-nums;line-height:1.1;margin-top:4px;}
.hh-note{font-size:var(--fs-micro);color:var(--ink-56);margin-top:4px;}
.hh-people{display:flex;flex-wrap:wrap;gap:10px;}
.hh-person{border:1px solid var(--line);border-radius:12px;padding:10px 14px;cursor:pointer;min-width:120px;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);}
.hh-person:hover{border-color:var(--accent);}
.hh-person.on{border-color:var(--accent);box-shadow:0 0 0 2px rgba(91,91,246,.12);}
.hh-pname{display:block;font-size:var(--fs-small);font-weight:700;color:var(--ink-87);}
.hh-pmode{display:block;font-size:var(--fs-micro);font-weight:600;letter-spacing:-0.005em;
  color:var(--ink-56);margin:1px 0 3px;}
.hh-person b{font-size:var(--fs-lead);font-weight:700;color:var(--accent-deep);font-variant-numeric:tabular-nums;}
.hh-stats{display:flex;gap:22px;margin-left:auto;flex-wrap:wrap;}
.hh-stat{text-align:right;}
.hh-stat span{display:block;font-size:var(--fs-micro);font-weight:600;letter-spacing:-0.005em;
  color:var(--ink-56);}
.hh-stat b{font-size:var(--fs-h3);font-weight:800;color:var(--ink-87);font-variant-numeric:tabular-nums;}

.ledger-row.range-row .k{font-size:var(--fs-small);}
.ledger-row.range-row .v{font-size:var(--fs-body);font-weight:600;color:var(--ink-60);}
.event-card select.ev-ccare{background:#fff;border:1px solid var(--line);border-radius:8px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-small);font-weight:600;padding:5px 6px;outline:none;}
.event-card select.ev-ccare:hover{border-color:var(--ink-60);}
.event-card select.ev-ccare:focus{border-color:var(--accent);}

.eq-row{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:10px;}
.eq-row label{flex:1;min-width:130px;font-size:var(--fs-small);font-weight:600;color:var(--ink-87);}
.eq-row .num-input{margin-top:4px;}

/* ---------- app shell + sidebar ---------- */
.app{display:flex;align-items:flex-start;min-height:100vh;}
.sidenav{position:sticky;top:0;flex:none;width:238px;height:100vh;display:flex;flex-direction:column;
  gap:4px;padding:22px 14px;background:#0A0E14;color:#fff;}
.sn-brand{font-weight:800;font-size:var(--fs-lead);color:var(--surface);text-decoration:none;letter-spacing:-0.01em;
  padding:0 8px;}
.sn-eyebrow{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;
  color:rgba(255,255,255,.36);padding:0 8px;margin-bottom:20px;}
.sn-list{display:flex;flex-direction:column;gap:3px;}
.sn-spacer{flex:1;}
.sn-list .tab{display:flex;align-items:center;gap:11px;width:100%;text-align:left;background:none;
  border:none;border-radius:11px;padding:11px 12px;color:rgba(255,255,255,.7);font-family:inherit;
  font-size:var(--fs-body);font-weight:600;cursor:pointer;
  transition:background .18s var(--ease),color .18s var(--ease);}
.sn-list .tab:hover{background:rgba(255,255,255,.08);color:#fff;}
.sn-list .tab.active{background:var(--accent);color:#fff;}
.sn-ico{font-size:var(--fs-lead);line-height:1;}
.sn-foot{border-top:1px solid rgba(255,255,255,.1);padding:14px 8px 0;}
.sn-foot p{font-size:var(--fs-micro);line-height:1.5;color:rgba(255,255,255,.42);margin:0 0 10px;}
.sn-foot a{font-size:var(--fs-micro);color:rgba(255,255,255,.62);text-decoration:none;}
.sn-foot a:hover{color:#fff;}
.appmain{flex:1;min-width:0;padding-top:0;}

/* ---------- top bar ---------- */
.topbar{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding:26px 0 4px;}
.topbar-title{font-size:var(--fs-h2);font-weight:900;letter-spacing:-0.02em;color:var(--ink-87);margin:0;
  flex:none;}
.topbar .scenario-bar{flex:1;min-width:280px;margin-top:0;padding:10px 14px;border-radius:14px;}

/* ---------- KPI strip ---------- */
.qe-strip,
.kpi-strip{display:grid;grid-template-columns:repeat(4,1fr);align-items:center;gap:10px;
  padding:14px 18px;background:#fff;border:1px solid var(--line-soft);border-radius:16px;
  box-shadow:var(--shadow-card);margin:12px 0 4px;position:sticky;top:12px;z-index:20;}
.qe-kpi,
.kpi{min-width:0;line-height:1.25;display:flex;flex-direction:column;justify-content:center;gap:2px;}
/* Five in the tool, four in Quick Estimate — Quick has no insights to count. */
.kpi-strip{grid-template-columns:repeat(5,1fr);}
@media (max-width:640px){
  .kpi-strip{grid-template-columns:repeat(2,1fr);}
  .kpi-strip > :last-child{grid-column:1/-1;}
}
.qe-kpi span,
.kpi span{display:block;line-height:1.3;font-size:var(--fs-micro);font-weight:700;
  letter-spacing:-0.005em;color:var(--ink-56);}
.qe-kpi b,
.kpi b{display:block;line-height:1.25;font-size:var(--fs-h3);font-weight:800;color:var(--ink-87);
  font-variant-numeric:tabular-nums;}
.kpi-lead b{color:var(--accent-deep);font-size:var(--fs-figure);}
.results-col{display:grid;grid-template-columns:1fr 1fr;gap:20px;align-items:start;}
.results-col>div{display:flex;flex-direction:column;gap:20px;min-width:0;}
@media (max-width:900px){.results-col{grid-template-columns:1fr;}}

/* ---------- net worth rings ---------- */
.nw-summary{background:#fff;border:1px solid var(--line-soft);border-radius:var(--radius-card);
  padding:26px 28px;box-shadow:var(--shadow-card);margin-bottom:20px;}
.ring-row{display:flex;flex-wrap:wrap;gap:30px;justify-content:flex-start;align-items:center;}
.ring{position:relative;width:150px;height:150px;flex:none;}
.ring svg{width:100%;height:100%;display:block;}
.ring-mid{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;text-align:center;pointer-events:none;}
.ring-mid b{font-size:var(--fs-figure);font-weight:800;color:var(--ink-87);font-variant-numeric:tabular-nums;
  letter-spacing:-0.01em;line-height:1.1;}
.ring-mid span{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;
  color:var(--ink-56);margin-top:3px;}
.ring-legend{display:flex;flex-wrap:wrap;gap:10px 22px;margin-top:22px;padding-top:18px;
  border-top:1px solid var(--line-soft);}
.rl{display:flex;align-items:center;gap:8px;font-size:var(--fs-small);color:var(--ink-60);}
.rl i{width:10px;height:10px;border-radius:3px;flex:none;}
.rl b{color:var(--ink-87);font-weight:700;font-variant-numeric:tabular-nums;}

@media (max-width:900px){
  .app{flex-direction:column;}
  /* Stacked, the main column is no longer a flex row item, so it needs an
     explicit width or wide content sizes it and the page scrolls sideways. */
  .appmain{width:100%;max-width:100%;}
  .sidenav{position:static;width:100%;height:auto;flex-direction:row;align-items:center;gap:10px;
    padding:12px 14px;overflow-x:auto;}
  .sn-eyebrow,.sn-foot{display:none;}
  .sn-brand{margin-right:8px;white-space:nowrap;}
  .sn-list{flex-direction:row;flex:1;}
  .sn-list .tab{white-space:nowrap;padding:9px 12px;}
  .kpi-strip{position:static;}
}

/* ---------- chart axes ---------- */
.chart-frame{display:flex;gap:8px;align-items:stretch;}
.chart-y{width:54px;flex:none;display:flex;flex-direction:column;justify-content:space-between;
  text-align:right;font-size:var(--fs-micro);color:var(--ink-56);font-variant-numeric:tabular-nums;padding:8px 0;
  line-height:1;}
#ySavings{padding:6px 0;}
.chart-frame>.chart,.chart-frame>.chart-hold{flex:1;min-width:0;}
.axis-inset{padding-left:62px;}

/* ---------- scenario picker ---------- */
.scen-note{font-size:var(--fs-micro);line-height:1.55;color:var(--ink-60);margin:0 0 12px;
  background:rgba(91,91,246,.04);border-radius:8px;padding:9px 11px;}
.scen-note b{color:var(--ink-87);font-weight:700;}

/* ---------- ages above the timeline ---------- */
.age-bar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:18px;background:#fff;
  border:1px solid var(--line-soft);border-radius:var(--radius-card);padding:18px 22px;
  box-shadow:var(--shadow-card);margin-bottom:16px;}
.age-field label{display:block;font-size:var(--fs-micro);font-weight:700;
  letter-spacing:-0.005em;color:var(--ink-56);margin-bottom:5px;}
.age-field .num-input{width:104px;}
.age-note{flex:1;min-width:220px;font-size:var(--fs-micro);color:var(--ink-56);margin:0;line-height:1.5;}
/* A partner's ages are the same question asked of someone else, so they join
   the card above rather than standing beside it as an equal. */
.age-bar:has(+ #partnerAges .age-bar){margin-bottom:0;
  border-bottom-left-radius:0;border-bottom-right-radius:0;}
.age-bar-partner{border-top:0;box-shadow:none;
  border-top-left-radius:0;border-top-right-radius:0;
  background:var(--paper-2, #fbfaf8);}
#partnerAges .you-note{margin-top:10px;}

/* ---------- timeline age ticks ---------- */
.tl-tick{position:absolute;top:50%;transform:translate(-50%,-50%);pointer-events:none;
  display:flex;flex-direction:column;align-items:center;z-index:1;}
.tl-tick i{display:block;width:1px;height:11px;background:var(--line);}
.tl-tick em{font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);margin-top:2px;
  font-variant-numeric:tabular-nums;}

.chart-hold{position:relative;}
.proj-markers{position:absolute;inset:0;pointer-events:none;}
.cb-row{grid-template-columns:1fr 132px 26px;}
.cb-row .cb-label{background:#fff;border:1px solid var(--line);border-radius:10px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-small);padding:8px 10px;outline:none;width:100%;
  transition:border-color .18s var(--ease);}
.cb-row .cb-label:hover{border-color:var(--ink-60);}
.cb-row .cb-label:focus{border-color:var(--accent);}
.cb-x{background:none;border:none;color:var(--ink-56);cursor:pointer;font-size:var(--fs-h3);
  transition:color .15s var(--ease),transform .15s var(--ease);}
.cb-x:hover{color:var(--brick);transform:scale(1.2);}
.pm{position:absolute;transform:translate(-50%,-50%);width:26px;height:26px;border-radius:50%;
  background:#fff;border:2px solid var(--warn);display:flex;align-items:center;justify-content:center;
  font-size:var(--fs-small);line-height:1;box-shadow:0 2px 6px rgba(0,0,0,.18);pointer-events:auto;cursor:default;
  transition:transform .15s var(--ease);}
.pm:hover{transform:translate(-50%,-50%) scale(1.18);z-index:4;}
.pm-lab{position:absolute;left:50%;top:calc(100% + 5px);transform:translateX(-50%);white-space:nowrap;max-width:min(210px,46vw);overflow:hidden;text-overflow:ellipsis;
  background:var(--ink-87);color:#fff;font-size:var(--fs-micro);font-weight:600;padding:3px 7px;border-radius:6px;
  opacity:0;transition:opacity .15s var(--ease);pointer-events:none;}
.pm:hover .pm-lab{opacity:1;}
.chart-tip{position:absolute;top:6px;transform:translateX(-50%);background:#fff;border:1px solid var(--line);
  border-radius:10px;box-shadow:var(--shadow-lift);padding:9px 12px;pointer-events:none;z-index:3;
  min-width:172px;display:flex;flex-direction:column;gap:3px;}
.chart-tip>b{font-size:var(--fs-micro);font-weight:800;letter-spacing:-0.005em;color:var(--ink-56);}
.chart-tip span{display:flex;align-items:center;gap:6px;font-size:var(--fs-micro);color:var(--ink-60);
  justify-content:space-between;}
.chart-tip span i{width:8px;height:8px;border-radius:2px;display:inline-block;flex:none;margin-right:-2px;}
.chart-tip span b{font-weight:700;color:var(--ink-87);font-variant-numeric:tabular-nums;margin-left:auto;}
.chart-tip .tip-total{border-top:1px solid var(--line-soft);margin-top:3px;padding-top:5px;}

.budget-summary{margin-top:12px;padding-top:10px;border-top:1px solid var(--line);}
.budget-summary .cf-row{padding:6px 0;}
.budget-summary .cf-row.total{margin-top:2px;padding-top:9px;font-size:var(--fs-lead);}

.nwp-grid{display:grid;gap:2px 8px;align-items:center;}
/* Real rows via subgrid: something for the eye to follow across five columns,
   and something to hover. Columns stay aligned to the parent track. */
.nwp-row{grid-column:1/-1;display:grid;grid-template-columns:subgrid;
  align-items:center;gap:8px;padding:3px 8px;margin:0 -8px;border-radius:10px;
  transition:background .14s var(--ease);}
.nwp-row:hover{background:rgba(11,14,20,.028);}
.nwp-names,.nwp-subs{padding-top:0;padding-bottom:0;}
.nwp-names:hover,.nwp-subs:hover{background:none;}
.nwp-head{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;
  color:var(--ink-87);text-align:center;padding-bottom:2px;grid-column:span 2;}
.nwp-label{font-size:var(--fs-small);color:var(--ink-87);font-weight:500;}
.nwp-label small{color:var(--ink-56);font-weight:500;font-size:var(--fs-micro);margin-left:3px;}
.nwp-cell{display:flex;align-items:center;background:#fff;border:1px solid var(--line);border-radius:8px;
  padding:0 8px;transition:border-color .18s var(--ease);}
.nwp-cell:hover{border-color:var(--ink-60);}
.nwp-cell:focus-within{border-color:var(--accent);}
.nwp-cell>span{color:var(--ink-56);font-size:var(--fs-small);margin-right:2px;}
.nwp-cell input{background:transparent;border:none;outline:none;width:100%;font-family:inherit;
  font-size:var(--fs-body);font-weight:600;color:var(--ink-87);padding:8px 0;font-variant-numeric:tabular-nums;}

.isa-opt{display:flex;align-items:flex-start;gap:9px;margin-top:12px;font-size:var(--fs-small);color:var(--ink-60);
  line-height:1.45;cursor:pointer;}
.isa-opt input{accent-color:var(--accent);width:16px;height:16px;flex:none;margin-top:1px;}
.isa-opt b{color:var(--accent-deep);font-weight:700;}
.nw-row label small{color:var(--ink-56);font-weight:500;font-size:var(--fs-micro);margin-left:3px;}

/* ---------- year-by-year bridge ---------- */
.bridge-toggle{margin-top:14px;width:100%;background:rgba(91,91,246,.05);border:1px dashed var(--line);
  border-radius:10px;color:var(--accent-deep);font-family:inherit;font-size:var(--fs-small);font-weight:700;
  padding:10px 12px;cursor:pointer;transition:background .18s var(--ease),border-color .18s var(--ease);}
.bridge-toggle:hover{background:rgba(91,91,246,.09);border-color:var(--accent);}
.bridge-scroll{max-height:340px;overflow:auto;margin-top:12px;border:1px solid var(--line-soft);border-radius:10px;}
.bridge-table{width:100%;border-collapse:collapse;font-size:var(--fs-body);font-variant-numeric:tabular-nums;}
.bridge-table th{position:sticky;top:0;background:#fff;text-align:right;font-size:var(--fs-micro);font-weight:700;
  letter-spacing:-0.005em;color:var(--ink-56);padding:9px 10px;
  border-bottom:1px solid var(--line);white-space:nowrap;}
.bridge-table th:first-child{text-align:left;}
.bridge-table td{text-align:right;padding:7px 10px;border-bottom:1px dashed var(--line-soft);color:var(--ink-60);}
.bridge-table td.age{text-align:left;font-weight:700;color:var(--ink-87);}
.bridge-table td.close{font-weight:700;color:var(--ink-87);}
.bridge-table td.pos{color:var(--accent-deep);}
.bridge-table td.neg{color:var(--brick);}
.bridge-table tr:hover td{background:rgba(91,91,246,.035);}

/* ---------- mode selector ---------- */
.mode-select{display:flex;align-items:center;gap:16px;margin-top:30px;flex-wrap:wrap;}
.mode-label{font-size:var(--fs-body);font-weight:600;color:var(--ink-87);}
.mode-btns{display:inline-flex;background:#fff;border:1px solid var(--line);border-radius:12px;padding:4px;gap:4px;
  box-shadow:var(--shadow-card);}
.mode-btn{border:none;background:none;font-family:inherit;font-size:var(--fs-body);font-weight:600;color:var(--ink-60);
  padding:9px 18px;border-radius:9px;cursor:pointer;transition:background .18s var(--ease),color .18s var(--ease);}
.mode-btn:hover{color:var(--ink-87);}
.mode-btn.active{background:var(--accent);color:#fff;}
.mode-btn.active:hover{color:#fff;}

/* ---------- net worth builder ---------- */
.networth-block{background:rgba(91,91,246,.04);border:1px solid var(--line-soft);border-radius:14px;
  padding:18px 18px 16px;margin-top:9px;}
.nw-subhead{font-size:var(--fs-micro);font-weight:700;letter-spacing:0.1em;color:var(--ink-56);
  margin:14px 0 10px;}
.nw-subhead:first-child{margin-top:0;}
.nw-row{display:grid;grid-template-columns:1fr 132px;gap:10px;align-items:center;margin-bottom:8px;}
.nw-row label{font-size:var(--fs-small);color:var(--ink-87);font-weight:500;margin:0;}
.nw-row .num-input{padding:0 10px;}
.nw-row .num-input input[type=number]{font-size:var(--fs-body);padding:8px 0;}
.nw-total{display:flex;justify-content:space-between;align-items:baseline;margin-top:14px;padding-top:12px;
  border-top:2px solid var(--accent);}
.nw-total span{font-size:var(--fs-small);font-weight:600;color:var(--ink-87);}
.nw-total b{font-size:var(--fs-figure);font-weight:800;color:var(--accent-deep);font-variant-numeric:tabular-nums;}

/* ---------- person bar (tabs + mode) ---------- */
.person-bar{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;
  margin-bottom:18px;}
.person-tabs{display:inline-flex;gap:6px;}
.p-tab{background:#fff;border:1px solid var(--line);border-radius:var(--radius-pill);font-family:inherit;font-size:var(--fs-body);
  font-weight:600;color:var(--ink-60);padding:8px 16px;cursor:pointer;box-shadow:var(--shadow-card);
  transition:border-color .18s var(--ease),color .18s var(--ease),background .18s var(--ease);}
.p-tab:hover{border-color:var(--accent);color:var(--ink-87);}
.p-tab.active{background:var(--accent);border-color:var(--accent);color:#fff;}
.p-tab.add{border-style:dashed;box-shadow:none;color:var(--accent-deep);}
.p-tab .p-x{margin-left:6px;opacity:.7;}
.p-tab .p-x:hover{opacity:1;}
.mode-btns{display:inline-flex;background:#fff;border:1px solid var(--line);border-radius:12px;padding:4px;gap:4px;
  box-shadow:var(--shadow-card);}
.mode-btn{border:none;background:none;font-family:inherit;font-size:var(--fs-body);font-weight:600;color:var(--ink-60);
  padding:9px 18px;border-radius:9px;cursor:pointer;transition:background .18s var(--ease),color .18s var(--ease);}
.mode-btn:hover{color:var(--ink-87);}
.mode-btn.active{background:var(--accent);color:#fff;}
.mode-btn.active:hover{color:#fff;}

/* ---------- tax drill-down ---------- */
.ledger-row.drillable{cursor:pointer;user-select:none;}
.ledger-row.drillable:hover .k{color:var(--ink-87);}
.ledger-row .chev{display:inline-block;border:1px solid var(--line);border-radius:var(--radius-pill);padding:1px 7px;
  font-size:var(--fs-micro);font-weight:700;color:var(--accent-deep);background:rgba(91,91,246,.06);
  margin-left:5px;vertical-align:middle;font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);margin-left:2px;}
.drill{background:rgba(3,105,161,.05);border-radius:10px;padding:10px 14px;margin:4px 0 8px;}
.drill-row{display:flex;justify-content:space-between;gap:12px;font-size:var(--fs-small);color:var(--ink-60);
  padding:4px 0;font-variant-numeric:tabular-nums;}
.drill-row b{color:var(--ink-87);font-weight:600;white-space:nowrap;}
.ledger-row.rowsub{border-bottom:none;padding:4px 0;font-size:var(--fs-lead);}
.ledger-row.rowsub .k{color:var(--ink-56);}
.row-note{font-size:var(--fs-micro);line-height:1.55;color:var(--ink-56);margin:10px 0 0;
  padding-top:9px;border-top:1px dashed var(--line-soft);}
.row-note b{color:var(--ink-60);font-weight:700;}

/* ---------- tax facts ---------- */
.facts-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:14px;}
.fact{background:#fff;border:1px solid var(--line-soft);border-radius:16px;
  padding:18px 20px;font-size:var(--fs-body);line-height:1.6;color:var(--ink-60);box-shadow:var(--shadow-card);
  transition:box-shadow .18s var(--ease),transform .18s var(--ease);}
.fact:hover{box-shadow:var(--shadow-lift);transform:translateY(-1px);}
.fact b{color:var(--ink-87);display:flex;align-items:center;gap:9px;font-size:var(--fs-lead);font-weight:800;
  letter-spacing:-0.01em;margin-bottom:6px;}
.fact b::before{content:'';flex:none;width:9px;height:9px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 3px rgba(91,91,246,.13);}

/* ---------- small seg variant ---------- */
.seg-sm .seg-btn{font-size:var(--fs-micro);padding:6px 11px;}
.nw-total b.neg,.cf-v.neg{color:var(--brick);}

/* ---------- inline segmented control (pension method) ---------- */
.seg{display:inline-flex;background:#fff;border:1px solid var(--line);border-radius:10px;padding:3px;gap:3px;
  flex-wrap:wrap;}
.seg-btn{border:none;background:none;font-family:inherit;font-size:var(--fs-small);font-weight:600;color:var(--ink-60);
  padding:7px 13px;border-radius:8px;cursor:pointer;transition:background .18s var(--ease),color .18s var(--ease);}
.seg-btn:hover{color:var(--ink-87);}
.seg-btn.active{background:var(--accent);color:#fff;}
.seg-btn.active:hover{color:#fff;}

/* ---------- timeline visual ---------- */
.timeline-wrap{background:#fff;border:1px solid var(--line-soft);border-radius:var(--radius-card);
  padding:24px 32px 20px;box-shadow:var(--shadow-card);margin-bottom:20px;}
.tl-head{display:flex;justify-content:space-between;align-items:baseline;}
.tl-title{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;color:var(--ink-56);}
.tl-title span{display:block;font-size:var(--fs-body);font-weight:800;letter-spacing:-0.01em;color:var(--ink-87);
  text-transform:none;margin-top:2px;}
.tl-title.right{text-align:right;}
.timeline-track{position:relative;height:200px;margin:6px 0 2px;transition:height .2s var(--ease);}
.tl-line{position:absolute;top:50%;left:0;right:0;height:3px;border-radius:3px;
  background:linear-gradient(90deg,var(--accent) 0%,#D97706 70%,var(--brick) 100%);transform:translateY(-50%);}
.tl-mark{position:absolute;top:0;bottom:0;width:0;}
.tl-dot{position:absolute;top:50%;left:50%;width:13px;height:13px;border-radius:50%;background:#fff;
  border:3px solid var(--accent);transform:translate(-50%,-50%);z-index:2;box-shadow:0 1px 4px rgba(0,0,0,.15);}
.tl-stem{position:absolute;left:50%;width:1px;background:var(--line);transform:translateX(-50%);}
.tl-mark.above .tl-stem{bottom:50%;height:var(--off,26px);}
.tl-mark.below .tl-stem{top:50%;height:var(--off,26px);}
.tl-mark{cursor:grab;}
.tl-mark.dragging{cursor:grabbing;z-index:5;}
.tl-mark.dragging .tl-pill{box-shadow:var(--shadow-lift);}
.tl-mark:focus-visible{outline:none;}
.tl-mark:focus-visible .tl-pill{outline:2px solid var(--accent);outline-offset:2px;}
.tl-pill{position:absolute;left:0;display:flex;align-items:center;gap:8px;max-width:min(230px, 42vw);
  background:#fff;border:1px solid var(--line);border-radius:12px;padding:8px 12px;box-shadow:var(--shadow-card);
  white-space:nowrap;transition:box-shadow .18s var(--ease);}
.tl-mark.above .tl-pill{bottom:calc(50% + var(--off,26px));}
.tl-mark.below .tl-pill{top:calc(50% + var(--off,26px));}
.tl-pill:hover{box-shadow:var(--shadow-lift);}
.tl-ico{font-size:var(--fs-h3);line-height:1;}
.tl-text{display:flex;flex-direction:column;line-height:1.3;}
.tl-text b{font-size:var(--fs-small);font-weight:700;color:var(--ink-87);}
.tl-text em{font-size:var(--fs-micro);font-style:normal;color:var(--ink-56);font-variant-numeric:tabular-nums;}
.tl-hint{font-size:var(--fs-micro);color:var(--ink-56);text-align:center;margin:2px 0 0;}
.tl-empty{text-align:center;color:var(--ink-56);font-size:var(--fs-body);padding:8px 0 4px;}

/* ---------- quick add chips ---------- */
.quick-add{display:flex;flex-direction:column;gap:12px;margin-bottom:18px;}
.qa-group{display:flex;flex-wrap:wrap;gap:8px;align-items:center;}
.qa-group .qa-label{flex:0 0 148px;}
@media (max-width:700px){.qa-group .qa-label{flex:1 0 100%;}}
.qa-label{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;color:var(--ink-56);
  margin-right:4px;}
.qa-btn{background:#fff;border:1px solid var(--line);border-radius:var(--radius-pill);font-family:inherit;font-size:var(--fs-small);
  font-weight:600;color:var(--ink-87);padding:8px 15px;cursor:pointer;box-shadow:var(--shadow-card);
  transition:border-color .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease);}
.qa-btn:hover{border-color:var(--accent);transform:translateY(-1px);box-shadow:var(--shadow-lift);}
.qa-btn:active{transform:translateY(0);}

/* ---------- milestone cards ---------- */
/* min() so the 310px floor can't exceed the container — below that width the
   track was staying at 310 and pushing each card past the screen edge. */
.event-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(310px,100%),1fr));gap:14px;}
.event-card{background:#fff;border:1px solid var(--line-soft);border-radius:14px;padding:16px;
  box-shadow:var(--shadow-card);transition:box-shadow .18s var(--ease);}
.event-card:hover{box-shadow:var(--shadow-lift);}
.event-head{display:grid;grid-template-columns:auto 1fr 26px;gap:9px;align-items:center;margin-bottom:11px;}
.ev-icon{font-size:var(--fs-figure);line-height:1;}
.event-head .ev-name{background:none;border:none;border-bottom:1px solid transparent;border-radius:0;
  color:var(--ink-87);font-family:inherit;font-size:var(--fs-lead);font-weight:700;padding:2px 0;outline:none;width:100%;
  transition:border-color .18s var(--ease);}
.event-head .ev-name:hover{border-bottom-color:var(--line);}
.event-head .ev-name:focus{border-bottom-color:var(--accent);}
.event-head .ev-remove{background:none;border:none;color:var(--ink-56);cursor:pointer;font-size:var(--fs-h3);
  transition:color .15s var(--ease),transform .15s var(--ease);}
.event-head .ev-remove:hover{color:var(--brick);transform:scale(1.2);}
.event-sub{display:flex;gap:8px;align-items:center;margin-bottom:12px;flex-wrap:wrap;}
.event-sub .ev-type{flex:1;min-width:140px;background:#fff;border:1px solid var(--line);border-radius:8px;
  color:var(--ink-60);font-family:inherit;font-size:var(--fs-small);padding:7px 9px;outline:none;
  transition:border-color .18s var(--ease);}
.event-sub .ev-type:hover{border-color:var(--ink-60);}
.event-sub .ev-type:focus{border-color:var(--accent);}
.event-body{display:flex;flex-wrap:wrap;gap:9px 12px;align-items:center;padding-top:11px;
  border-top:1px dashed var(--line-soft);}
.event-card label{display:inline-flex;align-items:center;gap:5px;font-size:var(--fs-small);color:var(--ink-60);
  font-weight:500;margin:0;}
.event-card .ev-group{display:inline-flex;flex-wrap:wrap;gap:9px 12px;align-items:center;}
.event-card input[type=number]{background:#fff;border:1px solid var(--line);border-radius:8px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-small);font-weight:600;padding:6px 8px;outline:none;width:78px;
  font-variant-numeric:tabular-nums;transition:border-color .18s var(--ease);}
.event-card input[type=number]:hover{border-color:var(--ink-60);}
.event-card input[type=number]:focus{border-color:var(--accent);}
.event-card .ev-when{width:52px;}
.ev-punit{color:var(--ink-56);font-size:var(--fs-micro);}

/* ---------- asset allocation ---------- */
.alloc-head{display:grid;grid-template-columns:1fr 90px 90px;gap:8px;
  font-size:var(--fs-micro);font-weight:700;color:var(--ink-56);letter-spacing:0.1em;margin-bottom:6px;}
.alloc-row{display:grid;grid-template-columns:1fr 90px 90px;gap:8px;align-items:center;margin-bottom:8px;}
/* min-width:0 or the 1fr never shrinks. A grid item's automatic minimum is its
   min-content, so "Private markets" held the first column at 138px inside a
   255px row and pushed the two 72px inputs 39px past the card — where .fold's
   overflow:hidden clipped the returns field off the screen entirely. On a
   phone the row stacks instead; see the 560px block. */
.alloc-row .alloc-name{font-size:var(--fs-body);color:var(--ink-87);display:flex;
  align-items:center;gap:8px;min-width:0;}
.alloc-row .alloc-name i{width:10px;height:10px;border-radius:3px;display:inline-block;flex:none;}
.alloc-row .alloc-name small{font-size:var(--fs-micro);color:var(--ink-56);font-weight:500;margin-left:2px;}
.alloc-row input{background:#fff;border:1px solid var(--line);border-radius:10px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-body);font-weight:500;padding:9px 10px;outline:none;width:100%;
  font-variant-numeric:tabular-nums;transition:border-color .18s var(--ease);}
.alloc-row input:hover{border-color:var(--ink-60);}
.alloc-row input:focus{border-color:var(--accent);}
.alloc-bar{display:flex;height:10px;border-radius:5px;overflow:hidden;margin-top:10px;background:var(--line-soft);}
.alloc-bar span{transition:width .3s var(--ease);}
.alloc-note{font-size:var(--fs-small);font-weight:600;color:var(--accent-deep);margin-top:8px;min-height:16px;}

/* ---------- output cards ---------- */
.ledger-card{padding:26px 28px 22px;position:relative;overflow:hidden;}
.ledger-title{letter-spacing:-0.005em;font-size:var(--fs-small);font-weight:600;
  color:var(--ink-56);margin-bottom:18px;border-bottom:1px solid var(--line-soft);padding-bottom:12px;}
/* Same row size as .cf-row: these two cards sit in one column and are read as
   one thing. Subtotals step to --fs-lead and totals to --fs-h3, so the scale
   still carries hierarchy — it just isn't the default any more. */
.ledger-row{display:flex;justify-content:space-between;align-items:baseline;padding:9.5px 0;
  border-bottom:1px dashed var(--line-soft);font-size:var(--fs-body);position:relative;z-index:1;}
.ledger-row.total{border-bottom:none;border-top:2px solid var(--accent);margin-top:6px;padding-top:14px;
  font-size:var(--fs-h3);}
.ledger-row .k{color:var(--ink-60);}
.ledger-row .v{font-weight:700;color:var(--ink-87);font-variant-numeric:tabular-nums;}
.stamp{position:absolute;top:20px;right:22px;background:rgba(91,91,246,.10);color:var(--accent-deep);
  border-radius:var(--radius-pill);padding:7px 16px;font-size:var(--fs-micro);font-weight:700;letter-spacing:0.04em;
  line-height:1.3;z-index:0;}
.stamp.restamp{animation:restamp .45s var(--ease);}
@keyframes restamp{
  0%{transform:scale(1);}
  35%{transform:scale(1.1);}
  100%{transform:scale(1);}
}
.why-panel{margin-top:22px;padding:24px 28px;}
.why-panel h3{font-weight:800;font-size:var(--fs-h3);color:var(--ink-87);margin:0 0 4px;}
.why-panel .sub2{font-size:var(--fs-small);color:var(--ink-56);margin-bottom:16px;}
.why-text{font-size:var(--fs-body);line-height:1.6;margin-top:14px;color:var(--ink-60);}
.why-text b{color:#D97706;}
svg.chart{width:100%;height:170px;display:block;}
.chart-legend{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:10px;font-size:var(--fs-micro);color:var(--ink-60);}
.chart-legend .key{display:inline-block;width:16px;height:3px;vertical-align:middle;margin-right:6px;border-radius:2px;}

/* ---------- cashflow card ---------- */
.cf-row{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:8px 0;
  border-bottom:1px dashed var(--line-soft);font-size:var(--fs-body);}
.cf-row:last-of-type{border-bottom:none;}
.cf-row.total{border-bottom:none;border-top:2px solid var(--accent);margin-top:4px;padding-top:12px;
  font-size:var(--fs-lead);font-weight:700;}
.cf-k{color:var(--ink-60);display:flex;flex-direction:column;line-height:1.35;}
.cf-k em{font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);font-variant-numeric:tabular-nums;}
.cf-row.total .cf-k{color:var(--ink-87);}
.cf-v{font-weight:700;color:var(--ink-87);font-variant-numeric:tabular-nums;white-space:nowrap;}
.cf-v.pos{color:var(--accent-deep);}
.cf-v.neg{color:var(--brick);}
.cf-chart{height:96px;margin-top:14px;}
.cf-axis{display:flex;justify-content:space-between;font-size:var(--fs-micro);color:var(--ink-56);margin-top:2px;
  font-variant-numeric:tabular-nums;}
.cf-note{font-size:var(--fs-micro);color:var(--ink-56);margin-top:10px;line-height:1.5;}

/* ---------- warning banner ---------- */
.warn{display:flex;gap:14px;align-items:flex-start;background:#fff;border:1px solid #F2DCC0;
  border-radius:16px;padding:18px 20px;margin-bottom:20px;box-shadow:var(--shadow-card);
  font-size:var(--fs-body);line-height:1.6;color:var(--ink-60);}
.warn::before{content:'!';flex:none;width:30px;height:30px;border-radius:50%;
  background:linear-gradient(140deg,#FDEBD2,#F6D3A6);color:var(--warn-deep);
  display:flex;align-items:center;justify-content:center;font-weight:900;font-size:var(--fs-h3);
  box-shadow:inset 0 0 0 1px rgba(217,119,6,.16);}
.warn-body{min-width:0;}
.warn b{display:block;color:var(--ink-87);font-weight:800;font-size:var(--fs-lead);
  letter-spacing:-0.01em;margin-bottom:3px;}

/* ---------- gap figure (signature moment, tool page) ---------- */
.gap-stamp{padding:38px 34px 32px;text-align:center;margin-top:26px;position:relative;}
.gap-stamp .gap-label{letter-spacing:-0.005em;font-size:var(--fs-micro);font-weight:700;
  color:var(--ink-56);margin-bottom:12px;}
.gap-stamp .gap-figure{font-weight:900;font-size:clamp(40px,6vw,64px);line-height:1.08;
  letter-spacing:-0.02em;font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;}
.gap-stamp .gap-sub{font-size:var(--fs-body);color:var(--ink-60);max-width:520px;margin:14px auto 0;}
.bar-row{margin-bottom:16px;margin-top:20px;}
/* space-between puts all the slack between the two, and none at all once the
   label is long enough to take the row — "Your optimised split, compounded"
   ended one pixel before £4,947,913 began, which reads as one broken word. A
   gap is the floor; the label gives way first because the figure must not
   wrap. */
.bar-label{display:flex;justify-content:space-between;gap:var(--space-3);
  font-size:var(--fs-small);margin-bottom:6px;color:var(--ink-60);}
.bar-label>:first-child{min-width:0;}
.bar-label b{white-space:nowrap;}
/* Which scenario the two figures are on, beside the label rather than in it —
   they used to say nothing, and read the base case whatever was selected. */
.bar-label em{font-style:normal;color:var(--ink-56);}
/* The caveat beside a recommendation, in the muted ink so it reads as part of
   the same sentence rather than a warning. */
.why-flat{display:block;margin-top:8px;color:var(--ink-56);}

/* The ranked levers. A numbered list, largest first — the rank is the point,
   so it is set as a figure rather than a bullet. Same type scale as every
   other table on this screen: one size for the prose, the figure on weight. */
.lev-lead{font-size:var(--fs-small);color:var(--ink-60);line-height:1.6;margin-bottom:var(--space-4);}
.lev-row{display:grid;grid-template-columns:28px 1fr;gap:var(--space-3);
  padding:var(--space-4) 0;border-bottom:1px solid var(--line-soft);}
.lev-row:last-of-type{border-bottom:none;}
.lev-rank{font-family:var(--mono);font-size:var(--fs-small);font-weight:600;
  color:var(--ink-56);line-height:1.5;}
.lev-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:var(--space-2) var(--space-4);}
.lev-head b{font-size:var(--fs-body);font-weight:700;color:var(--ink-87);}
.lev-fig{font-family:var(--mono);font-size:var(--fs-body);font-weight:800;
  color:var(--accent-deep);text-align:right;letter-spacing:-0.01em;}
.lev-fig em{display:block;font-style:normal;font-family:var(--sans);font-size:var(--fs-micro);
  font-weight:500;color:var(--ink-56);letter-spacing:0;}
.lev-body{margin:6px 0 0;font-size:var(--fs-small);line-height:1.65;color:var(--ink-60);
  max-width:70ch;}
.lev-foot{margin:var(--space-4) 0 0;font-size:var(--fs-micro);line-height:1.6;color:var(--ink-56);}
@media (max-width:560px){
  .lev-head{justify-content:flex-start;}
  .lev-fig{text-align:left;}
}
.bar-label b{color:var(--ink-87);font-weight:700;font-variant-numeric:tabular-nums;}
.bar-track{height:22px;background:var(--line-soft);border-radius:11px;overflow:hidden;}
.bar-fill{height:100%;background:var(--accent);transition:width .45s var(--ease);border-radius:11px 0 0 11px;}
.bar-fill.you{background:var(--accent);}

/* ---------- buttons ---------- */
.btn{display:inline-block;background:#111;border:none;color:#fff;font-weight:700;font-size:var(--fs-lead);
  padding:15px 30px;border-radius:14px;cursor:pointer;font-family:inherit;text-decoration:none;
  white-space:nowrap;transition:transform .18s var(--ease),box-shadow .18s var(--ease),background .18s var(--ease);}
.btn:hover{background:#000;transform:translateY(-2px);box-shadow:var(--shadow-lift);}
.btn:active{transform:translateY(0);box-shadow:none;}
.btn-ghost{background:none;border:1.5px solid var(--line);color:var(--ink-87);
  transition:border-color .18s var(--ease);}
.btn-ghost:hover{background:none;border-color:var(--ink-87);color:var(--ink-87);transform:none;box-shadow:none;}

/* ---------- signup ---------- */
.signup-panel{padding:40px 36px;text-align:center;margin-top:72px;}
.signup-panel p{color:var(--ink-60);max-width:480px;margin:0 auto 22px;font-size:var(--fs-lead);}
.signup-form{display:flex;gap:10px;max-width:460px;margin:0 auto;}
@media (max-width:520px){.signup-form{flex-direction:column;}}
.signup-form input[type=email]{flex:1;background:#fff;border:1px solid var(--line);border-radius:14px;
  color:var(--ink-87);font-family:inherit;font-size:var(--fs-lead);padding:13px 16px;outline:none;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);}
.signup-form input[type=email]:hover{border-color:var(--ink-60);}
.signup-form input[type=email]:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(91,91,246,.13);}
.signup-status{font-size:var(--fs-body);font-weight:600;color:var(--accent-deep);margin-top:14px;min-height:18px;}

/* ---------- landing: status columns ---------- */
.status-grid{display:grid;grid-template-columns:1fr 1fr;gap:22px;align-items:stretch;}
@media (max-width:860px){.status-grid{grid-template-columns:1fr;}}
.status-list{list-style:none;padding:0;margin:0;}
.status-list li{padding:14px 0 14px 30px;border-bottom:1px dashed var(--line-soft);position:relative;
  font-size:var(--fs-body);line-height:1.6;color:var(--ink-60);}
.status-list li:last-child{border-bottom:none;}
.status-list li::before{content:'✓';position:absolute;left:2px;top:14px;color:var(--accent);
  font-weight:900;font-size:var(--fs-lead);}
.status-list li b{display:block;font-weight:700;color:var(--ink-87);}
.roadmap-panel{padding:26px 28px;}
.roadmap-list{list-style:none;padding:0;margin:0;}
.roadmap-list li{padding:14px 0 14px 30px;border-bottom:1px dashed var(--line-soft);position:relative;
  font-size:var(--fs-body);line-height:1.6;color:var(--ink-60);}
.roadmap-list li:last-child{border-bottom:none;}
.roadmap-list li::before{content:'';position:absolute;left:5px;top:22px;width:7px;height:7px;border-radius:50%;
  background:var(--grad);}
.roadmap-list li b{display:block;font-weight:700;color:var(--ink-87);}
.roadmap-note{font-size:var(--fs-small);color:var(--ink-56);margin-top:18px;padding-top:14px;
  border-top:1px solid var(--line-soft);font-style:italic;}

/* ---------- landing: hero + misc ---------- */
.hero{padding:80px 0 12px;animation:fadeUp .55s var(--ease) both;}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}
.hero-ctas{display:flex;gap:14px;align-items:center;margin:34px 0 10px;flex-wrap:wrap;}
.hero-trust{font-size:var(--fs-small);font-weight:500;color:var(--ink-56);margin-top:18px;
  display:flex;align-items:center;gap:8px;}
.hero-trust::before{content:'';width:7px;height:7px;border-radius:50%;background:var(--green-ok);flex:none;}
.wedge{font-size:clamp(21px,2.7vw,28px);font-weight:400;line-height:1.5;
  color:var(--ink-87);max-width:780px;}
.wedge b{font-weight:800;background:var(--grad);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;}

/* ---------- footer ---------- */
footer{margin-top:72px;padding-top:26px;border-top:1px solid var(--line-soft);font-size:var(--fs-small);color:var(--ink-56);}
footer p{margin:0 0 10px;max-width:780px;}
footer .feedback{font-size:var(--fs-h3);font-weight:600;color:var(--ink-87);margin-top:20px;}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important;}
  html{scroll-behavior:auto;}
}

/* ---------- scenario overflow menu ---------- */
.sc-more{position:relative;}
.sc-icon{padding:8px 12px;font-size:var(--fs-h3);line-height:1;letter-spacing:.05em;}
.sc-menu{position:absolute;right:0;top:calc(100% + 6px);z-index:40;min-width:216px;
  background:#fff;border:1px solid var(--line-soft);border-radius:14px;box-shadow:var(--shadow-lift);
  padding:6px;display:flex;flex-direction:column;}
.sc-menu button{background:none;border:none;text-align:left;font-family:inherit;font-size:var(--fs-body);
  font-weight:600;color:var(--ink-87);padding:10px 12px;border-radius:9px;cursor:pointer;
  transition:background .15s var(--ease);}
.sc-menu button:hover{background:rgba(91,91,246,.07);}
.sc-menu button.danger{color:var(--brick);}
.sc-menu button.danger:hover{background:rgba(190,18,60,.07);}
.sc-sep{height:1px;background:var(--line-soft);margin:5px 4px;}

/* ---------- age picker on the projection card ---------- */
.card-title-row{display:flex;align-items:center;gap:9px;flex-wrap:wrap;}
.age-pick{background:var(--surface-sunk);border:1px solid transparent;border-radius:9px;color:var(--ink-87);
  font-family:inherit;font-size:var(--fs-micro);font-weight:700;padding:5px 8px;outline:none;cursor:pointer;
  text-transform:none;letter-spacing:0;transition:background .18s var(--ease),border-color .18s var(--ease);}
.age-pick:hover{background:#EFF3F1;}
.age-pick:focus{background:#fff;border-color:var(--accent);}

/* ---------- contextual actions ---------- */
.tab-actions{display:flex;justify-content:flex-end;margin-top:22px;}
.btn-ghost-sm{background:#fff;border:1px solid var(--line);border-radius:12px;font-family:inherit;
  font-size:var(--fs-body);font-weight:700;color:var(--ink-87);padding:11px 18px;cursor:pointer;
  box-shadow:var(--shadow-card);transition:border-color .18s var(--ease),transform .18s var(--ease);}
.btn-ghost-sm:hover{border-color:var(--accent);transform:translateY(-1px);}

/* ---------- worth-knowing card ---------- */
.facts-card{background:#fff;border:1px solid var(--line-soft);border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);padding:28px 30px;margin-top:26px;}
.facts-head{display:flex;flex-wrap:wrap;gap:12px 28px;align-items:flex-end;
  padding-bottom:20px;border-bottom:1px solid var(--line-soft);margin-bottom:6px;}
.facts-head h2{margin:0;font-size:var(--fs-h2);}
.facts-head p{flex:1;min-width:260px;font-size:var(--fs-small);color:var(--ink-56);margin:0;line-height:1.55;}
.facts-head p b{color:var(--ink-60);font-weight:700;}
.facts-list{display:flex;flex-direction:column;}
.facts-list .fact{display:flex;gap:14px;align-items:flex-start;background:none;border:none;
  border-bottom:1px solid var(--line-soft);border-radius:0;box-shadow:none;padding:18px 0;
  font-size:var(--fs-body);line-height:1.6;color:var(--ink-60);transform:none;}
.facts-list .fact:last-child{border-bottom:none;padding-bottom:2px;}
.facts-list .fact:hover{box-shadow:none;transform:none;}
.fact-ico{flex:none;width:26px;height:26px;border-radius:50%;display:flex;align-items:center;
  justify-content:center;background:rgba(91,91,246,.1);color:var(--accent-deep);
  font-size:var(--fs-small);font-weight:800;font-style:italic;}
.fact-ico.ok{font-style:normal;}
.fact-body b{display:block;color:var(--ink-87);font-weight:800;font-size:var(--fs-lead);
  letter-spacing:-0.01em;margin-bottom:3px;font-style:normal;}
.fact-body{min-width:0;}

/* ---------- year-by-year card ---------- */
.bridge-card{background:#fff;border:1px solid var(--line-soft);border-radius:var(--radius-card);
  box-shadow:var(--shadow-card);padding:26px 28px;margin-top:22px;}
.bridge-head{display:flex;flex-wrap:wrap;gap:14px;align-items:center;justify-content:space-between;
  margin-bottom:16px;}
.bridge-head h3{margin:0;font-size:var(--fs-figure);font-weight:800;color:var(--ink-87);letter-spacing:-0.01em;}
.bridge-head p{margin:2px 0 0;font-size:var(--fs-small);color:var(--ink-56);}
.bridge-card .bridge-table{width:100%;border-collapse:collapse;font-size:var(--fs-small);
  font-variant-numeric:tabular-nums;}
.bridge-card .bridge-table th{text-align:right;font-size:var(--fs-micro);font-weight:700;
  letter-spacing:-0.005em;color:var(--ink-56);padding:9px 10px;
  border-bottom:1px solid var(--line);white-space:nowrap;background:none;}
.bridge-card .bridge-table th.c-age{text-align:left;}
.bridge-card .bridge-table th.c-x{width:32px;}
.br-row{cursor:pointer;transition:background .15s var(--ease);}
.br-row td{text-align:right;padding:10px;border-bottom:1px solid var(--line-soft);color:var(--ink-60);}
.br-row td.c-age{text-align:left;font-weight:700;color:var(--ink-87);white-space:nowrap;}
.br-row td.close{font-weight:700;color:var(--ink-87);}
.br-row td.pos{color:var(--accent-deep);}
.br-row td.neg{color:var(--brick);}
.br-row:hover{background:rgba(91,91,246,.04);}
.br-row.open{background:rgba(91,91,246,.06);}
.br-row .part{font-style:normal;font-size:var(--fs-micro);font-weight:700;color:var(--warn);
  background:rgba(217,119,6,.1);border-radius:5px;padding:1px 5px;margin-left:4px;}
.br-chev{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;
  border-radius:50%;background:rgba(0,0,0,.05);color:var(--ink-60);font-weight:800;font-size:var(--fs-micro);}
.br-row.open .br-chev{background:var(--accent);color:#fff;}
.br-detail td{padding:0 10px 18px;background:rgba(91,91,246,.03);border-bottom:1px solid var(--line-soft);}
.bd-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:22px;padding-top:14px;}
.bd-col h5{margin:0 0 8px;font-size:var(--fs-micro);font-weight:800;letter-spacing:-0.005em;
  color:var(--ink-56);}
.bd-row{display:flex;justify-content:space-between;gap:12px;align-items:baseline;padding:5px 0;
  border-bottom:1px dashed var(--line-soft);font-size:var(--fs-small);color:var(--ink-60);}
.bd-row:last-child{border-bottom:none;}
.bd-row b{font-weight:700;color:var(--ink-87);white-space:nowrap;}
.bd-row b.pos{color:var(--accent-deep);}
.bd-row b.neg{color:var(--brick);}
.bd-row b.tot{border-top:2px solid var(--accent);padding-top:2px;}
.bd-note{font-size:var(--fs-micro);color:var(--ink-56);margin:14px 0 0;}
@media (max-width:820px){
  .bridge-card{padding:20px 14px;}
  /* Drop Opening, not Change and the chevron.
     Opening is the one column recoverable from the row itself — Closing minus
     Change — so it costs nothing to lose. Change is the number the row is
     about, and the chevron is the only cue that a year opens at all, which is
     the thing this table does that nothing else in the market does. Hiding
     those two to keep a derivable one was the wrong trade. */
  .bridge-card .bridge-table th.c-open,.br-row td.c-open{display:none;}
}

.kpi-muted b{font-size:var(--fs-body);}
.kpi-cta{background:none;border:none;padding:0;font-family:inherit;font-size:var(--fs-body);font-weight:700;
  color:var(--accent-deep);cursor:pointer;text-align:left;border-bottom:1.5px solid rgba(91,91,246,.35);
  transition:border-color .18s var(--ease);}
.kpi-cta:hover{border-bottom-color:var(--accent);}
.bd-note.warnish{color:var(--warn-deep);background:#FDF6EC;border-radius:9px;padding:9px 11px;}

/* ---------- waterfall ---------- */
.wf-axis{display:grid;gap:4px;padding-left:62px;margin-top:6px;}
.wf-tick{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;}
.wf-tick em{font-style:normal;font-size:var(--fs-micro);font-weight:600;color:var(--ink-56);
  letter-spacing:.04em;line-height:1.2;}
.wf-tick b{font-size:var(--fs-micro);font-weight:700;color:var(--ink-87);font-variant-numeric:tabular-nums;
  margin-top:2px;}
.wf-tick b.pos{color:var(--accent-deep);}
.wf-tick b.neg{color:var(--brick);}
@media (max-width:820px){.wf-tick em{display:none;}}

/* ---------- pot movement rows ---------- */
.pot-row b{display:inline-flex;align-items:baseline;gap:6px;}
.pot-from{color:var(--ink-56);font-weight:600;}
.pot-arrow{color:var(--ink-56);font-weight:400;}
.pot-to{color:var(--ink-87);font-weight:700;}
.pot-pc{font-style:normal;font-size:var(--fs-micro);font-weight:700;padding:1px 6px;border-radius:6px;
  background:rgba(0,0,0,.05);}
.pot-pc.pos{color:var(--accent-deep);background:rgba(91,91,246,.1);}
.pot-pc.neg{color:var(--brick);background:rgba(190,18,60,.09);}

/* ---------- does the money last ---------- */

/* ---- glidepath ---- */
.glide{margin-top:18px;padding-top:16px;border-top:1px solid var(--line-soft);}
.glide-switch{display:flex;align-items:center;gap:9px;cursor:pointer;
  font-size:var(--fs-body);font-weight:600;color:var(--ink);}
.glide-switch input{width:16px;height:16px;accent-color:var(--accent);cursor:pointer;margin:0;}
.glide-controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-top:12px;font-size:var(--fs-body);color:var(--ink-60);}
.glide-controls input{width:64px;padding:6px 8px;font:inherit;font-weight:600;
  color:var(--ink);text-align:center;border:1px solid var(--line);border-radius:8px;background:#fff;}
.glide-controls input:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent);}
.glide-viz{position:relative;margin-top:14px;}
.glide-viz svg{display:block;width:100%;height:88px;border-radius:8px;overflow:hidden;}
.glide-ticks{position:relative;height:16px;margin-top:5px;}
.glide-ticks span{position:absolute;transform:translateX(-50%);font-size:var(--fs-micro);
  color:var(--ink-56);font-variant-numeric:tabular-nums;}
.glide-ticks span:first-child{transform:none;}
.glide-ticks span:last-child{transform:translateX(-100%);}
.glide-note{margin-top:12px;font-size:var(--fs-small);line-height:1.55;color:var(--ink-60);}
.is-muted{opacity:.45;}
.is-muted input{cursor:not-allowed;}

/* ---- life after work readout ---- */
.lasts-lead{font-size:var(--fs-lead);line-height:1.6;color:var(--ink-87);margin:0 0 16px;max-width:60ch;}
.lasts-lead b{font-weight:800;color:var(--accent-deep);}
.lasts-assume{margin-top:18px;padding-top:14px;border-top:1px solid var(--line-soft);}
.lasts-assume b{display:block;font-size:var(--fs-micro);letter-spacing:-0.005em;
  color:var(--ink-56);margin-bottom:8px;}
.lasts-assume ul{margin:0;padding-left:17px;}
.lasts-assume li{font-size:var(--fs-small);line-height:1.6;color:var(--ink-60);margin-bottom:4px;}
.assume{margin-top:14px;font-size:var(--fs-small);line-height:1.55;color:var(--ink-60);}
.chart-legend .key-band{opacity:.28;border-radius:2px;}
.chart-legend .key-wash{opacity:.34;border-radius:2px;}

/* ---- allocation groups, custom rows, glide steps ---- */
.alloc-group{margin:16px 0 9px;font-size:var(--fs-micro);font-weight:800;color:var(--ink-87);
  letter-spacing:.01em;display:flex;flex-direction:column;gap:2px;}
.alloc-group:first-of-type{margin-top:10px;}
.alloc-group em{font-style:normal;font-size:var(--fs-micro);font-weight:500;color:var(--ink-56);
  line-height:1.45;}
.alloc-row.alloc-custom .alloc-name{gap:6px;min-width:0;flex-wrap:wrap;}
/* The name needs room to type in. If the kind and remove controls don't fit
   beside it they wrap under, rather than crushing the input to nothing. */
.alloc-label{flex:1 1 130px;min-width:120px;background:#fff;border:1px solid var(--line);
  border-radius:8px;padding:5px 8px;font:inherit;font-size:var(--fs-small);color:var(--ink-87);}
.alloc-label:focus{border-color:var(--accent);outline:none;}
.alloc-kind{flex:none;order:3;background:var(--line-soft);border:1px solid var(--line);border-radius:8px;
  padding:4px 6px;font:inherit;font-size:var(--fs-micro);color:var(--ink-60);cursor:pointer;}
.alloc-kind:focus{border-color:var(--accent);outline:none;}
.alloc-x{flex:none;order:4;margin-left:auto;width:22px;height:22px;border:none;background:none;cursor:pointer;
  color:var(--ink-56);font-size:var(--fs-h3);line-height:1;border-radius:6px;padding:0;}
.alloc-x:hover{background:var(--line-soft);color:var(--brick);}
.alloc-add{margin-top:4px;background:none;border:1px dashed var(--line);border-radius:9px;
  padding:7px 12px;font:inherit;font-size:var(--fs-small);font-weight:600;color:var(--ink-60);
  cursor:pointer;transition:all .15s var(--ease);}
.alloc-add:hover{border-color:var(--accent);color:var(--accent-deep);border-style:solid;}
.glide-stages{margin-top:14px;}
.stage-head{display:grid;grid-template-columns:110px 110px 28px;gap:8px;
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.1em;
  color:var(--ink-56);margin-bottom:7px;}
.stage-row{display:grid;grid-template-columns:110px 110px 28px;gap:8px;align-items:center;
  margin-bottom:7px;}
.stage-row .num-input{margin:0;}
.cf-row.cf-leg{padding:5px 0;border-bottom:none;}
.cf-row.cf-leg .cf-k{font-size:var(--fs-small);color:var(--ink-56);padding-left:10px;}
.cf-row.cf-leg .cf-v{font-size:var(--fs-small);color:var(--ink-60);font-weight:600;}

/* ---- allocation total ---- */
.alloc-total{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:10px;}
.at-sum{font-size:var(--fs-small);font-weight:800;color:var(--accent-deep);
  background:rgba(91,91,246,.08);border-radius:7px;padding:3px 9px;
  font-variant-numeric:tabular-nums;transition:all .15s var(--ease);}
.alloc-total.is-off .at-sum{color:var(--warn-deep);background:rgba(217,119,6,.11);}
.alloc-total.is-over .at-sum{color:var(--brick);background:rgba(190,18,60,.10);}
.at-fix{background:none;border:1px solid var(--line);border-radius:7px;padding:3px 9px;
  font:inherit;font-size:var(--fs-micro);font-weight:600;color:var(--ink-60);cursor:pointer;
  transition:all .15s var(--ease);}
.at-fix:hover{border-color:var(--accent);color:var(--accent-deep);}
.at-blend{font-size:var(--fs-small);font-weight:600;color:var(--ink-60);flex:1 1 100%;}
.alloc-total.is-off .at-blend{color:var(--warn-deep);}
.alloc-total.is-over .at-blend{color:var(--brick);}

/* ---- state pension per person ---- */
.sp-years{margin:10px 0 4px;}
.nw-row.sp-row{grid-template-columns:1fr 84px auto;align-items:center;gap:10px;}
.sp-amt{font-size:var(--fs-small);font-weight:700;color:var(--accent-deep);white-space:nowrap;
  font-variant-numeric:tabular-nums;min-width:76px;text-align:right;}
.sp-amt.is-none{color:var(--brick);font-weight:600;}
/* The first and last age ticks are centred on the track ends, so half of each
   would hang past the edge and widen the page. Pull them inside instead. */
.tl-tick:first-of-type{transform:translate(0,-50%);}
.tl-tick:last-of-type{transform:translate(-100%,-50%);}

/* A dozen money columns will never fit a phone. Let the table scroll inside its
   own box rather than dragging the whole page sideways. */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;}
.table-scroll .bridge-table{min-width:640px;}
/* That floor was sized for all five columns. Below 820px one of them is gone,
   and leaving the floor in place stretched the remaining four across 640px and
   made the card scroll anyway — so the reader still had to drag sideways to
   reach the closing figure. Four columns fit; drop the floor. */
@media (max-width:820px){
  .table-scroll .bridge-table{min-width:0;}
}

/* On a phone the generous card padding costs more than it's worth — the inner
   content ends up wider than the screen and the whole page slides sideways. */
@media (max-width:560px){
  .wrap{padding-left:14px;padding-right:14px;}
  .panel,.ledger-card,.why-panel,.signup-panel,.roadmap-panel,.bridge-card{
    padding-left:16px;padding-right:16px;}
  /* Three columns do not fit: the name column is held open by its own
     min-content and shoves the two inputs off the card. Give the name the
     full width and put the two figures under it, which also makes them wide
     enough to tap. The head loses its empty first cell so the two labels
     still sit over the columns they name. */
  .alloc-head,.alloc-row{grid-template-columns:1fr 1fr;gap:6px 8px;}
  .alloc-head span:first-child{display:none;}
  .alloc-row .alloc-name{grid-column:1/-1;}
  .alloc-row{margin-bottom:12px;}
  .stage-head,.stage-row{grid-template-columns:1fr 1fr 28px;}
}

/* =====================================================================
   Light technical pass — instrument, not brochure.
   Figures in mono so columns line up and digits read as data; hairline
   rules instead of soft elevation; tight radii; mono uppercase labels.
   ===================================================================== */

/* --- every number in the app --- */
.qe-kpi b, .kpi b, .hh-figure, .hh-stat b, .cf-v, .ledger-row .v, .bridge-table td,
.bridge-table th, .alloc-note, .at-sum, .at-blend, .sp-amt, .range-val,
.lasts-lead b, .num-input input, .alloc-pct, .alloc-ret, .stage-age, .stage-pct,
.chart-y span, .cf-axis span, .glide-ticks span, .tl-tick em, .fold-v,
.decomp-fig, .bar-label b, .potsLegend b, .chart-legend b, .sc-status{
  font-family:var(--mono);
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1,"zero" 1;
  letter-spacing:-0.01em;
}
.hh-figure{letter-spacing:-0.035em;}

/* --- field labels: the body face, sentence case, never shouty caps --- */
.kpi span, .ledger-title, .section-num, .alloc-head span, .stage-head span,
.hh-label, .hh-stat span, .lasts-assume b, .fold-t{
  font-family:var(--sans);
  font-size:var(--fs-small);font-weight:500;letter-spacing:-0.005em;color:var(--ink-60);
}
.ledger-title{font-size:var(--fs-body);font-weight:600;color:var(--ink-87);}
.section-num{font-size:var(--fs-small);font-weight:600;color:var(--accent);}
.kpi span{font-size:var(--fs-micro);}
.lasts-assume b,.fold-t{color:var(--ink-87);font-weight:600;}

/* --- geometry: hairlines, tight corners --- */
.panel,.ledger-card,.why-panel,.signup-panel,.roadmap-panel,.bridge-card,.lasts-card{
  border-radius:var(--radius-card);
  border:1px solid var(--line-soft);
  box-shadow:var(--shadow-card);
}
.num-input,.alloc-row input,.alloc-label,.alloc-kind,.glide-controls input,
.at-fix,.alloc-add,select,input[type=text],input[type=number],input[type=date]{
  border-radius:4px !important;
}
.kpi-strip{border-radius:var(--radius-card);border:1px solid var(--line-soft);}
.seg,.seg-btn,.sc-btn,.tab,.qa-chip{border-radius:4px;}
.alloc-bar{border-radius:2px;height:8px;}
.alloc-bar span{border-radius:0;}

/* --- data tables get denser and rule-lined --- */
.bridge-table td,.bridge-table th{padding:6px 10px;font-size:var(--fs-micro);}
.bridge-table th{border-bottom:1px solid var(--line);
  letter-spacing:-0.005em;font-size:var(--fs-micro);}
.bridge-table td{border-bottom:1px solid var(--line-soft);}
.bridge-table tr:hover td{background:rgba(91,91,246,.045);}

/* --- collapsible assumption groups --- */
.fold{border:1px solid var(--line-soft);border-radius:5px;margin-bottom:10px;
  background:var(--surface);overflow:hidden;}
.fold[open]{border-color:var(--line);}
.fold summary{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding:12px 14px;cursor:pointer;list-style:none;user-select:none;
  transition:background .15s var(--ease);}
.fold summary::-webkit-details-marker{display:none;}
.fold summary:hover{background:var(--surface-sunk);}
.fold summary::after{content:'+';margin-left:auto;font-family:var(--mono);
  font-size:var(--fs-lead);line-height:1;color:var(--ink-56);flex:none;}
.fold[open] summary::after{content:'–';}
.fold-t{color:var(--ink-87);}
.fold-s{font-size:var(--fs-micro);color:var(--ink-56);flex:1 1 100%;order:3;line-height:1.4;}
.fold-v{font-size:var(--fs-micro);font-weight:500;color:var(--accent-deep);
  background:rgba(91,91,246,.07);border-radius:3px;padding:2px 7px;}
.fold-body{padding:2px 14px 14px;border-top:1px solid var(--line-soft);}
.fold-body .field{margin-bottom:16px;}
.fold-body .field:last-child{margin-bottom:2px;}

/* --- retirement tab --- */
.retire-ages{margin-bottom:18px;}
#retireSummary{position:sticky;top:16px;}
/* The waterfall axis has one column per bar; on a phone the labels are wider
   than their column, so let them clip rather than push the row. */
@media (max-width:560px){
  .wf-axis{padding-left:0;gap:2px;}
  .wf-tick{overflow:hidden;}
  .wf-tick b{font-size:var(--fs-micro);overflow:hidden;text-overflow:ellipsis;max-width:100%;}
}

/* =====================================================================
   Landing — short and technical. The reasoning lives at /about.
   ===================================================================== */
.nav-right{display:flex;align-items:baseline;gap:20px;}
.nav-cta{font-weight:700;color:var(--accent-deep);}

/* The text is one span, not a bare text node, and that is load-bearing. Every
   run of text directly inside a flex container becomes its own anonymous flex
   item, so "UK · ", the tax-year span and " rates · runs in your browser" were
   three items with the 8px gap between each — and the whitespace at their
   edges stripped. Wide enough for one line it merely looked loosely spaced; on
   a phone it broke into a ragged two-line block with a hole in the middle. */
.lp-badge{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);
  font-size:var(--fs-micro);font-weight:500;letter-spacing:.06em;color:var(--ink-60);
  border:1px solid var(--line-soft);border-radius:var(--radius-pill);padding:5px 13px;
  background:var(--surface);margin-bottom:26px;}
/* Forty characters of mono at 11.5px does not fit 375px, so on a phone this
   wraps whatever it is told. Balanced, it wraps at the second separator and
   reads as two deliberate lines rather than one line with a word fallen off. */
.lp-badge-t{text-wrap:balance;}
.lp-badge i{width:6px;height:6px;border-radius:50%;background:var(--accent);flex:none;
  box-shadow:0 0 0 3px rgba(91,91,246,.16);}
.lp-hero h1{font-size:clamp(34px,5.2vw,60px);font-weight:800;letter-spacing:-0.035em;
  line-height:1.06;color:var(--ink-87);margin:0 0 20px;}
.lp-sub{font-size:var(--fs-h3);line-height:1.6;color:var(--ink-60);max-width:600px;margin:0 0 30px;}
.hero-tight{padding:64px 0 26px;}

/* the spec sheet — the landing's one real visual idea */
.spec{border:1px solid var(--line-soft);border-radius:var(--radius-card);
  background:var(--surface);overflow:hidden;margin-bottom:26px;}
.spec-head{display:grid;grid-template-columns:132px 1fr;gap:18px;padding:11px 20px;
  background:var(--surface-sunk);border-bottom:1px solid var(--line-soft);
  font-family:var(--sans);font-size:var(--fs-small);font-weight:500;
  letter-spacing:-0.005em;color:var(--ink-56);}
.spec-row{display:grid;grid-template-columns:132px 1fr;gap:18px;padding:13px 20px;
  border-bottom:1px solid var(--line-soft);transition:background .14s var(--ease);}
.spec-row:last-child{border-bottom:none;}
.spec-row:hover{background:var(--surface-sunk);}
.spec-k{font-family:var(--mono);font-size:var(--fs-micro);font-weight:500;color:var(--accent-deep);
  letter-spacing:-0.01em;}
.spec-v{font-size:var(--fs-body);line-height:1.55;color:var(--ink-60);}
.spec-v b{color:var(--ink-87);font-weight:600;}

/* A question doesn't fit the 132px key column, so the FAQ stacks inside the
   same card rather than getting a card of its own. */
/* The answers are reference, not something to read on the way past: the four
   questions carry the reassurance, the prose waits until it's asked for. */
/* Deliberately not display:grid. .spec-row is a grid, and overriding a
   <details> element's display is what historically stops it collapsing at all
   in some engines. The row is one column here, so the grid bought nothing. */
.spec-row.faq-row{display:block;padding:0;}
/* The padding lives on the summary, not the row, so the whole strip is the
   tap target rather than just the text — 23px of it otherwise, on a phone. */
.faq-row summary{list-style:none;cursor:pointer;display:flex;align-items:center;
  justify-content:space-between;gap:var(--space-3);padding:13px 20px;min-height:44px;
  box-sizing:border-box;}
.faq-row .spec-v{padding:0 20px 15px;}
.faq-row summary::-webkit-details-marker{display:none;}
.faq-row summary::after{content:'';flex:none;width:7px;height:7px;
  border-right:2px solid var(--ink-56);border-bottom:2px solid var(--ink-56);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .16s var(--ease);}
.faq-row[open] summary::after{transform:rotate(-135deg) translate(-2px,-2px);}
.faq-row summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px;}
.faq-row[open] .spec-v{display:block;}
/* A real h3, so the FAQ is navigable by heading rather than merely looking like
   headings. Sized by the type scale, not by the browser's h3 default. */
.faq-q{font-size:var(--fs-body);font-weight:650;color:var(--ink-87);
  letter-spacing:-0.01em;margin:0;}
.spec-head h2{font:inherit;font-weight:800;color:var(--ink-87);margin:0;}

/* The landing page names the three tiers and sends you to /about for the full
   list, rather than reprinting it. */
.lp-more{margin:-14px 0 26px;font-size:var(--fs-small);}
.lp-more a{color:var(--accent-deep);text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px;font-weight:600;}

/* Quick Estimate: net worth including the pension, today against retirement.
   Both columns are deliberately the same height — this compares composition,
   not magnitude. Scaling them to the totals made the first a stub. The size is
   the number underneath. Same categorical colours as the pots chart, so pension
   means the same thing wherever you meet it. */
.qe-chart{margin:var(--space-4) 0 var(--space-3);}
.qec-cols{display:flex;gap:var(--space-6);align-items:flex-end;}
.qec-col{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-2);}
.qec-lab{font-family:var(--mono);font-size:var(--fs-micro);color:var(--ink-56);
  letter-spacing:-0.005em;}
.qec-stack{height:132px;display:flex;flex-direction:column;overflow:hidden;
  border-radius:var(--radius-sm, 8px);background:var(--surface-sunk);}
.qec-stack i{display:flex;align-items:center;justify-content:center;
  transition:height .3s var(--ease);min-height:0;}
.qec-stack em{font-style:normal;font-family:var(--mono);font-size:var(--fs-micro);
  font-weight:600;color:#fff;white-space:nowrap;opacity:0;transition:opacity .2s var(--ease);}
.qec-stack i.has-room em{opacity:1;}
.qec-pen{background:var(--cat-pension);}
.qec-oth{background:var(--cat-isa);}
.qec-tot{font-family:var(--mono);font-size:var(--fs-h3);font-weight:800;
  color:var(--ink-87);letter-spacing:-0.02em;}
.qec-key{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-4);
  margin-top:var(--space-4);}
.qec-key span{display:flex;align-items:center;gap:6px;font-size:var(--fs-micro);
  color:var(--ink-56);}
.qec-key i{width:10px;height:10px;border-radius:3px;flex:none;}
.qec-key em{font-style:normal;color:var(--ink-56);}
@media (max-width:560px){
  .qec-cols{gap:var(--space-4);}
  .qec-stack{height:112px;}
}

.lp-note{border-left:0;padding:0 0 30px;}
.lp-note p{font-size:var(--fs-body);line-height:1.6;color:var(--ink-56);max-width:70ch;margin:0;}
.lp-note b{color:var(--ink-60);font-weight:600;}
.lp-note a,.feedback a{color:var(--accent-deep);text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px;}

@media (max-width:640px){
  .spec-head,.spec-row{grid-template-columns:1fr;gap:4px;}
  .spec-k{font-size:var(--fs-micro);}
  .nav-right{gap:14px;}
}

/* =====================================================================
   DESIGN PACK — "Aftertax Redesign". Indigo accent, light grey
   ground, 16px cards, filled inputs, dark sidebar with an accent glow.
   This block is authoritative; it comes last on purpose.
   ===================================================================== */

/* --- shell --- */
.app{background:var(--ground);}
.appmain{padding:28px 40px 64px;max-width:1200px;}
.sidenav{width:252px;padding:24px 14px;background:var(--sidebar);position:sticky;top:0;overflow:hidden;}
.sidenav::before{content:'';position:absolute;top:-120px;left:-60px;width:260px;height:260px;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,var(--accent-glow) 0%,transparent 70%);}
.sn-brand{position:relative;display:flex;align-items:center;gap:9px;padding:2px 8px 0;
  font-size:var(--fs-lead);font-weight:800;letter-spacing:-0.01em;}
.sn-brand::before{content:'';width:22px;height:22px;border-radius:7px;background:var(--grad);flex:none;}
.sn-eyebrow{position:relative;color:rgba(255,255,255,.42);letter-spacing:-0.005em;margin:6px 0 22px;}
.sn-list{position:relative;gap:2px;}
.sn-list .tab{border-radius:10px;padding:10px 12px;font-size:var(--fs-body);font-weight:600;
  color:rgba(255,255,255,.7);gap:11px;transition:background .15s ease,color .15s ease;}
.sn-list .tab:hover{background:rgba(255,255,255,.06);color:#fff;}
.sn-list .tab.active{background:var(--accent);color:#fff;}
.sn-foot{position:relative;border-top:1px solid rgba(255,255,255,.1);padding:14px 8px 0;}
.sn-foot p,.sn-foot a{color:rgba(255,255,255,.42);}

/* --- topbar + scenario --- */
.topbar-title{font-size:var(--fs-h2);font-weight:800;letter-spacing:-0.02em;color:var(--ink-87);}
.scenario-bar{background:#fff;border:1px solid var(--line-soft);border-radius:12px;
  padding:8px 12px;box-shadow:var(--shadow-card);gap:8px;}
.sc-label{font-size:var(--fs-micro);font-weight:700;letter-spacing:.1em;color:var(--ink-56);font-family:var(--sans);}
.scenario-bar select{background:var(--surface-sunk);border:1px solid transparent;border-radius:8px;
  color:var(--ink-87);font-size:var(--fs-small);font-weight:600;padding:7px 9px;}
.sc-btn{border-radius:8px;font-size:var(--fs-small);font-weight:600;padding:8px 14px;}
.sc-btn.primary{background:var(--grad);border:none;color:#fff;}

/* --- KPI strip: one card, five cells, rules between --- */
.kpi-strip{display:grid;grid-template-columns:repeat(5,1fr);gap:0;background:#fff;
  border:1px solid var(--line-soft);border-radius:16px;box-shadow:var(--shadow-card);
  margin-bottom:22px;overflow:hidden;padding:0;}
.kpi{padding:16px 20px;border-left:1px solid var(--line-soft);gap:4px;}
.kpi:first-child{border-left:none;}
.kpi span{font-family:var(--sans);font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;
  color:var(--ink-56);}
.kpi b{font-size:var(--fs-figure);font-weight:800;letter-spacing:-0.01em;color:var(--ink-87);}
.kpi-lead b{color:var(--accent-deep);}
/* The insight count is a button, so it needs the <button> defaults stripped
   back to the cell the other four are, plus the affordance they don't have. */
.kpi-ins{font:inherit;color:inherit;text-align:left;background:none;cursor:pointer;
  border:none;border-left:1px solid var(--line-soft);align-items:flex-start;}
.kpi-ins:hover:not(:disabled){background:var(--surface-sunk);}
.kpi-ins:disabled{cursor:default;}
.kpi-ins b{color:var(--accent-deep);}
.kpi-ins:disabled b{color:var(--ink-56);}

/* --- surfaces --- */
.panel,.ledger-card,.why-panel,.signup-panel,.roadmap-panel,.bridge-card,.spec,.hh-strip,
.nw-summary,.person-bar,.age-bar{
  background:#fff;border:1px solid var(--line-soft);border-radius:16px;
  box-shadow:var(--shadow-card);}
.panel,.ledger-card{padding:28px;}

/* --- inputs: filled, no border --- */
.num-input,.alloc-row input,.alloc-label,.glide-controls input,.stage-row .num-input,
input[type=text],input[type=number],input[type=date],select{
  background:var(--surface-sunk) !important;border:1px solid transparent !important;
  border-radius:10px !important;color:var(--ink-87);}
.num-input:focus-within,input:focus,select:focus{
  border-color:var(--accent) !important;outline:none;}
.num-input input{background:transparent !important;border:none !important;
  font-size:var(--fs-h3);font-weight:500;padding:11px 0;}
.alloc-row input{padding:8px 10px;font-weight:600;}

/* --- controls --- */
.seg{background:#fff;border:1px solid var(--line-soft);border-radius:12px;padding:4px;gap:4px;
  box-shadow:var(--shadow-card);}
.seg-btn{border-radius:9px;padding:9px 16px;font-size:var(--fs-body);font-weight:600;}
.seg-btn.active{background:var(--accent);color:#fff;}
.seg.seg-sm .seg-btn{padding:6px 12px;font-size:var(--fs-small);}
.mode-btn{border-radius:9px;font-weight:600;}
.mode-btn.active{background:var(--accent);color:#fff;}
.p-tab,.qa-chip,.alloc-add,.at-fix{border-radius:var(--radius-pill);}
.p-tab.active{background:var(--accent);border-color:var(--accent);color:#fff;}
.p-tab.add{border:1px dashed var(--line);color:var(--accent);background:#fff;}
.qa-chip{background:#fff;border:1px solid var(--line-soft);padding:8px 15px;font-size:var(--fs-small);
  font-weight:600;color:var(--ink-87);box-shadow:var(--shadow-card);}
.qa-chip:hover{border-color:var(--accent);color:var(--accent-deep);}
.btn-ghost{background:#fff;border:1px solid var(--line);color:var(--ink-87);}

/* --- accents on section headers and totals --- */
.section-num{color:var(--accent);letter-spacing:-0.005em;font-family:var(--sans);
  font-size:var(--fs-micro);font-weight:700;}
.cf-row.total{border-top:2px solid var(--accent);}
.nw-total{border-top:2px solid var(--accent);}
.hh-figure{background:var(--grad);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;font-family:var(--sans);font-weight:800;}
.ledger-title{color:var(--ink-56);}
.fold-v{color:var(--accent-deep);background:var(--accent-wash);}
.at-sum{color:var(--accent-deep);background:var(--accent-wash);}
.lasts-lead b{color:var(--accent-deep);}
.alloc-note,.at-blend{color:var(--ink-60);}

/* --- timeline --- */
.tl-line{background:linear-gradient(90deg,#5B5BF6 0%,#0D9488 100%);height:3px;border-radius:3px;}
.tl-dot,.ms-dot{background:#fff;border:3px solid var(--accent);
  box-shadow:0 1px 4px rgba(11,14,20,.15);}
.ms-pill{background:#fff;border:1px solid var(--line-soft);border-radius:12px;
  box-shadow:var(--shadow-card);}

/* --- panel entry --- */
@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.tab-panel:not([hidden]){animation:fadeUp .3s ease both;}
@media (prefers-reduced-motion:reduce){.tab-panel:not([hidden]){animation:none;}}

/* --- selection --- */
::selection{background:rgba(91,91,246,.22);}
input[type=range]{background:rgba(11,14,20,.10);}
input[type=range]::-webkit-slider-thumb{background:var(--accent);border:2.5px solid #fff;
  box-shadow:0 1px 4px rgba(11,14,20,.35);}
input[type=range]::-moz-range-thumb{background:var(--accent);border:2.5px solid #fff;}

@media (max-width:900px){
  .appmain{padding:20px 18px 56px;}
  .sidenav{width:100%;}
  .sidenav::before{display:none;}
}
@media (max-width:640px){
  .kpi-strip{grid-template-columns:repeat(2,1fr);}
  .kpi:nth-child(odd){border-left:none;}
  .kpi:nth-child(n+3){border-top:1px solid var(--line-soft);}
  /* five cells into two columns leaves the count alone on the last row */
  .kpi-strip > :last-child{grid-column:1/-1;}
}

/* Design-pack padding is generous by design; on a phone it makes the panel
   content wider than the column, so pull it back after that block wins. */
@media (max-width:560px){
  .appmain{padding:18px 12px 52px;}
  .panel,.ledger-card,.bridge-card,.signup-panel,.roadmap-panel,.why-panel{
    padding-left:16px;padding-right:16px;}
  .kpi{padding:13px 14px;}
  .hh-strip,.nw-summary,.person-bar,.age-bar{padding-left:16px;padding-right:16px;}
}

/* --- nav + header icons: 20px stroke marks, not emoji --- */
.sn-ico{width:20px;height:20px;flex:none;display:inline-flex;align-items:center;
  justify-content:center;color:currentColor;}
.sn-ico svg{width:20px;height:20px;display:block;}
.topbar-title{display:flex;align-items:center;gap:11px;}

/* The reference block, folded. Same disclosure pattern as the observations
   past the top few: padding on the <summary> rather than the row, or the tap
   target is a few pixels tall; no display:grid on the <details>, which breaks
   native collapse. */
.ref-fold{border:1px solid var(--line-soft);border-radius:var(--radius-card);
  background:var(--surface);overflow:hidden;}
.ref-fold > summary{list-style:none;cursor:pointer;padding:15px var(--space-6);
  display:flex;align-items:center;gap:8px;font-size:var(--fs-small);
  font-weight:600;color:var(--accent-deep);}
.ref-fold > summary::-webkit-details-marker{display:none;}
.ref-fold > summary::after{content:'▾';font-size:.85em;color:var(--ink-56);}
.ref-fold[open] > summary::after{content:'▴';}
.ref-fold > summary:hover{background:var(--surface-sunk);}
.ref-fold .rf-shut,.ref-fold[open] .rf-open{display:none;}
.ref-fold[open] .rf-shut{display:inline;}
.ref-fold[open] > summary{border-bottom:1px solid var(--line-soft);}
.ref-body{padding:var(--space-5) var(--space-6) var(--space-6);}
.ref-body .facts-card{border:none;box-shadow:none;padding:0;margin-top:var(--space-5);}

/* ---------- one scale for every table on a screen ----------
   Rows 14, indented sub-rows 13, column headers 11.5, totals 17 — and both
   halves of a row always agree. The projection screen had drifted to six
   sizes across five tables doing the same job, including .range-row, whose
   label and figure sat at different sizes inside one row. */
/* Sub-lines and range rows are set by the projection-ledger block in
   styles-mono.css, which is more specific and more considered than the two
   rules that used to sit here. */
/* The growth-rate line in the pots table's foot stays at caption size: it is a
   footnote about the table rather than a row in it, and `.bd-table tfoot
   .bd-rate td` already says so more specifically than anything here could. */

/* ---------- comparing two plans ----------
   Built from the same parts as the ledger cards: surface, hairlines, a mono
   micro-label, figures in the mono face. Every colour is a token, so the
   overlay recolours this along with everything else rather than needing its
   own copy of the palette. */
.cmp-card{background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--radius-card);box-shadow:var(--shadow-card);
  margin-bottom:var(--space-5);overflow:hidden;}
.cmp-head{display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--space-4);padding:18px var(--space-6) 14px;}
.cmp-head h2{margin:0;}
.cmp-close{flex:0 0 auto;background:none;border:none;cursor:pointer;
  font-size:22px;line-height:1;color:var(--ink-56);padding:2px 6px;
  border-radius:var(--radius-input);}
.cmp-close:hover{background:var(--surface-sunk);color:var(--ink-87);}

.cmp-pick{display:flex;align-items:center;flex-wrap:wrap;gap:8px;
  padding:0 var(--space-6) 16px;font-size:var(--fs-small);color:var(--ink-60);}
.cmp-pick select{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-input);padding:6px 9px;font-family:var(--sans);
  font-size:var(--fs-small);color:var(--ink-87);max-width:min(240px,40vw);}

.cmp-rows{border-top:1px solid var(--line-soft);}
.cmp-row{display:grid;grid-template-columns:1fr 150px 150px 130px;gap:var(--space-3);
  align-items:baseline;padding:11px var(--space-6);
  border-bottom:1px dotted var(--line);}
.cmp-row:last-child{border-bottom:none;}
.cmp-row b,.cmp-row .cmp-d{font-family:var(--mono);font-size:var(--fs-body);
  text-align:right;font-weight:500;color:var(--ink-87);
  font-variant-numeric:tabular-nums;}
.cmp-k{font-size:var(--fs-body);color:var(--ink-60);}
/* The header row names the two plans, so it is the one place the plan names
   are set in the reading face rather than the figure face. */
.cmp-hd{border-bottom:1px solid var(--line-soft);padding-top:14px;padding-bottom:10px;}
.cmp-hd b{font-family:var(--sans);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:-0.005em;color:var(--ink-87);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cmp-hd span:last-child{font-family:var(--sans);font-size:var(--fs-micro);
  font-weight:700;color:var(--ink-56);text-align:right;}

/* Direction, using the same convention as every other figure on the page:
   a minus sign and rose for down, plain ink for up. */
.cmp-d.down{color:var(--brick);}
.cmp-d.same{color:var(--ink-56);font-family:var(--sans);}
.cmp-note{margin:0;padding:14px var(--space-6);background:var(--surface-sunk);
  border-top:1px solid var(--line-soft);font-size:var(--fs-micro);
  line-height:1.55;color:var(--ink-56);}
.cmp-empty{margin:0;padding:var(--space-5) var(--space-6);
  font-size:var(--fs-small);color:var(--ink-56);}

@media (max-width:720px){
  .cmp-row{grid-template-columns:1fr 1fr 1fr;gap:var(--space-2);
    padding-left:var(--space-4);padding-right:var(--space-4);}
  /* The difference column is derivable from the two beside it, so it is the
     one that goes when there is no room for four. */
  .cmp-row .cmp-d,.cmp-hd span:last-child{display:none;}
  .cmp-k{grid-column:1/-1;}
  .cmp-head,.cmp-pick,.cmp-note{padding-left:var(--space-4);padding-right:var(--space-4);}
}

/* --- optional second step on signup --- */
.more{margin-top:20px;padding-top:20px;border-top:1px solid var(--line-soft);
  animation:fadeUp .3s ease both;}
.more-head b{display:block;font-size:var(--fs-lead);font-weight:700;color:var(--ink-87);margin-bottom:3px;}
.more-head span{font-size:var(--fs-small);color:var(--ink-56);}
.more-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-top:16px;}
.mf{display:flex;flex-direction:column;gap:5px;}
.mf > span{font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;
  color:var(--ink-56);}
.mf input,.mf select,.mf textarea{background:var(--surface-sunk);border:1px solid transparent;
  border-radius:10px;padding:11px 12px;font-family:inherit;font-size:var(--fs-body);color:var(--ink-87);
  outline:none;width:100%;}
.mf textarea{resize:vertical;min-height:74px;line-height:1.5;}
.mf input:focus,.mf select:focus,.mf textarea:focus{border-color:var(--accent);}
.mf-wide{margin-top:12px;}
.more-actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:16px;}
.more-skip{background:none;border:none;font-family:inherit;font-size:var(--fs-body);font-weight:600;
  color:var(--ink-56);cursor:pointer;padding:6px 2px;}
.more-skip:hover{color:var(--ink-60);}
.more-status{font-size:var(--fs-small);color:var(--ink-60);}
.more-note{font-size:var(--fs-micro);line-height:1.55;color:var(--ink-56);margin:14px 0 0;max-width:62ch;}
.more-thanks{font-size:var(--fs-lead);font-weight:600;color:var(--accent-deep);margin:0;}
@media (max-width:560px){ .more-grid{grid-template-columns:1fr;} }

/* =====================================================================
   MOBILE NAV — the sidebar's design-pack overflow:hidden was clipping the
   tab row (628px of tabs inside a 375px screen), so every section after
   Income was unreachable. On a phone the nav becomes a five-up icon bar
   pinned to the top, with short labels so all five actually fit.
   ===================================================================== */
.tab-short{display:none;}
@media (max-width:900px){
  .app{flex-direction:column;}
  .sidenav{position:sticky;top:0;z-index:60;width:100%;height:auto;overflow:visible;
    flex-direction:column;align-items:stretch;gap:8px;padding:9px 10px 7px;
    box-shadow:0 1px 0 rgba(255,255,255,.06),0 6px 18px rgba(11,14,20,.18);}
  .sidenav::before{display:none;}
  .sn-brand{font-size:var(--fs-body);padding:0 2px;gap:7px;}
  .sn-brand::before{width:17px;height:17px;border-radius:5px;}
  .sn-eyebrow,.sn-spacer,.sn-foot{display:none;}
  .sn-list{display:grid;grid-template-columns:repeat(6,1fr);gap:2px;flex-direction:row;}
  .sn-list .tab{flex-direction:column;justify-content:center;gap:3px;padding:7px 1px 6px;
    font-size:var(--fs-micro);font-weight:600;line-height:1.15;text-align:center;border-radius:9px;
    letter-spacing:-0.01em;}
  .sn-list .tab .tab-full{display:none;}
  .sn-list .tab .tab-short{display:block;}
  .sn-ico{width:17px;height:17px;}
  .sn-ico svg{width:17px;height:17px;}
  /* the title repeats the section, so it reads the same as the nav */
  .topbar{padding:16px 0 4px;}
  .topbar-title{font-size:var(--fs-figure);}
}
@media (max-width:900px){
  /* the scenario bar was wrapping its overflow button onto its own line */
  .scenario-bar{width:100%;flex-wrap:nowrap;gap:6px;padding:6px 8px;}
  .scenario-bar select{flex:1;min-width:0;}
  .sc-label{display:none;}
  .sc-btn{padding:8px 11px;white-space:nowrap;}
  /* two segmented controls in the table head need room on a phone */
  .bridge-head{flex-wrap:wrap;gap:8px;}
  #bridgeStride,#bridgeScenario{flex:1 1 auto;}
}

/* --- budget rows: amount plus an optional life --- */
.bg-yrs{display:flex;align-items:center;gap:4px;background:var(--surface-sunk);
  border:1px solid transparent;border-radius:10px;padding:0 9px;}
.bg-yrs input{background:transparent !important;border:none !important;width:100%;min-width:0;
  padding:10px 0;font:inherit;font-size:var(--fs-body);font-weight:500;color:var(--ink-87);text-align:right;outline:none;}
.bg-yrs span{font-size:var(--fs-micro);color:var(--ink-56);flex:none;}
.bg-yrs:focus-within{border-color:var(--accent) !important;}
.cb-row{grid-template-columns:1fr 118px 74px 26px !important;}
@media (max-width:560px){
  .cb-row{grid-template-columns:1fr 92px 62px 24px !important;}
}

/* --- savings card + timeline lead-in --- */
.card-h{font-size:var(--fs-h3);font-weight:700;letter-spacing:-0.01em;color:var(--ink-87);margin:0 0 5px;}
.card-sub{font-size:var(--fs-body);line-height:1.55;color:var(--ink-60);margin:0 0 16px;max-width:64ch;}
.card-sub em{font-style:italic;color:var(--ink-87);}
.lbl-lead{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  font-size:var(--fs-lead);font-weight:600;color:var(--ink-87);margin-bottom:4px;}
.lead-val{font-family:var(--mono);font-size:var(--fs-figure);font-weight:700;color:var(--accent-deep);
  letter-spacing:-0.02em;font-variant-numeric:tabular-nums;}

/* the step from budget to timeline needs a beat, or they read as one blur */
.tl-intro{display:flex;gap:16px;align-items:flex-start;margin:34px 0 16px;padding-top:26px;
  border-top:1px solid var(--line-soft);}
.tl-intro-num{flex:none;width:38px;height:38px;border-radius:11px;display:flex;align-items:center;
  justify-content:center;background:var(--accent-wash);color:var(--accent-deep);
  font-family:var(--mono);font-size:var(--fs-body);font-weight:700;}
.tl-intro .card-sub{margin-bottom:0;}

/* the line itself should read as the spine of the page */
.timeline-wrap{background:#fff;border:1px solid var(--line-soft);border-radius:16px;
  box-shadow:var(--shadow-card);padding:22px 26px 18px;}
.tl-line{height:4px;}
.tl-hint{font-size:var(--fs-micro);color:var(--ink-56);margin:14px 0 0;}

/* --- child stages --- */
.ev-phases{display:block;width:100%;}
.ph-head{display:grid;grid-template-columns:1fr 104px 92px 26px;gap:8px;margin-bottom:6px;
  font-size:var(--fs-micro);font-weight:700;letter-spacing:-0.005em;color:var(--ink-56);}
.ph-head span:nth-child(2),.ph-head span:nth-child(3){text-align:center;}
.ph-row{display:grid;grid-template-columns:1fr 104px 92px 26px;gap:8px;align-items:center;margin-bottom:6px;}
.ph-row input{font-size:var(--fs-small);}
.ph-row .num-input{padding:0 9px;}
.ph-row .num-input input{padding:8px 0;font-size:var(--fs-body);}
.ph-label{background:var(--surface-sunk);border:1px solid transparent;border-radius:10px;
  padding:8px 10px;font:inherit;font-size:var(--fs-small);color:var(--ink-87);outline:none;min-width:0;}
.ph-label:focus{border-color:var(--accent);}
.ph-x{border:none;background:none;color:var(--ink-56);font-size:var(--fs-h3);cursor:pointer;
  border-radius:6px;padding:0;height:24px;}
.ph-x:hover{background:var(--surface-sunk);color:var(--brick);}
.ph-add{margin-top:4px;background:none;border:1px dashed var(--line);border-radius:9px;
  padding:6px 11px;font:inherit;font-size:var(--fs-small);font-weight:600;color:var(--ink-60);cursor:pointer;}
.ph-add:hover{border-color:var(--accent);color:var(--accent-deep);border-style:solid;}
@media (max-width:560px){
  .ph-head{grid-template-columns:1fr 76px 68px 24px;}
  .ph-row{grid-template-columns:1fr 76px 68px 24px;}
}
/* milestone marks: same stroke language as the nav */
.qa-ico,.ev-icon,.tl-ico{display:inline-flex;align-items:center;justify-content:center;flex:none;}
.qa-ico{width:15px;height:15px;margin-right:7px;color:var(--accent);}
.qa-ico svg{width:15px;height:15px;}
.ev-icon{width:18px;height:18px;color:var(--accent);}
.ev-icon svg{width:18px;height:18px;}
.tl-ico{width:14px;height:14px;color:var(--accent);}
.tl-ico svg{width:14px;height:14px;}
.pm-ico svg{width:13px;height:13px;}
.hint-box{margin-top:14px;padding:14px 16px;background:var(--surface-sunk);border-radius:12px;}
.hint-box > b:first-child{display:block;font-size:var(--fs-small);font-weight:700;color:var(--ink-87);
  margin-bottom:5px;}
.hint-box p b{font-weight:700;color:var(--ink-87);}   /* inline, must not break the line */
.hint-box p{font-size:var(--fs-small);line-height:1.55;color:var(--ink-60);margin:0 0 7px;}
.hint-box p:last-child{margin-bottom:0;}
.hint-box em{font-style:normal;font-weight:600;color:var(--accent-deep);}
/* The badge is a fixed 26px dot; its label is an absolutely-positioned child, so
   the icon must not try to widen the dot itself. */
.pm{overflow:visible;}
.pm > svg{width:13px;height:13px;flex:none;}
.pm-lab{pointer-events:none;}

/* --- about you: children --- */
.kid-head{display:grid;grid-template-columns:1fr 104px 26px;gap:9px;margin-bottom:6px;
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.1em;color:var(--ink-56);}
.kid-head span:nth-child(2){text-align:center;}
.kid-row{display:grid;grid-template-columns:1fr 104px 26px;gap:9px;align-items:center;margin-bottom:7px;}
.kid-name{background:var(--surface-sunk);border:1px solid transparent;border-radius:10px;
  padding:10px 12px;font:inherit;font-size:var(--fs-body);color:var(--ink-87);outline:none;min-width:0;}
.kid-name:focus{border-color:var(--accent);}
.kid-row .num-input input{text-align:center;}
.p-tab.is-static{cursor:default;background:var(--surface-sunk);color:var(--ink-87);
  border:1px solid var(--line-soft);}
.ev-kidpick select{max-width:190px;}

/* --- a quiet plus so the chips read as "add this" --- */
.qa-btn{position:relative;padding-right:30px !important;}
.qa-plus{position:absolute;right:9px;top:50%;transform:translateY(-50%);
  width:16px;height:16px;border-radius:5px;display:flex;align-items:center;justify-content:center;
  background:var(--accent-wash);color:var(--accent-deep);font-size:var(--fs-small);font-weight:700;
  line-height:1;transition:all .15s var(--ease);}
.qa-btn:hover .qa-plus{background:var(--accent);color:#fff;}

/* --- run rate rows inside the merged budget table --- */
.bgt-table th{font-family:var(--sans);letter-spacing:-0.005em;}
.bgt-table td.c-amt,.bgt-table td.c-age{font-family:var(--mono);white-space:nowrap;}
.rr-plan td.c-lab{color:var(--accent-deep);}
.rr-plan td.c-lab::before{content:'';display:inline-block;width:5px;height:5px;border-radius:50%;
  background:var(--accent);margin-right:7px;vertical-align:middle;}
.rr-off{color:var(--ink-56);}
.rr-tot td{border-top:1px solid var(--line);font-weight:600;color:var(--ink-87);}
.rr-net td{border-top:2px solid var(--accent);font-weight:800;color:var(--ink-87);
  font-size:var(--fs-body);border-bottom:none;}
.rr-net td.neg{color:var(--brick);}
.rr-x{background:none;border:none;color:var(--ink-56);cursor:pointer;font-size:var(--fs-small);
  padding:0 0 0 6px;line-height:1;}
.rr-x:hover{color:var(--brick);}
.rr-add{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-top:14px;
  font-size:var(--fs-small);color:var(--ink-60);}
.rr-add .num-input{width:92px;}

/* --- timeline categories: colour tells you what kind of thing it is --- */
/* milestone category colours live in the pass 2 block below, as .cat-property
   / .cat-family / .cat-money / .cat-work driving --tl-cat */
/* The .tl-mark .tl-* rules that lived here are superseded by the pass 2 block.
   They were left behind at higher specificity (.tl-mark .tl-pill beats
   .tl-pill) still reading the retired --cat, so every pill fell back to the
   accent and the categories all looked identical.
   The quick-add buttons aren't in the pass 2 block, so they stay — on the
   new token. */
.qa-btn{border:1px solid color-mix(in srgb, var(--tl-cat,var(--accent)) 26%, transparent) !important;}
.qa-btn .qa-ico{color:var(--tl-cat,var(--accent));}
.qa-btn .qa-plus{background:transparent;color:var(--tl-cat,var(--accent));}
.qa-btn:hover{border-color:color-mix(in srgb, var(--tl-cat,var(--accent)) 60%, transparent) !important;
  box-shadow:0 2px 8px rgba(11,14,20,.08);}
.qa-btn:hover .qa-plus{background:var(--tl-cat,var(--accent));color:#fff;}

/* --- assumptions recap on the projection --- */
.assume-bar{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:20px;
  padding:12px 14px;background:#fff;border:1px solid var(--line-soft);border-radius:14px;
  box-shadow:var(--shadow-card);}
.ab-lab{font-family:var(--sans);font-size:var(--fs-small);font-weight:500;
  letter-spacing:.1em;color:var(--ink-56);}
.ab-chip{display:inline-flex;align-items:baseline;gap:6px;background:var(--surface-sunk);
  border:1px solid transparent;border-radius:9px;padding:6px 11px;cursor:pointer;font:inherit;
  transition:all .15s var(--ease);}
.ab-chip b{font-family:var(--mono);font-size:var(--fs-small);font-weight:700;color:var(--ink-87);}
.ab-chip span{font-size:var(--fs-micro);color:var(--ink-60);}
.ab-chip:hover{border-color:var(--accent);background:#fff;box-shadow:0 2px 8px rgba(11,14,20,.07);}
.ab-hint{font-size:var(--fs-micro);color:var(--ink-56);margin-left:auto;}
@media (max-width:640px){ .ab-hint{display:none;} }
.name-row{display:flex;align-items:center;gap:10px;margin-top:12px;min-width:0;}
.name-row label{flex:none;font-size:var(--fs-small);color:var(--ink-60);}
.name-row input{flex:1;min-width:0;background:var(--surface-sunk);border:1px solid transparent;
  border-radius:10px;padding:10px 12px;font:inherit;font-size:var(--fs-body);color:var(--ink-87);outline:none;}
.name-row input:focus{border-color:var(--accent);}
.hh-monthly{font-size:var(--fs-lead);font-weight:600;color:var(--ink-60);margin-top:2px;
  font-variant-numeric:tabular-nums;}

/* --- inline help --- */
.help-i{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;
  margin-left:7px;border-radius:50%;border:1px solid var(--line);background:transparent;
  font-family:var(--sans);font-size:var(--fs-micro);font-weight:700;font-style:italic;
  color:var(--ink-56);cursor:pointer;vertical-align:middle;line-height:1;padding:0;
  transition:all .15s var(--ease);flex:none;}
.help-i:hover{border-color:var(--accent);color:var(--accent);}
.help-i.is-open{background:var(--accent);border-color:var(--accent);color:#fff;}
/* Marker tooltips are absolutely positioned and nowrap, so near the right edge
   they were widening the page. Clip on X only — Y must stay visible so the
   label can sit under the dot — and flip the label inward at the edges. */
.proj-markers{overflow-x:clip;overflow-y:visible;}
.pm[style*="left: 9"] .pm-lab,.pm[style*="left: 8"] .pm-lab{left:auto;right:0;transform:none;}
.pm[style*="left: 0"] .pm-lab,.pm[style*="left: 1%"] .pm-lab{left:0;right:auto;transform:none;}

/* =====================================================================
   TYPE SCALE
   The app had drifted to 25 distinct sizes. This is eight steps, scoped
   to .app so it beats the earlier rules, and applied last. It changes
   only which rung each thing sits on — never weight or colour.
   ===================================================================== */
.app .gap-figure{font-size:var(--fs-display);}
.app .hh-figure{font-size:var(--fs-hero);}
.app h2{font-size:var(--fs-h2);}
.app .kpi b,.app .ring-mid b,.app .nw-total b{font-size:var(--fs-figure);}
.app .lead-val{font-size:var(--fs-figure);}
/* Totals and card headings, not every row. This read `.ledger-row .k/.v`
   unscoped, so an entire ledger sat at the emphasis size while the cashflow
   card directly above it — whose half of this rule IS scoped to .total — sat
   three steps smaller. Two tables in one column, two sizes, same job. */
.app .card-h,.app .ledger-row.total .k,.app .ledger-row.total .v,
.app .cf-row.total .cf-k,.app .cf-row.total .cf-v,
.app .rr-net td{font-size:var(--fs-h3);}
.app .sub,.app .card-sub,.app .lasts-lead,.app .hh-monthly{font-size:var(--fs-lead);}
.app .cf-k,.app .cf-v,.app .nw-row label,
.app .num-input input,.app .name-row input,.app .kid-name,
.app .alloc-row .alloc-name,.app .qa-btn,.app .sn-list .tab,
.app option,.app select,.app input[type=text],
.app input[type=number],.app input[type=date]{font-size:var(--fs-body);}
.app .caption,.app .hint,.app .tl-hint,.app .age-note,
.app .cf-note,.app .alloc-note,.app .at-blend,.app .lasts-assume li,
.app .spec-k,.app .fold-s,.app .seg-btn,.app .pot-from,.app .pot-arrow,
.app .pot-to,.app .bd-row b,.app .bd-row span,
.app .ev-group label,.app .ev-group input,.app .ev-group select{font-size:var(--fs-small);}
/* The year-by-year cells were in the line above, grouped with captions, hints
   and notes — so the one table on the screen made of nothing but figures was
   sized as supporting text. They are data, and read at the row size every
   other table on this screen uses. */
.app .br-row td{font-size:var(--fs-body);}
.app .kpi span,.app .ledger-title,.app .section-num,.app .hh-label,
.app .hh-stat span,.app .fold-t,.app .fold-v,.app .alloc-head span,
.app .stage-head span,.app .kid-head span,
.app .ab-lab,.app .ab-chip span,
.app .lasts-assume b,.app .tl-title,.app .qa-label,.app .nw-subhead,
.app .chart-legend,.app .cf-axis span,.app .chart-y span{font-size:var(--fs-micro);}
.app .help-i{font-size:var(--fs-micro);}

/* Captions should use the width they are given rather than wrapping early. */
.app .card-sub,.app .caption,.app .hint,.app .cf-note,.app .age-note{max-width:none;}
.app .panel .card-sub,.app .panel .caption{max-width:74ch;}
.sub,.lp-sub{max-width:62ch;}

/* whose milestone is it — a quiet select in the card's sub row */
.ev-owner{background:var(--surface-sunk);border:1px solid transparent;border-radius:8px;
  padding:5px 8px;font:inherit;color:var(--ink-60);outline:none;cursor:pointer;max-width:120px;}
.ev-owner:focus{border-color:var(--accent);}
.ev-owner:hover{color:var(--ink-87);}

/* Near-duplicates left over from older rules: 13.5 and 12.5 are both "small",
   16.5 is "h3". Snap them so the ladder has no half-rungs. */
.app .ev-group,.app .ev-group *,.app .more-note,.app .more-status,
.app .roadmap-note,.app .feedback,.app .sc-status,.app .budget-summary,
.app .glide-note,.app .retSpendNote,.app .prorateNote,.app .bufferNote{
  font-size:var(--fs-small);}
.app .card-h,.app h3{font-size:var(--fs-h3);}
.app .p-tab,.app .mode-btn,.app .sc-btn,.app .btn{font-size:var(--fs-body);}

/* =====================================================================
   Keyboard access. 37 controls had no visible focus state, so tabbing
   through the app was invisible. One ring, everywhere, on the accent.
   ===================================================================== */
.app a:focus-visible,.app button:focus-visible,.app input:focus-visible,
.app select:focus-visible,.app textarea:focus-visible,.app [tabindex]:focus-visible,
.lp a:focus-visible,.lp button:focus-visible,.lp input:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:6px;
}
/* the dark sidebar needs a light ring to be visible at all */
.sidenav a:focus-visible,.sidenav button:focus-visible{
  outline:2px solid #fff;outline-offset:2px;
}
/* never remove the ring without replacing it */
.app *:focus{outline-color:var(--accent);}

/* A long milestone name must not push its pill off the track and over the
   sidebar. Cap the text and let the label ellipsis rather than overflow. */
.tl-pill .tl-text{min-width:0;}
.tl-pill .tl-text b,.tl-pill .tl-text em{display:block;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;max-width:100%;}

/* ---- Insights strip ------------------------------------------------- */
/* The headline output of the Insights page: the rate the next pound meets,
   which is the number that actually changes a decision. */
.ins-strip{display:grid;gap:14px;margin:0 0 22px;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));}
.ins-tile{background:#fff;border:1px solid var(--line-soft);border-radius:var(--radius-card);
  padding:18px 20px;box-shadow:var(--shadow-card);}
.ins-who{font-weight:650;color:var(--ink-87);margin-bottom:2px;}
.ins-fig{font-weight:700;color:var(--accent);letter-spacing:-.02em;line-height:1.1;}
.ins-cap{color:var(--ink-60);margin-top:2px;}
.ins-foot{color:var(--ink-56);margin-top:10px;padding-top:10px;
  border-top:1px solid var(--line-soft);}
.app .ins-who{font-size:var(--fs-h3);}
.app .ins-fig{font-size:var(--fs-hero);}
.app .ins-cap{font-size:var(--fs-small);}
.app .ins-foot{font-size:var(--fs-micro);}

/* ---- Merged budget + run-rate table ---------------------------------- */
/* One table: the "Today" column is editable, every other column is the same
   lines projected to an age, so a cost starting or stopping is visible. */
.bgt-bar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-bottom:10px;}
.bgt-bar .nw-subhead{margin:0;}
.bgt-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;}
.bgt-table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;}
.bgt-table th{text-align:right;padding:8px 10px;white-space:nowrap;
  border-bottom:1px solid var(--line);color:var(--ink-56);font-weight:600;}
.bgt-table th.c-lab{text-align:left;}
.bgt-table td{padding:6px 10px;border-bottom:1px solid var(--line-soft);
  text-align:right;vertical-align:middle;}
.bgt-table td.c-lab{text-align:left;color:var(--ink-87);min-width:170px;}
/* Every budget row carries an empty hint slot; only childcare uses one so far.
   :not(:empty) keeps the other six from growing a blank second line. */
.bgt-table td.c-lab label span:not(:empty){display:block;font-size:var(--fs-micro);
  color:var(--ink-56);font-weight:400;line-height:1.35;margin-top:3px;max-width:34ch;}
.bgt-table td.c-amt{width:132px;}
.bgt-table td.c-yrs{width:112px;}
.bgt-table td.c-age{width:112px;color:var(--ink-60);}
.bgt-table .c-yrs{white-space:nowrap;}
.bgt-table td.c-yrs .bg-yrs{display:inline-flex;}
.bgt-table .num-input{width:100%;}
.cb-row .cb-label{width:100%;}
.cb-x{background:none;border:none;color:var(--ink-56);cursor:pointer;
  padding:0 2px;margin-left:6px;}
.cb-x:hover{color:var(--brick);}
.rr-plan .rr-src{display:block;color:var(--ink-56);font-style:normal;}
.bgt-table tfoot .c-lab{color:var(--ink-87);font-weight:600;}
.bgt-table tfoot .rr-tot td{border-top:1px solid var(--line);font-weight:600;}
.bgt-table tfoot .rr-net td{border-top:2px solid var(--accent);font-weight:800;
  color:var(--ink-87);}
.bgt-table tfoot .neg{color:var(--brick);}
.bgt-actions{display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap;margin-top:12px;}
.bgt-actions .rr-add{margin-top:0;}
.app .bgt-table{font-size:var(--fs-small);}
.app .bgt-table th{font-size:var(--fs-micro);}
.app .rr-plan .rr-src{font-size:var(--fs-micro);}
@media (max-width:720px){
  .bgt-table{min-width:520px;}
}
.bgt-table th .rr-ret{display:block;font-style:normal;font-weight:500;
  color:var(--ink-56);text-transform:none;}
.bgt-table th .rr-x{margin-left:6px;}
.bgt-table .rr-note td{text-align:left;color:var(--ink-56);border-bottom:none;
  padding-top:10px;line-height:1.5;}
.bgt-table .rr-note a{color:var(--accent);}
.app .bgt-table th .rr-ret,.app .bgt-table .rr-note td{font-size:var(--fs-micro);}
.bgt-table th .rr-h{display:flex;align-items:center;justify-content:flex-end;gap:4px;}
.bgt-table th .rr-x{margin:0;line-height:1;}

/* ---- Help popover ---------------------------------------------------- */
/* A floating answer to "why does this matter", anchored to the (i) that
   opened it. One at a time; dismissed by clicking anywhere or pressing Esc. */
.help-pop{position:fixed;z-index:60;max-width:min(340px,calc(100vw - 24px));
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:16px 18px 14px;box-shadow:0 12px 34px rgba(11,14,20,.16);}
.help-pop b{display:block;color:var(--ink-87);margin-bottom:7px;}
.help-pop p{margin:0 0 9px;color:var(--ink-60);line-height:1.62;}
.help-pop p:last-of-type{margin-bottom:0;}
.help-close{position:absolute;top:8px;right:9px;background:none;border:none;
  color:var(--ink-56);cursor:pointer;line-height:1;padding:3px 5px;border-radius:6px;}
.help-close:hover{color:var(--ink-87);background:var(--surface-sunk);}
/* The popover lives on <body>, outside .app, so it has to carry its own
   family and size — the scoped type scale never reaches it. */
.help-pop{font-family:var(--sans);}
.help-pop b{font-size:var(--fs-body);}
.help-pop p{font-size:var(--fs-small);}
.eq-lab{color:var(--ink-56);margin:12px 0 6px;}
.app .eq-lab{font-size:var(--fs-micro);}
.bgt-unit-help{margin-left:auto;}

/* ---- Panel pager ------------------------------------------------------ */
/* The prev/next pair at the foot of every tab. It had no styling at all,
   which is why it was the last thing off the type scale. */
.panel-nav{display:flex;justify-content:space-between;gap:12px;
  margin:26px 0 4px;padding-top:18px;border-top:1px solid var(--line-soft);}
.panel-nav button{background:#fff;border:1px solid var(--line);border-radius:11px;
  font-family:inherit;font-size:var(--fs-small);font-weight:600;color:var(--ink-60);
  padding:9px 14px;cursor:pointer;
  transition:border-color .18s var(--ease),color .18s var(--ease);}
.panel-nav button:hover:not(:disabled){border-color:var(--accent);color:var(--accent);}
.panel-nav button:disabled{opacity:0;pointer-events:none;}




/* ==========================================================================
   DESIGN PASS 2 — Claude Design, "Aftertax Foundations".
   Supersedes the pass 1 block, which it re-states with both reported bugs
   fixed (.lp-shot img height:auto, and the invalid color-mix over 100%).
   Adds the milestone timeline and the pots chart's scrub states.
   ========================================================================== */

/* ==========================================================================
   Budget table  —  .bgt-table
   ========================================================================== */
.bgt-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:var(--radius-card);}
.bgt-table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;}

/* label column stays put while the age columns scroll underneath it */
.bgt-table th.c-lab,.bgt-table td.c-lab{
  position:sticky;left:0;z-index:1;background:var(--surface);
  min-width:180px;padding:var(--space-3) var(--space-4);text-align:left;color:var(--ink-87);
}

.bgt-table th{
  text-align:right;padding:var(--space-2) var(--space-3);white-space:nowrap;
  border-bottom:1px solid var(--line);color:var(--ink-56);font-weight:600;
  font-family:var(--sans);letter-spacing:-0.005em;
}
.bgt-table td{
  padding:var(--space-2) var(--space-3);border-bottom:1px solid var(--line-soft);
  text-align:right;vertical-align:middle;
}

/* the input lane: only the Today column ever holds a keyboard input, so the
   whole column carries a soft wash instead of each cell fighting the plain
   read-only figures next to it with its own chip border. */
.bgt-table th.c-amt,.bgt-table td.c-amt{
  width:112px;background:var(--surface-sunk);
  border-left:1px solid var(--line-soft);border-right:1px solid var(--line-soft);
}
.bgt-table td.c-amt .num-input{background:transparent;border-radius:var(--radius-input);padding:0 var(--space-2);}
.bgt-table td.c-amt .num-input:hover{background:rgba(11,14,20,.04);}
.bgt-table td.c-amt .num-input:focus-within{background:#fff;box-shadow:0 0 0 2px var(--accent-wash);}
.bgt-table td.c-amt input{font-family:var(--mono);text-align:right;}

/* Lasts: still an input, narrower, the last thing in the "you type this" lane */
.bgt-table th.c-yrs,.bgt-table td.c-yrs{width:92px;color:var(--ink-56);border-right:1px solid var(--line);}
.bg-yrs{display:inline-flex;align-items:center;gap:4px;background:var(--surface);
  border:1px solid var(--line-soft);border-radius:var(--radius-input);padding:0 var(--space-2);}
.bg-yrs input{background:transparent;border:none;width:100%;min-width:0;
  padding:var(--space-2) 0;font:inherit;font-size:var(--fs-body);font-weight:500;
  color:var(--ink-87);text-align:right;outline:none;}
.bg-yrs span{font-size:var(--fs-micro);color:var(--ink-56);}
.bg-yrs:focus-within{border-color:var(--accent);}

/* the answer lane: every age column. Full-contrast ink because this is the
   actual output of the tool, not a muted afterthought. */
.bgt-table th.c-age,.bgt-table td.c-age{width:92px;color:var(--ink-87);font-family:var(--mono);white-space:nowrap;}
.bgt-table th.c-age{color:var(--ink-56);}
.bgt-table th .rr-h{display:flex;align-items:center;justify-content:flex-end;gap:4px;}
.bgt-table th .rr-ret{display:block;font-style:normal;font-weight:600;
  color:var(--warn);text-transform:none;margin-top:2px;}
.bgt-table th .rr-x{margin:0;line-height:1;background:none;border:none;
  color:var(--ink-56);cursor:pointer;padding:0 0 0 var(--space-1);}
.bgt-table th .rr-x:hover{color:var(--brick);}
.bgt-table td.c-age.is-ended{color:var(--ink-56);}
.bgt-table td.c-age.is-ended::after{content:'–';}   /* EMPTY in tool.js */

/* rows sourced from a timeline milestone read as their own class of thing —
   a whole-row wash, not a stripe down one side (per the brief's ban). */
.bgt-table tr.rr-plan{background:var(--accent-wash);}
.bgt-table tr.rr-plan td.c-amt,.bgt-table tr.rr-plan td.c-yrs{background:color-mix(in srgb, var(--accent-wash) 140%, transparent);}
.rr-plan td.c-lab{color:var(--accent-deep);font-weight:600;}
.rr-plan td.c-lab::before{content:'';display:inline-block;width:5px;height:5px;
  border-radius:50%;background:var(--accent);margin-right:var(--space-2);vertical-align:middle;}
.rr-plan .rr-src{display:block;font-size:var(--fs-micro);font-weight:400;
  color:var(--accent-deep);opacity:.72;font-style:normal;margin-top:1px;}
.rr-plan td.c-amt,.rr-plan td.c-age{color:var(--accent-deep);font-weight:600;}
/* fix: color-mix() with a percentage over 100% is invalid and the whole
   declaration drops silently. var(--accent-wash) is already ~6% accent, so
   140% of it was an attempt at ~16% accent flat — express that directly. */
.bgt-table tr.rr-plan td.c-amt,.bgt-table tr.rr-plan td.c-yrs{background:color-mix(in srgb, var(--accent) 16%, transparent);}

.cb-row .cb-label{width:100%;}
.cb-x{background:none;border:none;color:var(--ink-56);cursor:pointer;padding:0 var(--space-1);}
.cb-x:hover{color:var(--brick);}

/* footer: subtotal, a plain reference row, then the number that matters */
.bgt-table tfoot td{padding:var(--space-2) var(--space-3);}
.bgt-table tfoot tr:first-child td{padding-top:var(--space-4);}
.bgt-table tfoot .c-lab{color:var(--ink-87);font-weight:600;}
.bgt-table tfoot .rr-tot td{border-top:1px solid var(--line);font-weight:600;}
.bgt-table tfoot .rr-ref td{color:var(--ink-60);}
.bgt-table tfoot .rr-net td{border-top:2px solid var(--accent);font-weight:800;
  color:var(--ink-87);padding-top:var(--space-3);}
.bgt-table tfoot .pos{color:var(--green-ok);}
.bgt-table tfoot .neg{color:var(--brick);}
.bgt-table .rr-note td{text-align:left;color:var(--ink-56);border-bottom:none;
  padding-top:var(--space-3);line-height:1.5;}
.bgt-table .rr-note a{color:var(--accent);}

.app .bgt-table{font-size:var(--fs-small);}
.app .bgt-table th{font-size:var(--fs-micro);}
.app .rr-plan .rr-src{font-size:var(--fs-micro);}

.bgt-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);
  flex-wrap:wrap;margin-bottom:var(--space-3);}
.bgt-actions{display:flex;align-items:center;justify-content:space-between;
  gap:var(--space-4);flex-wrap:wrap;margin-top:var(--space-3);}
.rr-add{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;
  font-size:var(--fs-small);color:var(--ink-60);}
.rr-add .num-input{width:88px;}

@media (max-width:720px){
  .bgt-table{min-width:640px;}
}

/* ==========================================================================
   Landing hero  —  .lp-hero-row / .lp-hero / .lp-shot  (now full-bleed)
   ========================================================================== */
.lp-hero-row{display:flex;flex-direction:column;padding:var(--space-8) 0 var(--space-6);}
.lp-hero{padding:0;max-width:720px;margin-bottom:var(--space-7);}
/* The shot is a capture of a card that already carries its own background,
   border and radius, so the frame adds only the lift — a second background
   here double-frames it. No fixed ratio either: the image sets its own. */
.lp-shot{position:relative;border-radius:var(--radius-card);overflow:hidden;
  box-shadow:var(--shadow-lift);display:block;}
/* fix: width:100% with no height:auto let the img's height attribute win and
   squash the shot. Always pair the two. */
.lp-shot img{display:block;width:100%;height:auto;}
/* The same summary card the tool renders, reused as the landing hero. In the
   tool it is a fixed 1100px because it existed to be screenshotted; here it has
   to survive a phone, and .lp-shot already supplies the card's shell. */
.lp-shot .hero-summary{width:auto;border:0;border-radius:inherit;box-shadow:none;}
@media (max-width:900px){
  .lp-shot .hero-summary{grid-template-columns:1fr;gap:var(--space-5);}
  .lp-shot .hs-end{padding-left:0;border-left:0;
    padding-top:var(--space-5);border-top:1px solid var(--line);}
}
.lp-shot-cap{position:absolute;left:var(--space-4);bottom:var(--space-4);
  background:rgba(11,14,20,.86);color:#fff;font-family:var(--mono);font-size:var(--fs-micro);
  padding:var(--space-1) var(--space-2);border-radius:8px;}

/* ==========================================================================
   Milestone timeline  —  .timeline-wrap / .tl-track / .tl-pill / .tl-tick /
   .event-card / .qa-btn
   ========================================================================== */
.timeline-wrap{background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--radius-card);padding:var(--space-6) var(--space-7) var(--space-5);
  box-shadow:var(--shadow-card);margin-bottom:var(--space-5);}
.tl-head{display:flex;justify-content:space-between;align-items:baseline;}
.tl-title{font-size:var(--fs-micro);font-weight:700;color:var(--ink-56);}
.tl-title span{display:block;font-size:var(--fs-body);font-weight:800;color:var(--ink-87);margin-top:2px;}
.tl-title.right{text-align:right;}

.timeline-track{position:relative;height:220px;margin:var(--space-2) 0;transition:height .2s var(--ease);}

/* accumulation fill: a quiet sparkline of projected net worth behind the
   line, drawn from the same year-by-year total the pots chart already has —
   so the track carries information instead of being a flat gradient rule.
   Render as one <path>, no stroke, low opacity; y maps 0 -> track bottom,
   max(net worth over the span) -> near the top. */
.tl-track-fill{position:absolute;inset:0;pointer-events:none;}
.tl-track-fill path{fill:var(--accent);opacity:.08;}

.tl-line{position:absolute;top:50%;left:0;right:0;height:2px;border-radius:2px;
  background:var(--line);transform:translateY(-50%);}

.tl-tick{position:absolute;top:50%;transform:translate(-50%,-50%);pointer-events:none;
  display:flex;flex-direction:column;align-items:center;z-index:1;}
.tl-tick i{display:block;width:1px;height:11px;background:var(--line);}
.tl-tick em{font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);margin-top:2px;
  font-variant-numeric:tabular-nums;}

/* --tl-cat replaces --cat: same mechanism, new namespace (see markup notes) */
.cat-property{--tl-cat:var(--tl-prop);}
.cat-family{--tl-cat:var(--tl-family);}
.cat-money{--tl-cat:var(--tl-money);}
.cat-work{--tl-cat:var(--tl-work);}

.tl-mark{position:absolute;top:0;bottom:0;width:0;cursor:grab;}
.tl-mark.dragging{cursor:grabbing;z-index:5;}
.tl-mark:focus-visible{outline:none;}
.tl-mark:focus-visible .tl-pill{outline:2px solid var(--tl-cat,var(--accent));outline-offset:2px;}
.tl-stem{position:absolute;left:50%;width:1px;background:var(--tl-cat,var(--line));
  opacity:.35;transform:translateX(-50%);}
.tl-mark.above .tl-stem{bottom:50%;height:var(--off,26px);}
.tl-mark.below .tl-stem{top:50%;height:var(--off,26px);}
.tl-dot{position:absolute;top:50%;left:50%;width:11px;height:11px;border-radius:50%;
  background:#fff;border:3px solid var(--tl-cat,var(--accent));transform:translate(-50%,-50%);
  z-index:2;box-shadow:0 1px 4px rgba(11,14,20,.15);}
.tl-pill{position:absolute;left:0;display:flex;align-items:center;gap:var(--space-2);
  max-width:min(230px,42vw);background:#fff;border:1px solid color-mix(in srgb, var(--tl-cat,var(--accent)) 30%, transparent);
  box-shadow:0 1px 2px rgba(11,14,20,.05), 0 0 0 3px color-mix(in srgb, var(--tl-cat,var(--accent)) 7%, transparent);
  border-radius:12px;padding:var(--space-2) var(--space-3);white-space:nowrap;
  transition:box-shadow .18s var(--ease),max-width .18s var(--ease);}
.tl-mark.above .tl-pill{bottom:calc(50% + var(--off,26px));}
.tl-mark.below .tl-pill{top:calc(50% + var(--off,26px));}
.tl-mark:hover .tl-pill{box-shadow:0 3px 10px rgba(11,14,20,.10), 0 0 0 3px color-mix(in srgb, var(--tl-cat,var(--accent)) 12%, transparent);}
.tl-ico{width:15px;height:15px;flex:none;color:var(--tl-cat,var(--accent));}
.tl-ico svg{width:15px;height:15px;}
.tl-text{display:flex;flex-direction:column;line-height:1.3;overflow:hidden;}
.tl-text b{font-size:var(--fs-small);font-weight:700;color:var(--ink-87);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tl-text em{font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* clustering: past two lanes deep, drop the summary line so density never
   costs legibility — icon, name and age only. Driven by an is-compact class
   layoutTimelineLanes() adds once a mark's lane index > 1. */
.tl-mark.is-compact .tl-pill{padding:6px var(--space-2);}
.tl-mark.is-compact .tl-text em{display:none;}
.tl-mark.is-compact .tl-text b{font-size:var(--fs-micro);}

/* ==========================================================================
   Pots over time  —  #chartPots / .chart-frame / .cf-axis / #potsLegend
   ========================================================================== */
.chart-frame{position:relative;}
.chart-frame svg{display:block;width:100%;height:180px;}
.chart-y{display:flex;flex-direction:column;justify-content:space-between;
  font-size:var(--fs-micro);color:var(--ink-56);font-variant-numeric:tabular-nums;
  text-align:right;padding:2px 0;}
.cf-axis{display:flex;justify-content:space-between;font-size:var(--fs-micro);
  color:var(--ink-56);margin-top:var(--space-2);font-variant-numeric:tabular-nums;}
.cf-axis em{font-style:normal;}
.cf-axis em.is-scrubbed{color:var(--accent-deep);font-weight:700;}

/* solid fills + a crisp top-edge stroke, drawn as its own path so
   preserveAspectRatio="none" doesn't stretch it thin — replaces the old
   five-band 0.5-opacity overlap, which read as muddy at that count. */
.pots-band{opacity:1;}
.pots-band-edge{fill:none;stroke-width:1.5;}

.pots-crosshair{stroke:var(--ink-87);stroke-width:1;stroke-dasharray:2 3;opacity:0;
  transition:opacity .12s var(--ease);}
.chart-frame.is-scrubbing .pots-crosshair{opacity:.5;}
.pots-cross-dot{r:3.5;stroke:#fff;stroke-width:1.5;opacity:0;transition:opacity .12s var(--ease);}
.chart-frame.is-scrubbing .pots-cross-dot{opacity:1;}
.pots-ahead-veil{fill:#fff;opacity:0;transition:opacity .12s var(--ease);}
.chart-frame.is-scrubbing .pots-ahead-veil{opacity:.55;}

#potsLegend{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-5);margin-top:var(--space-4);}
.pots-at{display:flex;align-items:center;gap:var(--space-2);font-size:var(--fs-small);}
.pots-at i{width:10px;height:10px;border-radius:3px;flex:none;}
.pots-at b{font-family:var(--mono);color:var(--ink-87);margin-left:auto;padding-left:var(--space-3);}
.chart-legend.is-scrubbing .pots-at b{color:var(--accent-deep);}
.pots-total{display:flex;justify-content:space-between;align-items:baseline;
  /* full row: the border-top and space-between only read as a summary line if
     it spans the legend rather than shrinking to its own content */
  flex:1 0 100%;gap:var(--space-4);
  border-top:1px solid var(--line);margin-top:var(--space-3);padding-top:var(--space-2);
  font-weight:700;color:var(--ink-87);}
.pots-total b{font-family:var(--mono);font-size:var(--fs-lead);}
.chart-legend.is-scrubbing .pots-total b{color:var(--accent-deep);}

/* keyboard focus: ring the whole frame, not an SVG child the browser can
   clip differently across engines. */
.chart-frame{outline:none;}
.chart-frame:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:12px;}


/* ==========================================================================
   Landing hero — local amendments to the pass 2 block
   ========================================================================== */
/* Pass 2's mobile answer is a 4/3 box, which letterboxes the shot but doesn't
   make it readable: the bridge needs ~1100px before columns clip, so at 390px
   it renders at about a third size. Give it its own horizontal scroll at a
   legible height instead — the same gesture the real table asks for. */
@media (max-width:860px){
  .lp-shot{aspect-ratio:auto;display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .lp-shot img{width:auto;height:300px;max-width:none;}
}

/* ==========================================================================
   Front door — the entry sequence for a first-time visitor
   ========================================================================== */
body.fd-open{overflow:hidden;}
.fd{position:fixed;inset:0;z-index:80;display:flex;align-items:flex-start;
  justify-content:center;overflow-y:auto;padding:var(--space-6) var(--space-4);
  background:color-mix(in srgb, var(--sidebar) 55%, transparent);
  backdrop-filter:blur(2px);}
.fd-card{background:var(--surface);border-radius:var(--radius-card);
  box-shadow:var(--shadow-lift);padding:var(--space-7);width:100%;max-width:520px;
  margin:auto;}
.fd-eyebrow{font-family:var(--mono);font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.04em;color:var(--accent);margin:0 0 var(--space-2);}
.fd-card h2{font-size:var(--fs-h2);font-weight:800;letter-spacing:-0.02em;
  color:var(--ink-87);margin:0 0 var(--space-2);}
.fd-sub{font-size:var(--fs-lead);color:var(--ink-60);margin:0 0 var(--space-6);}
.fd-q{margin-bottom:var(--space-5);}
.fd-q>label{display:block;font-size:var(--fs-small);font-weight:700;
  color:var(--ink-87);margin-bottom:var(--space-2);}
.fd-opts{display:flex;flex-wrap:wrap;gap:var(--space-2);}
.fd-opts button{font:inherit;font-size:var(--fs-small);font-weight:600;
  color:var(--ink-60);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-pill);padding:var(--space-2) var(--space-4);cursor:pointer;
  transition:border-color .15s var(--ease),color .15s var(--ease);}
.fd-opts button:hover{border-color:var(--ink-56);}
.fd-opts button.active{border-color:var(--accent);color:var(--accent-deep);
  background:var(--accent-wash);}
.fd-ages{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4);}
.fd-ages label{display:block;font-size:var(--fs-small);font-weight:700;
  color:var(--ink-87);margin-bottom:var(--space-2);}
.fd-actions{display:flex;flex-direction:column;gap:var(--space-3);
  margin-top:var(--space-6);}
.fd-actions .btn{width:100%;text-align:center;}
.fd-skip{background:none;border:none;font:inherit;font-size:var(--fs-small);
  color:var(--ink-56);cursor:pointer;text-decoration:underline;
  text-underline-offset:3px;}
.fd-skip:hover{color:var(--ink-60);}
.fd-figs{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4);
  margin:var(--space-5) 0;}
.fd-figs>div{background:var(--surface-sunk);border-radius:12px;
  padding:var(--space-4);}
.fd-figs span{display:block;font-size:var(--fs-micro);color:var(--ink-60);
  margin-bottom:var(--space-1);}
.fd-figs b{font-family:var(--mono);font-size:var(--fs-figure);font-weight:700;
  color:var(--ink-87);}
.fd-caveat{font-size:var(--fs-small);color:var(--ink-60);line-height:1.55;margin:0;}
@media (max-width:520px){
  .fd-card{padding:var(--space-5);}
  .fd-ages,.fd-figs{grid-template-columns:1fr;}
}
.fd-group{font-family:var(--mono);font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.04em;color:var(--ink-56);text-transform:uppercase;
  margin:var(--space-6) 0 var(--space-3);padding-top:var(--space-4);
  border-top:1px solid var(--line-soft);}
.fd-note{margin:calc(var(--space-3) * -1) 0 0;}

/* ==========================================================================
   Two tiers — Quick Estimate / Detailed Plan
   ========================================================================== */
.tier-bar{display:flex;align-items:center;gap:var(--space-3);margin-left:auto;
  padding-right:var(--space-4);}
.tier-badge{font-family:var(--mono);font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.03em;color:var(--accent-deep);background:var(--accent-wash);
  border-radius:var(--radius-pill);padding:var(--space-1) var(--space-3);white-space:nowrap;}
.tier-switch{font:inherit;font-size:var(--fs-small);font-weight:600;
  color:var(--ink-60);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-pill);padding:var(--space-2) var(--space-4);cursor:pointer;
  white-space:nowrap;transition:border-color .15s var(--ease),color .15s var(--ease);}
.tier-switch:hover{border-color:var(--accent);color:var(--accent-deep);}
.fd-card-inline{padding:var(--space-6);}
.fd-select{width:100%;font:inherit;font-size:var(--fs-body);color:var(--ink-87);
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  padding:var(--space-3);}
.fd-select:focus{outline:none;border-color:var(--accent);}
.qe-out{margin-top:var(--space-5);padding:var(--space-6);}
.qe-basis{font-size:var(--fs-lead);font-weight:600;color:var(--ink-87);
  margin:0 0 var(--space-3);}
.qe-limits{font-size:var(--fs-small);color:var(--ink-60);line-height:1.6;margin:0;}
.qe-prompt{margin-top:var(--space-5);padding-top:var(--space-5);
  border-top:1px solid var(--line);}
.qe-prompt p{font-size:var(--fs-body);color:var(--ink-87);margin:0 0 var(--space-4);}
.qe-prompt-actions{display:flex;align-items:center;gap:var(--space-4);flex-wrap:wrap;}
@media (max-width:760px){
  .tier-bar{width:100%;margin:var(--space-3) 0 0;padding-right:0;}
}

/* Quick Estimate uses the app's own card, field, ledger and kpi components, so
   the two tiers are the same product. Only these few extras are specific. */
/* The tier switch is primary navigation — it changes what product you're
   looking at. The scenario picker just loads a file. They were reading as
   peers; this gives the switch more weight and, at narrow widths, first claim
   on the row: it holds its size while the scenario bar wraps beneath. */
.tier-seg{margin-left:auto;margin-right:var(--space-4);flex:0 0 auto;order:1;
  padding:3px;background:var(--surface-sunk);border:1px solid var(--line);
  border-radius:var(--radius-pill);}
.tier-seg .seg-btn{font-size:var(--fs-small);font-weight:700;
  padding:var(--space-2) var(--space-5);border-radius:var(--radius-pill);}
.tier-seg .seg-btn.active{background:var(--accent);color:#fff;
  box-shadow:0 1px 2px rgba(11,14,20,.12);}
.topbar .scenario-bar{order:2;}
@media (max-width:860px){
  .topbar{align-items:flex-start;}
  .tier-seg{margin-left:0;margin-right:0;width:auto;}
  .tier-seg .seg-btn{flex:1 1 auto;text-align:center;}
  .topbar .scenario-bar{width:100%;}
}
.qe-aside{border-top:1px solid var(--line);margin-top:var(--space-3);
  padding-top:var(--space-3);}
.qe-check{margin-top:var(--space-3);}
.qe-strip{grid-template-columns:repeat(2,1fr);margin:var(--space-5) 0 var(--space-4);}
.qe-prompt{margin-top:var(--space-5);padding-top:var(--space-5);
  border-top:1px solid var(--line);}
.qe-prompt p{font-size:var(--fs-body);color:var(--ink-87);margin:0 0 var(--space-4);}
.qe-prompt-actions{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;}
.grid.three{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-4);}
@media (max-width:760px){
  .grid.three{grid-template-columns:1fr;}
}

/* ==========================================================================
   "About you" as a strip at the head of Income, rather than its own tab
   ========================================================================== */
.you-strip-full{margin-bottom:0;}
.you-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-5);
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--radius-card);box-shadow:var(--shadow-card);
  padding:var(--space-5) var(--space-6);margin-bottom:var(--space-5);}
.you-block{min-width:0;}
.you-lab{display:block;font-family:var(--mono);font-size:var(--fs-micro);
  font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-56);margin-bottom:var(--space-3);}
.you-name{display:flex;align-items:center;gap:var(--space-3);margin-top:var(--space-3);}
.you-name label{font-size:var(--fs-small);font-weight:600;color:var(--ink-60);flex:none;}
.you-name input{flex:1;min-width:0;}
.you-note{font-size:var(--fs-micro);color:var(--ink-56);line-height:1.5;
  margin:var(--space-2) 0 0;}
.you-strip .age-bar{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3);
  background:none;border:0;padding:0;margin:0;}
@media (max-width:980px){ .you-strip{grid-template-columns:1fr;} }

/* Employer pension is money that never passes through your pay. A bracket and
   a dashed connector say "adjacent to this, not part of it" without needing
   another sentence. */
.qe-adjacent{position:relative;margin-left:var(--space-5);padding-left:var(--space-4);
  border-left:1px dashed var(--line);}
.qe-adjacent::before{content:'';position:absolute;left:0;top:50%;width:10px;
  height:1px;border-top:1px dashed var(--line);}
.qe-adjacent .k,.qe-adjacent .v{color:var(--ink-60);}
.qe-caveat{font-size:var(--fs-lead);font-weight:600;color:var(--ink-87);
  margin:var(--space-4) 0 var(--space-2);}

/* Timeline sparkline: it carries the projected net worth, so give it a scale
   to be read against instead of leaving it as a backdrop. */
.tl-track-fill{position:absolute;inset:0;pointer-events:none;}
.tlf-grid{stroke:var(--accent);stroke-opacity:.16;stroke-width:1;
  stroke-dasharray:2 4;vector-effect:non-scaling-stroke;}
.tlf-max,.tlf-half{position:absolute;right:2px;font-family:var(--mono);
  font-size:var(--fs-micro);color:var(--ink-56);background:var(--surface);
  padding:0 4px;border-radius:4px;transform:translateY(-50%);}
.tlf-max{top:14%;}
.tlf-half{top:57%;}

/* Projection crosshair — the partner to the pots one, so a scrub in either
   chart is visible in both. */
.proj-cross{position:absolute;top:0;bottom:0;width:1px;background:var(--ink-87);
  opacity:.5;pointer-events:none;z-index:3;}

/* The bridge's column-by-column reconciliation, moved into the expansion so
   the default row is just opening, change and closing. */
.br-parts{display:flex;flex-wrap:wrap;gap:var(--space-3) var(--space-6);
  padding:0 0 var(--space-4);margin-bottom:var(--space-4);
  border-bottom:1px solid var(--line-soft);}
.br-part{display:flex;flex-direction:column;gap:2px;min-width:0;}
.br-part em{font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);}
/* The figures in the reconciliation strip sit beside the flow card's figures
   and the pot table's figures, and were a step under both. One size for every
   figure in the expansion; the label above stays a note. */
.br-part b{font-family:var(--mono);font-size:var(--fs-body);color:var(--ink-87);}
.br-part-sum{margin-left:auto;padding-left:var(--space-5);
  border-left:1px solid var(--line);}
.br-part b.pos{color:var(--accent-deep);}
.br-part b.neg{color:var(--brick);}
/* A td sized by its own content can widen the whole table. Pin it to zero and
   let the expansion scroll inside itself if it ever needs to, so opening a
   year never pushes the collapsed columns sideways. */
.bridge-table .br-detail > td{max-width:0;}
.bridge-table .br-detail > td > *{max-width:100%;overflow-x:auto;}

/* Landing: the spec grid now runs Quick first, then Detailed, then the
   director-only depth — so the first thing read describes the fast path. */
.spec-tier{background:var(--surface-sunk);}
.spec-tier span:first-child{font-weight:800;color:var(--ink-87);}
.spec-tier span:last-child{color:var(--ink-56);}
.spec-tier:not(:first-child){margin-top:var(--space-5);}
.hero-ctas .btn{display:inline-flex;flex-direction:column;align-items:center;
  line-height:1.25;gap:1px;}
.hero-ctas .btn em{font-style:normal;font-size:var(--fs-micro);font-weight:500;
  opacity:.72;}
/* Two fields in a column sized for one. The .nw-row track is 1fr 132px; two
   96px inputs plus a gap want 200, so both got crushed until the digits sat
   behind the padding. Widen the track for this row only — the right edge is
   what lines up with the rows above, and that doesn't move. */
#mortTermsRow{grid-template-columns:1fr 204px;}
.mort-terms{display:flex;gap:var(--space-2);}
.mort-terms .num-input{flex:1;min-width:0;}
.mort-terms .num-input input[type=number]{min-width:0;}
/* Trailing unit, so the margin belongs on the other side. */
.mort-terms .num-input span{margin-right:0;margin-left:5px;}
/* "% / yr" was breaking across two lines in a 132px column. */
.num-input span{white-space:nowrap;}
.nw-note{font-size:var(--fs-micro);color:var(--ink-56);line-height:1.5;
  margin:var(--space-2) 0 0;}

/* ==========================================================================
   Capture-only hero summary. Never shown in the app — the screenshot pipeline
   reveals it so the landing page can show real output at a readable size.
   ========================================================================== */
.hero-summary{display:grid;grid-template-columns:1fr 1fr 1.15fr;gap:var(--space-7);
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--radius-card);box-shadow:var(--shadow-card);
  padding:var(--space-6) var(--space-7);width:1100px;}
.hs-col{min-width:0;display:flex;flex-direction:column;}
.hs-lab{font-family:var(--mono);font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;color:var(--ink-56);
  margin-bottom:var(--space-4);}
.hs-row{display:flex;justify-content:space-between;align-items:baseline;
  gap:var(--space-4);padding:var(--space-2) 0;
  border-bottom:1px dotted var(--line-soft);}
.hs-row span{font-size:var(--fs-small);color:var(--ink-60);}
.hs-row b{font-family:var(--mono);font-size:var(--fs-small);color:var(--ink-87);}
.hs-row.hs-strong b{font-size:var(--fs-h3);color:var(--accent-deep);}
.hs-row.hs-owed b{color:var(--brick);}
.hs-row.hs-total{border-bottom:none;border-top:2px solid var(--accent);
  margin-top:var(--space-2);padding-top:var(--space-3);}
.hs-row.hs-total span{font-weight:700;color:var(--ink-87);}
.hs-row.hs-total b{font-size:var(--fs-figure);font-weight:800;}
.hs-note{font-size:var(--fs-micro);color:var(--ink-56);line-height:1.5;
  margin:var(--space-3) 0 0;}
.hs-end{padding-left:var(--space-6);border-left:1px solid var(--line);}
.hs-figure{font-family:var(--mono);font-size:var(--fs-display);font-weight:800;
  letter-spacing:-0.02em;color:var(--accent-deep);line-height:1;
  margin-bottom:var(--space-4);}
.hs-bar{display:flex;height:12px;border-radius:var(--radius-pill);overflow:hidden;
  background:var(--surface-sunk);}
.hs-bar i{display:block;height:100%;}
.k-now{background:var(--cat-taxable);}
.k-add{background:var(--cat-isa);}
.k-grow{background:var(--accent);}
.hs-key{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-4);
  margin-top:var(--space-3);}
.hs-key span{display:flex;align-items:center;gap:6px;font-size:var(--fs-micro);
  color:var(--ink-60);}
.hs-key i{width:10px;height:10px;border-radius:3px;flex:none;}

/* ==========================================================================
   Year-by-year expansion — the year's money, then where it ended up
   ========================================================================== */
/* Stacked, not side by side: six columns of six-figure sums need the full
   width, and half of it clipped the End column clean off. It also reads as a
   sequence — the year's money, then where it ended up. */
.bd-grid2{display:grid;grid-template-columns:1fr;gap:var(--space-6);}
.bd-flow{max-width:520px;}
.bd-grid2 h5{font-family:var(--mono);font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;color:var(--ink-56);
  margin:0 0 var(--space-3);}
.bd-line{display:flex;justify-content:space-between;align-items:baseline;
  gap:var(--space-4);padding:var(--space-2) 0;
  border-bottom:1px dotted var(--line-soft);}
.bd-line span{font-size:var(--fs-body);color:var(--ink-60);}
/* The basis of each line — after tax, gross, and so on. A second line under the
   label rather than a longer label, so the column of figures stays scannable. */
.bd-line span em{display:block;font-style:normal;font-size:var(--fs-micro);
  line-height:1.4;color:var(--ink-56);}
.bd-line b{font-family:var(--mono);font-size:var(--fs-body);color:var(--ink-87);}
.bd-line.neg b{color:var(--brick);}
.bd-line.pos b{color:var(--accent-deep);}
.bd-line.tot{border-bottom:none;border-top:2px solid var(--accent);
  margin-top:var(--space-2);padding-top:var(--space-3);}
.bd-line.tot span{font-weight:700;color:var(--ink-87);}
/* The total sits at the size of the lines it sums. It used to step up to
   --fs-h3, which made this the third size in a card that already had two, and
   a column of figures reads as one column or it reads as nothing. The accent
   rule above it and the weight below already say "total". */
.bd-line.tot b{font-size:var(--fs-body);font-weight:800;letter-spacing:-0.01em;}
/* pensions never pass through take-home, so they sit apart from the run */
.bd-line.aside{border-bottom:none;margin-left:var(--space-5);
  padding-left:var(--space-4);border-left:1px dashed var(--line);}
.bd-line.aside span,.bd-line.aside b{color:var(--ink-60);}

.bd-table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums;}
.bd-table th{text-align:right;font-size:var(--fs-micro);font-weight:600;
  color:var(--ink-56);padding:var(--space-2) var(--space-3);white-space:nowrap;}
.bd-table thead th{border-bottom:1px solid var(--line);}
/* This table is nested inside .bridge-table, so .bridge-card .bridge-table th
   (0,2,1) outranks a plain .bd-table th rule. Scope to match. */
.bridge-card .bd-table th{text-align:right;}
/* The pot name is the label of its own row, so it reads at the row's size.
   It was a step below the figures sitting beside it. */
.bridge-card .bd-table tbody th,
.bridge-card .bd-table tfoot th{text-align:left;font-size:var(--fs-body);
  font-weight:500;color:var(--ink-87);}
/* keep the label column tight so the figures aren't stranded */
.bridge-card .bd-table tbody th,
.bridge-card .bd-table tfoot th{width:1%;white-space:nowrap;padding-right:var(--space-6);}
.bd-table td{text-align:right;font-family:var(--mono);font-size:var(--fs-body);
  color:var(--ink-60);padding:var(--space-2) var(--space-3);white-space:nowrap;}
.bd-table td.pos{color:var(--accent-deep);}
.bd-table td.neg{color:var(--brick);}
.bd-table td.bd-end{color:var(--ink-87);font-weight:700;}
.bd-table tbody tr{border-bottom:1px dotted var(--line-soft);}
.bd-table tfoot tr{border-top:2px solid var(--accent);}
.bd-table tfoot th{font-weight:700;}
.bd-table tfoot .bd-rate{border-top:none;}
.bd-table tfoot .bd-rate th{font-weight:500;color:var(--ink-60);
  font-size:var(--fs-micro);}
.bd-table tfoot .bd-rate td{text-align:right;color:var(--ink-60);
  font-size:var(--fs-micro);}

/* the note under the flow is explanatory, not a warning */
.bd-grid2 .bd-note{font-size:var(--fs-micro);color:var(--ink-56);line-height:1.55;
  margin:var(--space-3) 0 0;max-width:60ch;}

/* ==========================================================================
   Estate panel — the inheritance-tax view and the drawdown-order question
   ========================================================================== */
#estateOrder{margin-top:var(--space-5);padding-top:var(--space-4);
  border-top:1px solid var(--line-soft);}
.est-q{font-size:var(--fs-small);line-height:1.6;color:var(--ink-60);
  margin-bottom:var(--space-4);}
.est-q b{color:var(--ink-87);font-weight:700;}
.est-q p{margin:var(--space-3) 0 0;}

/* The two orders, side by side. Same convention as every other table on the
   projection: one size for every figure, and the levels carried by weight —
   a plain row at 600, the outcome at 800 under an accent rule. Reads down as
   a reconciliation, estate less inheritance tax is what passes on, and the
   income tax line is why the two estates differ in the first place. */
#estateTrade{margin-top:var(--space-4);}
/* The label sits on its own line above its three figures rather than beside
   them. This card is the right column of the retire tab's grid — 375px of
   content — and four columns of six- and seven-figure sums came to 421. The
   alternative was widening the card, which is a change to the page's layout to
   accommodate one table. */
.et-row{display:grid;grid-template-columns:repeat(3,1fr);gap:2px var(--space-3);
  align-items:baseline;padding:8px 0;border-bottom:1px solid var(--line-soft);}
.et-k{grid-column:1/-1;font-size:var(--fs-body);color:var(--ink-60);}
.et-v{font-family:var(--mono);font-size:var(--fs-body);font-weight:600;
  color:var(--ink-87);text-align:right;font-variant-numeric:tabular-nums;}
.et-hd{padding-bottom:6px;border-bottom:1px solid var(--line);}
/* nothing to label in the head row, and an empty span would still take a line */
.et-hd .et-k{display:none;}
/* The column heads are labels, not figures, so they read as the notes do */
.et-hd .et-v{font-family:var(--sans);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.03em;text-transform:uppercase;color:var(--ink-56);}
/* "now" marks which column the tool is currently running, so the other one is
   unambiguously the counterfactual rather than a second saved plan */
.et-hd .et-v em{display:block;font-style:normal;font-weight:500;
  letter-spacing:0;text-transform:none;color:var(--accent);}
.et-row.total{border-bottom:none;border-top:1.5px solid var(--accent);
  margin-top:6px;padding-top:12px;}
.et-row.total .et-k{font-weight:600;color:var(--ink-87);}
.et-row.total .et-v{font-weight:800;letter-spacing:-0.01em;}
.et-say{margin:var(--space-4) 0 0;font-size:var(--fs-small);line-height:1.6;
  color:var(--ink-60);}
.et-say b{color:var(--ink-87);font-weight:700;}
/* The mechanism behind the gap, subordinate to the result it explains */
.et-why{margin-top:var(--space-3);color:var(--ink-56);}

/* The difference column, in the same vocabulary as the plan comparison card:
   green-free, direction by the palette's two reds, "the same" set in the sans
   so a null result never looks like a figure. */
.et-d{font-family:var(--mono);font-size:var(--fs-body);font-weight:600;
  text-align:right;font-variant-numeric:tabular-nums;color:var(--ink-60);}
.et-d.up{color:var(--accent-deep);}
.et-d.down{color:var(--brick);}
.et-d.same{font-family:var(--sans);font-size:var(--fs-small);color:var(--ink-56);}
.et-hd .et-d{font-family:var(--sans);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.03em;text-transform:uppercase;color:var(--ink-56);}
/* The two "while you are alive" lines are a group; the three below them
   reconcile on their own, and the rule says so without a second heading. */
.et-row.et-gap{border-bottom:1px solid var(--line);padding-bottom:12px;}
.et-row.et-gap + .et-row{padding-top:12px;}

/* On a narrow phone the card gets the full width but three seven-figure sums
   still do not fit at body size. Everything in the table steps down together,
   so it stays one size within itself — which is the rule that matters here. */
@media (max-width:380px){
  .et-v,.et-d,.et-k{font-size:var(--fs-small);}
  .et-row{gap:2px var(--space-2);}
}

/* ==========================================================================
   Capital gains position — Wealth tab, under the net-worth block
   ========================================================================== */
.cg-now,.cg-plan{margin-top:var(--space-3);}
.cg-plan{margin-top:var(--space-5);padding-top:var(--space-4);
  border-top:1px solid var(--line-soft);}
.cg-table{width:100%;border-collapse:collapse;margin-top:var(--space-4);
  font-variant-numeric:tabular-nums;}
.cg-table th{text-align:right;font-family:var(--mono);font-size:var(--fs-micro);
  font-weight:600;color:var(--ink-56);padding:6px 0;}
.cg-table thead th{border-bottom:1px solid var(--line);}
.cg-table tbody th{text-align:left;font-family:var(--mono);font-size:var(--fs-small);
  color:var(--ink-87);font-weight:600;}
.cg-table td{text-align:right;font-family:var(--mono);font-size:var(--fs-small);
  color:var(--ink-87);padding:6px 0;}
.cg-table tbody tr{border-bottom:1px dotted var(--line-soft);}
.cg-table td.pos{color:var(--accent-deep);}
.cg-table td.neg{color:var(--brick);}
.cg-none{margin-top:var(--space-4);font-size:var(--fs-small);line-height:1.6;
  color:var(--ink-60);}

/* Milestone note that reads the projection back — sell-investments card */
.ev-note{display:block;width:100%;margin-top:var(--space-3);
  font-size:var(--fs-micro);line-height:1.6;color:var(--ink-60);}
.ev-note b{color:var(--ink-87);font-weight:700;}
.ev-note .ev-warn{color:var(--brick);}

/* ==========================================================================
   Raising cash — the year-by-year gains planner on Wealth
   ========================================================================== */
.cg-controls{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-4);
  margin-top:var(--space-4);}
.cg-ctl{display:inline-flex;align-items:center;gap:var(--space-2);
  font-size:var(--fs-small);color:var(--ink-60);margin:0;}
.cg-ctl input[type=number]{width:104px;background:var(--surface-sunk);border:1px solid transparent;
  border-radius:11px;padding:8px 10px;font-family:var(--mono);font-size:var(--fs-body);
  font-weight:500;color:var(--ink-87);outline:none;}
.cg-ctl input[type=number]:focus{background:#fff;border-color:var(--accent);
  box-shadow:0 0 0 3px rgba(91,91,246,.13);}
.cg-unit{display:inline-flex;align-items:center;background:var(--surface-sunk);border-radius:11px;
  padding:0 0 0 10px;}
.cg-unit>span{color:var(--ink-56);font-size:var(--fs-lead);}
.cg-unit input{background:transparent !important;}
.cg-ofpot{font-size:var(--fs-micro);color:var(--ink-56);}
.cg-slider{width:100%;margin-top:var(--space-3);accent-color:var(--accent);}

.cg-at{margin-top:var(--space-5);}
.cg-at-head{font-size:var(--fs-small);color:var(--ink-60);margin-bottom:var(--space-3);}
.cg-at-head b{color:var(--ink-87);font-weight:700;}
.cg-at-pots{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));
  gap:var(--space-3);}
.cg-pot{background:var(--surface-sunk);border-radius:12px;padding:var(--space-3) var(--space-4);}
.cg-pot span{display:block;font-size:var(--fs-micro);color:var(--ink-56);}
.cg-pot b{display:block;font-family:var(--mono);font-size:var(--fs-lead);
  color:var(--ink-87);font-weight:700;margin-top:2px;}
.cg-pot em{display:block;font-style:normal;font-size:var(--fs-micro);
  color:var(--ink-56);margin-top:2px;}

.cg-opts{width:100%;border-collapse:collapse;margin-top:var(--space-5);
  font-variant-numeric:tabular-nums;}
.cg-opts th{text-align:right;font-size:var(--fs-micro);font-weight:600;
  color:var(--ink-56);padding:7px 0;}
.cg-opts thead th{border-bottom:1px solid var(--line);}
.cg-opts tbody th{text-align:left;font-size:var(--fs-small);color:var(--ink-87);
  font-weight:600;padding-right:var(--space-4);}
.cg-opts tbody th em{display:block;font-style:normal;font-size:var(--fs-micro);
  color:var(--ink-56);font-weight:500;margin-top:1px;}
.cg-opts td{text-align:right;font-family:var(--mono);font-size:var(--fs-small);
  color:var(--ink-87);padding:7px 0;}
.cg-opts td.neg{color:var(--brick);}
.cg-opts tbody tr{border-bottom:1px dotted var(--line-soft);}
.cg-opts tr.is-best td.cg-end{color:var(--accent-deep);font-weight:700;}
.cg-opts td.cg-end i{display:block;font-style:normal;font-size:var(--fs-micro);
  color:var(--accent-deep);font-weight:600;}
.cg-verdict{margin-top:var(--space-4);font-size:var(--fs-small);line-height:1.6;
  color:var(--ink-60);}
.cg-verdict b{color:var(--ink-87);font-weight:700;}
/* .btn-ghost is normally used inside .btn, which sets the size; standalone it
   falls back to the UA default and lands off the type scale. */
#cgToTimeline{margin-top:var(--space-4);font-family:inherit;font-size:var(--fs-small);
  font-weight:600;border-radius:11px;padding:9px 15px;cursor:pointer;}
.cg-plan-h{font-size:var(--fs-micro);font-weight:700;letter-spacing:.06em;
  text-transform:none;color:var(--ink-56);margin-bottom:var(--space-2);}
.cg-caveat{margin:var(--space-3) 0 0;font-size:var(--fs-micro);color:var(--ink-56);
  line-height:1.55;}
/* The planner is a table of four routes; it needs the full column, not half of
   a two-up grid where the figures collide. */
.cg-panel{margin-top:var(--space-6);}
.cg-panel .cg-opts th:first-child,.cg-panel .cg-opts td:first-child{min-width:200px;}
/* Right-aligned monospace figures in adjacent columns run into each other with
   no gutter — "£86,854£235,924". Give every numeric column its own room. */
.cg-opts th+th,.cg-opts td{padding-left:var(--space-5);}
.cg-opts thead th:not(:first-child){min-width:96px;}
@media (max-width:640px){
  /* Four columns cannot hold on a phone. Scrolling them sideways hid the
     figures entirely and left only the route names — on a comparison table
     that removes the reason it exists. So each route becomes its own block
     with its numbers labelled underneath. */
  .cg-opts,.cg-opts tbody,.cg-opts tr,.cg-opts th,.cg-opts td{display:block;width:auto;}
  .cg-opts thead{display:none;}
  .cg-opts tbody tr{border-bottom:1px solid var(--line);padding:var(--space-4) 0;}
  .cg-opts tbody tr:last-child{border-bottom:none;}
  .cg-opts tbody th{padding:0 0 var(--space-3);min-width:0;}
  .cg-opts td{display:flex;justify-content:space-between;align-items:baseline;
    padding:3px 0;text-align:right;}
  .cg-opts td::before{content:attr(data-l);font-family:var(--sans);
    font-size:var(--fs-micro);font-weight:600;color:var(--ink-56);
    text-align:left;padding-right:var(--space-4);}
  .cg-opts td.cg-end i{display:inline;margin-left:var(--space-2);}
  .cg-opts tr.is-best{background:color-mix(in oklch, var(--accent) 5%, transparent);
    border-radius:12px;padding-left:var(--space-3);padding-right:var(--space-3);}
}

/* ==========================================================================
   Mobile audit fixes
   ========================================================================== */

/* The waterfall gives each bar a slice of a 390px screen. A full figure gets
   ellipsised to "£3,522,8…", which is a worse lie than rounding — so show the
   short form instead and keep the exact one for wider screens. */
.wf-short{display:none;}
@media (max-width:720px){
  .wf-full{display:none;}
  .wf-short{display:inline;}
  .wf-tick b{overflow:visible;text-overflow:clip;}
}

/* A 16px circle is a fine visual marker and a poor finger target. Keep the
   drawn size and extend the hit area past it, so nothing shifts on screen.
   Only on touch/coarse pointers, so the desktop hover target stays honest. */
@media (pointer:coarse){
  .help-i{position:relative;}
  .help-i::after{content:"";position:absolute;top:50%;left:50%;
    width:44px;height:44px;transform:translate(-50%,-50%);}
}
/* And a real size bump on narrow screens, which doesn't depend on the pointer
   type being reported correctly. */
@media (max-width:640px){
  .help-i{width:22px;height:22px;}
}

/* Grid and flex children default to min-width:auto, so they refuse to shrink
   below their min-content and push the whole panel past the viewport. At 320px
   that was making the Wealth panel 358px wide inside a 320px screen. Letting
   them shrink is the fix; the scrollable tables opt back out below. */
.grid>*,.panel,.field{min-width:0;}
.bridge-card,.table-scroll{min-width:auto;}

/* The "for how many years" column collapsed to 22px on mobile — too narrow to
   tap and too narrow to show two digits. */
@media (max-width:640px){
  .bgt-row input[type=number].yrs,
  .bgt-wrap input[id$="Yrs"]{min-width:48px;}
}

/* Below this the milestone summary is ellipsised down to "£50,000 from wh…",
   which reads as broken rather than abbreviated. The name and age still
   identify the milestone; the detail is a tap away on the card itself. */
@media (max-width:560px){
  .tl-pill .tl-text em{display:none;}
  /* With the age line gone the pill is a single line, so the name can have the
     second one rather than being ellipsised at 109px into "Helping Priya's
     pa…". A milestone you cannot name is not one you can find on the track. */
  .tl-pill .tl-text b{white-space:normal;overflow:visible;text-overflow:clip;}
}

/* ==========================================================================
   Touch
   ========================================================================== */
/* iOS Safari zooms the whole page in whenever a focused form control computes
   under 16px, and it does not zoom back out when the field blurs. This tool is
   115 number fields; every single tap on one jolted the layout and left the
   page magnified, and the way out was a pinch.

   !important, and not lightly. The fields are styled by their component —
   .nw-row .num-input input[type=number], .alloc-row .alloc-pct, .nwp-cell and
   about thirty more — so a blanket rule here loses the cascade to every one of
   them. Measured: it moved 22 of 115 fields and left 93 zooming. This is a
   floor rather than a design decision, it is confined to one media query, and
   the alternative is enumerating every component that has ever styled an input
   and re-enumerating it whenever one is added.

   The type scale is unaffected above this width, and 16px is the minimum iOS
   accepts — not a rounded-up guess. */
@media (max-width:900px){
  input[type=text],input[type=number],input[type=email],input[type=tel],
  input[type=date],input[type=search],input[type=url],
  select,textarea{font-size:16px !important;}
}

/* Both of this tool's drag interactions were dead on touch, while the UI told
   you to drag. They are wired with pointerdown/pointermove, which does fire for
   a finger — but a touch gesture belongs to the browser's panning until the
   element says otherwise, so the page scrolled and the pointermove handler
   never saw a second event. preventDefault() on pointerdown does not change
   that; only touch-action does.

   pan-y rather than none for both: they are horizontal interactions, so the
   browser keeps vertical panning and the app takes the sideways drag. `none`
   would have made the projection chart a dead zone you could not scroll past
   on a phone, which is most of the screen. */
.tl-mark{touch-action:pan-y;}
#potsFrame,#chartPots{touch-action:pan-y;}

/* A segmented control that does not fit wraps its last option onto a row of
   its own, hard left, which reads as a stray button rather than part of the
   set — "Show the range · Downside · Base" then "Upside" underneath. Below
   560px they lay out as a grid instead, two up, and an odd one out spans the
   full width so every row is full. Two options stay two; four become a tidy
   2x2. The tier switch in the utility bar keeps its compact inline shape.

   This also makes every option a good deal wider than a fingertip, which the
   13px inline buttons were not. */
@media (max-width:560px){
  /* Two columns, always — auto-fit was tried first and is the wrong tool here:
     the column count then depends on the longest label, so a four-option
     control packed three-up and left the fourth stranded again. Two is
     deterministic, and an odd last option spans so no row is half empty.
     Two options stay side by side, three become two plus a full-width third,
     four become 2x2. */
  .seg:not(.tier-seg){display:grid;grid-template-columns:repeat(2,1fr);}
  .seg:not(.tier-seg) .seg-btn{text-align:center;}
  .seg:not(.tier-seg) .seg-btn:last-child:nth-child(odd){grid-column:1/-1;}
}

/* The projection chart's milestone markers are 26px discs, and on a phone four
   milestones a year or two apart land 10px from each other — they overlapped
   into one unreadable blob. The white ring makes an overlap read as stacked
   coins rather than a smudge, and the smaller disc leaves the guide line under
   each one visible, which is the part that says when.

   Their labels are hover-only, so on a touch screen they can never be read at
   all. That is not fixable by making them permanent — four labels a few pixels
   apart overlap worse than the icons do — so the icon and its guide line carry
   the "when" and "what kind", and the milestone's name stays where it is
   already legible, on the timeline in Spending & plans. */
@media (hover:none){
  .pm{width:18px;height:18px;box-shadow:0 0 0 2px var(--surface);}
  .pm-ico svg,.pm > svg{width:10px;height:10px;}
  .pm-lab{display:none;}
}

/* Hit areas. Apple and Google both put the floor at around 44px; these were
   16px checkboxes inside 24px labels, and a 16px slider thumb on a 4px track.
   Gated on the pointer rather than the width, because the thing that makes
   these hard to hit is a fingertip, not a narrow screen. */
@media (pointer:coarse){
  /* "focus one and use the arrow keys" has no meaning without a keyboard. */
  .kb-only{display:none;}
  /* The small segmented controls are 28px tall, which is a comfortable click
     and a poor tap. They are already full-width columns on a phone, so the
     only thing missing is height. */
  .seg-btn{padding-top:11px;padding-bottom:11px;}
  /* .seg.seg-sm .seg-btn is set further up with a padding shorthand, so this
     needs the same two classes to reach it. */
  .seg.seg-sm .seg-btn{padding-top:10px;padding-bottom:10px;}
  /* The tier switch keeps its compact inline shape in the utility bar, but 27px
     is a poor target for the control that decides which version of the whole
     tool you get. Three classes deep because styles-mono.css sizes it with two
     and loads after this file. */
  .seg.tier-seg .seg-btn{padding-top:10px;padding-bottom:10px;}
  .checkbox-row input,input[type=checkbox]{width:20px;height:20px;}
  /* The label is the real target — it wraps the box and its text — so it is
     the thing that has to be tall enough. */
  label.isa-opt,.checkbox-row{min-height:44px;align-items:center;}
  input[type=range]{height:22px;background:none;}
  /* With the input itself 22px tall the track has to be drawn rather than
     inherited from the element's own background. */
  input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:4px;
    background:var(--line);}
  input[type=range]::-moz-range-track{height:4px;border-radius:4px;background:var(--line);}
  input[type=range]::-webkit-slider-thumb{width:22px;height:22px;margin-top:-9px;}
  input[type=range]::-moz-range-thumb{width:22px;height:22px;}
  /* A thumb that grows under the finger is a mouse affordance; on touch it
     just lags the drag. */
  input[type=range]::-webkit-slider-thumb:hover,
  input[type=range]::-moz-range-thumb:hover{transform:none;}
}

/* ==========================================================================
   Timeline clustering — three or more milestones bunched into one marker
   ========================================================================== */
.tl-mark.is-clustered{display:none;}
.tl-cluster{position:absolute;top:50%;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:2px;
  background:#fff;border:1px solid var(--line);border-radius:14px;
  padding:8px 12px;cursor:pointer;z-index:3;font-family:inherit;
  box-shadow:var(--shadow-card);transition:border-color .15s var(--ease),
    box-shadow .15s var(--ease);}
.tl-cluster:hover{border-color:var(--accent);box-shadow:var(--shadow-lift);}
.tl-cluster:focus-visible{outline:2px solid var(--accent);outline-offset:2px;}
.tlc-dots{display:flex;gap:3px;}
.tlc-dots i{width:7px;height:7px;border-radius:50%;background:var(--cat,var(--accent));}
.tl-cluster b{font-size:var(--fs-small);font-weight:700;color:var(--ink-87);
  white-space:nowrap;}
.tl-cluster em{font-style:normal;font-size:var(--fs-micro);color:var(--ink-56);
  white-space:nowrap;font-variant-numeric:tabular-nums;}
/* Open: a quiet chip that only offers to put them back, so it doesn't compete
   with the milestones it just revealed. */
.tl-cluster.is-open{padding:4px 10px;background:transparent;
  border-style:dashed;box-shadow:none;}
.tl-cluster.is-open b{font-size:var(--fs-micro);font-weight:600;color:var(--ink-56);}
.tl-cluster.is-open:hover b{color:var(--ink-87);}

/* Decomposition scrub — same treatment as pots: the age reads in the legend,
   not in a tooltip that would cover the bands being read. */
.dec-age{font-family:var(--mono);font-size:var(--fs-micro);font-weight:700;
  color:var(--accent-deep);}
#decompLegend.is-scrubbing b{color:var(--accent-deep) !important;}

/* Reconciliation flag on the Quick output — a note, not an error. It says the
   numbers don't look right; it never stops anyone continuing. */
.qe-flag{margin-top:var(--space-3);padding:10px 12px;border-radius:10px;
  background:#FDF6EC;color:#8A5A12;font-size:var(--fs-micro);line-height:1.6;}
.qe-flag b{color:#6B430B;font-weight:700;}

/* Value / Cost sub-header on the net-worth grid. Cost is an attribute of the
   holding beside it, not another line that adds up — which is exactly how it
   read when it was its own row. */
.nwp-sub{font-size:var(--fs-micro);font-weight:600;color:var(--ink-56);
  text-align:right;padding-right:2px;letter-spacing:.01em;}
.nwp-sub:first-child{text-align:left;}
/* Rows outside capital gains get a dash, not an empty box that looks fillable. */
.nwp-none{color:var(--ink-56);text-align:center;font-size:var(--fs-small);}
/* Cost is an attribute of the Value beside it, so it must not compete with it.
   Same box, quieter: no fill, a lighter rule, lighter figures. It sharpens on
   hover and focus like any other field — secondary, not disabled. */
.nwp-cell.is-cost{background:transparent;border-color:var(--line-soft);}
.nwp-cell.is-cost input{font-weight:500;color:var(--ink-60);}
.nwp-cell.is-cost:focus-within{background:#fff;border-color:var(--accent);}
.nwp-cell.is-cost:focus-within input{color:var(--ink-87);}
.nwp-sub.is-cost{color:var(--ink-56);font-weight:500;}
/* The three rows that carry a cost belong together; a hairline groups them
   without drawing a box round them. */
.nwp-row.is-taxable + .nwp-row:not(.is-taxable){
  border-top:1px solid var(--line-soft);margin-top:4px;padding-top:7px;}
.nwp-subhelp{display:flex;justify-content:flex-end;}

@media (max-width:640px){
  /* The grid emits 1 label + 2 cells per person, so the column count can't be
     overridden without every row falling out of alignment. Shrink the cells
     and let the label wrap into the space that frees up. */
  .nwp-cost{gap:5px 5px;}
  .nwp-cost .nwp-cell{padding:4px 6px;}
  .nwp-cost .nwp-cell input{font-size:var(--fs-small);}
  .nwp-label{line-height:1.3;}
  /* One person fits. Two needs five columns, which a phone does not have, and
     the alternative is dropping the Cost column — losing the thing that makes
     a sale calculable. So this one block keeps a contained sideways scroll;
     it is the only one left in the app, and it only appears for a couple. */
  /* Only when there are two of you. One person is three columns and fits, so
     forcing max-content there made the label refuse to wrap and scroll for no
     reason. */
  #nwPersonal:has(.nwp-multi){overflow-x:auto;-webkit-overflow-scrolling:touch;}
  #nwPersonal .nwp-multi{min-width:max-content;}
}

/* Wealth stacks rather than sitting two-up. The net-worth block now carries a
   Value and a Cost per person — five columns for a couple — and at half width
   the labels were down to 79px against the 180px they need, wrapping mid-
   phrase. The inputs are the primary thing on this tab; the assumptions can
   follow underneath. */
.grid-stack{grid-template-columns:1fr;}

/* ==========================================================================
   Projection ledger — category dots and the taxable sub-rows
   ========================================================================== */
/* The same --cat-* ramp the wealth donut and the pots chart already use, so a
   row here and a band there are recognisably the same pot. No new colours. */
.ledger-row .k{display:inline-flex;align-items:center;gap:8px;}
.ledger-row .dot{width:8px;height:8px;border-radius:50%;flex:none;
  background:var(--ink-56);}
.dot[data-cat="cash"]{background:var(--cat-cash);}
.dot[data-cat="isa"]{background:var(--cat-isa);}
.dot[data-cat="taxable"]{background:var(--cat-taxable);}
.dot[data-cat="pension"]{background:var(--cat-pension);}
.dot[data-cat="property"]{background:var(--cat-property);}
.dot[data-cat="equity"]{background:var(--cat-equity);}

/* The gain and the tax on it hang off the row above, indented and quieter —
   they qualify a balance rather than being balances of their own. */
/* One step down from the row above, matching .cf-row.cf-leg — the other
   indented sub-line on this screen. These were two steps down, so two kinds of
   sub-row sat at two different sizes doing the same job. */
.gain-row .k{padding-left:16px;color:var(--ink-56);font-size:var(--fs-small);}
.gain-row .v{font-size:var(--fs-small);color:var(--ink-60);}
.gain-row .v.neg{color:var(--brick);}

/* ==========================================================================
   Aftertax — pass 3. Landing page: gradient discipline, ink buttons,
   the split bar promoted to its own band, one dark band.
   ========================================================================== */

/* 1. Gradient discipline — one use, or none. The wordmark square goes flat
      ink: a gradient read as decoration on a page whose whole argument is
      that the arithmetic is trustworthy. .grad-text is gone from the H1. */
.wordmark::before{background:#111;}

/* 2. Buttons — ink, not gradient. */
.btn{display:inline-block;background:#111;border:none;color:#fff;font-weight:700;
  font-size:var(--fs-lead);border-radius:var(--radius-pill);
  padding:13px 26px;cursor:pointer;text-decoration:none;
  transition:background .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease);}
.btn:hover{background:#000;transform:translateY(-2px);box-shadow:var(--shadow-lift);}
.btn:active{transform:translateY(0);box-shadow:none;}
.btn-ghost{background:#fff;border:1px solid var(--line);color:var(--ink-87);}
.btn-ghost:hover{background:#fff;border-color:var(--ink-87);transform:translateY(-2px);
  box-shadow:var(--shadow-lift);}

.hero-ctas{display:flex;gap:var(--space-3);align-items:center;
  margin:var(--space-6) 0 var(--space-2);flex-wrap:wrap;}
.hero-ctas .btn{display:inline-flex;flex-direction:column;align-items:center;
  line-height:1.25;}
.hero-ctas .btn em{font-style:normal;font-size:var(--fs-micro);font-weight:500;
  opacity:.62;margin-top:2px;}
.hero-ctas .btn-ghost em{opacity:1;color:var(--ink-56);}

/* 3. Hero shot — the split bar promoted to its own band. No aspect-ratio:
      the shot is markup now, not a fixed-ratio image slot. */
.lp-shot{position:relative;border-radius:var(--radius-card);overflow:hidden;
  background:var(--surface);border:1px solid var(--line-soft);
  box-shadow:var(--shadow-lift);}
.lp-shot img{display:block;width:100%;height:auto;}
.lp-shot .hero-summary{width:auto;border:0;border-radius:0;box-shadow:none;
  padding:var(--space-6) 36px var(--space-5);}

.hs-band{border-top:1px solid var(--line-soft);background:#FAFAFB;
  padding:22px 36px var(--space-5);}
.hs-band-head{display:flex;justify-content:space-between;align-items:baseline;
  margin-bottom:var(--space-3);}
.hs-band-head span:first-child{font-family:var(--mono);font-size:var(--fs-micro);
  font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-56);}
.hs-band-head span:last-child{font-size:12px;color:var(--ink-56);}

/* 30px, full width of the card, values inside the segments. This is the
   compounding argument; it should be the largest graphic on the page. */
.hs-bar{display:flex;height:30px;border-radius:var(--radius-pill);
  overflow:hidden;background:rgba(11,14,20,.05);}
.hs-bar i{display:flex;align-items:center;height:100%;padding-left:14px;
  font-family:var(--mono);font-size:12px;font-weight:700;color:#fff;
  font-style:normal;white-space:nowrap;overflow:hidden;}
/* Bar and key together. Scoping these to .hs-bar alone left the legend on the
   older pass-2 values, so every key named the wrong band: "what you have
   today" was drawn red and keyed grey, "what you add" drawn purple and keyed
   teal, "growth" drawn teal and keyed indigo. A legend that disagrees with its
   own chart is worse than no legend. */
.hs-bar .k-now,.hs-key .k-now{background:var(--cat-equity);}
.hs-bar .k-add,.hs-key .k-add{background:var(--cat-pension);}
.hs-bar .k-grow,.hs-key .k-grow{background:var(--cat-isa);}

.hs-key{display:flex;flex-wrap:wrap;gap:var(--space-2) 28px;margin-top:var(--space-3);}
.hs-key span{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink-60);}
.hs-key i{width:10px;height:10px;border-radius:3px;flex:none;}
.hs-key em{font-style:normal;font-family:var(--mono);color:var(--ink-56);}

/* column three keeps label, figure, note — the bar and key have left it */
.hs-end{padding-left:var(--space-6);border-left:1px solid var(--line);}
.hs-figure{font-family:var(--mono);font-size:var(--fs-display);font-weight:800;
  letter-spacing:-0.03em;color:var(--ink-87);line-height:1;
  display:flex;align-items:baseline;gap:var(--space-2);}
/* 4. the rounding, stated as a rounding */
.hs-approx{font-size:var(--fs-h2);font-weight:500;color:var(--ink-56);}

/* 5. Signup — the one dark band on the page. Breaks out of the 1240px
      column without touching the markup's place in .wrap. */
/* Scoped to .lp — the landing page. The tool renders its signup inside a
   narrower main column beside a 238px sidenav, where calc(50% - 50vw) is
   measured against that column and threw the band 126px past the right edge.
   The dark treatment is a landing-page device; the tool keeps its own. */
.lp .signup-panel{background:#0B0E14;color:#fff;text-align:left;
  padding:var(--space-8) 0 60px;margin-top:0;
  width:100vw;margin-left:calc(50% - 50vw);}
/* One column since the release-notes list beside the ask was dropped: the
   sign-up block is shared with the tool now, and says one thing. The inner
   box keeps the text on the page's measure inside the full-bleed band. */
.lp .signup-inner{max-width:1240px;margin:0 auto;padding:0 var(--space-5);}
.lp .signup-panel h2{font-size:var(--fs-h2);font-weight:800;letter-spacing:-0.02em;
  margin:0 0 var(--space-3);color:#fff;}
.lp .signup-panel p{font-size:var(--fs-lead);line-height:1.65;
  color:rgba(255,255,255,.62);margin:0 0 22px;max-width:52ch;}
.signup-form{display:flex;gap:10px;max-width:460px;margin:0;}
.signup-form input[type=email]{flex:1;background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.16);border-radius:var(--radius-pill);
  padding:13px 18px;font-family:inherit;font-size:var(--fs-lead);color:#fff;}
.signup-form input[type=email]::placeholder{color:rgba(255,255,255,.38);}
.signup-form input[type=email]:hover{border-color:rgba(255,255,255,.30);}
.signup-form input[type=email]:focus{outline:none;border-color:#fff;
  box-shadow:0 0 0 3px rgba(255,255,255,.14);}
.lp .signup-panel .btn{background:#fff;color:#0B0E14;white-space:nowrap;}
.lp .signup-panel .btn:hover{background:#fff;}
.signup-status{color:#fff;margin-top:var(--space-3);}

.lp .signup-panel .more{text-align:left;}
.lp .signup-panel .mf span{color:rgba(255,255,255,.62);}
.lp .signup-panel .mf input,.lp .signup-panel .mf select,.lp .signup-panel .mf textarea{
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.16);
  color:#fff;border-radius:var(--radius-input);}
.lp .signup-panel .more-note,.lp .signup-panel .more-status{color:rgba(255,255,255,.5);}
.lp .signup-panel .more-skip{color:rgba(255,255,255,.62);background:none;border:none;}

/* 6. Footer omissions — a list, not a wall. */
.nm-head{font-size:12.5px;color:var(--ink-56);margin:var(--space-4) 0 var(--space-2);}
.not-modelled{display:grid;grid-template-columns:repeat(3,1fr);
  gap:6px var(--space-6);max-width:940px;margin:0;}
.not-modelled span{font-size:12.5px;color:var(--ink-56);
  border-top:1px solid var(--line-soft);padding-top:6px;}

/* 7. Responsive */
@media (max-width:900px){
  .hero-summary{grid-template-columns:1fr;gap:var(--space-5);}
  .hs-end{padding-left:0;border-left:0;border-top:1px solid var(--line);
    padding-top:var(--space-4);}
  .not-modelled{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:560px){
  .lp-shot .hero-summary{padding:var(--space-5) 20px var(--space-4);}
  .hs-band{padding:18px 20px var(--space-4);}
  .hs-bar{height:26px;}
  .hs-bar i{font-size:11px;padding-left:10px;}
  .not-modelled{grid-template-columns:1fr;}
  .hero-ctas{flex-direction:column;align-items:stretch;}
  .hero-ctas .btn{width:100%;}
}
/* The optional second step sits outside the two-column grid so it can run
   full width, but .signup-panel has no horizontal padding of its own — it
   would otherwise touch both edges of the viewport. */
.lp .signup-panel .more{max-width:1240px;margin:var(--space-6) auto 0;
  padding:0 var(--space-5);}
/* The dark band is 100vw so it can escape the 1240px column. 100vw counts the
   scrollbar, so on any platform that reserves space for one (Windows, or macOS
   set to always show them) the band is ~15px wider than the content area and
   the page grows a horizontal scrollbar. This browser uses overlay scrollbars,
   so it doesn't show up locally — hence the guard rather than a fix I could
   see working. `clip` rather than `hidden`: it doesn't create a scroll
   container, so nothing sticky breaks. */
html{overflow-x:clip;}

/* ==========================================================================
   Aftertax — pass 4. The tool brought in line with the landing page.
   ========================================================================== */

/* 1. Token bug. --warn-deep was var(--warn-deep) — the same self-reference
      --brick had, so it resolved to nothing and the amber warning text in
      .warn, .bd-note.warnish and .alloc-total.is-off rendered in body ink.
      #A85C06 rather than --warn's #D97706: this is only ever text on a pale
      amber wash, where #D97706 misses 4.5:1. */
/* (the two token fixes are made at source, in the :root at the top) */

/* 2. The gradient, resolved. Pass 3 flattened the landing page and left the
      tool, so the two halves stopped matching. styles.css:100 says .wordmark
      and .sn-brand share a lockup "so the logo doesn't change shape depending
      which page you landed on" — flattening one and not the other broke the
      thing that comment was protecting. */
.wordmark::before,
.sn-brand::before{background:#111;}
/* #111 on the #0A0E14 sidebar is invisible; same mark, inverted */
.sidenav .sn-brand::before{background:#fff;}

.hh-figure,
.gap-stamp .gap-figure,
.wedge b,
.grad-text{
  background:none;
  -webkit-background-clip:border-box;
  background-clip:border-box;
  -webkit-text-fill-color:currentColor;
  color:var(--ink-87);
}
/* the one place a flat fill loses something real — give it the accent back
   deliberately, as a colour rather than as a gradient */
.gap-stamp .gap-figure{color:var(--accent-deep);}

/* One rule for colour, across both halves of the product:
     an ACTION you press          -> ink #111   (.btn everywhere, and this)
     a SELECTION / current state  -> --accent   (.seg-btn.active, .mode-btn.active, .p-tab.active)
     an emphasised figure or link -> --accent-deep

   Pass 4 made Save --accent on the grounds that it matched "every other
   primary control in the tool" — but those are selection states, not actions,
   and it left Save as the only button in the product that wasn't ink. */
.sc-btn.primary{background:#111;border:1px solid #111;color:#fff;}
.sc-btn.primary:hover{background:#000;border-color:#000;}
.roadmap-list li::before{background:var(--accent);}

/* 3. The categorical palette, into the tool. The swatches now carry data-cat
      instead of an inline hex, so a wrapper is one colour everywhere. */
.alloc-row .alloc-name i[data-cat],
.chart-legend .key[data-cat]{background:var(--cat-taxable);}
.alloc-row .alloc-name i[data-cat="cash"],
.chart-legend .key[data-cat="cash"]{background:var(--cat-cash);}
.alloc-row .alloc-name i[data-cat="isa"],
.chart-legend .key[data-cat="isa"]{background:var(--cat-isa);}
.alloc-row .alloc-name i[data-cat="taxable"],
.chart-legend .key[data-cat="taxable"]{background:var(--cat-taxable);}
.alloc-row .alloc-name i[data-cat="pension"],
.chart-legend .key[data-cat="pension"]{background:var(--cat-pension);}
.alloc-row .alloc-name i[data-cat="property"],
.chart-legend .key[data-cat="property"]{background:var(--cat-property);}
.alloc-row .alloc-name i[data-cat="equity"],
.chart-legend .key[data-cat="equity"]{background:var(--cat-equity);}
.chart-legend .key[data-cat="accent"]{background:var(--accent);}

.ledger-row .dot{width:9px;height:9px;border-radius:3px;display:inline-block;
  margin-right:var(--space-2);vertical-align:middle;flex:none;}
.ledger-row .dot[data-cat="cash"]{background:var(--cat-cash);}
.ledger-row .dot[data-cat="isa"]{background:var(--cat-isa);}
.ledger-row .dot[data-cat="taxable"]{background:var(--cat-taxable);}
.ledger-row .dot[data-cat="pension"]{background:var(--cat-pension);}
.ledger-row .dot[data-cat="property"]{background:var(--cat-property);}
.ledger-row .dot[data-cat="equity"]{background:var(--cat-equity);}

/* 4. The bridge table, onto the pass-1 pattern. .bridge-table th was sticky
      at 428 and cancelled by position:static at 822, so the header scrolled
      away on the densest table in the app. Horizontal scroll stays — this
      table reconciles across its columns and squeezing it would break that. */
.bridge-card .table-scroll,
.bridge-card .bridge-scroll{
  overflow:auto;max-height:420px;
  border:1px solid var(--line-soft);border-radius:var(--radius-input);
  background:
    linear-gradient(to right, var(--surface) 30%, rgba(246,247,249,0)),
    linear-gradient(to right, rgba(11,14,20,.10), rgba(11,14,20,0) 12px) 100% 0,
    linear-gradient(to left,  var(--surface) 30%, rgba(246,247,249,0)) 100% 0,
    linear-gradient(to left,  rgba(11,14,20,.10), rgba(11,14,20,0) 12px);
  background-repeat:no-repeat;
  background-size:44px 100%, 14px 100%, 44px 100%, 14px 100%;
  background-attachment:local, scroll, local, scroll;
}
.bridge-card .bridge-table th{
  position:sticky;top:0;z-index:2;background:var(--surface);
  border-bottom:1px solid var(--line);
}
/* the renderer already emits class="c-age" on body cells, so the .age
   selector the spec offered would match nothing — left out */
.bridge-card .bridge-table th.c-age,
.bridge-card .bridge-table td.c-age{
  position:sticky;left:0;z-index:1;background:var(--surface);
  text-align:left;font-weight:700;color:var(--ink-87);
  border-right:1px solid var(--line);
}
.bridge-card .bridge-table th.c-age{z-index:3;}
.bridge-card .bridge-table td.close{font-weight:700;color:var(--ink-87);}
.bridge-card .bridge-table td.pos{color:var(--green-ok);}
.bridge-card .bridge-table td.neg{color:var(--brick);}

/* one sticky stack, explicitly ordered, so the KPI strip always wins:
   kpi-strip 20 > bridge corner 3 > bridge header 2 > bridge first col 1 */
.kpi-strip,.qe-strip{z-index:20;}
.bgt-table th.c-lab{z-index:3;}
.bgt-table thead th{z-index:2;}
.bgt-table td.c-lab{z-index:1;}

/* 5. Button radii — one scale. Seven were in play across controls doing the
      same job. Two rules, by what a control IS: press it, it's a pill; type
      into it, it's --radius-input. The seg controls keep their own, being a
      track with buttons inside rather than a button. */
.btn,.btn-ghost,.btn-ghost-sm,.sc-btn,.qa-btn,.qa-chip,
.p-tab,.alloc-add,.add-source,.at-fix,.mode-btn{
  border-radius:var(--radius-pill);
}
.num-input,.bg-yrs,#scenarioSelect,.fd-select,
.event-card select.ev-ccare,.event-head .ev-name{
  border-radius:var(--radius-input);
}
.seg{border-radius:12px;}
.seg-btn{border-radius:9px;}
.btn-ghost{background:#fff;border:1px solid var(--line);color:var(--ink-87);}

/* 6. Card padding — one scale. Seven paddings on identical chrome, none on
      the 4px ramp. Three sizes, chosen by density rather than by card. */
.panel,.facts-card{padding:var(--space-6);}
.ledger-card,.bridge-card,.why-panel{padding:var(--space-5) var(--space-6);}
.hh-strip{padding:var(--space-5) var(--space-6);}
.scenario-bar,.topbar .scenario-bar{padding:var(--space-3) var(--space-4);}
.kpi-strip,.qe-strip{padding:var(--space-3) var(--space-4);}
.gap-stamp{padding:var(--space-7) var(--space-6) var(--space-6);}
.ledger-card,.bridge-card,.facts-card,.gap-stamp{margin-top:var(--space-5);}
.results-col{gap:var(--space-5);}
.results-col>div{gap:var(--space-5);}

/* 7. One page header for all six tabs. Quick Estimate had its own component
      for the one job, on the screen a first-time visitor lands on. */
.tab-panel[data-panel="quick"]>.eyebrow{
  font-size:var(--fs-micro);font-weight:700;color:var(--accent);
  letter-spacing:-0.005em;margin:0 0 var(--space-2);
}
.tab-panel[data-panel="quick"]>.panel-h{
  font-weight:900;font-size:var(--fs-h2);letter-spacing:-0.01em;
  color:var(--ink-87);margin:0 0 6px;
}
/* .section-divider's 72px top margin and rule are right between sections of
   one page, wrong as the first thing in a panel — every tab was opening with
   a horizontal rule above its own title. */
.tab-panel>.section-divider:first-child{
  margin-top:0;padding-top:0;border-top:none;
}

/* Insights, per the design pass: the card gets a header and footer band in the
   landing page's vocabulary, and each row a mono figure rail beside the prose.
   The rail says what the number IS before the sentence explains it. */
.insight-block{background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--radius-card);box-shadow:var(--shadow-card);
  margin-top:var(--space-5);overflow:hidden;}
.insight-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--space-3);padding:14px var(--space-6);background:var(--surface-sunk);
  border-bottom:1px solid var(--line-soft);}
.insight-head span:first-child{font-family:var(--mono);font-size:var(--fs-micro);
  font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-56);}
.insight-count{font-family:var(--mono);font-size:var(--fs-micro);color:var(--ink-56);}
.insight-list{padding:0 var(--space-6);}

/* group headers: a label, a rule, and why this block is where it is */
.ins-sec{display:flex;align-items:center;gap:var(--space-4);padding:26px 0 4px;}
.ins-sec-lab{font-family:var(--mono);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-56);white-space:nowrap;}
.ins-sec.is-lead .ins-sec-lab{color:var(--accent-deep);}
.ins-sec-rule{flex:1;height:1px;background:var(--line-soft);}
.ins-sec-hint{font-family:var(--mono);font-size:var(--fs-micro);color:var(--ink-56);
  white-space:nowrap;}

.ins-rail{display:flex;flex-direction:column;gap:2px;padding-left:0;border-left:none;}
.insight{display:grid;grid-template-columns:150px 1fr;gap:36px;padding:22px 0;
  border-bottom:1px dotted var(--line);}
.insight:last-child{border-bottom:none;}

.ins-n{display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:50%;box-sizing:border-box;
  border:1px solid var(--line);color:var(--ink-56);
  font-family:var(--mono);font-size:11px;font-weight:500;margin-bottom:10px;}
.insight[data-lead] .ins-n{background:var(--accent);border-color:var(--accent);color:#fff;}
.ins-fig{font-family:var(--mono);font-size:var(--fs-figure);font-weight:500;
  letter-spacing:-0.01em;color:var(--ink-87);}
.insight[data-lead] .ins-fig{color:var(--accent);}

.insight[data-lead]{background:var(--surface);
  border:1px solid rgba(146,2,2,.16);border-radius:14px;
  padding:26px 28px;margin:10px 0 14px;
  box-shadow:0 1px 2px rgba(11,14,20,.03),0 10px 30px -12px rgba(146,2,2,.18);}
.insight[data-lead]+.insight{border-top:none;}
.insight[data-lead] .ins-body b{font-size:19px;letter-spacing:-0.02em;}
/* Was a CSS `content:` reading "worth acting on" — a fixed string, and an
   instruction. It is markup now, and the words come from the insight's group,
   so a deadline card says it expires and a projection card says where it came
   from. See INSIGHT_GROUPS.mark. */
.insight[data-lead] .ins-lead-mark{display:block;
  font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:var(--accent);
  margin-bottom:12px;}
.ins-note{font-size:var(--fs-micro);line-height:1.45;color:var(--ink-56);}
.ins-body{display:grid;gap:6px;min-width:0;}
.ins-body b{font-size:var(--fs-body);font-weight:700;color:var(--ink-87);
  letter-spacing:-0.01em;}
.ins-body p{margin:0;font-size:var(--fs-small);line-height:1.65;color:var(--ink-60);
  max-width:70ch;}

.insight-empty{margin:0;padding:var(--space-5) var(--space-6);font-size:var(--fs-small);
  line-height:1.6;color:var(--ink-56);}
.insight-foot{margin:0;padding:16px var(--space-6);background:var(--surface-sunk);
  border-top:1px solid var(--line-soft);font-size:var(--fs-micro);line-height:1.55;
  color:var(--ink-56);}

/* the rail stacks under the prose on a phone rather than squeezing both */
@media (max-width:640px){
  .insight{grid-template-columns:1fr;gap:var(--space-3);}
  .ins-sec{flex-wrap:wrap;gap:var(--space-2);}
  .ins-sec-rule{display:none;}
}
.insight-empty{margin:0;font-size:var(--fs-small);line-height:1.6;color:var(--ink-56);}

/* The block leads the projection screen, so it sits above the heading's usual
   gap rather than below a chart. */
.insight-block{margin-bottom:var(--space-5);}

/* Everything past the top three. A <details>, so it keeps native disclosure —
   no display:grid on the element itself, which breaks the animation and the
   open state both. Padding goes on the <summary>, not the row, or the tap
   target ends up 23px tall. */
.insight-rest{border-top:1px dotted var(--line);}
.insight-rest > summary{list-style:none;cursor:pointer;padding:14px var(--space-6);
  display:flex;align-items:center;gap:8px;font-family:var(--sans);
  font-size:var(--fs-small);font-weight:600;color:var(--accent-deep);}
.insight-rest > summary::-webkit-details-marker{display:none;}
.insight-rest > summary::after{content:'▾';font-size:.85em;color:var(--ink-56);}
.insight-rest[open] > summary::after{content:'▴';}
.insight-rest > summary:hover{background:var(--surface-sunk);}
.insight-rest .ir-shut,.insight-rest[open] .ir-open{display:none;}
.insight-rest[open] .ir-shut{display:inline;}
.insight-rest .insight-list{padding-bottom:var(--space-4);}

/* The row an inline pointer scrolls to, marked briefly so the eye lands on it. */
.insight.is-flash{animation:insFlash 1.4s ease-out;}
@keyframes insFlash{
  0%,55%{background:color-mix(in oklch, var(--accent) 9%, transparent);}
  100%{background:transparent;}
}

/* Inline slots: the same observation, one line, beside the input that produced
   it. Deliberately not the card — a second full card on an input page would
   compete with the fields instead of annotating them. */
.ins-inline{margin-top:var(--space-5);border-top:1px solid var(--line-soft);
  padding-top:var(--space-3);}
.ii-head{font-family:var(--mono);font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.05em;text-transform:uppercase;color:var(--ink-56);
  margin-bottom:6px;}
.ii-row{display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:var(--space-4);width:100%;text-align:left;background:none;cursor:pointer;
  border:none;border-left:2px solid var(--line);padding:10px var(--space-3);
  border-radius:0 var(--radius-input) var(--radius-input) 0;}
.ii-row[data-lead]{border-left-color:var(--accent);}
.ii-row:hover{background:var(--surface-sunk);}
.ii-fig{font-family:var(--mono);font-size:var(--fs-small);font-weight:500;
  color:var(--ink-87);white-space:nowrap;}
.ii-row[data-lead] .ii-fig{color:var(--accent-deep);}
.ii-txt{display:grid;gap:1px;min-width:0;}
.ii-txt > b{font-size:var(--fs-small);font-weight:600;color:var(--ink-87);
  letter-spacing:-0.005em;}
.ii-note{font-size:var(--fs-micro);color:var(--ink-56);}
.ii-go{color:var(--ink-56);font-size:var(--fs-small);}
.ii-row:hover .ii-go{color:var(--accent-deep);}
@media (max-width:640px){
  .ii-row{grid-template-columns:1fr auto;}
  .ii-fig{grid-column:1/-1;}
}
