:root{
  --bg:#F2F2F7; --surface:#FFFFFF; --field:#F2F2F7;
  --ink:#1C1C1E; --ink-soft:#6E6E73; --ink-faint:#AEAEB2;
  --line: rgba(60,60,67,.13); --line-strong: rgba(60,60,67,.22);
  --green:#1B8F44; --green-fill:#34C759; --green-wash: rgba(52,199,89,.12);
  --red:#D6402F; --red-fill:#FF3B30; --red-wash: rgba(255,59,48,.10);
  /* --red lands at ~4.1:1 on --field, which fails AA for small text.
     This is the same hue pushed to 4.5:1+ for figures set on a field chip. */
  --red-strong:#BE2F1E;
  /* --green is 4.15:1 on white, which fails AA for small text. Same hue,
     pushed past 4.5:1, for green set at label sizes. */
  --green-strong:#157A3A;
  --gold:#AD7415;
  --shadow-card: 0 1px 1px rgba(0,0,0,.03), 0 8px 24px rgba(0,0,0,.06), 0 1px 0 rgba(0,0,0,.02);
  --shadow-pop: 0 1px 3px rgba(0,0,0,.12), 0 6px 16px rgba(0,0,0,.10);
  --spring: cubic-bezier(.32,.72,0,1);
  --sf: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", ui-sans-serif, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* deep, theme-invariant tones — guarantee 4.5:1 for the white bar labels regardless of theme */
  --bar-green:#1E7E3B; --bar-red:#B23B28;
}
@media (prefers-color-scheme: dark){
  :root{
    --bg:#000000; --surface:#1C1C1E; --field:#2C2C2E;
    --ink:#F2F2F2; --ink-soft:#98989D; --ink-faint:#636366;
    --line: rgba(255,255,255,.12); --line-strong: rgba(255,255,255,.20);
    --green:#30D158; --green-fill:#30D158; --green-wash: rgba(48,209,88,.16);
    --red:#FF453A; --red-fill:#FF453A; --red-wash: rgba(255,69,58,.14);
    --red-strong:#FF7268;
    --green-strong:#30D158;
    --gold:#E8B85C;
    --shadow-card: 0 0 0 1px rgba(255,255,255,.06), 0 8px 24px rgba(0,0,0,.5);
    --shadow-pop: 0 6px 20px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"]{
  --bg:#000000; --surface:#1C1C1E; --field:#2C2C2E;
  --ink:#F2F2F2; --ink-soft:#98989D; --ink-faint:#636366;
  --line: rgba(255,255,255,.12); --line-strong: rgba(255,255,255,.20);
  --green:#30D158; --green-fill:#30D158; --green-wash: rgba(48,209,88,.16);
  --red:#FF453A; --red-fill:#FF453A; --red-wash: rgba(255,69,58,.14);
  --red-strong:#FF7268;
  --green-strong:#30D158;
  --gold:#E8B85C;
  --shadow-card: 0 0 0 1px rgba(255,255,255,.06), 0 8px 24px rgba(0,0,0,.5);
  --shadow-pop: 0 6px 20px rgba(0,0,0,.55);
}
:root[data-theme="light"]{
  --bg:#F2F2F7; --surface:#FFFFFF; --field:#F2F2F7;
  --ink:#1C1C1E; --ink-soft:#6E6E73; --ink-faint:#AEAEB2;
  --line: rgba(60,60,67,.13); --line-strong: rgba(60,60,67,.22);
  --green:#1B8F44; --green-fill:#34C759; --green-wash: rgba(52,199,89,.12);
  --red:#D6402F; --red-fill:#FF3B30; --red-wash: rgba(255,59,48,.10);
  --red-strong:#BE2F1E;
  --green-strong:#157A3A;
  --gold:#AD7415;
  --shadow-card: 0 1px 1px rgba(0,0,0,.03), 0 8px 24px rgba(0,0,0,.06), 0 1px 0 rgba(0,0,0,.02);
  --shadow-pop: 0 1px 3px rgba(0,0,0,.12), 0 6px 16px rgba(0,0,0,.10);
}

*{box-sizing:border-box}
html{scrollbar-gutter:stable}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--sf); font-size:15px; line-height:1.47;
  -webkit-font-smoothing:antialiased;
}
.wrap{max-width:1180px;margin:0 auto;padding:28px 22px 90px}

