/* Extra Payment — tool-specific layout (styles/app.css)
   Layer 6 of the theme contract: pon7ryr kit → hfg-base → hfg-mobile →
   hfg-report → hfg-tool-ui → this file. Only what is unique to THIS tool
   lives here; the report shell, form extras, mobile bubble fields, and share
   overlay come verbatim from the bundled hfg-report.css / hfg-tool-ui.css.
   Colors only via var(--…) tokens. No inline styles anywhere (CSP). */

/* interest-rate field uses the custom .spin chevrons — hide the native
   (tiny) number-input spinner so there aren't two sets of arrows */
#rate::-webkit-inner-spin-button,#rate::-webkit-outer-spin-button{-webkit-appearance:none;margin:0;}
#rate{-moz-appearance:textfield;appearance:textfield;}

/* ── REPORT: balance-over-time chart curves (tokens only; SVG attrs can't use var()) ──
   Scheduled = muted dashed; With extra = solid lime with a soft area fill. */
.rp .ln-sched{stroke:var(--rp-mut);stroke-width:3;stroke-dasharray:2 7;}
.rp .ln-accel{stroke:var(--rp-lime);stroke-width:2.8;}
.grad-accel stop:first-child{stop-color:var(--rp-lime);stop-opacity:.18;}
.grad-accel stop:last-child{stop-color:var(--rp-lime);stop-opacity:.01;}
/* legend swatches for this tool: solid = with-extra (lime), dashed = scheduled (mut) */
.rp .lgd .d{background:var(--rp-lime);}
.rp .lgd .d.dash{border-top:3px dotted var(--rp-mut);background:none;}

/* ── REPORT: standard-vs-accelerated comparison table ── */
.rp .ctab{border:1px solid var(--rp-line);border-radius:12px;overflow:hidden;}
.rp .ctr{display:grid;grid-template-columns:1.3fr 1fr 1fr 1fr;border-top:1px solid var(--rp-line);font-size:12px;font-variant-numeric:tabular-nums;}
.rp .ctr:first-child{border-top:0;}
.rp .ctr > div{padding:9px 14px;}
.rp .ctr.h{background:var(--off-white);font-family:var(--mono);font-size:9.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:var(--rp-navy);}
.rp .ctr.h > div:not(:first-child),.rp .ctr > div:not(:first-child){text-align:right;}
.rp .ctr .lbl{color:var(--rp-ink2);font-weight:700;}
.rp .ctr .std{font-weight:800;color:var(--rp-ink);}
.rp .ctr .acc{font-weight:800;color:var(--rp-navy);}
.rp .ctr .dif{font-weight:800;color:var(--rp-lime-ink);}
.rp .ctr.tot{background:linear-gradient(120deg,var(--rp-limebg),var(--off-white));border-top:2px solid var(--rp-navy);}
.rp .ctr.tot .lbl{color:var(--rp-lime-ink);font-weight:800;text-transform:uppercase;letter-spacing:.3px;font-size:11px;}
.rp .ctr.tot .std,.rp .ctr.tot .acc,.rp .ctr.tot .dif{font-size:13px;}
@media print{.rp .ctab{break-inside:avoid;}}

/* ═══════════ MOBILE (#mv) — dark-shell tokens only ═══════════ */

#mv .seclab{font-size:11px;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:var(--ink);margin:20px 2px 11px;}

/* live interest-saved banner (this tool's hero) */
#mv .ex-banner{margin:6px 0 4px;padding:24px 22px 22px;text-align:center;color:#fff;position:relative;overflow:hidden;border-radius:22px;background:linear-gradient(158deg,var(--panel2),var(--panel) 78%);border:1px solid rgba(188,214,74,.4);box-shadow:0 16px 34px rgba(0,0,0,.34);}
#mv .ex-banner .glow{position:absolute;border-radius:50%;background:rgba(255,255,255,.06);pointer-events:none;}
#mv .ex-banner .glow.g1{width:230px;height:230px;top:-70px;right:-60px;}
#mv .ex-banner .glow.g2{width:150px;height:150px;bottom:-60px;left:-30px;}
#mv .ex-banner .bl{font-size:13px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:var(--ink2);}
#mv .ex-banner .ex-big{font-size:46px;font-weight:800;letter-spacing:-2px;line-height:1.02;margin:5px 0 4px;font-variant-numeric:tabular-nums;color:var(--lime);}
#mv .ex-banner .ex-sub{font-size:13px;color:var(--ink2);line-height:1.45;max-width:300px;margin:0 auto;}
#mv .ex-banner .ex-sub b{color:#fff;}
#mv .ex-stat3{display:flex;background:rgba(255,255,255,.08);border:1px solid var(--line);border-radius:15px;margin-top:17px;overflow:hidden;}
#mv .ex-stat3 .c{flex:1;padding:11px 8px;text-align:center;}
#mv .ex-stat3 .c + .c{border-left:1px solid var(--line);}
#mv .ex-stat3 .c .l{font-size:10.5px;color:var(--ink2);font-weight:700;line-height:1.25;}
#mv .ex-stat3 .c .v{font-size:17px;font-weight:800;margin-top:4px;font-variant-numeric:tabular-nums;letter-spacing:-.4px;color:#fff;}

