/* Financial Freedom Calculator — page-specific layer.
   Tokens and shared components come from ../dark.css, ../light.css, ../shared.css. */
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700;800&family=DM+Mono:wght@400;500;600&display=swap');

.container{max-width:1440px;}
.layout{grid-template-columns:380px 1fr;}
/* The column layout, the inner scroller and the pinned tab bar come from
   shared.css (.controls:has(.ctrl-scroll) / .ctrl-scroll / .ctrl-tabs).
   Here the action row sits below the scroller, so it stays put as well. */
.ctrl-scroll{flex:1 1 auto;}
.btn-row{flex-shrink:0;}
.btn-row .btn-primary,.btn-row .btn-secondary{padding:10px 16px;font-size:.86rem;}
.btn-back{text-decoration:none;display:inline-flex;align-items:center;}
h1{font-size:1.85rem;margin:0 0 4px;}

/* ── Quick Start scenarios ──
   Pinned above .ctrl-scroll, so the row never scrolls away with the panel. */
.quick-start-row{display:flex;align-items:center;gap:10px;padding:10px 16px;border-bottom:1px solid var(--border);flex-wrap:wrap;}
.quick-start-label{display:inline-flex;align-items:center;gap:5px;font-weight:700;font-size:.82rem;color:var(--muted);white-space:nowrap;flex-shrink:0;}
.quick-start-label .tico{width:1.05em;height:1.05em;}
.quick-start-btns{display:flex;gap:6px;flex-wrap:wrap;}
.quick-start-btn{background:var(--input-bg);border:1.5px solid var(--border);border-radius:var(--radius-md);color:var(--muted);padding:5px 11px;font-size:.78rem;font-weight:600;cursor:pointer;transition:all var(--motion-fast);white-space:nowrap;font-family:inherit;}
.quick-start-btn:hover{border-color:var(--accent);color:var(--text);}
.quick-start-btn.active{border-color:var(--accent2);color:var(--text);background:rgba(143,205,189,.15);}

/* ── Control panel extras ── */
.ctrl-tab{padding:10px 4px;font-size:.78rem;line-height:1.3;}
.ctrl-tabs.stacked .tico{width:1.45em;height:1.45em;}
.field-group>:first-child{border-top:none;}
.ctrl-panel>:first-child{margin-top:0;}
.inline-row{display:flex;gap:8px;align-items:center;}
.inline-row .grow{flex:1;min-width:0;}
.inline-row .period{flex:0 0 108px;width:108px;}
/* A basis that can be "% of living" needs a little more room than a period. */
.inline-row .period.basis{flex-basis:128px;width:128px;}
.inline-row .age-in{flex:0 0 96px;width:96px;}
/* shared.css ships .toggle-switch / .toggle-track / .toggle-knob but not the
   row that holds them, which the design reference documents. The switch is a
   <label>, so it only takes a width once this row makes it a flex item. */