header{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin:22px 0 24px;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:11px}
.glyph{
  width:44px;height:44px;border-radius:12px;flex:0 0 auto;
  background:linear-gradient(160deg,#3DDB6C,#1B8F44);
  display:grid;place-items:center;box-shadow:var(--shadow-pop);
}
.glyph svg{width:24px;height:24px}
h1.mark{margin:0;font-size:26px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.kicker{margin:1px 0 0;font-size:12.5px;font-weight:590;color:var(--ink-soft);letter-spacing:.01em}
header .today{font-size:12.5px;color:var(--ink-faint);font-variant-numeric:tabular-nums}

.studio{display:grid;grid-template-columns:344px 1fr;gap:20px;align-items:start}
/* grid/flex children default to min-width:auto, which lets a nowrap chip
   inside a card widen the whole page. Floor them at 0 so columns truly track
   the viewport. */
.studio > *{min-width:0}
@media (max-width:940px){ .studio{grid-template-columns:1fr} }
.sidebar{display:flex;flex-direction:column;gap:16px;position:sticky;top:20px}
@media (max-width:940px){ .sidebar{position:static} }

.card{ background:var(--surface);border-radius:20px;box-shadow:var(--shadow-card);border:.5px solid var(--line) }
.panel-pad{padding:18px}
h2.sect-title{
  font-size:12.5px;font-weight:590;letter-spacing:.01em;text-transform:uppercase;
  color:var(--ink-soft);margin:2px 4px 12px;display:flex;align-items:center;gap:8px;
}

label.fld,.fld{display:block;padding:12px 4px}
.fld + .fld, .fld + label.fld, label.fld + .fld { border-top:.5px solid var(--line) }
.fld-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:7px}
.fld-name{font-size:14.5px;font-weight:400;color:var(--ink)}
.fld-hint{font-size:12.5px;color:var(--ink-faint);font-variant-numeric:tabular-nums}

.input-money{position:relative}
.input-money .pre{position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--ink-faint);font-size:15px}
input[type=text],input[type=number]{
  width:100%;padding:11px 14px 11px 26px;border:none;border-radius:12px;
  background:var(--field);color:var(--ink);font-family:var(--sf);font-size:16px;font-weight:590;
  font-variant-numeric:tabular-nums;outline:none;transition:box-shadow .18s var(--spring);
}
.input-plain input{padding-left:14px}
input:focus{box-shadow:0 0 0 3.5px var(--green-wash), 0 0 0 1px var(--green) inset}