/* comparison: two stacked tracks */
#mv .ex-cmp{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:4px 16px 14px;margin-bottom:14px;}
#mv .ex-cmp .crow{display:grid;grid-template-columns:1fr auto auto;gap:10px;align-items:baseline;padding:12px 0;border-top:1px solid var(--line);}
#mv .ex-cmp .crow:first-child{border-top:0;}
#mv .ex-cmp .ch2{font-size:10.5px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;color:var(--mut);}
#mv .ex-cmp .ch2 span:nth-child(2),#mv .ex-cmp .crow .a,#mv .ex-cmp .ch2 span:nth-child(3),#mv .ex-cmp .crow .b{min-width:84px;text-align:right;}
#mv .ex-cmp .cl{font-size:13.5px;color:var(--ink2);font-weight:700;}
#mv .ex-cmp .a{font-size:14.5px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;}
#mv .ex-cmp .b{font-size:14.5px;font-weight:800;color:var(--steel);font-variant-numeric:tabular-nums;}
#mv .ex-cmp .save{margin:4px -16px -14px;padding:14px 16px;border-top:2px solid rgba(188,214,74,.5);background:linear-gradient(120deg,rgba(188,214,74,.14),rgba(95,168,196,.07));border-radius:0 0 18px 18px;display:flex;align-items:center;justify-content:space-between;gap:12px;}
#mv .ex-cmp .save .sl{font-size:13px;font-weight:800;color:var(--ink);}
#mv .ex-cmp .save .sv{font-size:22px;font-weight:800;letter-spacing:-.5px;color:var(--lime);font-variant-numeric:tabular-nums;}

/* ── AUTH GATE + FAIL-CLOSED FIRST PAINT (MSAL Entra) ──
   The body ships data-auth-state="checking" in static HTML, and every protected
   region stays display:none in ANY state except signed-in — so the tool can never
   flash before auth completes, even if JavaScript fails entirely.
   scripts/auth.js advances the state machine: checking | signed-out | signed-in | error. */
body:not([data-auth-state="signed-in"]) .site-nav,
body:not([data-auth-state="signed-in"]) #pg1,
body:not([data-auth-state="signed-in"]) #pg2,
body:not([data-auth-state="signed-in"]) #mv{display:none!important;}
body[data-auth-state="signed-in"] .auth-gate{display:none;}
.auth-gate{position:fixed;inset:0;z-index:1000;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;background:var(--hfg-blue-deep);text-align:center;padding:24px;}
.auth-title{font-family:var(--sans);font-size:26px;font-weight:800;color:#fff;letter-spacing:-.01em;}
.auth-msg{font-size:13px;color:rgba(255,255,255,.45);max-width:380px;line-height:1.55;}
.auth-btn{margin-top:8px;padding:10px 22px;border-radius:8px;background:var(--hfg-teal);border:none;color:#fff;font-family:var(--sans);font-size:14px;font-weight:500;cursor:pointer;}
.auth-btn:hover{background:var(--hfg-teal-dark);}
.auth-btn[hidden]{display:none;}

/* LO Graph-autofill note (shown after sign-in when /me populated fields) */
.lo-autofill-note{margin:0 0 14px;padding:9px 13px;border-radius:8px;background:var(--hfg-teal-pale);color:var(--hfg-blue-deep);font-size:12px;line-height:1.5;}
.lo-autofill-note[hidden]{display:none;}

/* LO headshot avatar (Graph /me photo) — report PDF + mobile share card.
   .av is a fixed circle; with a photo we drop the initials background and let
   the image fill it. Falls back to the initials circle when no photo. */
.rp .lo .av.has-photo,
#mv .sheet .lo .av.has-photo{background:none;padding:0;overflow:hidden;}
.rp .lo .av.has-photo img,
#mv .sheet .lo .av.has-photo img{width:100%;height:100%;object-fit:cover;display:block;}

/* Share-overlay action buttons set display:flex, which outranks the UA
   [hidden] rule — restate it so a hidden action (Print / Save PDF, disabled on
   mobile for now) actually stays hidden. Re-enabling the button later just means
   removing the `hidden` attribute in mobile-view.js; this rule is a harmless
   no-op once no action carries [hidden]. */
#mv .shov .actions button[hidden]{display:none!important;}

/* Mobile raster-PDF capture (scripts/report-pdf.js): the balance-over-time SVG
   chart is pre-rasterized onto a sibling canvas via a blob: URL because
   html2canvas loads inline SVG as a data: image, which img-src blocks under the
   strict CSP. Class-based so the swap survives html2canvas's DOM clone. */
.pdf-svg-raster{display:block;width:100%;height:auto;}
.pdf-svg-hidden{display:none!important;}