.toggle-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-top:1px solid var(--border);}
.toggle-label{font-weight:700;font-size:.88rem;flex:1;}
.field-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:7px;}
.field-head .field-label{margin:0;}
.seg-toggle{display:inline-flex;flex-wrap:wrap;max-width:100%;background:var(--input-bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:3px;gap:2px;flex-shrink:0;}
.seg-btn{background:transparent;border:none;border-radius:7px;padding:5px 12px;font-size:.82rem;font-weight:600;color:var(--muted);cursor:pointer;transition:all var(--motion-fast);font-family:inherit;white-space:nowrap;flex-shrink:0;}
.seg-btn.active{background:var(--accent-strong);color:var(--text-inv);box-shadow:var(--shadow-sm);}
.seg-btn:hover:not(.active){color:var(--text);}
.note{color:var(--muted);font-size:.79rem;line-height:1.45;margin:6px 0 0;}
.note strong{color:var(--text);}
/* ── Life stages (Money out, Detailed) ──
   One card per stage, the shape of the cost lists on the Rent vs Own page:
   a name and its remove button, the two ages, then the figure and its basis. */
.stage-list{display:grid;gap:8px;margin-top:6px;}
.stage-list:empty{display:none;}
.stage-row{background:var(--input-bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:9px 10px;display:grid;gap:7px;}
.stage-row.stage-off{border-style:dashed;}
.stage-row.stage-off .stage-note{color:var(--negative-em);}
.stage-row .note{margin:0;}
/* The card is already the input colour, so its own fields sit on the panel
   colour, a size down, the way the Rent vs Own cost cards do it. */
.stage-row .txt-input,.stage-row .num-input,.stage-row .currency-input{background:var(--panel);padding-top:7px;padding-bottom:7px;font-size:.86rem;}
.stage-row .txt-input,.stage-row .num-input{padding-left:9px;padding-right:9px;}
.stage-row .sel-input{background-color:var(--panel);padding-top:7px;padding-bottom:7px;font-size:.84rem;}
.stage-head{display:flex;align-items:center;gap:7px;}
.stage-head .stage-name{flex:1;min-width:0;}
.stage-del{background:transparent;color:var(--negative-em);border:1px solid var(--data-neg-border);border-radius:var(--radius-sm);padding:5px 9px;font-size:.75rem;font-weight:700;cursor:pointer;flex-shrink:0;font-family:inherit;}
.stage-del:hover{background:var(--negative-bg);}
.stage-ages{display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
.stage-lbl{font-size:.8rem;color:var(--muted);}
.stage-ages .num-input{width:5.4em;flex:0 0 auto;}
.stage-actions{display:flex;margin-top:8px;}
.stage-actions .btn-sm{flex:1;}
.stage-actions .btn-sm:disabled{opacity:.5;cursor:not-allowed;}
/* ── Detailed Money out: living and retirement expenses as locked stages ──
   The same two fields as in Simple, framed as the first and last card of the
   list, each with its name locked and a line saying which ages it covers. */
#moneyOut:not(.is-detailed) .detailed-only{display:none !important;}
#moneyOut.is-detailed .simple-only{display:none;}
#moneyOut.is-detailed>.money-stage{background:var(--input-bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:9px 10px;gap:7px;margin:10px 0 0;}
#moneyOut.is-detailed>.money-stage .txt-input,#moneyOut.is-detailed>.money-stage .currency-input{background:var(--panel);padding-top:7px;padding-bottom:7px;font-size:.86rem;}
#moneyOut.is-detailed>.money-stage .txt-input{padding-left:9px;padding-right:9px;}
#moneyOut.is-detailed>.money-stage .sel-input{background-color:var(--panel);padding-top:7px;padding-bottom:7px;font-size:.84rem;}
#moneyOut.is-detailed>.money-stage .note{margin:0;}
#moneyOut.is-detailed>#stagesBlock{margin-top:8px;}
#moneyOut.is-detailed>.stage-timeline{margin-bottom:12px;}
#moneyOut.is-detailed>.stage-timeline+.field-row{border-top:1px solid var(--border);}
.stage-head .tip-wrap{flex-shrink:0;}
.money-stage .stage-name-locked{font-weight:700;color:var(--text);cursor:not-allowed;border-style:dashed;}
#moneyOut.is-detailed>.money-stage .stage-name-locked{background:var(--bg-subtle);}
.money-stage .stage-name-locked:focus{border-color:var(--border);}
.stage-lock{display:inline-flex;align-items:center;justify-content:center;width:31px;height:28px;color:var(--muted);flex-shrink:0;}
.stage-lock svg{width:15px;height:15px;}

/* ── Detailed Money in: today's figure as the locked first stage ──
   The same two fields as in Simple (the figure and its growth), framed as the
   first card of the list. In Simple the model switch and the figure read as
   one row, the way they always did. */
#moneyIn:not(.is-detailed) .detailed-only{display:none !important;}
#moneyIn.is-detailed .simple-only{display:none !important;}
#moneyIn:not(.is-detailed) #savingsModeRow{padding-bottom:0;}
#moneyIn:not(.is-detailed) #savingsRow{padding-top:5px;border-top:none;}
#moneyIn.is-detailed>.money-stage{display:grid;background:var(--input-bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:9px 10px;gap:7px;margin:10px 0 0;}
#moneyIn.is-detailed>.money-stage>.field-row{padding:0;border-top:none;gap:7px;}
#moneyIn.is-detailed>.money-stage .txt-input,#moneyIn.is-detailed>.money-stage .currency-input,#moneyIn.is-detailed>.money-stage .num-input{background:var(--panel);padding-top:7px;padding-bottom:7px;font-size:.86rem;}
#moneyIn.is-detailed>.money-stage .txt-input,#moneyIn.is-detailed>.money-stage .num-input{padding-left:9px;padding-right:9px;}
#moneyIn.is-detailed>.money-stage .sel-input{background-color:var(--panel);padding-top:7px;padding-bottom:7px;font-size:.84rem;}
#moneyIn.is-detailed>.money-stage .note{margin:0;}
#moneyIn.is-detailed>.money-stage .stage-name-locked{background:var(--bg-subtle);}
#moneyIn.is-detailed>#inStagesBlock{margin-top:8px;}
#moneyIn.is-detailed>.stage-timeline{margin-bottom:12px;}
/* Growth reads as a sentence on a card, "Grows 3 % a year, from today", the
   way a stage's ages read "From age 28 to 33". */
#moneyIn.is-detailed .growth-line,.stage-grow{display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
#moneyIn.is-detailed .grow-wrap,.stage-grow .grow-wrap{width:7.4em;flex:0 0 auto;}
#moneyIn.is-detailed .growth-line,.stage-grow{flex-wrap:nowrap;}
.grow-tail{flex:1 1 0;min-width:0;}
/* Whether a stage is still paid once you stop work: a switch on the card. */
.stage-keep{display:flex;align-items:center;gap:7px;}
.stage-keep .stage-lbl{flex:1;color:var(--text);font-weight:600;}
.stage-keep .tip-wrap{flex-shrink:0;}
.stage-row .toggle-track{background:var(--panel);}

/* What the list resolves to, at the slider's retirement age. */
.stage-timeline{margin-top:10px;padding:8px 10px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-subtle);}
.tl-head{font-size:.76rem;font-weight:700;color:var(--muted);margin-bottom:5px;}
.tl-list{list-style:none;margin:0;padding:0;display:grid;gap:3px;font-size:.79rem;}
.tl-list li{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:baseline;}
.tl-ages{font-family:'DM Mono',monospace;color:var(--muted);font-size:.75rem;white-space:nowrap;}
.tl-name{color:var(--text);min-width:0;overflow-wrap:break-word;}
.tl-amt{font-family:'DM Mono',monospace;color:var(--text);white-space:nowrap;}
.ticker-row{display:flex;gap:8px;align-items:stretch;}
.ticker-row .txt-input{flex:1;min-width:0;text-transform:uppercase;}
.ticker-ref-link{display:inline-block;margin-top:7px;font-size:.78rem;color:var(--accent);text-decoration:none;}
.ticker-ref-link:hover{text-decoration:underline;}
#tickerStatus{margin-top:8px;font-size:.79rem;line-height:1.45;color:var(--muted);min-height:1em;}
#tickerStatus.err{color:var(--negative-em);}

/* ── The two boards ──
   The page answers two different questions and they are not the same question,
   so each one gets a band of its own: a heading, then the cards, the charts and
   the table that belong to it. The rule down the left is what stops the two
   reading as one long scroll. */
.board{margin:0 0 26px;padding-left:16px;border-left:3px solid var(--accent);}
#boardCash{border-left-color:var(--accent2);}
.board-head{margin:0 0 14px;}
.board-head h2{margin:0 0 6px;font-size:1.3rem;}
/* Path to freedom carries the money switch on its heading row: it changes how
   every figure on the page reads, so it sits with the results, not the inputs. */
.board-head-split{display:flex;align-items:center;justify-content:space-between;gap:8px 16px;flex-wrap:wrap;}
.board-head-split h2{margin:0;}
.board-head .money-toggle{border-top:none;padding:6px 12px;gap:10px;flex:0 0 auto;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-subtle);}
.board-head .money-toggle .toggle-label{font-size:.84rem;flex:0 1 auto;}
.chart-head h3,.detail-head h3{font-size:1.02rem;}

/* ── Retirement-age sensitivity slider ──
   It is a control, but it belongs to the section it moves rather than to the
   input panel, so it is styled as part of the board header. */
.retire-slider{margin-top:14px;padding:13px 16px 11px;border:1px solid var(--border);border-radius:var(--radius-md);background:var(--bg-subtle);}
.retire-slider .slider-block{padding:0;border-top:none;}
.retire-slider .slider-value{color:var(--accent2);font-size:1.05rem;}
.slider-scale{display:flex;justify-content:space-between;gap:10px;margin-top:5px;color:var(--muted);font-size:.74rem;}
/* The verdict on the slider's own age hangs directly off the slider, so it
   keeps the banner's look and drops the banner's bottom margin. */
.board-head .verdict{margin:12px 0 0;}
#ageRetire{accent-color:var(--accent2);}

/* ── KPI strip ── */
.metrics{grid-template-columns:repeat(4,1fr);}
.metrics-3{grid-template-columns:repeat(3,1fr);}
.metric{padding:14px 16px;min-height:96px;}
.metric .label{display:flex;align-items:center;gap:5px;}
.metric .value{font-size:1.35rem;}
.metric .value.small{font-size:1.02rem;letter-spacing:0;}
.metric .sub{color:var(--muted);font-size:.78rem;margin-top:5px;line-height:1.35;}
.metric .value.pos{color:var(--data-pos-em);}
.metric .value.neg{color:var(--data-neg-em);}

/* ── Verdict banner: styled by shared.css (.verdict); the remedy list is ours ── */
.remedies{list-style:none;margin:12px 0 0;padding:0;display:grid;gap:8px;}
.remedies li{background:var(--card-bg);border:1px solid var(--border);border-radius:var(--radius-md);padding:9px 12px;font-size:.85rem;line-height:1.45;color:var(--muted);}
.remedies li strong{color:var(--text);display:block;font-size:.8rem;text-transform:uppercase;letter-spacing:.05em;margin-bottom:2px;}

/* ── Charts ──
   The export row itself — .chart-head, .detail-head, .btn-cluster, .btn-sm and
   their phone layout — is shared.css's, so every tool on the site carries the
   same cluster. Only what is particular to this page is set here. */
.chart-card{padding:20px;margin-bottom:18px;}
.chart-card>.sub{color:var(--muted);font-size:.8rem;margin:5px 0 0;line-height:1.4;}
.detail-head{margin-bottom:4px;}
.legend{display:flex;gap:14px;flex-wrap:wrap;margin:12px 0 14px;font-size:.84rem;}
.legend-item{display:flex;align-items:center;gap:7px;cursor:pointer;transition:opacity .15s;}
.legend-item.hidden{opacity:.35;}
/* A key grouped by pane: one row per group, each led by the pane's name, the
   names in one column so the two rows' entries start in line. */
.legend.legend-grouped{flex-direction:column;gap:8px;}
.legend-group{display:flex;gap:14px;flex-wrap:wrap;align-items:center;}
.legend-group-label{color:var(--muted);font-weight:600;min-width:6.6em;}
@media (max-width:600px){
  /* On a phone the entries wrap, so the name takes a line of its own above
     them rather than leaving the second line of a group hanging under it. */
  .legend.legend-grouped{gap:4px;}
  .legend-group{row-gap:6px;}
  .legend-group-label{flex-basis:100%;min-width:0;}
  .legend-group + .legend-group{margin-top:6px;}
}
.canvas-wrap{height:430px;border:1px solid var(--border);border-radius:14px;overflow:hidden;background:var(--card-bg);}
/* The cashflow card draws two plot areas on ONE canvas — the flows above, the
   balance they leave behind below — so it needs room for both. */
.canvas-wrap-cash{height:620px;}
.hover-box{margin-top:10px;color:var(--muted);font-size:.84rem;min-height:22px;line-height:1.5;}

/* ── Detail tables and notes ── */
.detail-section{padding:20px;margin-bottom:18px;}
.detail-section h2{margin:0 0 4px;}
.detail-section .sub{color:var(--muted);font-size:.8rem;margin:0 0 12px;line-height:1.45;}
table{width:100%;border-collapse:collapse;font-family:'DM Mono',monospace;font-variant-numeric:tabular-nums;font-size:.85rem;}
th,td{padding:9px 8px;border-bottom:1px solid var(--border);text-align:right;white-space:nowrap;}
th:first-child,td:first-child{text-align:left;white-space:normal;font-family:'DM Sans',sans-serif;}
th{color:var(--muted);font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;position:sticky;top:0;background:var(--panel);z-index:1;}
.table-wrap{max-height:460px;overflow:auto;}
tr:hover td{background:rgba(141,187,255,.05);}
body.light tr:hover td{background:rgba(90,145,232,.05);}
/* The marked row is the RETIREMENT year: this table is measured at the age on
   the Cashflows slider, not at the freedom age section 1 solves for. */
tr.free td{background:rgba(141,187,255,.12);font-weight:700;border-top:1.5px solid var(--accent2);}
body.light tr.free td{background:rgba(90,145,232,.12);}
td.neg{color:var(--data-neg-em);}
td.pos{color:var(--data-pos-em);}

.page-footer{max-width:1440px;margin:0 auto;padding:0 24px 24px;}

/* ── The Simulate gate ──────────────────────────────────────────────────────
   A thousand simulated futures is too much work to repeat on every keystroke,
   so the form does not run the engine — Simulate does. That only works if the
   page is honest about it: the moment an assumption changes, the answer below
   steps back and the button steps forward, so nobody reads a verdict that no
   longer belongs to the numbers on screen. */
.stale-note{display:none;flex-basis:100%;margin:0 0 4px;font-size:.78rem;font-weight:700;color:var(--accent2);}
body.is-stale .stale-note{display:block;}
body.is-stale main .card{opacity:.45;}
main .card{transition:opacity var(--transition-fast);}
.btn-primary.needs-run{box-shadow:0 0 0 2px var(--card-bg),0 0 0 4px var(--accent2);}

@media(max-width:1100px){
  .layout{grid-template-columns:1fr;}
  .controls{position:static;max-height:none;}
  .metrics,.metrics-3{grid-template-columns:repeat(2,1fr);}
  .canvas-wrap{height:360px;}
  .canvas-wrap-cash{height:500px;}
}
@media(max-width:600px){
  h1{font-size:1.35rem;}
  .container{padding:10px;}
  .page-footer{padding:0 10px 16px;}
  .metrics,.metrics-3{grid-template-columns:1fr;}
  .board{padding-left:11px;}
  .canvas-wrap{height:300px;}
  .canvas-wrap-cash{height:420px;}
  .btn-row{flex-direction:column;}
  .btn-row .btn-primary,.btn-row .btn-secondary{flex:1 1 auto;}
  .ctrl-tab{font-size:.7rem;}
  .inline-row{flex-wrap:wrap;}
  .inline-row .period,.inline-row .period.basis{flex:1 1 100%;width:auto;}
}