.chips{display:flex;gap:7px;margin-top:9px}
.chips button{
  flex:1;border:none;background:var(--field);border-radius:100px;padding:7px 0;cursor:pointer;
  font-family:var(--sf);font-size:13px;font-weight:590;color:var(--ink-soft);
  transition:background .18s var(--spring), color .18s var(--spring), transform .12s var(--spring);
}
.chips button:hover{background:var(--line-strong)}
.chips button:active{transform:scale(.96)}
.chips button.on{background:var(--green);color:#fff}

.seg{display:flex;background:var(--field);border-radius:11px;padding:2px;gap:2px;position:relative}
.seg button{
  flex:1;border:0;background:transparent;padding:8px 4px;border-radius:9px;cursor:pointer;
  font-family:var(--sf);font-size:13.5px;font-weight:590;color:var(--ink-soft);
  transition:color .18s var(--spring), background .18s var(--spring), box-shadow .18s var(--spring);position:relative;z-index:1;
}
.seg button.on{color:var(--ink);background:var(--surface);box-shadow:var(--shadow-pop)}

.toggle{width:51px;height:31px;border-radius:31px;background:var(--line-strong);position:relative;flex:0 0 auto;cursor:pointer;transition:background .24s var(--spring)}
.toggle::after{content:"";position:absolute;top:2px;left:2px;width:27px;height:27px;border-radius:50%;background:#fff;box-shadow:0 3px 8px rgba(0,0,0,.18), 0 1px 1px rgba(0,0,0,.1);transition:transform .24s var(--spring)}
.scn.on > .scn-head .toggle, .toggle.on{background:var(--green-fill)}
.scn.on > .scn-head .toggle::after, .toggle.on::after{transform:translateX(20px)}

.scn{border-radius:16px;overflow:hidden;transition:box-shadow .2s var(--spring)}
.scn.on{box-shadow:0 0 0 1.5px var(--green-wash) inset}
.scn-head{display:flex;align-items:center;gap:12px;padding:13px 4px;cursor:pointer;user-select:none}
.scn + .scn{border-top:.5px solid var(--line)}
.scn-ico{width:32px;height:32px;flex:0 0 auto;border-radius:9px;display:grid;place-items:center;background:var(--field);color:var(--ink-soft);font-size:15px}
.scn.on > .scn-head .scn-ico{background:var(--green-wash);color:var(--green)}
.scn-tt{flex:1;min-width:0}
.scn-tt h3{margin:0;font-size:14.5px;font-weight:500;color:var(--ink)}
.scn-tt span{font-size:12.5px;color:var(--ink-faint)}
.scn-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s var(--spring)}
/* Direct-child scoping, not descendant: the budget card nests a second .scn
   inside its body, and a descendant selector would force the child open
   whenever the parent opened. */
.scn.on > .scn-body{grid-template-rows:1fr}
.scn-body-inner{overflow:hidden;min-height:0;padding:0 4px}
.scn.on > .scn-body > .scn-body-inner{padding:2px 4px 14px}
.mini-note{font-size:12.5px;color:var(--ink-faint);margin:8px 4px 0;line-height:1.5}

.lump-item + .lump-item{margin-top:14px;padding-top:14px;border-top:.5px dashed var(--line-strong)}
.lump-rm{border:0;background:transparent;color:var(--ink-faint);cursor:pointer;font-size:12px;font-family:var(--sf);text-decoration:underline;padding:0}
.lump-rm:hover{color:var(--red)}
.add-item{margin-top:12px;width:100%;border:1.5px dashed var(--line-strong);background:transparent;color:var(--ink-soft);border-radius:12px;padding:9px;cursor:pointer;font-family:var(--sf);font-size:13px;font-weight:590;transition:.18s var(--spring)}
.add-item:hover{border-color:var(--green);color:var(--green)}

/* The visual track is thin, but the ELEMENT is the hit area — at 4px tall it
   was a 4px tap target. Give the input real height and move the track to the
   pseudo-element so it still looks thin. */
input[type=range]{
  -webkit-appearance:none;appearance:none;width:100%;height:26px;
  background:transparent;margin:6px 0 0;cursor:pointer;
}
input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:4px;background:var(--line-strong)}
input[type=range]::-moz-range-track{height:4px;border-radius:4px;background:var(--line-strong)}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:24px;height:24px;border-radius:50%;background:#fff;box-shadow:0 3px 8px rgba(0,0,0,.2), 0 0 0 .5px rgba(0,0,0,.04);cursor:pointer;margin-top:-10px}
input[type=range]::-moz-range-thumb{width:24px;height:24px;border-radius:50%;background:#fff;border:none;box-shadow:0 3px 8px rgba(0,0,0,.2);cursor:pointer}
@media (pointer:coarse){
  input[type=range]{height:32px}
  input[type=range]::-webkit-slider-runnable-track,
  input[type=range]::-moz-range-track{height:6px}
  input[type=range]::-webkit-slider-thumb{width:30px;height:30px;margin-top:-12px}
  input[type=range]::-moz-range-thumb{width:28px;height:28px}
}

.main{display:flex;flex-direction:column;gap:20px}
.hero-stats{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:14px;min-height:118px}
@media (max-width:640px){ .hero-stats{grid-template-columns:1fr 1fr} }
.stat{padding:18px}
.stat .lab{font-size:12.5px;font-weight:590;color:var(--ink-soft);margin-bottom:9px}
.stat .big{font-size:30px;font-weight:700;letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.08}
.stat.freedom .big{font-size:30px;color:var(--green)}
@media (max-width:640px){ .stat.freedom{grid-column:span 2} }
.stat .big.sm{font-size:26px}
.stat .sub{font-size:12.5px;color:var(--ink-soft);margin-top:8px;min-height:34px;line-height:1.4}
.stat.freedom .sub{min-height:38px}
.stat .sub b{color:var(--ink);font-weight:590}
.stat.saved .big{color:var(--ink)}
.save-green{color:var(--green)}

.runway{padding:22px 22px 18px;position:relative;overflow:hidden}
.runway::before{
  content:"";position:absolute;inset:0;z-index:0;opacity:.6;pointer-events:none;
  background:radial-gradient(520px 260px at 8% -10%, var(--green-wash), transparent 60%);
}
.runway > *{position:relative;z-index:1}
.runway-head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:12px;margin-bottom:6px}
.runway-head h2{margin:0;font-size:19px;font-weight:650;letter-spacing:-.01em;color:var(--ink)}
.runway-head p{margin:4px 0 0;font-size:13px;color:var(--ink-soft);max-width:420px}
.legend{display:flex;gap:16px;flex-wrap:wrap}
.lg{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink-soft);font-weight:500}
.lg[hidden]{display:none}   /* display:flex would otherwise beat the attribute */
.lg i{width:16px;height:3px;border-radius:2px;display:inline-block;background:var(--green-fill)}
/* mirrors the chart's "1 6" dasharray — a CSS dashed border is too coarse at this width */
.lg.dash i{height:2px;border-radius:0;background:repeating-linear-gradient(to right,var(--ink-faint) 0 2px,transparent 2px 5px)}
.lg.sq i{width:10px;height:10px;border-radius:3px}
.lg.sq.int i{background:var(--red-fill)}
.lg.sq.prin i{background:var(--green-fill)}

/* ---------- runway chart + drag grip ---------- */
.chart-shell{position:relative;min-height:256px}
/* Touch keeps page-scroll over the chart; the grip is the only touch-drag
   surface. Precise pointers get the whole plot. */
#runwaySvg{touch-action:pan-y}
@media (pointer:fine){ #runwaySvg{cursor:crosshair} }
#runwaySvg.dragging{cursor:grabbing}
html.rw-dragging, html.rw-dragging body{user-select:none;-webkit-user-select:none}

.rw-grip{position:absolute;left:0;top:0;transform:translate(-50%,-50%);z-index:2;line-height:0}
.rw-grip[hidden]{display:none}
.rw-knob{
  display:block;position:relative;width:26px;height:26px;padding:0;border-radius:50%;
  background:var(--surface);border:3px solid var(--green-fill);
  box-shadow:var(--shadow-pop);cursor:grab;touch-action:none;
  transition:transform .18s var(--spring), box-shadow .18s var(--spring);
}
/* 48px hit circle, sized explicitly — `inset` would resolve against the
   knob's padding box and land short of the 44px floor */
.rw-knob::after{
  content:"";position:absolute;left:50%;top:50%;width:48px;height:48px;
  transform:translate(-50%,-50%);border-radius:50%;
}
/* the global focus ring squares off corners — keep the knob round */
.rw-knob:focus-visible{border-radius:50%;outline-offset:4px}
.rw-knob:hover{transform:scale(1.12)}
.rw-knob:active,.rw-grip.live .rw-knob{cursor:grabbing;transform:scale(1.18)}
.rw-bubble{
  position:absolute;bottom:calc(100% + 10px);left:50%;transform:translate(-50%,4px);
  background:var(--ink);color:var(--surface);border-radius:8px;padding:4px 9px;
  font-size:12px;font-weight:590;line-height:1.35;white-space:nowrap;
  font-variant-numeric:tabular-nums;pointer-events:none;
  opacity:0;transition:opacity .16s var(--spring), transform .16s var(--spring);
}
.rw-grip.live .rw-bubble,.rw-grip:hover .rw-bubble{opacity:1;transform:translate(-50%,0)}

/* One-time nudge that the dot is grabbable; stops for good after first use */
@keyframes rwPulse{ 0%{transform:scale(1);opacity:.55} 70%,100%{transform:scale(2.1);opacity:0} }
.rw-grip::before{
  content:"";position:absolute;left:50%;top:50%;width:26px;height:26px;margin:-13px 0 0 -13px;
  border-radius:50%;background:var(--green-fill);pointer-events:none;
  animation:rwPulse 2.4s var(--spring) .8s 3 both;
}
.rw-grip.live::before,.rw-grip.used::before{animation:none;opacity:0}

.chart-hint{
  margin:10px 2px 0;font-size:12.5px;line-height:1.45;color:var(--ink-faint);
  display:flex;gap:7px;align-items:baseline;
}
.chart-hint b{color:var(--ink-soft);font-weight:590}
.chart-hint .spark{color:var(--green);flex:0 0 auto}
.chart-hint.used{opacity:.55}
.compare{margin-top:14px;border-top:.5px solid var(--line);padding-top:13px;display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.compare-lab{font-size:11.5px;font-weight:590;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);margin-right:2px}
.cmp-chip{display:flex;align-items:center;gap:8px;background:var(--field);border-radius:100px;padding:4px 4px 4px 11px;font-size:12px;color:var(--ink);max-width:100%;min-width:0}
.cmp-chip .dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
.cmp-chip .cmp-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cmp-chip .meta{font-size:11px;color:var(--ink-faint);font-variant-numeric:tabular-nums;flex:0 0 auto;white-space:nowrap}
/* total interest: weight as well as colour, so it doesn't read by hue alone */
.cmp-chip .cmp-int{color:var(--red-strong);font-weight:650}
.cmp-chip button{
  border:0;background:transparent;color:var(--ink-faint);cursor:pointer;font-size:16px;line-height:1;
  flex:0 0 auto;width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  transition:background .15s var(--spring), color .15s var(--spring);
}
.cmp-chip button:hover{color:var(--red);background:var(--red-wash)}
.cmp-save{display:flex;align-items:center;gap:6px;border:none;background:var(--green-wash);color:var(--green);border-radius:100px;padding:7px 14px;cursor:pointer;font-size:12.5px;font-weight:590;font-family:var(--sf);transition:.18s var(--spring)}
.cmp-save:hover{background:var(--green);color:#fff}
.cmp-empty{font-size:12px;color:var(--ink-faint)}

.chart-card{padding:20px 22px}
.chart-card .chead{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;margin-bottom:2px}
.chart-card h2{margin:0;font-size:17px;font-weight:650;letter-spacing:-.01em;color:var(--ink)}
.chart-card .csub{margin:4px 0 0;font-size:13px;color:var(--ink-soft);max-width:480px}
.insight{margin-top:12px;padding:12px 14px;border-radius:14px;background:var(--field);font-size:13px;color:var(--ink-soft);display:flex;gap:10px;align-items:flex-start}
.insight b{color:var(--ink);font-weight:590}
.insight .spark{color:var(--gold);flex:0 0 auto;font-size:14px;line-height:1.3}

svg{display:block;width:100%;height:auto}
.ax{font-family:var(--sf);font-size:11px;font-variant-numeric:tabular-nums}
/* knocks the card colour out from behind in-chart callouts so a gridline or
   the bank curve never runs through the type */
.chart-lab{
  font-family:var(--sf);font-weight:600;font-variant-numeric:tabular-nums;
  paint-order:stroke;stroke:var(--surface);stroke-width:3.5px;stroke-linejoin:round;
}

#splitSvg{min-height:190px}
#lifeBars{min-height:120px}

.life-row{display:flex;align-items:center;gap:14px;margin-top:14px}
.life-row:first-child{margin-top:0}
.life-lab{width:130px;flex:0 0 auto;font-size:12.5px;color:var(--ink-soft)}
.life-lab b{display:block;color:var(--ink);font-weight:590;font-size:13px}
.bar-track{flex:1;height:32px;background:var(--field);border-radius:16px;overflow:hidden;position:relative}
.bar-fill{height:100%;display:flex;align-items:center;justify-content:flex-end;padding-right:12px;color:#fff;font-size:12.5px;font-weight:590;font-variant-numeric:tabular-nums;min-width:56px;transition:width .5s var(--spring)}
.bar-int{background:var(--bar-red)}
.bar-prin{background:var(--bar-green)}

/* ---------- affordability ---------- */
/* The budget card has an extra border the loan card doesn't: the .scn state
   ring. Content sat 4px inside it with the field separators running flush,
   which reads as cramped. Pull the card's own padding in and let the ring's
   interior carry the inset, so the content still lands on the loan card's
   rail (card edge -> input) while gaining real space inside the ring. */
/* Budget rail = card padding + the 10px flush inset, and it has to equal the
   loan card's rail (.panel-pad + .fld's 4px). panel-pad is 18px here and 14px
   on narrow screens, so this padding tracks it: 12+10 = 22, 8+10 = 18.
   .card.budget-card, not .budget-card, so the narrow .panel-pad override
   later in the file can't win on source order. */
.card.budget-card{padding:12px}
.card.budget-card > h2.sect-title{margin:10px 10px 10px}

/* The horizontal inset is applied exactly once, by the outermost flush body.
   Nested scns, their fields and their headers all contribute zero, so the
   costs section lines up with the fields above it instead of stepping in. */
.scn-body-inner.flush,
.scn.on > .scn-body > .scn-body-inner.flush{padding-left:10px;padding-right:10px}
.scn-body-inner.flush .scn-body-inner.flush,
.scn.on > .scn-body > .scn-body-inner.flush .scn-body-inner.flush{padding-left:0;padding-right:0}
.scn-body-inner.flush .fld{padding-left:0;padding-right:0}
.scn-body-inner.flush .scn-head{padding-left:0;padding-right:0}
#budgetScn > .scn-head{padding-left:10px;padding-right:10px}
.scn-body-inner.flush > .fld:first-child{padding-top:4px}
.scn-body-inner.flush > .scn{margin-top:8px}
/* a disclosure is not an active scenario: no green state ring */
.scn.plain{box-shadow:none}
.scn-caret{color:var(--ink-faint);font-size:19px;line-height:1;flex:0 0 auto;transition:transform .24s var(--spring)}
.scn.on > .scn-head .scn-caret{transform:rotate(90deg)}
.input-money .suf{
  position:absolute;right:13px;top:50%;transform:translateY(-50%);
  color:var(--ink-faint);font-size:12.5px;pointer-events:none;
}
.input-money:has(.suf) input{padding-right:56px}

/* A rate that isn't currently being charged. The value stays editable and
   remembered — it applies again the moment the down payment drops — but a
   bold "0.6" with only small grey text beside it reads as a live charge. */
.fld.inactive .fld-name{color:var(--ink-soft)}
.fld.inactive .input-money input{color:var(--ink-soft);background:transparent;box-shadow:inset 0 0 0 1px var(--line-strong)}
.fld.inactive .input-money .suf,
.fld.inactive .input-money .pre{color:var(--ink-faint);opacity:.7}
.fld.inactive .fld-hint{color:var(--green-strong);font-weight:590}
.fld.inactive .input-money input:focus{color:var(--ink);background:var(--field);box-shadow:0 0 0 3.5px var(--green-wash), 0 0 0 1px var(--green) inset}

.afd-row{display:flex;align-items:center;gap:14px;margin-top:18px}
.afd-row + .afd-row{margin-top:28px}   /* headroom for the tick label above the track */
.afd-lab{width:150px;flex:0 0 auto;font-size:12.5px;color:var(--ink-soft)}
.afd-lab b{display:block;color:var(--ink);font-weight:590;font-size:13px;font-variant-numeric:tabular-nums}
.afd-track{position:relative;overflow:visible;border-radius:16px}
.afd-fill{background:var(--bar-green);border-radius:16px 0 0 16px;min-width:4px;transition:width .4s var(--spring)}
.afd-fill.over{background:var(--bar-red)}
/* income tax is reported, not judged: no threshold, so no pass/fail colour */
.afd-fill.neutral{background:var(--ink-soft)}
.afd-sublab{display:block;font-size:11.5px;color:var(--ink-soft);margin-top:2px;font-weight:400}
.afd-yr{font-weight:400;letter-spacing:0;text-transform:none;color:var(--ink-soft)}
/* bullet-bar target: length plus a threshold tick reads more precisely than a gauge */
.afd-tick{position:absolute;top:-5px;bottom:-5px;width:2px;background:var(--ink-soft);border-radius:2px}
.afd-tick span{
  position:absolute;left:50%;top:-16px;transform:translateX(-50%);
  /* a threshold label is data, not chrome: --ink-faint is only 2.2:1 here */
  font-size:10.5px;color:var(--ink-soft);font-variant-numeric:tabular-nums;white-space:nowrap;
}

.afd-verdict{
  display:flex;gap:9px;align-items:flex-start;margin:22px 0 0;
  font-size:13px;line-height:1.5;color:var(--ink-soft);
}
.afd-ico{
  flex:0 0 auto;width:18px;height:18px;border-radius:50%;display:grid;place-items:center;
  font-size:11px;font-weight:700;margin-top:1px;
}
.afd-verdict.ok .afd-ico{background:var(--green-wash);color:var(--green)}
.afd-verdict.warn .afd-ico{background:var(--red-wash);color:var(--red-strong)}

.afd-max{
  display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  margin-top:18px;padding:16px;border-radius:16px;background:var(--field);
}
.afd-max .lab{font-size:12.5px;font-weight:590;color:var(--ink-soft);margin-bottom:5px}
.afd-price{font-size:27px;font-weight:700;letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.1}
.afd-sub{font-size:12px;color:var(--ink-soft);margin-top:5px;max-width:34ch;line-height:1.45}
.afd-apply{
  /* --bar-green is the token minted for white-on-green: --green is only
     4.15:1 behind 13px text */
  flex:0 0 auto;border:none;background:var(--bar-green);color:#fff;border-radius:100px;
  padding:11px 18px;cursor:pointer;font-family:var(--sf);font-size:13px;font-weight:590;
  transition:transform .12s var(--spring), filter .18s var(--spring);
}
.afd-apply:hover{filter:brightness(1.08)}
.afd-apply:active{transform:scale(.97)}
/* the PMI-free ceiling is the quieter, secondary option */
.afd-max.alt{margin-top:8px;background:transparent;border:1px dashed var(--line-strong)}
.afd-price.sm{font-size:22px}
.afd-apply.ghost{background:transparent;color:var(--green);box-shadow:inset 0 0 0 1.5px var(--green)}
.afd-apply.ghost:hover{background:var(--green-wash);filter:none}

.afd-break{margin-top:18px;border-top:.5px solid var(--line);padding-top:14px}
.afd-break-t{
  margin:0 0 8px;font-size:11.5px;font-weight:590;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-faint);
}
.afd-line{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-size:13px;color:var(--ink-soft);padding:5px 0}
.afd-line b{color:var(--ink);font-weight:590;font-variant-numeric:tabular-nums}
.afd-line.total{border-top:.5px solid var(--line);margin-top:5px;padding-top:9px;color:var(--ink);font-weight:590}
.afd-line.total b{font-size:15px}
.afd-note{color:var(--ink-soft);font-size:11.5px;margin-left:7px}
.afd-note-b{margin:10px 0 0;font-size:12px;color:var(--ink-soft);line-height:1.5}
.afd-empty{margin:2px 0 0;font-size:13px;color:var(--ink-soft);line-height:1.55}
.afd-empty b{color:var(--ink);font-weight:590}

@media (max-width:640px){
  /* Stacked, the label row occupies the space the tick caption wants, so
     the caption moves under the bar. */
  .afd-row{display:block;margin-top:18px;padding-bottom:16px}
  .afd-row + .afd-row{margin-top:18px}
  .afd-lab{width:auto;display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;margin-bottom:9px}
  .afd-lab b{display:inline}
  .afd-sublab{flex:1 0 100%;margin-top:0}   /* onto its own line, not beside the value */
  .afd-tick span{top:auto;bottom:-17px}
  .afd-max{padding:14px}
  .afd-apply{width:100%;justify-content:center}
  .afd-price{font-size:24px}
}

footer{margin-top:30px;text-align:center;font-size:12px;color:var(--ink-faint);line-height:1.6}
footer b{color:var(--ink-soft)}
.reset-link{
  margin-top:7px;border:0;background:transparent;padding:6px 8px;cursor:pointer;
  font-family:var(--sf);font-size:12px;color:var(--ink-faint);text-decoration:underline;
  text-underline-offset:2px;border-radius:6px;transition:color .15s var(--spring);
}
.reset-link:hover{color:var(--red)}

/* ============================================================
   NARROW SCREENS
   Charts are measured in JS, so the job here is reclaiming the
   horizontal room they measure against, and unstacking the rows
   that only make sense at desktop width.
============================================================ */
@media (max-width:640px){
  .wrap{padding:16px 14px 64px}
  header{margin:6px 0 18px}
  .glyph{width:40px;height:40px;border-radius:11px}
  .glyph svg{width:22px;height:22px}
  h1.mark{font-size:23px}

  .studio{gap:14px}
  .main{gap:14px}
  .sidebar{gap:14px}
  .card{border-radius:18px}
  .panel-pad{padding:14px}
  .card.budget-card{padding:8px}   /* keeps 8+10 = 14+4, the loan card's rail */
  .runway{padding:16px 14px 14px}
  .chart-card{padding:16px 14px}

  .hero-stats{gap:10px;min-height:0}
  .stat{padding:15px}
  .stat .big{font-size:27px}
  .stat .big.sm{font-size:22px}
  .stat.freedom .big{font-size:29px}
  /* Reserve two lines. These strings are rewritten on every drag frame, and
     a slot that resizes when the text rewraps moves the chart under the
     finger. Sized for the largest state, per the layout-stability rule. */
  .stat .sub{font-size:12px;min-height:34px}
  .stat.freedom .sub{min-height:34px}

  .runway-head{gap:8px;margin-bottom:10px}
  .runway-head h2{font-size:18px}
  .chart-card h2{font-size:16.5px}
  .runway-head p,.chart-card .csub{font-size:12.5px}
  .chart-card .chead{flex-direction:column;align-items:flex-start;gap:8px;margin-bottom:8px}
  .legend{gap:14px}

  .chart-shell{min-height:190px}

  /* Chips go full width so a long strategy label truncates predictably
     instead of reflowing its own metadata onto a second line. */
  .compare{gap:7px}
  .cmp-chip{width:100%}
  .cmp-save{width:100%;justify-content:center;padding:11px 14px}

  /* Bar label above the bar frees the full width for the bar itself */
  .life-row{display:block;margin-top:16px}
  .life-lab{width:auto;display:flex;align-items:baseline;gap:6px;margin-bottom:7px}
  .life-lab b{display:inline}
  .bar-track{height:30px}

  .insight{padding:11px 12px;font-size:12.5px}
  footer{margin-top:24px}
}

/* Deliberately keep the 2-up stat pair down to the narrowest phones: stacking
   all three would push the runway chart a full card below the fold. */
@media (max-width:400px){
  .stat{padding:13px}
  .stat .big.sm{font-size:20px}
  .cmp-chip .meta{font-size:10.5px}
}

@media (prefers-reduced-motion: reduce){ *{transition:none!important;animation:none!important} }
:focus-visible{outline:2.5px solid var(--green);outline-offset:2px;border-radius:6px}
.scn-head:focus-visible{outline-offset:-2px;border-radius:12px}
