/* Saava styles.css — extracted from index.html in V204 (restructure R2).
   Order preserved exactly: cascade and specificity ties depend on it. */

/* ══════ Block 1: Core (head) ══════ */
/* ── Reset ───────────────────────────────── */
*{box-sizing:border-box;margin:0;padding:0}

/* ── Design tokens (Phase 2 — Vela design brief) ─────────────────────
   Light theme is the primary surface. Variable NAMES are kept stable
   so the rest of the file (~9000 lines) doesn't need to be touched —
   only the VALUES move to the new palette. New tokens (--accent-soft,
   --gold, motion durations) are additive.
   Palette story: warm off-white "quiet morning" page, deep navy accent
   ("Vela blue"), forest green for positive money, dusty red for
   negative money, warm amber for warnings, gold for celebration only.
   ──────────────────────────────────────────────────────────────────── */
:root{
  --ovr-col:1200px; /* V210 — shared Overview content-column width */
  /* ── Saava — editorial bold (vermilion + navy + bone) ───────────────
     Page bg is bone (warm but not cream). Cards are pure white with a
     1px charcoal hairline. Navy is the workhorse — text, headers, key
     numbers. Vermilion is reserved for ACCENT only — CTAs, key labels,
     active tab underline, hero label. Less is more here.
     ──────────────────────────────────────────────────────────────────── */
  --bg:#F5F1E8;          /* bone page */
  --surface:#FFFFFF;     /* pure white card */
  --surface2:#E8E3D9;    /* warm muted — input bg, disabled tiles */
  --border:#E5E0D4;      /* V136: soft warm hairline (default everywhere). Was #D8D3C7 — too dark; brief spec is E5E0D4. Aligns with --ot-bd already used on Overview. */
  --border-strong:#1A1A1A; /* charcoal — used selectively on hero, primary cards */
  --border2:#B8B2A2;     /* slightly stronger neutral border for inputs */
  /* text — rich cobalt navy & charcoal */
  --text:#1B3367;        /* deep cobalt navy — primary text & numbers */
  --text2:#5F6470;       /* V136: muted body text. Was #3A3A40 (too dark, competing with --text). Brief spec is #5F6470 — also matches --ot-t2 on Overview. */
  --text3:#63636C;          /* V219 a11y — was #7A7A82 (3.7:1); now 4.7:1 on cream */       /* muted captions */
  --ink:#0E1116;         /* V136: near-black for high-contrast moments (active topbar tabs, primary CTAs, large numbers). Was #1A1A1A. Brief spec; matches --ot-ink. */
  /* Brief-aligned aliases (V136). Cream is the cream-on-ink-or-vermilion fill text token; --ot-bd duplicates --border for Overview-page scoped CSS. */
  --ot-bd:var(--border);
  --ot-bg:var(--bg);
  --ot-surf:var(--surface);
  --ot-ink:var(--ink);
  --ot-t2:var(--text2);
  --ot-t3:var(--text3);
  --ot-ver:var(--accent,#D8431B);
  --ot-dark:#111418;
  --ot-font:"Inter Tight","Inter",-apple-system,sans-serif;
  /* PRIMARY ACCENT — bright vermilion-orange (sampled from references).
     Brighter and more saturated than the previous coral attempt. Used
     SPARINGLY: CTAs, key alerts, hero label, active tab underline,
     monogram. Money values stay navy. */
  --blue:#D8431B;
  /* V160 — tinted state backgrounds (red-bg / orange-bg / blue-bg /
     green-bg / navy-bg / surface2) were the loudest legacy carryover
     across HST / Timeline / Pay / Settings. Aliased to neutral
     editorial surfaces so render functions don't need rewriting —
     tinted cards become white-on-cream with hairline borders. */
  --blue-bg:var(--ot-surf,#FFFFFF);
  --blue-light:var(--ot-bd,#E5E0D4);
  --accent:#D8431B;
  --accent-soft:rgba(232,74,26,0.06);
  --accent-glow:rgba(232,74,26,.30);
  /* V234 continuity — accessible vermilion for SMALL text/links (>=4.5:1 on
     cream). Mirrors the landing's --verm-ink. Use this, not --accent, whenever
     vermilion appears as body-size text or a hyperlink. */
  --verm-ink:#B43A10;
  /* Phase 16 — semantic tokens added to retire 14 hardcoded var(--accent-text),
     3+ hardcoded var(--green-dark), and 3 competing destructive-hover tones. */
  /* V138 untangle: was `var(--accent-text)` self-reference, which fell
     through to inherited navy on every callsite. The intent across
     ~14 consumers (Log charge CTA, Manage button, prof-seg active,
     decision-helper, Got-extra, avalanche/snowball badges, invoice
     Save CTA, debt-card back-face data, lock-screen eyebrow/name/
     tagline, lock-screen CTA bg) is consistently "cream on vermilion"
     or "cream on navy". A single cream token serves all of them. The
     lock-screen CTA bg (background:var(--accent-text)) becomes a cream
     button — readable against the navy inner arch it sits on. */
  --accent-text:#F4EFE6;                  /* cream — text/icons on accent (vermilion or navy) fills */
  --accent-hover:#C8351A;      /* slightly darker vermilion for :hover */
  --navy:#1B3367;
  /* V160 — tinted bgs aliased to neutral editorial surfaces. */
  --navy-bg:var(--ot-surf,#FFFFFF);
  --navy-soft:var(--ot-surf,#FFFFFF);
  --navy-hover:#162E54;        /* deeper navy for :hover on navy buttons */
  /* positive money — muted forest, calm. Foreground color stays for
     "paid" / "filled" / income semantics. Background tints aliased. */
  --green:#246347;           /* V219 a11y — was #2E7D5B (4.36:1 with cream text); now 6.2:1 */
  --green-bg:var(--ot-surf,#FFFFFF);
  --green-light:var(--ot-bd,#E5E0D4);
  --green-dark:#226343;                  /* V138 untangle: was self-reference; darker forest for :hover on green buttons */
  /* negative money — dusty red, STATE only (overdue, debt amounts).
     V160 — bg tint now a very subtle vermilion wash; light border
     a soft vermilion hairline. Tinted "overdue" cards become quietly
     accented instead of red-tinted-panel loud. */
  --red:#B23A48;
  --red-bg:rgba(232,74,26,0.04);
  --red-light:rgba(232,74,26,0.30);
  --red-hover:#8E2C38;         /* destructive :hover (kept for legacy callers) */
  /* warning — warm amber, STATE only. V160 — bg/light aliased neutral. */
  --orange:#955718;          /* V219 a11y — was #C97B2E (2.9:1 on cream); now 5:1 */
  --orange-bg:var(--ot-surf,#FFFFFF);
  --orange-light:var(--ot-bd,#E5E0D4);
  /* celebration only (debt-free, paid-off card) */
  --gold:#B8944D;
  /* Brand wordmark — change here to rebrand globally. */
  --brand-name-1:'Saava';
  --brand-name-2:'Savings';
  /* shape — Saava editorial: sharp corners everywhere except the
     drag-handle on bottom-sheet modals (kept slightly rounded on mobile
     to signal "this is a sheet") and avatar circles (kept full-pill). */
  --radius:0;            /* cards — was 12, now sharp */
  --radius-sm:0;         /* small cards — was 8, now sharp */
  --radius-xs:0;         /* inputs — was 6, now sharp */
  --radius-modal:0;      /* modal desktop — was 20, now sharp; mobile overrides for sheet */
  --radius-pill:0;       /* "pills" no longer rounded — editorial uses sharp tags */
  --radius-circle:50%;   /* explicit for avatar / monogram circles */
  /* V136: brief-spec named radii — the editorial canon. Three values, that's the system. */
  --r-chip:8px;          /* small interactive elements (chips, inputs, tags) */
  --r-card:18px;         /* cards, surfaces, primary CTAs */
  --r-slab:0;            /* sharp-corner editorial slabs (the dark Today block) */
  /* V136: brief-spec section rhythm tokens */
  --section-py:clamp(56px,7vw,88px);
  --section-px:clamp(24px,3vw,56px);
  /* shared shadow language — only two ramps (brief) */
  --shadow:0 1px 2px rgba(26,29,36,.04),0 8px 24px rgba(26,29,36,.06);
  --shadow-md:0 1px 2px rgba(26,29,36,.05),0 16px 40px rgba(26,29,36,.10);
  /* type */
  --font-display:"Fraunces",ui-serif,Georgia,serif;  /* V137 — hybrid font choice. Display = Fraunces (warm transitional serif) for page mastheads, h1/h2, hero numbers on editorial tabs. Inter Tight is reserved for stat-cell tabular numerals via --ot-font (scoped to .ovr-page and inherited by stat templates) — it reads precise for data. Pure Inter Tight everywhere reads as a generic startup template; pure Fraunces everywhere muddies tabular columns. Hybrid restores the editorial register the founder identified as missing in V136. */
  --font-sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-mono:"JetBrains Mono","SF Mono",Monaco,monospace;  /* Legacy. Brief: do not use; tabular-nums on Inter Tight covers all tabular needs. */
  /* Letter-spacing scale — only four values exist in the system.
     Eliminates the 6-variant chaos that made labels feel arbitrary. */
  --ls-tight:-.04em;     /* display type (italic Fraunces large) */
  --ls-normal:0;         /* body text */
  --ls-tracked:.14em;    /* small labels, tags, captions */
  --ls-cap:.28em;        /* uppercase eyebrows, masthead labels */
  /* ── Easing blueprint (animations.dev / Emil Kowalski) ──
     Named curves so each motion picks the RIGHT type, not just a
     stronger ease-out. Built-in ease-out is too weak — these are
     stronger custom variants Emil endorses. */
  --ease:cubic-bezier(0.22, 0.61, 0.36, 1);   /* legacy default, moderate ease-out */
  --ease-out:cubic-bezier(0.16, 1, 0.3, 1);   /* strong ease-out: enter/exit (modals, dropdowns, page entry) */
  --ease-in-out:cubic-bezier(0.83, 0, 0.17, 1); /* strong ease-in-out: morphing on-screen (tab indicator, Dynamic Island) */
  --ease-drawer:cubic-bezier(0.32, 0.72, 0, 1); /* Vaul/iOS sheet curve — only for bottom drawers */
  --ease-bounce:cubic-bezier(0.34, 1.56, 0.64, 1); /* subtle overshoot — rare, for emphasis */
  --ease-hover:ease;                          /* built-in ease for hover/color/bg — gentler, elegant */
  --dur-fast:180ms;
  --dur-mid:280ms;
  --dur-slow:480ms;
}

/* ── Base ──────────────────────────────────── */
body{font-family:var(--font-sans);background:var(--bg);color:var(--text);font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;font-optical-sizing:auto}
#wrap{min-height:100vh}
/* Display serif on first-class headings — the "this isn't a bank" cue. */
h1,h2,.hn,.hero-num,.disp{font-family:var(--font-display);font-optical-sizing:auto;letter-spacing:-.01em}
/* Tabular numerals everywhere money lives — keeps columns aligned. */
.mono,[data-tabular],.t3 td,.t3 th{font-variant-numeric:tabular-nums}

/* Phase 1 a11y — Larger Text mode. Scales root font ~12% / ~22% so all
   relative units bump proportionally without touching inline styles. The body
   uses px so we override that explicitly. */
html[data-text-size="lg"] body{font-size:15px}
html[data-text-size="xl"] body{font-size:16px;line-height:1.6}
html[data-text-size="lg"]{font-size:112.5%}
html[data-text-size="xl"]{font-size:122%}

/* ── Settings styling (V168) ────────────────────────────────────────
   The V165 left-rail grid layout is gone in V168. Settings is now a
   five-page section — Profile, Setup, Sources, Sync, Advanced — and the
   top sub-tabs strip (.sub-tabs-bar) handles the routing. Each settings
   page flows like Plan / Pay / History inside the standard 1280px content
   cage; the internal .set-tabs nav from renderSettings is now hidden
   inside any pg-profile/setup/sources/sync/advanced container since the
   forceView arg strips it from the output, and we never render the
   combined view on the new routes. */
.set-section{padding-left:0}
.set-h{margin-bottom:32px;padding-top:0}
.set-h::before{display:none}
.set-h-title{padding-top:0;font-size:32px;line-height:1.05}

/* ════════════════════════════════════════════════════════════════════
   V184 — Editorial vibes refresh for Profile + Sources sub-pages.
   User feedback: "i love the visual vibes of the overview page and
   want that all accross every page. profile page and sources page is
   not visually appealing at all and doesnt match the vibe of overview".
   The strategy: keep the existing renderSettings HTML structure but
   layer editorial styling on top — bigger section heads with italic
   vermilion accents, card-wrapped row groups, more breathing room,
   cinematic Fraunces title in the section header.
   ════════════════════════════════════════════════════════════════════ */

/* The page wrapper title — use editorial Fraunces with italic accent
   instead of the boxy Inter Tight. Matches the Overview hero feel. */
/* V191 — match the page-mast title tuning (single Inter Tight family,
   bolder, larger, signature -0.035em tracking). */
#pg-profile .set-h-title,
:is(#pg-sources, #pg-sync, #pg-advanced) .set-h-title,
#pg-setup .set-h-title,
#pg-sync .set-h-title,
#pg-advanced .set-h-title{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:clamp(36px,4vw,52px);
  font-weight:700;
  letter-spacing:-0.035em;
  line-height:1.05;
  color:var(--ot-ink,#0E1116);
}
#pg-profile .set-h-sub,
:is(#pg-sources, #pg-sync, #pg-advanced) .set-h-sub,
#pg-setup .set-h-sub,
#pg-sync .set-h-sub,
#pg-advanced .set-h-sub{
  font-family:var(--ot-font);
  font-size:14px;
  color:var(--ot-t2,#5F6470);
  margin-top:10px;
  max-width:60ch;
  line-height:1.55;
}

/* Section heads — replace the tiny tracked label with a real editorial
   eyebrow + italic vermilion accent, matching .ed-eyebrow on Overview's
   spending / scenarios cards. Drops the divider underneath since the
   card wrapping below provides natural separation. */
#pg-profile .prof-section-head,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-section-head{
  display:block;
  margin:48px 0 14px;
  padding-bottom:0;
  border-bottom:none;
  font-family:'Fraunces',serif;
  font-size:24px;
  font-weight:600;
  letter-spacing:-0.015em;
  line-height:1.15;
  color:var(--ot-ink,#0E1116);
}
#pg-profile .prof-bar,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-bar{display:none}
#pg-profile .prof-section-title,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-section-title{
  font-family:inherit;
  font-size:inherit;
  font-weight:inherit;
  letter-spacing:inherit;
  text-transform:none;
  color:inherit;
}
/* Add a quiet italic vermilion accent to the last word of every section
   title. Pure CSS — works for "Account & security", "Preferences",
   "Notifications", "Data partitions", "About". User upgrade is purely
   visual; no HTML rewrite needed. */
#pg-profile .prof-section-head .prof-section-title::after,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-section-head .prof-section-title::after{
  content:'.';
  color:var(--ot-ver,#D8431B);
  font-style:italic;
}

/* Identity hero — cinematic upgrade. Was a thin bar+avatar+name row.
   Now a proper editorial card with rounded corners, soft shadow, and
   a vermilion accent that reads like the Overview debt cards. */
#pg-profile .prof-hero{
  display:flex;align-items:center;gap:20px;
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  box-shadow:var(--shadow-soft,0 1px 0 rgba(14,17,22,.02),0 12px 32px rgba(14,17,22,.04));
  padding:28px 32px;
  margin-bottom:48px;
  position:relative;
  overflow:hidden;
}
/* Replace the 3px vermilion side-stripe with a top-edge stripe to keep
   it on-brand (the codebase's 3px vermilion topbar stripe is a brand
   non-negotiable; mirroring it on the hero ties the page to the app). */
#pg-profile .prof-hero::before{
  content:'';
  position:absolute;
  top:0;left:0;right:0;
  height:3px;
  background:var(--ot-ver,#D8431B);
}
#pg-profile .prof-hero-avatar{
  width:72px;height:72px;
  border-radius:50%;
  font-size:28px;
}
#pg-profile .prof-hero-name{
  font-family:'Fraunces',serif;
  font-size:26px;
  font-weight:600;
  letter-spacing:-0.015em;
  color:var(--ot-ink,#0E1116);
}
#pg-profile .prof-hero-meta{
  font-size:13px;
  color:var(--ot-t2,#5F6470);
  margin-top:4px;
}

/* Row groups — wrap each .prof-rows container in editorial card chrome
   so settings rows feel like part of a magazine spread, not a system
   table. Adds rounded corners, soft shadow, generous padding, and
   replaces tight 10px row padding with 16px. */
#pg-profile .prof-rows,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-rows{
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  box-shadow:var(--shadow-soft,0 1px 0 rgba(14,17,22,.02),0 12px 32px rgba(14,17,22,.04));
  overflow:hidden;
  margin-bottom:24px;
}
#pg-profile .prof-row,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-row{
  padding:16px 22px;
  font-size:14px;
  border-bottom-color:var(--ot-bd,#E5E0D4);
  transition:background 180ms ease;
}
#pg-profile .prof-row:hover,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-row:hover{
  background:rgba(232,74,26,0.025);
}
#pg-profile .prof-row-label,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-row-label{
  font-family:var(--ot-font);
  font-size:11px;
  font-weight:600;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ot-t3,#9CA0AA);
}
#pg-profile .prof-row-value,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-row-value{
  font-family:var(--ot-font);
  font-size:14px;
  font-weight:500;
  color:var(--ot-ink,#0E1116);
}
#pg-profile .prof-row-action,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-row-action{
  font-family:var(--ot-font);
  font-size:11px;
  font-weight:700;
  letter-spacing:.10em;
  text-transform:uppercase;
  color:var(--ot-ver,#D8431B);
  padding:6px 10px;
  border-radius:6px;
  transition:background 180ms ease,color 180ms ease;
}
#pg-profile .prof-row-action:hover,
:is(#pg-sources, #pg-sync, #pg-advanced) .prof-row-action:hover{
  background:rgba(232,74,26,0.06);
}

/* Page container padding — let the editorial layout breathe like
   Overview. Was 0 inherited from .pg defaults; now a generous reading
   width with consistent horizontal padding matching the Overview cards. */
#pg-profile .set-section,
:is(#pg-sources, #pg-sync, #pg-advanced) .set-section{
  max-width:var(--ovr-col,1200px);
  margin:0 auto;
  padding:0 28px 80px;
}
@media(min-width:900px){
  #pg-profile .set-section,
  :is(#pg-sources, #pg-sync, #pg-advanced) .set-section{
    padding:0 clamp(32px,5vw,80px) 100px;
  }
}
/* Tighten section heads' first occurrence so it doesn't double up
   with the page mast. */
#pg-profile .set-section > .prof-section-head:first-of-type,
:is(#pg-sources, #pg-sync, #pg-advanced) .set-section > .prof-section-head:first-of-type{
  margin-top:8px;
}
/* V185 — Preferences Save bar. Hidden by default; the .dirty class is
   added by _velaStagePref when the user changes any of currency / date
   format / week start. Designed as a sticky island below the prefs
   card so the user can't miss it without overshadowing the page. */
.vela-pref-savebar{
  display:none;
  margin:18px 0 32px;
  padding:16px 22px;
  background:rgba(232,74,26,0.06);
  border:1px solid rgba(232,74,26,0.25);
  border-left:3px solid var(--ot-ver,#D8431B);
  border-radius:var(--r-card,18px);
  align-items:center;
  justify-content:space-between;
  gap:14px;
  flex-wrap:wrap;
  animation:saava-savebar-in 220ms cubic-bezier(0.22,0.61,0.36,1);
}
.vela-pref-savebar.dirty{display:flex}
@keyframes saava-savebar-in{
  from{opacity:0;transform:translateY(6px)}
  to  {opacity:1;transform:translateY(0)}
}
.vela-pref-savebar .pref-savebar-msg{
  font-family:var(--ot-font);
  font-size:13px;color:var(--ot-ink,#0E1116);
  line-height:1.45;
}
.vela-pref-savebar .pref-savebar-msg em{
  font-family:'Fraunces',serif;font-style:italic;
  font-weight:600;color:var(--ot-ver,#D8431B);
}
.vela-pref-savebar .pref-savebar-actions{
  display:flex;gap:10px;flex-shrink:0;align-items:center;
}
.vela-pref-savebar .pref-cancel,
.vela-pref-savebar .pref-save{
  font-family:var(--ot-font);
  font-size:12px;font-weight:600;letter-spacing:.04em;
  padding:9px 18px;
  border-radius:var(--r-chip,8px);
  cursor:pointer;
  transition:transform 160ms ease,background 160ms ease,box-shadow 160ms ease;
}
.vela-pref-savebar .pref-cancel{
  background:transparent;
  color:var(--ot-t2,#5F6470);
  border:1px solid var(--ot-bd,#E5E0D4);
}
.vela-pref-savebar .pref-cancel:hover{
  color:var(--ot-ink,#0E1116);
  border-color:var(--ot-t2,#5F6470);
}
.vela-pref-savebar .pref-save{
  background:var(--ot-ver,#D8431B);
  color:var(--ot-bg,#F5F1E8);
  border:1px solid var(--ot-ver,#D8431B);
  box-shadow:0 1px 0 rgba(14,17,22,.04),0 4px 12px rgba(232,74,26,.18);
}
.vela-pref-savebar .pref-save:hover{
  transform:translateY(-1px);
  box-shadow:0 1px 0 rgba(14,17,22,.04),0 6px 16px rgba(232,74,26,.28);
}
@media(max-width:540px){
  .vela-pref-savebar{flex-direction:column;align-items:stretch}
  .vela-pref-savebar .pref-savebar-actions{justify-content:flex-end}
}
/* ════════════════════════════════════════════════════════════════════
   V186 — Sources page editorial overlay.
   User feedback: "sources and profile pages still not visually good".
   The Sources page uses .sec / .csm / .bp / .btn / .br2 / .inf classes
   that my v185 .prof-* overlay didn't touch. This block restyles them
   ONLY within :is(#pg-sources, #pg-sync, #pg-advanced) so the rest of the app is untouched.
   Goal: match Overview's premium card vibe — rounded surfaces, soft
   shadow, italic vermilion accents, generous breathing room. No more
   tan info banners, no more cheap outlined buttons.
   ════════════════════════════════════════════════════════════════════ */

/* Page container — centered max-width layout matching Profile + Overview */
:is(#pg-sources, #pg-sync, #pg-advanced){
  background:var(--ot-bg,#F5F1E8);
}
:is(#pg-sources, #pg-sync, #pg-advanced) > *{
  max-width:var(--ovr-col,1200px);
  margin-left:auto;
  margin-right:auto;
  padding-left:clamp(24px,3vw,56px);
  padding-right:clamp(24px,3vw,56px);
}

/* Section eyebrows — replace the tiny gray uppercase + tiny dark pill
   with editorial heading rows: serif title on left, ghost CTA on right. */
:is(#pg-sources, #pg-sync, #pg-advanced) .sec{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:16px;
  margin:48px 0 18px;
  padding:0 4px;
  border:none;
  font-family:'Fraunces',serif;
  font-size:24px;
  font-weight:600;
  letter-spacing:-0.015em;
  line-height:1.15;
  color:var(--ot-ink,#0E1116);
  text-transform:none;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .sec > span:first-child{
  position:relative;
}
/* Italic vermilion accent at the end of every section title */
:is(#pg-sources, #pg-sync, #pg-advanced) .sec > span:first-child::after{
  content:'.';
  color:var(--ot-ver,#D8431B);
  font-style:italic;
}
/* The + Add button on the right side of each .sec */
:is(#pg-sources, #pg-sync, #pg-advanced) .sec .bp{
  font-family:var(--ot-font);
  font-size:11px !important;
  font-weight:600;
  letter-spacing:.10em;
  text-transform:uppercase;
  padding:9px 14px !important;
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  border:1px solid var(--ot-ink,#0E1116);
  border-radius:var(--r-chip,8px);
  cursor:pointer;
  transition:transform 160ms ease,box-shadow 160ms ease;
  box-shadow:0 1px 0 rgba(14,17,22,.04),0 4px 12px rgba(14,17,22,.12);
}
:is(#pg-sources, #pg-sync, #pg-advanced) .sec .bp:hover{
  transform:translateY(-1px);
  box-shadow:0 1px 0 rgba(14,17,22,.04),0 6px 16px rgba(14,17,22,.18);
}

/* Item cards (.csm) — was a tight bordered row; now an editorial card
   with rounded corners, soft shadow, and generous padding. */
:is(#pg-sources, #pg-sync, #pg-advanced) .csm{
  background:var(--ot-surf,#FFFFFF) !important;
  border:0.5px solid var(--ot-bd,#E5E0D4) !important;
  border-radius:var(--r-card,18px) !important;
  box-shadow:var(--shadow-soft,0 1px 0 rgba(14,17,22,.02),0 12px 32px rgba(14,17,22,.04));
  padding:20px 26px !important;
  margin-bottom:12px !important;
  transition:border-color 200ms ease,transform 200ms ease;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm:hover{
  border-color:rgba(232,74,26,0.25) !important;
}

/* Info banners (.inf) — was a tan box that looked like a build warning.
   Now a quiet vermilion-accent note matching the editorial language. */
:is(#pg-sources, #pg-sync, #pg-advanced) .inf{
  background:rgba(232,74,26,0.04) !important;
  border:1px solid rgba(232,74,26,0.18) !important;
  border-left:3px solid var(--ot-ver,#D8431B) !important;
  border-radius:10px !important;
  padding:14px 18px !important;
  margin:12px 0 18px !important;
  font-family:var(--ot-font);
  font-size:13px !important;
  color:var(--ot-ink,#0E1116) !important;
  line-height:1.55 !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .inf strong{color:var(--ot-ink,#0E1116);font-weight:600}
:is(#pg-sources, #pg-sync, #pg-advanced) .inf em{
  font-family:'Fraunces',serif;
  font-style:italic;
  color:var(--ot-ver,#D8431B);
  font-weight:600;
}

/* Item content — make the name/type lines feel more editorial */
:is(#pg-sources, #pg-sync, #pg-advanced) .csm > div > div:first-child > div:first-child{
  font-family:var(--ot-font);
  font-size:15px !important;
  font-weight:600 !important;
  color:var(--ot-ink,#0E1116) !important;
  line-height:1.3;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm > div > div:first-child > div:nth-child(2){
  font-size:12px !important;
  color:var(--ot-t3,#9CA0AA) !important;
  margin-top:4px !important;
  font-weight:500;
}

/* Up/down reorder buttons — were tiny gray boxes with arrows. Make
   them ghost icon buttons that look intentional. */
:is(#pg-sources, #pg-sync, #pg-advanced) .csm button[onclick^="moveIncome"]{
  background:transparent !important;
  border:1px solid var(--ot-bd,#E5E0D4) !important;
  border-radius:6px !important;
  width:24px !important;
  height:22px !important;
  color:var(--ot-t3,#9CA0AA) !important;
  cursor:pointer;
  transition:border-color 160ms ease,color 160ms ease;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm button[onclick^="moveIncome"]:not(:disabled):hover{
  border-color:var(--ot-ver,#D8431B) !important;
  color:var(--ot-ver,#D8431B) !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm button[onclick^="moveIncome"]:disabled{
  opacity:.35 !important;
  cursor:default !important;
}

/* Edit / Remove buttons (.btn / .br2) — were tiny outlined boxes that
   felt cheap. Now editorial action buttons matching .prof-row-action. */
:is(#pg-sources, #pg-sync, #pg-advanced) .csm .btn,
:is(#pg-sources, #pg-sync, #pg-advanced) .csm .br2{
  font-family:var(--ot-font) !important;
  font-size:11px !important;
  font-weight:700 !important;
  letter-spacing:.08em !important;
  text-transform:uppercase !important;
  padding:8px 14px !important;
  border-radius:8px !important;
  cursor:pointer;
  transition:background 180ms ease,color 180ms ease,border-color 180ms ease;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm .btn{
  background:transparent !important;
  color:var(--ot-ink,#0E1116) !important;
  border:1px solid var(--ot-bd,#E5E0D4) !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm .btn:hover{
  background:var(--ot-ink,#0E1116) !important;
  color:var(--ot-bg,#F5F1E8) !important;
  border-color:var(--ot-ink,#0E1116) !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm .br2{
  background:transparent !important;
  color:var(--ot-t2,#5F6470) !important;
  border:1px solid var(--ot-bd,#E5E0D4) !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm .br2:hover{
  color:var(--ot-ver,#D8431B) !important;
  border-color:var(--ot-ver,#D8431B) !important;
}

/* Subtle frequency chip (BI-WEEKLY, 1ST & 15TH) — was a flat bordered
   box; bump to a refined pill */
:is(#pg-sources, #pg-sync, #pg-advanced) .csm span[style*="background:var(--surface2)"][style*="border-radius:0"]{
  border-radius:999px !important;
  background:rgba(14,17,22,0.05) !important;
  color:var(--ot-t2,#5F6470) !important;
  border:1px solid transparent !important;
  padding:3px 9px !important;
  font-size:9px !important;
  letter-spacing:.10em !important;
}

/* Account totals grid (Liquid / Assets / Net worth) — was a tan box
   with a dense grid. Lift it into a proper editorial card. */
:is(#pg-sources, #pg-sync, #pg-advanced) .csm[style*="grid-template-columns:1fr 1fr 1fr"]{
  background:var(--ot-surf,#FFFFFF) !important;
  border:0.5px solid var(--ot-bd,#E5E0D4) !important;
  border-radius:var(--r-card,18px) !important;
  box-shadow:var(--shadow-soft,0 1px 0 rgba(14,17,22,.02),0 12px 32px rgba(14,17,22,.04));
  padding:8px 0 !important;
  margin-bottom:14px !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm[style*="grid-template-columns:1fr 1fr 1fr"] > div{
  padding:18px 24px !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm[style*="grid-template-columns:1fr 1fr 1fr"] > div > div:first-child{
  font-family:var(--ot-font);
  font-size:10px !important;
  letter-spacing:.14em !important;
  color:var(--ot-t3,#9CA0AA) !important;
  text-transform:uppercase;
  margin-bottom:6px !important;
}
:is(#pg-sources, #pg-sync, #pg-advanced) .csm[style*="grid-template-columns:1fr 1fr 1fr"] > div > div:nth-child(2){
  font-family:'Inter Tight','Inter',sans-serif;
  font-size:22px !important;
  font-weight:600 !important;
  color:var(--ot-ink,#0E1116);
  letter-spacing:-0.015em;
}
/* V186 — Sources automation actions row. Forced to 4 columns on desktop
   in the inline style; this media query stacks them to 2-up on tablets
   and 1-up on narrow phones so the labels don't crush. */
@media(max-width:900px){
  :is(#pg-sources, #pg-sync, #pg-advanced) .vela-src-actions{
    grid-template-columns:repeat(2,minmax(0,1fr)) !important;
  }
}
@media(max-width:520px){
  :is(#pg-sources, #pg-sync, #pg-advanced) .vela-src-actions{
    grid-template-columns:1fr !important;
  }
}
/* End V186 Sources overlay ───────────────────────────────────────── */

/* ════════════════════════════════════════════════════════════════════
   V186 — Editorial overlay for HST · Income Tax · Savings · Invoice.
   These pages already use .ed-card and editorial typography in their
   modern sections (V160+ rewrites), but their action rows still use
   the cramped .bp/.btn/.br2 buttons and the page titles render via
   _velaPageMast which the global rule sized at 24px Inter Tight. This
   block lifts the page titles to Fraunces serif (matching Overview's
   hero feel) and polishes the action-row buttons.
   ════════════════════════════════════════════════════════════════════ */

/* Page titles via _velaPageMast on these tabs — Fraunces editorial */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast{
  /* V191 — back to generous hero-scale padding to match the bigger title. */
  padding:48px 24px 20px;
  max-width:var(--ovr-col,1200px);
  margin:0 auto;
}
/* V191 — single-font-family approach. Mixing Inter Tight sans + Fraunces
   serif italic at the same size created visual jank (the italic word
   looked like it was from a different system). User feedback: "still
   shit on all pages. also too small." Going BIGGER and using Inter Tight
   throughout — italic vermilion via the SAME font's italic variant
   instead of a serif foreign body. This is the simpler, more confident
   editorial gesture. */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast-title{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif !important;
  font-size:clamp(36px,4vw,52px) !important;
  font-weight:700 !important;
  letter-spacing:-0.035em !important;
  line-height:1.05 !important;
  color:var(--ot-ink,#0E1116) !important;
  text-wrap:balance;
  max-width:780px;
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast-title em{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif !important;
  font-style:italic !important;
  font-weight:700 !important;
  color:var(--ot-ver,#D8431B) !important;
  font-size:1em !important;
  letter-spacing:-0.04em !important;
}
/* Reveal the eyebrow (the parent rule hides it). Use italic vermilion.
   V190 — tightened to 10px / 10px-margin to feel like a label, not
   compete with the title. */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast-eyebrow{
  display:block !important;
  font-family:var(--ot-font);
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  font-weight:700;color:var(--ot-ver,#D8431B);
  margin-bottom:10px;
}
/* V188 — removed the ::after period accent. All the _velaPageMast
   titles already END with a period ("Cash flow.", "Income tax owing.",
   etc.), so the ::after produced double-dots ("Cash flow..", "owing.."
   visible in the screenshot). The italic vermilion now lives on the
   <em> word inside the title (handled by the rule above) instead. */
/* Reveal the subtitle line. V190 — slightly smaller for proper rhythm
   below the smaller title. */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast-sub{
  display:block !important;
  font-family:var(--ot-font);
  font-size:13px;
  color:var(--ot-t2,#5F6470);
  margin-top:8px;
  max-width:56ch;
  line-height:1.55;
}
@media(max-width:640px){
  :is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast{
    padding:28px 20px 14px;
  }
  :is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) .pg-mast-title{
    font-size:clamp(28px,7vw,38px) !important;
  }
}

/* Page content max-width centered to match Overview/Profile.
   V187 fix: use > * and !important so inline `margin: ...` shorthands
   (which were resetting margin-left/right to 0) can't kill the centering.
   Box-sizing ensures any horizontal padding is contained inside the 980. */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > *{
  max-width:var(--ovr-col,1200px) !important;
  margin-left:auto !important;
  margin-right:auto !important;
  box-sizing:border-box;
}
/* The Year-end export row needs explicit horizontal padding to align
   with .pg-mast's 24px content edge (otherwise it visually slips to
   the left of the title because flex-end pushes content right but the
   container starts at x=0). */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > .vela-yearend-row{
  padding-left:24px;
  padding-right:24px;
}

/* Action row buttons (.bp / .btn / .br2) outside of inputs/cards.
   Used by HST's "+ Batch invoices / Log payment" row and Income Tax
   payment row. Bumped to editorial action-button size. */
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .bp,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .bp,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .btn,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .btn,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .br2,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .br2{
  font-family:var(--ot-font) !important;
  font-size:11px !important;
  font-weight:700 !important;
  letter-spacing:.08em !important;
  text-transform:uppercase !important;
  padding:9px 14px !important;
  border-radius:8px !important;
  cursor:pointer;
  transition:transform 160ms ease,background 160ms ease,color 160ms ease,box-shadow 160ms ease;
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .bp,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .bp{
  background:var(--ot-ink,#0E1116) !important;
  color:var(--ot-bg,#F5F1E8) !important;
  border:1px solid var(--ot-ink,#0E1116) !important;
  box-shadow:0 1px 0 rgba(14,17,22,.04),0 4px 12px rgba(14,17,22,.12);
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .bp:hover,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .bp:hover{
  transform:translateY(-1px);
  box-shadow:0 1px 0 rgba(14,17,22,.04),0 6px 16px rgba(14,17,22,.18);
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .btn,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .btn{
  background:transparent !important;
  color:var(--ot-ink,#0E1116) !important;
  border:1px solid var(--ot-bd,#E5E0D4) !important;
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .btn:hover,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .btn:hover{
  background:var(--ot-ink,#0E1116) !important;
  color:var(--ot-bg,#F5F1E8) !important;
  border-color:var(--ot-ink,#0E1116) !important;
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .br2,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .br2{
  background:transparent !important;
  color:var(--ot-t2,#5F6470) !important;
  border:1px solid var(--ot-bd,#E5E0D4) !important;
}
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > div > .br2:hover,
:is(#pg-cra, #pg-income_tax, #pg-savings, #pg-invoice, #pg-plan, #pg-execute, #pg-history, #pg-3mo, #pg-timeline, #pg-cashflow) > section > .br2:hover{
  color:var(--ot-ver,#D8431B) !important;
  border-color:var(--ot-ver,#D8431B) !important;
}
/* End V186 HST/Tax/Savings/Invoice overlay ─────────────────────────── */

/* End V184 editorial refresh ─────────────────────────────────────── */

/* V127 Phase E: Settings section tabs unified with the rest of the
   app's editorial filled-pill pattern. Was a row of tabs with a
   `border-bottom: 3px solid var(--accent)` underline on active (the
   bottom-stripe variant of the banned side-stripe pattern). Now
   pill buttons with an ink+cream active state, like Plan/History/
   Timeline toggles. */
.set-tabs{
  display:flex;flex-wrap:wrap;gap:8px;margin-bottom:24px;
  background:transparent;border:none;
  padding:0;
  overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.set-tabs::-webkit-scrollbar{display:none}
.set-tab{
  flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:12px 16px;
  border:0.5px solid var(--ot-bd);
  background:transparent;
  font-family:var(--ot-font);font-size:13px;font-weight:600;
  color:var(--ot-ink);
  border-radius:var(--r-chip);
  cursor:pointer;white-space:nowrap;
  letter-spacing:0.04em;
  transition:background 200ms ease,color 200ms ease,border-color 200ms ease;
}
.set-tab svg{flex-shrink:0;color:var(--ot-t2)}
@media (hover: hover) and (pointer: fine){
  .set-tab:hover{border-color:var(--ot-ink)}
  .set-tab:hover svg{color:var(--ot-ink)}
}
.set-tab.on{
  background:var(--ot-ink);
  color:var(--ot-bg);
  border-color:var(--ot-ink);
}
.set-tab.on svg{color:var(--ot-bg)}
.set-section{animation:fadeIn 240ms var(--ease)}
/* Editorial section hero */
.set-h{
  margin-bottom:24px;padding-bottom:18px;
  border-bottom:1px solid var(--border-strong);
  position:relative;
}
.set-h::before{
  content:'';position:absolute;top:-8px;left:0;
  width:40px;height:4px;background:var(--accent);
}
.set-h-title{
  font-family:var(--font-display);
  font-size:34px;font-weight:600;letter-spacing:-.02em;
  color:var(--navy);line-height:1.05;
  padding-top:14px;
}
.set-h-sub{font-size:13px;color:var(--text2);margin-top:6px;line-height:1.5}

/* Phase 1 — Settings accordion. Native <details> with custom-styled summaries. */
.acc-group{background:var(--surface);border:1px solid var(--border);border-radius:12px;margin-bottom:10px;overflow:hidden}
.acc-group>summary{list-style:none;cursor:pointer;padding:14px 18px;font-size:14px;font-weight:700;color:var(--text);display:flex;align-items:center;justify-content:space-between;gap:8px;user-select:none}
.acc-group>summary::-webkit-details-marker{display:none}
.acc-group>summary::after{content:'▾';color:var(--text3);font-size:12px;transition:transform .2s}
.acc-group[open]>summary::after{transform:rotate(180deg)}
.acc-group>summary:hover{background:var(--surface2)}
.acc-group>summary .acc-icon{font-size:16px;margin-right:10px;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;color:var(--text2)}
.acc-group>summary .acc-icon svg{width:18px;height:18px;display:block}
.acc-group.danger>summary .acc-icon{color:var(--red)}
.acc-group>summary .acc-sub{font-size:11px;font-weight:500;color:var(--text3);margin-left:auto;margin-right:10px}
.acc-body{padding:6px 14px 16px;border-top:1px solid var(--border)}
.acc-body .sec{margin-top:14px}
.acc-body .sec:first-child{margin-top:4px}
.acc-group.danger>summary{color:var(--red,#dc2626)}
.acc-group.danger{border-color:#fecaca}

/* ── Profile page (Saava — full-app account hub) ────────────────────── */
/* Identity hero — avatar circle + name + member-since + primary action */
.prof-hero{
  display:flex;align-items:center;gap:14px;
  background:var(--surface);
  border:1px solid var(--border-strong);
  padding:18px 18px;margin-bottom:24px;
  position:relative;
}
.prof-hero::before{
  content:'';position:absolute;top:-1px;left:-1px;
  width:48px;height:3px;background:var(--accent);
}
.prof-hero-avatar{
  width:56px;height:56px;flex-shrink:0;
  background:var(--accent);color:var(--accent-text);
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-weight:700;font-style:italic;
  font-size:22px;letter-spacing:-.04em;
  overflow:hidden;
}
.prof-hero-avatar img{width:100%;height:100%;object-fit:cover;display:block}
.prof-hero-body{flex:1;min-width:0}
.prof-hero-name{
  font-family:var(--font-sans);font-size:17px;font-weight:700;
  color:var(--navy);letter-spacing:-.01em;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.prof-hero-meta{
  font-size:12px;color:var(--text2);margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.prof-hero-meta span{color:var(--text3)}
.prof-hero-actions{flex-shrink:0}
@media(max-width:520px){
  .prof-hero{flex-wrap:wrap}
  .prof-hero-actions{flex-basis:100%;margin-top:6px}
  .prof-hero-actions .hero-cta{width:100%;justify-content:center}
}

/* Section headers — vermilion bar + tracked uppercase title */
.prof-section-head{
  display:flex;align-items:center;gap:10px;
  margin:24px 0 12px;
  padding-bottom:8px;
  border-bottom:1px solid var(--border);
}
.prof-bar{display:inline-block;width:18px;height:3px;background:var(--accent);flex-shrink:0}
.prof-section-title{
  font-family:var(--font-sans);
  font-size:11px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  color:var(--navy);
}

/* Setting rows — label/value/action layout, hairline separators.
   Tightened: label column is content-width (auto, capped) so short
   labels like "APP" don't reserve 140px of dead space. Vertical padding
   trimmed to 10px so rows breathe without bloating. */
.prof-rows{
  background:var(--surface);
  border:1px solid var(--border);
}
.prof-row{
  display:grid;
  grid-template-columns:minmax(90px,auto) 1fr auto;
  align-items:center;
  gap:12px;
  padding:10px 14px;
  border-bottom:1px solid var(--border);
  font-size:13px;
}
.prof-row:last-child{border-bottom:none}
.prof-row-label{
  font-family:var(--font-sans);
  font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text3);min-width:0;
}
.prof-row-value{
  font-family:var(--font-sans);
  font-size:13px;color:var(--text);font-weight:500;
  min-width:0;overflow:hidden;text-overflow:ellipsis;
}
.prof-row-action{
  background:none;border:none;
  font-family:var(--font-sans);font-size:11px;font-weight:700;
  color:var(--accent);cursor:pointer;
  letter-spacing:.06em;text-transform:uppercase;
  padding:4px 8px;flex-shrink:0;
  transition:color 180ms var(--ease);
}
.prof-row-action:hover{color:var(--accent-hover)}
.prof-row-action.danger{color:var(--red)}
.prof-row-action.danger:hover{color:var(--red-hover)}
.prof-row.prof-row-wide .prof-row-value{grid-column:2 / -1}
@media(max-width:520px){
  .prof-row{
    grid-template-columns:1fr;
    gap:4px;align-items:flex-start;
    padding:12px 14px;
  }
  .prof-row-action{margin-left:auto;justify-self:end}
}

/* Segmented buttons — used for text-size picker inside a row */
.prof-seg{
  font-family:var(--font-sans);font-size:11px;font-weight:600;
  padding:7px 11px;
  background:var(--surface);
  border:1px solid var(--border2);
  color:var(--text2);cursor:pointer;
  letter-spacing:.06em;text-transform:uppercase;
  transition:background 180ms var(--ease),color 180ms var(--ease);
}
.prof-seg:hover{background:var(--bg);color:var(--navy)}
.prof-seg.on{background:var(--accent);color:var(--accent-text);border-color:var(--accent)}

/* ── Profile toggles (What applies to you) — editorial, two-line, no emoji */
.prof-tog-grid{display:grid;grid-template-columns:1fr;gap:8px}
@media(min-width:560px){.prof-tog-grid{grid-template-columns:1fr 1fr}}
.prof-tog{
  /* V135 Phase F: removed `border-left: 3px solid` on .prof-tog. The
     toggle's active state is now a full ink hairline + the existing
     checkbox state — no side-stripe needed. */
  display:flex;align-items:flex-start;gap:12px;
  padding:14px 14px;
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  cursor:pointer;user-select:none;
  transition:border-color 180ms ease,background 180ms ease;
}
@media (hover: hover) and (pointer: fine){
  .prof-tog:hover{border-color:var(--ot-t2,#5F6470)}
}
.prof-tog.on{
  background:var(--ot-surf,#FFFFFF);
  border-color:var(--ot-ink,#0E1116);
}
.prof-tog input[type="checkbox"]{
  flex-shrink:0;width:18px;height:18px;margin:1px 0 0;
  cursor:pointer;accent-color:var(--accent);
}
.prof-tog .pt-body{
  display:flex;flex-direction:column;gap:3px;min-width:0;flex:1;
}
.prof-tog .pt-label{
  font-family:var(--font-sans);
  font-size:13px;font-weight:600;color:var(--navy);line-height:1.25;
  letter-spacing:-.005em;
}
.prof-tog .pt-desc{
  font-family:var(--font-sans);
  font-size:11px;font-weight:400;color:var(--text2);line-height:1.4;
}

/* V170+7 — Setup page redesign + custom confirm modal. */
.setup-hero{
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  padding:32px 28px;
  border-radius:var(--r-card,18px);
  margin-bottom:28px;
  display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap;
}
.setup-hero-eyebrow{
  font-family:var(--font-sans);font-size:10px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ot-ver,#D8431B);margin-bottom:8px;
}
/* V192 — switched to Inter Tight to match the unified title typography
   used across the rest of the app's editorial pages. */
.setup-hero-title{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:clamp(36px,4vw,52px);font-weight:700;line-height:1.05;letter-spacing:-.035em;
}
.setup-hero-title em{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-style:italic;color:var(--ot-ver,#D8431B);font-weight:700;letter-spacing:-.04em;
}
.setup-hero-sub{font-size:13px;color:rgba(255,255,255,.65);margin-top:10px;line-height:1.5;max-width:480px}
.setup-hero-stats{
  display:flex;flex-direction:column;align-items:flex-end;gap:2px;flex-shrink:0;
}
.setup-hero-stats-num{
  font-family:var(--ot-font,'Fraunces',serif);
  font-size:48px;font-weight:500;line-height:1;font-variant-numeric:tabular-nums;
  color:var(--ot-bg,#F5F1E8);letter-spacing:-.02em;
}
.setup-hero-stats-num em{font-style:italic;color:var(--ot-ver,#D8431B);font-weight:500}
.setup-hero-stats-label{
  font-size:10px;letter-spacing:.18em;text-transform:uppercase;font-weight:600;
  color:rgba(255,255,255,.5);
}
.setup-group{margin-bottom:32px}
.setup-group-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  margin-bottom:16px;padding-bottom:12px;
  border-bottom:1px solid var(--ot-bd,#E5E0D4);
}
.setup-group-title{
  font-family:var(--ot-font,'Fraunces',serif);
  font-size:22px;font-weight:500;letter-spacing:-.01em;color:var(--ot-ink,#0E1116);
}
.setup-group-title em{font-style:italic;color:var(--ot-ver,#D8431B);font-weight:500}
.setup-group-count{
  font-family:var(--font-sans);font-size:11px;font-weight:600;letter-spacing:.06em;
  color:var(--ot-t3,#9CA0AA);text-transform:uppercase;
}
.setup-group-count em{font-style:normal;color:var(--ot-ver,#D8431B);font-weight:700}

/* Custom confirm modal — replaces native confirm() */
.vela-confirm{padding:32px 32px 28px;max-width:520px}
.vela-confirm-eyebrow{
  font-family:var(--font-sans);font-size:10px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ot-ver,#D8431B);margin-bottom:14px;
  display:flex;align-items:center;gap:8px;
}
.vela-confirm-eyebrow::before{content:'';width:8px;height:8px;background:var(--ot-ver,#D8431B);display:inline-block}
.vela-confirm-title{
  font-family:var(--ot-font,'Fraunces',serif);
  font-size:clamp(24px,3vw,30px);font-weight:500;line-height:1.15;letter-spacing:-.015em;
  color:var(--ot-ink,#0E1116);margin:0 0 14px;
}
.vela-confirm-title em{font-style:italic;color:var(--ot-ver,#D8431B);font-weight:500}
.vela-confirm-body{
  font-family:var(--font-sans);font-size:14px;line-height:1.55;color:var(--ot-t2,#5F6470);
  margin:0 0 20px;
}
.vela-confirm-impact{
  border:1px solid var(--ot-bd,#E5E0D4);
  padding:14px 16px;margin-bottom:14px;border-radius:12px;
  background:var(--ot-surf,#FFFFFF);
}
.vela-confirm-impact.gain{border-color:rgba(46,125,91,0.3);background:rgba(46,125,91,0.04)}
.vela-confirm-impact.lose{border-color:rgba(232,74,26,0.3);background:rgba(232,74,26,0.04)}
.vela-confirm-impact-label{
  font-size:10px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ot-t3,#9CA0AA);margin-bottom:8px;display:flex;align-items:center;gap:6px;
}
.vela-confirm-impact.gain .vela-confirm-impact-label{color:var(--green,#2E7D5B)}
.vela-confirm-impact.lose .vela-confirm-impact-label{color:var(--ot-ver,#D8431B)}
.vela-confirm-impact ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px}
.vela-confirm-impact li{
  font-size:13px;font-weight:500;color:var(--ot-ink,#0E1116);
  display:flex;align-items:center;gap:8px;
}
.vela-confirm-impact li::before{
  content:'';width:6px;height:6px;border-radius:50%;background:currentColor;flex-shrink:0;opacity:.6;
}
.vela-confirm-actions{
  display:flex;gap:10px;justify-content:flex-end;margin-top:24px;padding-top:20px;
  border-top:1px solid var(--ot-bd,#E5E0D4);
}
.vela-confirm-cancel{
  background:transparent;border:0.5px solid var(--ot-bd,#E5E0D4);
  color:var(--ot-ink,#0E1116);font-family:var(--font-sans);font-size:12px;font-weight:600;
  letter-spacing:.06em;padding:11px 22px;cursor:pointer;border-radius:999px;
  transition:background 180ms ease,border-color 180ms ease;
}
.vela-confirm-cancel:hover{background:var(--ot-bg,#F5F1E8);border-color:var(--ot-t2,#5F6470)}
.vela-confirm-go{
  background:var(--ot-ink,#0E1116);color:var(--ot-bg,#F5F1E8);
  border:0.5px solid var(--ot-ink,#0E1116);
  font-family:var(--font-sans);font-size:12px;font-weight:600;letter-spacing:.06em;
  padding:11px 22px;cursor:pointer;border-radius:999px;
  transition:background 180ms ease,color 180ms ease;
}
.vela-confirm-go:hover{background:var(--ot-ver,#D8431B);border-color:var(--ot-ver,#D8431B)}
.vela-confirm-go.danger{background:var(--ot-ver,#D8431B);border-color:var(--ot-ver,#D8431B)}
.vela-confirm-go.danger:hover{background:#C73E15;border-color:#C73E15}
@media(max-width:520px){
  .vela-confirm{padding:24px 20px}
  .vela-confirm-actions{flex-direction:column-reverse}
  .vela-confirm-cancel,.vela-confirm-go{width:100%}
}

/* ── Statement-period cards (Saava — editorial form chrome) ───────────
   Each period is a tight strip with a vermilion left accent, a small
   uppercase header, and three properly-styled date inputs. Designed
   for mobile-first — fits on a 380px screen without overflow. */
.stmt-period{
  /* V135 Phase F: removed border-left:3px accent. The period heading
     and tabular date inputs already make this read as a discrete
     unit; the stripe was decorative. */
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  padding:14px 16px;
  margin-bottom:8px;
}
.stmt-period .sp-head{
  display:flex;justify-content:space-between;align-items:baseline;
  margin-bottom:10px;padding-bottom:8px;
  border-bottom:1px solid var(--border);
}
.stmt-period .sp-title{
  font-family:var(--font-sans);
  font-size:10px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  color:var(--navy);
}
.stmt-period .sp-tag{
  font-family:var(--font-sans);
  font-size:9px;font-weight:600;letter-spacing:.08em;color:var(--text3);text-transform:uppercase;
}
.stmt-period .sp-grid{
  display:grid;grid-template-columns:1fr 1fr;gap:10px;
}
.stmt-period .sp-cell{
  display:flex;flex-direction:column;gap:5px;
}
.stmt-period .sp-cell.full{grid-column:1 / -1}
.stmt-period .sp-cell label{
  font-family:var(--font-sans);
  font-size:9px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text3);line-height:1;
}
.stmt-period .sp-cell input[type="date"]{
  font-family:var(--font-sans);
  font-size:14px;font-weight:500;
  padding:10px 12px;
  border:1px solid var(--border2);
  border-radius:0;
  background:var(--surface);
  color:var(--navy);
  width:100%;min-width:0;
  margin:0;
  -webkit-appearance:none;appearance:none;
  /* iOS Safari shows the placeholder for empty date inputs — make it
     visible and styled consistently. */
  text-align:left;
}
.stmt-period .sp-cell input[type="date"]::-webkit-date-and-time-value{text-align:left}
.stmt-period .sp-cell input[type="date"]:focus{
  outline:none;border-color:var(--accent);
  box-shadow:0 0 0 2px var(--accent-soft);
}
.stmt-period .sp-cell input[type="date"]::placeholder{color:var(--text3);font-weight:400}
/* Number-input style — shared with the "Add statement balance" mini-form */
.sp-cell input[type="number"]{
  font-family:var(--font-mono);
  font-size:15px;font-weight:600;
  padding:10px 12px;
  border:1px solid var(--border2);
  border-radius:0;
  background:var(--surface);
  color:var(--navy);
  width:100%;min-width:0;
  margin:0;
  -webkit-appearance:none;appearance:none;
  font-variant-numeric:tabular-nums;
}
.sp-cell input[type="number"]:focus{
  outline:none;border-color:var(--accent);
  box-shadow:0 0 0 2px var(--accent-soft);
}

/* Phase 1 — Inline collapse for the debt form's "Advanced" section. */
details.adv-fold>summary{position:relative}
details.adv-fold>summary::-webkit-details-marker{display:none}
details.adv-fold>summary::after{content:'▾';position:absolute;right:14px;top:50%;transform:translateY(-50%);color:var(--text3);font-size:11px;transition:transform .2s}
details.adv-fold[open]>summary::after{transform:translateY(-50%) rotate(180deg)}
details.adv-fold>summary:hover{background:var(--surface)}

/* ── Top nav (Saava editorial — masthead composition) ────────────────
   84px tall, with a thin vermilion stripe above and a charcoal
   hairline below. Wordmark is BIG italic Fraunces — the magazine cover
   typographic move. Below the wordmark, a small uppercase tracked tag
   in vermilion (the "Savings" mark). Profile button is composed (initial
   on a navy tile, charcoal hairline, vermilion on hover). */
body{position:relative}
/* Masthead stripe — anchored to the top of the topbar (NOT body), so it
   reads as the topbar's own top edge instead of a floating red line.
   Implemented via .topbar::before so it scrolls/sticks with the bar.
   V138-rev: kept (removed in V138, reverted same release — user
   preferred the stripe as part of the brand identity). */
.topbar{
  background:var(--bg);
  border-bottom:none;
  padding:3px 24px 0;height:84px;
  display:flex;align-items:center;gap:24px;
  position:sticky;top:0;z-index:50;
}
.topbar::before{
  content:'';position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--accent);pointer-events:none;
}
.logo{
  display:flex;flex-direction:row;align-items:center;gap:10px;
  cursor:pointer;user-select:none;flex-shrink:0;line-height:1;
  transition:opacity var(--dur-fast) var(--ease);
}
.logo:hover{opacity:.82}
.logo:hover .logo-tag{color:var(--accent)}
.logo-mark{
  display:none;          /* monogram replaced with type-led wordmark */
}
.logo-glyph{
  width:26px;height:26px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
}
.logo-glyph svg{width:100%;height:100%;animation:logo-tilt 14s ease-in-out infinite}
@keyframes logo-tilt{0%,100%{transform:rotate(-12deg)}50%{transform:rotate(12deg)}}
.logo-name{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-style:normal;font-weight:700;font-size:25px;letter-spacing:-.05em;
  color:#0E1116;line-height:1;
}
.logo-name em{font-family:'Newsreader',Georgia,serif;font-style:italic;font-weight:600;color:var(--accent);letter-spacing:-.01em}
.logo-tag{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-weight:500;font-size:10px;
  letter-spacing:.28em;text-transform:uppercase;
  color:var(--accent);line-height:1;align-self:center;padding-top:2px;
  transition:color 180ms var(--ease);
  margin-left:4px;
}
@media(max-width:900px){
  .topbar{height:72px;padding:3px 18px 0}
  .logo{gap:8px}
  .logo-glyph{width:22px;height:22px}
  .logo-name{font-size:22px}
  .logo-tag{font-size:9px;letter-spacing:.24em}
}
@media(max-width:520px){
  .logo-tag{display:none}
  /* V275 — tighten the topbar on phones so the right-edge cluster
     (icons + profile) never overflows the viewport. The build chip is a
     power-user cache-reset affordance; it's hidden on small screens to
     reclaim its width (force-reset is still reachable on desktop). */
  .topbar{gap:12px;padding:3px 12px 0}
  #buildChip{display:none}
}
.saved-ind{font-size:11px;color:var(--text3)}
.saved-ind.flash{color:var(--green);font-weight:600}
/* V161 — sync-pending / sync-error states for the savedAt badge.
   Vermilion text + a leading pulsing dot to signal "your edit is not
   yet in the cloud" (the most common state when offline). */
.saved-ind.sync-pending,.saved-ind.sync-error{color:var(--ot-ver,#D8431B);font-weight:600;position:relative;padding-left:14px}
.saved-ind.sync-pending::before,.saved-ind.sync-error::before{
  content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:7px;height:7px;border-radius:50%;background:var(--ot-ver,#D8431B);
  animation:savedat-pulse 1.5s ease-in-out infinite;
}
@keyframes savedat-pulse{0%,100%{opacity:1}50%{opacity:0.4}}

/* ── Profile button (top-right) — composed initial tile ──
   Editorial: vermilion 3px top accent + navy fill + italic Fraunces
   initial. Picks up the user's first initial from Clerk via JS.
   Sharp corners on desktop, circular on mobile for thumb-friendliness. */
.profile-btn{
  width:42px;height:42px;
  background:var(--navy);color:#F5F1E8;
  border:1px solid var(--ink);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-style:italic;font-weight:700;
  font-size:18px;letter-spacing:-.04em;
  flex-shrink:0;padding:0;line-height:1;
  background-size:cover;background-position:center;
  position:relative;
  transition:transform 180ms var(--ease),background 180ms var(--ease);
}
.profile-btn::before{
  content:'';position:absolute;top:-1px;left:-1px;right:-1px;height:3px;
  background:var(--accent);
}
@media (hover: hover) and (pointer: fine){
  .profile-btn:hover{background:var(--accent);transform:translateY(-1px)}
  .profile-btn:hover::before{background:var(--navy)}
}
.profile-btn:active{transform:translateY(0)}
.profile-btn .pf-initial{pointer-events:none;font-family:var(--font-display);font-style:italic;font-weight:700}

/* ── Profile dropdown menu ───────────────────────────────────────── */
.profile-menu{
  position:absolute;top:46px;right:0;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius);
  box-shadow:var(--shadow-md);
  width:288px;max-width:calc(100vw - 28px);
  z-index:60;
  display:none;overflow:hidden;
  transform-origin:top right;
}
/* On phones the menu becomes a fixed sheet so it never clips off-screen
   no matter where the trigger sits. */
@media(max-width:520px){
  .profile-menu{
    position:fixed;
    top:auto;bottom:calc(72px + env(safe-area-inset-bottom));
    left:10px;right:10px;
    width:auto;max-width:none;max-height:70vh;
    overflow-y:auto;
    transform-origin:bottom center;
  }
}
.profile-menu.open{display:block;animation:vela-modal-in 240ms var(--ease)}
.pm-head{display:flex;align-items:center;gap:12px;padding:14px 16px;border-bottom:1px solid var(--border)}
.pm-avatar-lg{
  width:42px;height:42px;border-radius:50%;
  background:var(--accent);color:#fff;font-weight:600;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:17px;flex-shrink:0;
  background-size:cover;background-position:center;
}
.pm-name{font-weight:600;font-size:14px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pm-email{font-size:11px;color:var(--text3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px}
.pm-section{padding:6px 6px;border-bottom:1px solid var(--border)}
.pm-section:last-child{border-bottom:none}
.pm-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text3);padding:6px 10px 4px}
.pm-item{
  display:flex;align-items:center;gap:10px;
  width:100%;padding:8px 10px;
  background:none;border:none;
  font-size:13px;color:var(--text);
  font-family:inherit;text-align:left;cursor:pointer;
  border-radius:6px;
  transition:background var(--dur-fast) var(--ease);
}
.pm-item:hover{background:var(--surface2)}
.pm-item.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.pm-item .pm-icon{flex-shrink:0;width:18px;height:18px;display:inline-flex;align-items:center;justify-content:center;color:var(--text3)}
.pm-item.on .pm-icon{color:var(--accent)}
.pm-item .pm-check{margin-left:auto;font-size:14px;color:var(--accent);flex-shrink:0}
.pm-item .pm-kbd{margin-left:auto;font-size:10px;color:var(--text3);font-family:var(--font-mono);background:var(--surface2);padding:1px 5px;border-radius:4px}
.pm-item.danger{color:var(--red)}
.pm-item.danger .pm-icon{color:var(--red)}
.pm-foot{padding:10px 16px;font-size:10px;color:var(--text3);background:var(--surface2);text-align:center}
.pm-theme-row{display:flex;gap:4px;padding:0 6px 4px}
.pm-theme-btn{
  flex:1;padding:8px 4px;border:1px solid var(--border);
  background:var(--surface);border-radius:6px;cursor:pointer;
  font-size:11px;font-family:inherit;color:var(--text2);
  display:flex;flex-direction:column;align-items:center;gap:4px;
  transition:transform var(--dur-fast) var(--ease-out),background var(--dur-fast) ease,color var(--dur-fast) ease,border-color var(--dur-fast) ease;
}
.pm-theme-btn svg{color:var(--text3)}
.pm-theme-btn.on{background:var(--accent-soft);color:var(--accent);border-color:var(--accent);font-weight:600}
.pm-theme-btn.on svg{color:var(--accent)}
.pm-theme-btn:hover:not(.on){background:var(--surface2)}

/* ── Tabs INSIDE the topbar — single-row nav ──────────────────────
   The .tabs container is now a flex child of .topbar. It takes the
   center of the bar; on mobile it's hidden (bottom nav handles it). */
.tabs{
  background:transparent;border:none;padding:0;
  flex:1;min-width:0;
  display:flex;align-items:center;gap:2px;
  height:84px;
  overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;
  mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent 100%);
  -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent 100%);
}
.tabs::-webkit-scrollbar{display:none}
.tabs .tab{scroll-snap-align:start;flex-shrink:0}
@media(max-width:900px){.tabs{display:none}}
.tab{
  height:84px;padding:0 16px;
  display:inline-flex;align-items:center;
  /* V141 — strip browser default button chrome. .tab was a <button>
     element and the CSS never reset background/border, so Chrome was
     rendering each tab as a light-gray rectangle with a thin border
     ("ugly and chunky" boxes). Tabs now read as pure text labels;
     the active state is the morphing vermilion indicator below the
     row, plus the navy + bold color/weight change. */
  background:transparent;
  border:none;
  border-radius:0;
  font-family:var(--font-sans);
  font-size:12px;font-weight:600;
  color:var(--text2);cursor:pointer;
  border-bottom:none;
  white-space:nowrap;user-select:none;
  transition:color 200ms ease;
  letter-spacing:.06em;text-transform:uppercase;
  position:relative;
}
.tab:hover{color:var(--navy)}
.tab.on{color:var(--navy);font-weight:700}
/* ── Emil-style morphing tab indicator ──
   A single pill positioned absolutely under the tabs row. As the
   user switches tabs, JS updates its --tab-x and --tab-w CSS vars
   and the indicator smoothly translates + resizes via a spring
   easing. The classic Vercel / Linear / Sonner move. */
.tabs{position:relative}
.tab-indicator{
  position:absolute;
  bottom:0;
  left:0;
  height:3px;
  width:var(--tab-w,0px);
  transform:translateX(var(--tab-x,0px));
  background:var(--accent);
  border-radius:3px 3px 0 0;
  /* Tab indicator MORPHS between positions on screen — blueprint
     says ease-in-out for elements changing position/shape without
     leaving the screen. Was Vaul drawer curve (wrong type). */
  transition:transform 260ms var(--ease-in-out),
             width 260ms var(--ease-in-out);
  pointer-events:none;
  z-index:1;
  /* Hidden until JS positions it — prevents a flash at 0,0 on load */
  opacity:0;
}
.tab-indicator.ready{opacity:1}

/* ── V162 Phase 1: Section nav (4 primary sections) ──────────────
   The 10-tab strip collapsed into 4 primary sections (Money, Tax,
   Forecast, Settings). Section buttons live in the topbar where
   .tabs used to be. The sub-tab strip below the topbar shows the
   current section's pages (e.g. Plan/Pay/History under Money).
   Hash routing wires #money/plan etc. */
.sec-nav{
  background:transparent;border:none;padding:0;
  flex:1;min-width:0;
  display:flex;align-items:center;gap:4px;
  height:84px;
}
.sec-nav .sec-tab{
  height:84px;padding:0 22px;
  display:inline-flex;align-items:center;gap:8px;
  background:transparent;border:none;border-radius:0;
  font-family:var(--font-sans);
  font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text2);cursor:pointer;
  white-space:nowrap;user-select:none;
  position:relative;
  transition:color 200ms ease;
}
.sec-nav .sec-tab:hover{color:var(--navy)}
.sec-nav .sec-tab.on{color:var(--navy);font-weight:700}
.sec-nav .sec-tab.on::after{
  content:'';position:absolute;left:14px;right:14px;bottom:0;height:3px;
  background:var(--accent);border-radius:3px 3px 0 0;
}
.sec-nav .sec-tab svg{width:16px;height:16px;flex-shrink:0}
@media(max-width:900px){.sec-nav{display:none}}

/* Sub-tab strip — appears below topbar when active section has 2+ pages */
.sub-tabs-bar{
  background:var(--bg);
  border-bottom:1px solid var(--ot-bd,var(--border));
  padding:0 24px;
  position:sticky;top:84px;z-index:49;
  display:none;
}
.sub-tabs-bar.has-subs{display:block}
.sub-tabs-bar .tabs{height:44px;mask-image:none;-webkit-mask-image:none}
.sub-tabs-bar .tab{height:44px;padding:0 14px;font-size:11px;letter-spacing:.08em}
.sub-tabs-bar .tab-indicator{height:2px}
@media(max-width:900px){
  .sub-tabs-bar{top:72px;padding:0 16px}
  .sub-tabs-bar .tabs{display:flex}
  .sub-tabs-bar .tab{height:40px;font-size:10px;padding:0 12px}
}

.tab-more{position:relative}
.more-tabs-menu{
  position:absolute;top:84px;right:24px;
  background:var(--surface);
  border:1px solid var(--border-strong);
  border-radius:0;
  min-width:200px;padding:8px;
  box-shadow:0 12px 32px rgba(0,0,0,.12);
  z-index:60;display:none;
}
.more-tabs-menu.open{display:block;animation:fadeIn 180ms var(--ease)}
.mtm-item{
  display:block;width:100%;text-align:left;
  padding:11px 14px;border:none;background:transparent;
  font-family:var(--font-sans);font-size:12px;font-weight:600;
  color:var(--text2);cursor:pointer;
  letter-spacing:.06em;text-transform:uppercase;
}
.mtm-item:hover{background:var(--accent-soft);color:var(--navy)}
@media(max-width:900px){.more-tabs-menu{display:none!important}}

/* ── Mobile bottom nav (Batch 1 #20) ────── */
.bottom-nav{display:none;position:fixed;bottom:0;left:0;right:0;background:var(--surface);border-top:1px solid var(--border);padding:6px 4px calc(6px + env(safe-area-inset-bottom));z-index:60;box-shadow:0 -4px 16px rgba(0,0,0,.05)}
.bottom-nav-inner{display:flex;justify-content:space-around;align-items:stretch;max-width:500px;margin:0 auto}
.bn-item{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:7px 4px;cursor:pointer;color:var(--text3);font-size:10px;font-weight:600;user-select:none;-webkit-tap-highlight-color:transparent;border:none;background:transparent;font-family:inherit;transition:color .15s;min-height:48px;border-radius:var(--r-chip,8px)}
.bn-item:hover{color:var(--text2)}
.bn-item.on{color:var(--blue)}
.bn-item .bn-icon{font-size:19px;margin-bottom:3px;line-height:0;display:inline-flex;align-items:center;justify-content:center;height:22px}
.bn-item .bn-icon svg{width:22px;height:22px;display:block}
/* Lucide icons inherit the parent's text color, so .bn-item.on (var(--blue))
   automatically tints the icon the same way the label tints. */
.bn-more-menu{position:fixed;bottom:calc(62px + env(safe-area-inset-bottom));left:50%;transform:translateX(-50%) translateY(10px);background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:8px;box-shadow:0 16px 40px rgba(0,0,0,.15);z-index:61;display:none;min-width:200px;opacity:0;transition:opacity .2s,transform .2s}
.bn-more-menu.open{display:block;opacity:1;transform:translateX(-50%) translateY(0)}
.bn-more-menu button{display:block;width:100%;text-align:left;padding:10px 14px;background:none;border:none;font-family:inherit;font-size:13px;color:var(--text2);cursor:pointer;border-radius:var(--r-chip,8px);font-weight:500}
.bn-more-menu button:hover{background:var(--surface2);color:var(--text)}
.bn-more-menu button.on{color:var(--blue);font-weight:600;background:var(--blue-bg)}

@media(max-width:640px){
  .bottom-nav{display:block}
  .tabs{display:none}
  /* Reserve room at the bottom for BOTH the bottom-nav (~62px) AND the
     next-action-bar (~58px when shown). Without this, the bar covers
     the last card on the page and the user can't scroll past it. */
  .pg{padding-bottom:calc(170px + env(safe-area-inset-bottom))}
  .topbar{top:0}
}

/* ── Floating Action Button (Batch 1 #17) ──
   V161 — FAB now ALSO shown on mobile. The previous decision to hide
   it < 640px left the daily-driver "Log a charge" action with no
   first-class entry on the iPhone PWA (5+ taps via Pay → debt card →
   expand Edit balances → fill form). With the FAB visible, mobile
   matches desktop's 2-tap log-charge flow. Bottom-nav sits above the
   FAB so they don't overlap (FAB raised to bottom:88px on mobile). */
.fab{position:fixed;bottom:24px;right:20px;width:56px;height:56px;border-radius:50%;background:var(--accent);color:#fff;border:none;cursor:pointer;box-shadow:0 8px 24px rgba(30,58,95,.35),0 2px 6px rgba(0,0,0,.1);z-index:55;display:flex;align-items:center;justify-content:center;transition:transform var(--dur-fast) var(--ease),box-shadow var(--dur-fast) var(--ease);padding:0}
.fab:hover{transform:scale(1.05);box-shadow:0 12px 32px rgba(30,58,95,.45)}
.fab:active{transform:scale(.95)}
@media(max-width:900px){.fab{bottom:calc(72px + env(safe-area-inset-bottom));right:16px;width:52px;height:52px}}

/* ── Bulk operations bar (Phase 5 — History → Payments) ─────────────── */
.bulk-bar{
  position:fixed;
  left:50%;transform:translateX(-50%) translateY(20px);
  width:calc(100% - 28px);max-width:560px;
  background:var(--accent);color:#fff;
  border-radius:var(--radius);
  box-shadow:0 12px 32px rgba(30,58,95,.32);
  padding:10px 14px;
  display:none;align-items:center;gap:10px;
  z-index:54;
  opacity:0;
  transition:opacity var(--dur-mid) var(--ease),transform var(--dur-mid) var(--ease);
  bottom:24px;
}
@media(max-width:640px){
  .bulk-bar{bottom:calc(78px + env(safe-area-inset-bottom));max-width:none;width:calc(100% - 20px)}
}
.bulk-bar.show{display:flex;opacity:1;transform:translateX(-50%) translateY(0)}
.bulk-bar .bb-count{flex:1;font-size:13px;font-weight:600;min-width:0}
.bulk-bar .bb-btn{
  background:rgba(255,255,255,.18);color:#fff;border:1px solid rgba(255,255,255,.3);
  padding:6px 12px;font-size:12px;font-weight:600;border-radius:var(--radius-pill);
  cursor:pointer;font-family:inherit;flex-shrink:0;
  transition:background var(--dur-fast) var(--ease);
}
.bulk-bar .bb-btn:hover{background:rgba(255,255,255,.28)}
.bulk-bar .bb-btn.danger{background:rgba(255,255,255,.95);color:var(--red);border-color:#fff}
.bulk-bar .bb-btn.danger:hover{background:#fff}
.csm.is-selected{background:var(--accent-soft);border-color:var(--accent)}
@media print{.bulk-bar{display:none!important}}

/* ── Command palette (Phase 4 — ⌘K / ⌃K) ───────────────────────────────
   Centered overlay with search input + filtered items list. Items
   come from velaCmdKItems(). Arrow keys navigate; Enter runs the
   action; Esc closes. Visible on desktop only by default but works
   on mobile too. */
.cmdk-overlay{
  position:fixed;inset:0;z-index:998;display:none;
  background:rgba(15,23,42,.4);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  align-items:flex-start;justify-content:center;padding:80px 16px 16px;
  animation:vela-backdrop-in 200ms var(--ease);
}
.cmdk-overlay.open{display:flex}
.cmdk-modal{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow-md);
  width:100%;max-width:560px;display:flex;flex-direction:column;overflow:hidden;
  max-height:calc(100vh - 96px);
  animation:vela-modal-in 280ms var(--ease);
}
.cmdk-input{
  border:none;padding:16px 18px;font-size:15px;font-family:var(--font-sans);
  color:var(--text);background:var(--surface);outline:none;
  border-bottom:1px solid var(--border);
}
.cmdk-list{flex:1;overflow-y:auto;padding:6px 0;min-height:80px;max-height:60vh}
.cmdk-section{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--text3);padding:10px 18px 4px}
.cmdk-item{
  display:flex;align-items:center;gap:12px;
  padding:9px 18px;cursor:pointer;color:var(--text);
  font-size:13px;line-height:1.4;
}
.cmdk-item:hover,.cmdk-item.on{background:var(--accent-soft);color:var(--accent)}
.cmdk-item .ck-ic{flex-shrink:0;width:18px;height:18px;color:var(--text3);display:inline-flex;align-items:center;justify-content:center}
.cmdk-item.on .ck-ic{color:var(--accent)}
.cmdk-item .ck-lbl{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-item .ck-sub{font-size:11px;color:var(--text3);flex-shrink:0;margin-left:8px}
.cmdk-empty{padding:24px 18px;text-align:center;color:var(--text3);font-size:12px}
.cmdk-foot{
  border-top:1px solid var(--border);padding:8px 18px;font-size:10px;color:var(--text3);
  display:flex;gap:14px;justify-content:flex-end;flex-wrap:wrap;
}
.cmdk-foot kbd{
  background:var(--surface2);border:1px solid var(--border);border-radius:4px;
  padding:1px 5px;font-size:10px;font-family:var(--font-mono);color:var(--text2);
}
@media (prefers-reduced-motion: reduce){
  .cmdk-overlay,.cmdk-modal{animation:none}
}

/* ── Sticky next-action bar (Phase 2 design brief) ────────────────────
   Floats at the bottom of the Overview page with a single recommended
   action: pay an overdue debt, log income on pay day, decide what to do
   with surplus, or just confirm "you're on track". Hidden on other pages
   and when a modal is open. Above the mobile bottom-nav and FAB.
   ──────────────────────────────────────────────────────────────────── */
/* V210 — bar is now ink-dark: as a fixed element it floats over both the
   cream page AND the dark Today slab; the old white surface read as a
   stray pill when it crossed the slab. Ink + cream text + vermilion CTA
   matches the slab's own design language, so it looks intentional
   everywhere it floats. */
.next-action-bar{
  position:fixed;
  left:50%;transform:translateX(-50%) translateY(20px);
  width:calc(100% - 28px);max-width:640px;
  background:var(--ink,#0E1116);
  border:1px solid rgba(255,255,255,.09);
  border-radius:var(--radius);
  box-shadow:0 14px 44px rgba(14,17,22,.35);
  padding:12px 14px;
  display:none;align-items:center;gap:12px;
  z-index:54;
  opacity:0;
  transition:opacity var(--dur-mid) var(--ease),transform var(--dur-mid) var(--ease);
  bottom:24px;
}
@media(max-width:640px){
  .next-action-bar{bottom:calc(78px + env(safe-area-inset-bottom));max-width:none;width:calc(100% - 20px)}
}
.next-action-bar.show{display:flex;opacity:1;transform:translateX(-50%) translateY(0)}
.next-action-bar .na-icon{font-size:18px;flex-shrink:0;line-height:1;width:24px;text-align:center}
.next-action-bar .na-msg{flex:1;font-size:13px;line-height:1.4;color:#DDD8CC;min-width:0}
.next-action-bar .na-msg strong{font-weight:600;color:#FFFFFF}
.next-action-bar .na-close{
  flex-shrink:0;width:28px;height:28px;border-radius:50%;
  background:transparent;border:none;color:#B9B4A9;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  padding:0;font-family:inherit;
  transition:background 180ms var(--ease),color 180ms var(--ease);
}
.next-action-bar .na-close:hover{background:rgba(255,255,255,.12);color:#FFFFFF}
.next-action-bar .na-close:active{transform:scale(.92)}
.next-action-bar .na-close svg{width:14px;height:14px}
.next-action-bar .na-cta{
  flex-shrink:0;padding:8px 14px;font-size:12px;font-weight:600;
  border-radius:var(--radius-pill);background:var(--accent);color:#fff;
  border:none;cursor:pointer;font-family:inherit;
  transition:background var(--dur-fast) ease,transform var(--dur-fast) var(--ease-out);
}
/* V136 Phase F: hover stays vermilion (darker), was shifting to
   navy which was a hue jump. One accent rule. */
.next-action-bar .na-cta:hover{background:var(--accent-hover,#C8351A)}
.next-action-bar .na-cta:active{transform:scale(.97)}
.next-action-bar.urgent{border-color:var(--red);background:var(--red-bg)}
.next-action-bar.urgent .na-cta{background:var(--red)}
.next-action-bar.urgent .na-cta:hover{background:var(--red-hover)}
/* V136: dark theme override updated to match the vermilion-stays-vermilion rule */
html[data-theme="dark"] .next-action-bar .na-cta:hover{background:var(--accent-hover,#C8351A)}
@media print{.next-action-bar{display:none!important}}

/* ── Skeleton loaders (Batch 1 #13) ────── */
@keyframes skel-pulse{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
.skel{background:linear-gradient(90deg,var(--surface2) 0%,var(--border) 50%,var(--surface2) 100%);background-size:200% 100%;animation:skel-pulse 1.5s ease-in-out infinite;border-radius:var(--radius-xs);display:inline-block}
.skel-line{height:14px;width:100%;margin:4px 0}
.skel-line.short{width:60%}
.skel-line.mid{width:80%}
.skel-line.big{height:28px}
.skel-card{background:var(--surface);border-radius:var(--radius);padding:18px;margin-bottom:12px;border:1px solid var(--border)}

/* ── Consistent card heights (Batch 1 #15) ── */
.card-grid{display:grid;grid-template-columns:1fr;gap:12px;margin-bottom:12px}
@media(min-width:560px){.card-grid.g2{grid-template-columns:1fr 1fr}}
.card-grid>*{margin-bottom:0 !important;height:100%}

/* ── Page containers ─────────────────────── */
.pg{display:none;padding:20px 20px 80px;max-width:700px;margin:0 auto}
/* Overview breaks out of the 700px cage entirely so the v21 hero,
   marquees, bento, and Saava-can rows can use the full canvas. The
   inner .ovr-page handles its own max-width + centering. Phase 1 fix:
   the previous 920px cap (and the .pg 20px lateral padding) were
   crushing the hero into a narrow column on desktop — that's why the
   ring touched the number and there was so much empty space on either
   side of a wide screen. */
#pg-overview{padding:0;max-width:none}
#pg-overview .ovr-page{max-width:1280px;margin:0 auto;padding-bottom:96px}
@media(min-width:900px){
  #pg-overview .hn{font-size:clamp(72px,11vw,156px)}
}
/* Editorial entry: page fades + lifts 12px; direct children stagger
   in 70ms apart so the page composes like a magazine spread, not
   flickering in as one block. Reduced-motion strips this entirely. */
/* V166 — was: animation:fadeIn 280ms var(--ease). Killed to match the
   higher-specificity rule below; mixed durations caused a "double swap"
   flicker on sub-tab switches. */
.pg.on{display:block}
@media (prefers-reduced-motion: no-preference){
  .pg.on > *{
    /* V278 — BOLD tab transitions. Each section slides up a clear distance
       with an overshoot settle so the page visibly "assembles" on every
       switch and on first load. Vertical-only travel so the overshoot can
       never create horizontal overflow. */
    animation:saava-stagger 620ms var(--ease-bounce,cubic-bezier(0.34,1.56,0.64,1)) both;
  }
  .pg.on > *:nth-child(1){animation-delay:0ms}
  .pg.on > *:nth-child(2){animation-delay:75ms}
  .pg.on > *:nth-child(3){animation-delay:150ms}
  .pg.on > *:nth-child(4){animation-delay:225ms}
  .pg.on > *:nth-child(5){animation-delay:300ms}
  .pg.on > *:nth-child(6){animation-delay:375ms}
  .pg.on > *:nth-child(7){animation-delay:450ms}
  .pg.on > *:nth-child(8){animation-delay:525ms}
  /* Cap so late items don't wait too long. */
  .pg.on > *:nth-child(n+9){animation-delay:600ms}
}
@keyframes saava-stagger{
  from{opacity:0;transform:translateY(46px)}
  to{opacity:1;transform:translateY(0)}
}

/* ── Page header (Saava — disciplined single h1) ─────────────────
   No masthead chrome. No rules. No section numbers. Just an italic
   Fraunces title and an optional subtitle. Less is more. */
.saava-mast-page{padding:10px 0 22px;margin-bottom:6px}
.saava-mast-page .smp-bar{display:none}
.saava-mast-page .smp-title{
  font-family:var(--font-display);
  font-size:clamp(34px, 7vw, 56px);
  font-weight:500;font-style:italic;
  line-height:.98;letter-spacing:var(--ls-tight);
  color:var(--navy);margin:0 0 10px;
}
.saava-mast-page .smp-sub{
  font-family:var(--font-sans);
  font-size:13px;color:var(--text2);line-height:1.55;
  margin-bottom:0;max-width:50ch;
}

/* ── HERO (Saava — restrained typographic moment + signature mark) ──
   Single hero number in italic Fraunces, with the SIGNATURE vermilion
   annotation mark hand-drawn-looking SVG underline beneath. The
   annotation mark is the recurring identity motif used wherever a
   meaningful number lives. */
.saava-hero{padding:14px 0 28px;margin-bottom:8px;position:relative}
.saava-hero .sh-context{
  font-family:var(--font-sans);
  font-size:11px;font-weight:600;letter-spacing:var(--ls-tracked);
  text-transform:uppercase;color:var(--text2);
  margin-bottom:14px;
}
.saava-hero .sh-number-wrap{
  position:relative;display:inline-block;margin-bottom:14px;
}
.saava-hero .sh-number{
  font-family:var(--font-display);
  font-size:clamp(64px, 13vw, 124px);
  font-weight:500;font-style:italic;
  line-height:.96;letter-spacing:var(--ls-tight);
  color:var(--navy);
  font-variant-numeric:tabular-nums;
  display:block;
}
/* SIGNATURE — the vermilion annotation mark.
   Hand-drawn-feeling SVG underline curl. Recurs across the app
   wherever a meaningful number is highlighted. THIS is Saava's
   identity element — not a logo tile, not a stripe. A mark. */
.saava-hero .sh-mark{
  position:absolute;left:-4px;right:-12px;bottom:-4px;
  width:calc(100% + 16px);height:14px;
  color:var(--accent);overflow:visible;
  pointer-events:none;
  opacity:0;
  animation:saava-mark-draw 700ms cubic-bezier(0.22,0.61,0.36,1) 200ms forwards;
}
@keyframes saava-mark-draw{
  from{opacity:0;transform:scaleX(.4) translateY(2px);transform-origin:left}
  to{opacity:1;transform:scaleX(1) translateY(0)}
}
.saava-hero .sh-progress-label{
  font-family:var(--font-sans);
  font-size:11px;font-weight:600;letter-spacing:var(--ls-tracked);
  text-transform:uppercase;color:var(--text2);margin-top:14px;
}
.saava-hero .sh-networth{
  display:inline-flex;align-items:baseline;gap:10px;
  padding-top:14px;margin-top:8px;
  border-top:1px solid var(--border);
}
.saava-hero .sh-nw-lbl{
  font-family:var(--font-sans);font-size:10px;font-weight:700;
  letter-spacing:var(--ls-cap);text-transform:uppercase;color:var(--text3);
}
.saava-hero .sh-nw-val{
  font-family:var(--font-mono);font-size:15px;font-weight:600;
  letter-spacing:var(--ls-normal);
}

/* The reusable signature mark — apply class .saava-underline to any
   element to give it the vermilion annotation. Used on key numbers,
   section labels, status pills throughout. */
.saava-underline{
  position:relative;display:inline-block;
}
.saava-underline::after{
  content:'';position:absolute;left:-2px;right:-6px;bottom:-3px;
  height:6px;
  background:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 6' preserveAspectRatio='none'%3E%3Cpath d='M1 4 Q 25 1, 50 3.5 T 99 3' fill='none' stroke='%23D8431B' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center/100% 100%;
  pointer-events:none;
}

/* Stats — flush page width, no card, vertical dividers between cells */
.saava-stats{
  display:grid;grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--ink);
  border-bottom:1px solid var(--border);
  margin:0 0 32px;
}
.saava-stats .ss-cell{
  padding:14px 12px;
  border-right:1px solid var(--border);
  min-width:0;
}
.saava-stats .ss-cell:last-child{border-right:none}
.saava-stats .ss-lbl{
  font-family:var(--font-sans);
  font-size:9px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text3);margin-bottom:6px;line-height:1.2;
}
.saava-stats .ss-val{
  font-family:var(--font-mono);
  font-size:15px;font-weight:600;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;
  line-height:1.1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
@media(max-width:520px){
  .saava-stats{grid-template-columns:repeat(2,1fr)}
  .saava-stats .ss-cell:nth-child(2){border-right:none}
  .saava-stats .ss-cell:nth-child(1),
  .saava-stats .ss-cell:nth-child(2){border-bottom:1px solid var(--border)}
}

/* ── TODAY alert (Saava — slim, never dominates the hero) ──────────
   An ALERT, not a magazine cover. The hero (total debt) is the king;
   this is the small heads-up above it. One row on most screens, max
   two on phones. Single accent color (vermilion) for all urgent states
   — no second red. Stays out of the way when nothing's urgent. */
/* V135 Phase F: removed border-left:3px accent. State signal lives
   in the inline content (icon + colored badge for urgency). */
.saava-today{
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  padding:14px 16px;
  margin-bottom:14px;
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  position:relative;
  box-shadow:var(--shadow-soft);
}
.saava-today.saava-today-ontrack{
  border-left-color:var(--green);
  background:var(--surface);
}
.saava-today.saava-today-firstrun{
  border-left-color:var(--navy);
}
.saava-today .st-eyebrow{
  display:none;          /* the left-border IS the eyebrow */
}
.saava-today .st-bar{display:none}
.saava-today .st-headline{
  font-family:var(--font-sans);
  font-size:13px;
  font-weight:600;line-height:1.35;letter-spacing:-.005em;
  color:var(--navy);margin:0;flex:1;min-width:180px;
}
.saava-today .st-verb{color:var(--text2);font-weight:500}
.saava-today .st-target{
  font-style:italic;font-weight:700;color:var(--navy);
  font-family:var(--font-display);font-size:15px;letter-spacing:-.01em;
}
.saava-today.saava-today-urgent .st-target{color:var(--accent)}
.saava-today .st-amount{
  font-family:var(--font-mono);
  font-size:15px;font-weight:700;font-style:normal;
  line-height:1;letter-spacing:-.01em;
  color:var(--accent);
  font-variant-numeric:tabular-nums;
  margin:0;flex-shrink:0;
}
.saava-today .st-meta{
  font-family:var(--font-sans);
  font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text3);flex-shrink:0;
}
.saava-today.saava-today-urgent .st-meta{color:var(--accent)}
.saava-today .st-cta{
  display:inline-flex;align-items:center;gap:6px;
  padding:8px 14px;
  background:var(--accent);color:var(--accent-text);
  border:none;cursor:pointer;
  font-family:var(--font-sans);font-size:10px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;
  transition:transform 180ms var(--ease),background 180ms var(--ease);
  flex-shrink:0;
}
.saava-today .st-cta svg{width:12px;height:12px}
.saava-today .st-cta:hover{background:var(--accent-hover);transform:translateY(-1px)}
.saava-today .st-cta:active{transform:translateY(0)}
.saava-today.saava-today-ontrack .st-cta{background:var(--navy)}
.saava-today.saava-today-ontrack .st-cta:hover{background:#0e2549}

/* ── Hero (Saava — editorial bold) ──────────────────────────────────
   Pure white card on bone page. Charcoal 1px hairline (the "design"
   feel). Vermilion eyebrow label + monogram square. Solid navy Fraunces
   total-debt number — no italic, no gradient, max readability. Below:
   stat tiles in monospace navy. ONE big vermilion CTA pill. The 3D
   sculpture sits OUTSIDE the data zone (corner anchor), never overlaps
   numbers. No parallax tilt, no drift gradient — motion ONLY where
   it serves clarity.
   ──────────────────────────────────────────────────────────────────── */
.hero{
  position:relative;overflow:visible;
  background:var(--surface);
  border:1px solid var(--border-strong);
  border-radius:var(--radius);
  padding:32px 32px 28px;
  margin-bottom:16px;
  box-shadow:none;
}
.hero::before{
  /* a thin vermilion 4px bar in the top-left — editorial accent */
  content:'';position:absolute;top:-1px;left:-1px;
  width:64px;height:4px;
  background:var(--accent);
  border-radius:0;
}
/* Hero static mark — small editorial composition, top-right. */
.hero .hero-mark{
  position:absolute;top:20px;right:20px;
  width:100px;height:100px;
  pointer-events:none;
  z-index:2;
}
.hero .hero-mark .m-sq{
  position:absolute;top:0;right:0;
  width:58px;height:58px;
  background:var(--accent);
}
.hero .hero-mark .m-cir{
  position:absolute;bottom:0;left:0;
  width:70px;height:70px;border-radius:50%;
  background:var(--navy);
}
.hero .hero-mark .m-bar{
  position:absolute;bottom:14px;right:0;
  width:30px;height:6px;
  background:var(--ink);
}
@media(max-width:640px){
  .hero .hero-mark{width:74px;height:74px;top:16px;right:16px}
  .hero .hero-mark .m-sq{width:42px;height:42px}
  .hero .hero-mark .m-cir{width:52px;height:52px}
  .hero .hero-mark .m-bar{width:22px;height:5px}
  .hero{padding:26px 20px 22px}
}
.hn{
  font-family:var(--font-display);
  font-size:clamp(56px, 11vw, 104px);
  font-weight:500;
  font-style:normal;          /* italic OFF — readability */
  line-height:.92;
  letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
  font-optical-sizing:auto;
  color:var(--navy);          /* solid navy — no gradient */
  -webkit-text-fill-color:initial;
  background:none;
  display:block;
  margin-bottom:6px;
}
.hl{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--font-sans);
  font-size:10px;text-transform:uppercase;letter-spacing:.28em;
  color:var(--ink);margin-bottom:18px;font-weight:700;
}
.hl::before{
  /* tiny vermilion square — design system flag */
  content:'';display:inline-block;
  width:10px;height:10px;background:var(--accent);
  flex-shrink:0;
}
.hd{font-size:13px;margin-top:8px;color:var(--text2)}
.hgrid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:10px;
  margin-top:24px;
  padding-top:20px;
  border-top:1px solid var(--border);
}
@media(min-width:500px){.hgrid{grid-template-columns:repeat(4,1fr)}}
.hbox{
  background:transparent;
  padding:4px 0;
  border:none;
  position:relative;
}
.hbl{
  display:inline-flex;align-items:center;gap:6px;
  font-size:9px;color:var(--ink);margin-bottom:8px;
  font-weight:700;text-transform:uppercase;letter-spacing:.16em;
}
.hbl::before{
  content:'';display:inline-block;width:6px;height:6px;
  background:var(--accent);flex-shrink:0;
}
.hbv{
  font-size:18px;font-weight:600;
  font-family:var(--font-mono);
  color:var(--navy);
  font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;
}
/* Big vermilion CTA inside the hero — "Pay something" */
.hero-cta{
  display:inline-flex;align-items:center;gap:10px;
  margin-top:22px;padding:14px 24px;
  background:var(--accent);color:var(--accent-text);
  border:none;border-radius:0;            /* sharp = editorial */
  font-family:var(--font-sans);font-size:13px;font-weight:700;
  letter-spacing:.04em;cursor:pointer;
  transition:background 180ms var(--ease),transform 180ms var(--ease);
  font-family:inherit;
}
.hero-cta:hover{background:var(--accent-hover);transform:translateY(-1px)}
.hero-cta:active{transform:translateY(0)}
.hero-cta svg{width:14px;height:14px}

/* ── Cards (Saava editorial — composed depth) ───────────────────────
   White on bone, charcoal hairline. Resting: 1px outline + flat. On
   hover (desktop only — touch devices skip this): the card lifts 2px
   with a directional charcoal shadow + vermilion left-stripe appears.
   This is the "premium 3D-without-being-tacky" trick: real shadows
   moving in response to attention, not gimmick parallax. */
.crd{
  background:var(--surface);
  border-radius:var(--radius);padding:18px;margin-bottom:12px;
  border:1px solid var(--border-strong);
  box-shadow:none;
  position:relative;
  transition:border-color 220ms var(--ease),transform 280ms cubic-bezier(0.22,0.61,0.36,1),box-shadow 280ms var(--ease);
}
@media (hover: hover){
  .crd:hover{
    transform:translateY(-2px);
    box-shadow:4px 6px 0 var(--ink), 0 12px 24px rgba(0,0,0,.06);
  }
}
.csm{
  background:var(--surface);
  border-radius:var(--radius-sm);padding:12px 14px;margin-bottom:0;
  border:1px solid var(--border-strong);
  box-shadow:none;
}

/* ── Debt cards ─────────────────────────── */
/* V133 Phase F: Settings debt card. Was `border-left: 4px solid` —
   the banned side-stripe pattern with a vermilion shift on hover.
   Now a full hairline border that darkens to ink on hover, plus a
   small vertical-lift transform. State signal (overdue / paid /
   normal) lives in inline content per row, not in a stripe. */
.dc{
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  padding:18px;
  margin-bottom:10px;
  box-shadow:var(--shadow-soft);
  transition:transform 180ms var(--ease-out),border-color 180ms ease,box-shadow 240ms ease;
  position:relative;
}
@media (hover: hover) and (pointer: fine){
  .dc:hover{
    transform:translateY(-2px);
    border-color:var(--ot-ink,#0E1116);
    box-shadow:var(--shadow-hover);
  }
}
@media (hover: none){
  .dc:active{transform:scale(.98)}
}
.dc.r{border-left-color:var(--red)}
.dc.o{border-left-color:var(--orange)}
.dc.y{border-left-color:#f59e0b}
.dc.g{border-left-color:var(--green)}

/* ── Badges ──────────────────────────────── */
.bdg{font-size:11px;padding:3px 9px;border-radius:0;font-weight:600;display:inline-block;letter-spacing:.01em}
/* Phase 2 brief — light-mode color variants (dark mode overrides exist further down). */
.bdg.bm_{background:var(--surface2);color:var(--text2)}
.bdg.br_{background:var(--red-bg);color:var(--red);position:relative}
.bdg.bw_{background:var(--orange-bg);color:var(--orange)}
.bdg.bg_{background:var(--green-bg);color:var(--green)}
.bdg.bp_{background:var(--blue-bg);color:var(--blue)}
/* Phase 2 brief — overdue red badge has a gentle box-shadow pulse every
   1.6s. "Gentle, not anxious." Kept subtle on purpose. */
.bdg.br_,.vela-pulse{animation:vela-pulse 1.6s var(--ease) infinite}
@keyframes vela-pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(178,58,72,.35)}
  50%{box-shadow:0 0 0 6px rgba(178,58,72,0)}
}
@media (prefers-reduced-motion: reduce){
  .bdg.br_,.vela-pulse{animation:none}
}
/* Phase 2 brief — progress bars animate fill from 0 → current over
   600ms eased on first render. Apply class .vela-pbar-fill on the
   inner fill element (the rail itself doesn't need a class). Uses
   scaleX transform with transform-origin:left so the inline width
   percentage is preserved; the animation just grows it in. */
.vela-pbar-fill{transform-origin:left center;animation:vela-progress-grow 600ms var(--ease)}
@keyframes vela-progress-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@media (prefers-reduced-motion: reduce){
  .vela-pbar-fill{animation:none}
}

/* Phase 2 brief — celebration when a debt is paid off. The card bounces
   once (scale 1 → 1.04 → 1 over 600ms) and a small confetti burst fires
   from its center (8–12 particles in earth tones: gold, navy, forest).
   Only triggered from velaCelebrate() — never auto-applied. */
@keyframes vela-bounce-pop{
  0%,100%{transform:scale(1)}
  40%{transform:scale(1.04)}
  70%{transform:scale(.99)}
}
.vela-bounce{animation:vela-bounce-pop 600ms var(--ease)}
.vela-confetti-burst{position:absolute;inset:0;pointer-events:none;overflow:visible;z-index:100}
.vela-confetti{
  position:absolute;top:50%;left:50%;
  width:7px;height:7px;border-radius:1px;
  --tx:0px;--ty:0px;
  animation:vela-confetti-fly 900ms cubic-bezier(0.22,0.61,0.36,1) forwards;
}
@keyframes vela-confetti-fly{
  0%{transform:translate(-50%,-50%) translate(0,0) rotate(0deg);opacity:1}
  100%{transform:translate(-50%,-50%) translate(var(--tx),var(--ty)) rotate(180deg);opacity:0}
}
@media (prefers-reduced-motion: reduce){
  .vela-bounce{animation:none}
  .vela-confetti{display:none}
}
.br_{background:var(--red-bg);color:var(--red)}
.bw_{background:var(--orange-bg);color:var(--orange)}
.by_{background:#fef3c7;color:#92400e}
.bg_{background:var(--green-bg);color:var(--green)}
.bm_{background:var(--surface2);color:var(--text2);border:1px solid var(--border)}
.bp_{background:var(--blue-bg);color:var(--blue)}

/* ── Buttons ──────────────────────────────── */
/* V160 — Legacy .btn / .bp / .bg2 classes upgraded to editorial styling
   so render functions across HST / Settings / History / Income Tax
   pick up the new chrome without per-callsite rewrites. .bp now
   matches .ed-btn-primary (ink fill, cream text, vermilion hover,
   ed-chip radius, no drop-shadow box). .btn is a quieter secondary.
   .bg2 (formerly green Add button) joins .bp as a primary action —
   "Add" is an action, not a positive-state semantic. */
.btn{
  padding:9px 14px;
  border-radius:var(--r-chip,8px);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  background:transparent;
  color:var(--ot-t2,#5F6470);
  font-size:12px;font-weight:500;
  letter-spacing:.04em;
  cursor:pointer;font-family:inherit;
  transition:background 180ms ease,border-color 180ms ease,color 180ms ease;
}
.btn:hover{
  background:var(--ot-bg,#F5F1E8);
  border-color:var(--ot-ink,#0E1116);
  color:var(--ot-ink,#0E1116);
}
.bp{
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  border:none;
  padding:12px 22px;
  border-radius:var(--r-chip,8px);
  font-size:12px;font-weight:600;
  letter-spacing:.06em;
  text-transform:uppercase;
  cursor:pointer;font-family:inherit;
  box-shadow:none;
  transition:background 180ms ease,transform 150ms var(--ease-out,ease);
}
.bp:hover{background:var(--ot-ver,#D8431B)}
.bp:active{transform:scale(0.97)}
.bg2{
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  border:none;
  padding:10px 18px;
  border-radius:var(--r-chip,8px);
  font-size:12px;font-weight:600;
  letter-spacing:.06em;
  text-transform:uppercase;
  cursor:pointer;font-family:inherit;
  box-shadow:none;
  transition:background 180ms ease,transform 150ms var(--ease-out,ease);
}
.bg2:hover{background:var(--ot-ver,#D8431B)}
.bg2:active{transform:scale(0.97)}
/* Phase 16 — ghost-navy Remove button (was bright red).
   Destructive intent is communicated by the word "Remove," not by
   shouting in red. Vermilion only emerges on hover. */
.br2{background:transparent;color:var(--text2);border:1px solid var(--border2);padding:8px 12px;border-radius:var(--radius-xs);font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;letter-spacing:.02em;transition:transform 160ms var(--ease-out),background 160ms ease,color 160ms ease,border-color 160ms ease}
.br2:hover{background:transparent;color:var(--accent);border-color:var(--accent)}
.btns{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
button{font-family:inherit}

/* ── Forms ──────────────────────────────────── */
input,select{font-family:inherit;font-size:13px;color:var(--text);background:var(--surface);border:1.5px solid var(--border);border-radius:var(--radius-xs);padding:10px 12px;width:100%;outline:none;transition:border-color .2s,box-shadow .2s}
/* iOS Safari auto-zooms on focus when input font-size is below 16px.
   Bump every text-entry control to 16px on phones to prevent the zoom.
   V184 Phase 4D — added !important so this beats the 31 inline
   `style="font-size:13px"` declarations on legacy inputs that haven't
   been migrated to .ed-input yet. Without !important, inline styles
   win and iOS still zoom-flashes on tap. */
@media(max-width:768px){
  input[type="text"],input[type="number"],input[type="email"],input[type="tel"],
  input[type="password"],input[type="search"],input[type="url"],input[type="date"],
  input[type="datetime-local"],input[type="month"],input[type="time"],
  textarea,select{
    font-size:16px !important;
  }
}
input:focus,select:focus,textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(30,58,95,.15);outline:none}
.fl{font-size:11px;color:var(--text3);margin-bottom:4px;font-weight:600;display:block;letter-spacing:.02em}
.fg{margin-bottom:12px}
.g2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.g3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px}

/* ── Section labels ──────────────────────── */
/* V160 — .sec / .sec-divider upgraded to match .ed-eyebrow editorial
   style across Settings / History / 3-Month / HST inner. Was bold
   uppercase --text3 muted; now matches editorial eyebrow:
   600-weight, looser tracking, ot-t2 quiet, with italic vermilion
   accent for the trailing word when one is wrapped in <em>. */
.sec{
  font-family:var(--ot-font);
  font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.18em;
  color:var(--ot-t2,#5F6470);
  margin:24px 0 12px;
  display:flex;justify-content:space-between;align-items:center;gap:10px;
}
.sec em{font-style:italic;font-weight:600;color:var(--ot-ver,#D8431B);text-transform:none;letter-spacing:0.02em}
.sec-divider{
  font-family:var(--ot-font);
  font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.18em;
  color:var(--ot-t2,#5F6470);
  margin:24px 0 12px;
  padding-bottom:8px;
  border-bottom:0.5px solid var(--ot-bd,#E5E0D4);
}
.sec-divider em{font-style:italic;font-weight:600;color:var(--ot-ver,#D8431B);text-transform:none;letter-spacing:0.02em}

/* ── Info strips ──────────────────────────── */
.inf{background:var(--surface2);border-radius:var(--radius-xs);padding:12px 16px;font-size:12px;color:var(--text2);margin-bottom:12px;border:1px solid var(--border)}
.alr{background:var(--red-bg);border:1px solid #fecaca;border-radius:var(--radius-sm);padding:11px 14px;font-size:12px;color:var(--red);display:flex;gap:9px;margin-bottom:12px;align-items:flex-start}
.sug{background:var(--green-bg);border:1px solid #a7f3d0;border-radius:var(--radius-sm);padding:11px 14px;font-size:12px;color:var(--green);margin-bottom:12px}

/* ── Expand panels ────────────────────────── */
.ep{background:var(--surface2);border-radius:var(--radius-sm);padding:14px;margin-top:10px;display:none;border:1px solid var(--border)}
.ep.open{display:block}

/* ── Modal overlay (Phase 2 brief: backdrop 200ms fade, modal 280ms scale) */
.ov{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(15,23,42,.5);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);z-index:999;align-items:flex-start;justify-content:center;padding:28px 16px;overflow-y:auto}
.ov.open{display:flex;animation:vela-backdrop-in 200ms var(--ease)}
.modal{background:var(--surface);border-radius:var(--radius-modal);padding:24px;width:100%;max-width:460px;border:1px solid var(--border);box-shadow:var(--shadow-md);margin:auto;animation:vela-modal-in 280ms var(--ease)}
@media (max-width:640px){
  /* Bottom-sheet pattern on phones. The modal docks to the bottom edge
     with rounded top corners, slides up, and shows a small drag handle
     so the gesture is discoverable. Max-height respects safe-area inset. */
  .ov{padding:0;align-items:stretch}
  .modal{
    max-width:100%;
    border-radius:18px 18px 0 0;
    padding:26px 18px calc(20px + env(safe-area-inset-bottom));
    margin:auto 0 0;
    align-self:flex-end;
    max-height:92vh;overflow-y:auto;-webkit-overflow-scrolling:touch;
    box-shadow:0 -8px 32px rgba(0,0,0,.18);
    animation:saava-sheet-up 320ms cubic-bezier(0.22,0.61,0.36,1);
    position:relative;
  }
  /* Drag-handle indicator at the top of every bottom-sheet modal */
  .modal::before{
    content:'';
    position:absolute;
    top:8px;left:50%;transform:translateX(-50%);
    width:40px;height:4px;
    background:var(--border2);
    border-radius:2px;
    pointer-events:none;
  }
}
@keyframes saava-sheet-up{
  from{opacity:0;transform:translateY(24px)}
  to  {opacity:1;transform:translateY(0)}
}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes vela-backdrop-in{from{opacity:0}to{opacity:1}}
/* Vaul-style modal scale + backdrop blur (Phase 23 / Emil pattern).
   Animation-skill rule: never scale from below 0.96 (starting from
   nothing looks cheap). Was 0.94, refined to 0.96 + smaller rise. */
@keyframes vela-modal-in{
  from{opacity:0;transform:scale(.96) translateY(6px)}
  to  {opacity:1;transform:scale(1)   translateY(0)}
}
.modal-backdrop{
  backdrop-filter:blur(14px) saturate(1.2);
  -webkit-backdrop-filter:blur(14px) saturate(1.2);
  /* V129 Phase E: backdrop tint warmed slightly. Was rgba(20,24,37,
     0.4) which read as cold navy haze on the cream page. Switched to
     warm ink tint that matches the page palette. */
  background:rgba(14,17,22,0.42);
}
.modal{
  animation:vela-modal-in 280ms var(--ease-out) !important;
  transform-origin:center;
}
/* V129 Phase E: editorial defaults inside modals. Headings without
   inline styles (rare but possible in new code) get Inter Tight
   automatically. Most existing modals override these via inline
   style, which is fine — these are the fallback floor. */
.modal h1,.modal h2,.modal h3,.modal .modal-title{
  font-family:var(--ot-font);
  font-weight:600;
  letter-spacing:-0.02em;
  line-height:1.15;
  color:var(--ot-ink);
  margin:0 0 12px 0;
}
.modal h1 em,.modal h2 em,.modal h3 em,.modal .modal-title em{
  font-style:italic;
  font-weight:700;
  color:var(--ot-ver);
}
.modal h1{font-size:clamp(22px,2.4vw,28px)}
.modal h2{font-size:clamp(20px,2.2vw,24px)}
.modal h3{font-size:18px}

/* ── Sonner-style toast (Phase 23 / Emil pattern) ────────────────
   Bottom-right corner, off-white surface, dark text, subtle layered
   shadow. Slides up + scales in with spring. Replaces the old
   bottom-center pill with the recognizable Emil Sonner shape. */
#vela-toast{
  position:fixed;
  bottom:24px;right:24px;
  left:auto;
  background:#FFFFFF;
  color:#0E1116;
  padding:14px 18px;
  border-radius:14px;
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:13.5px;
  font-weight:500;
  letter-spacing:-0.005em;
  z-index:9999;
  opacity:0;
  pointer-events:none;
  white-space:nowrap;
  max-width:380px;
  border:1px solid rgba(14,17,22,0.08);
  box-shadow:
    0 1px 2px rgba(14,17,22,0.04),
    0 4px 12px -2px rgba(14,17,22,0.08),
    0 16px 40px -8px rgba(14,17,22,0.16);
  transform:translateY(24px) scale(0.92);
  transform-origin:bottom right;
}
#vela-toast.show{
  opacity:1;
  /* Emil's actual Sonner uses built-in `ease` — feels more elegant
     than a custom curve. Was Vaul drawer curve (wrong feel for a
     toast — drawers are dragged, toasts arrive). */
  animation:sonner-toast-in 400ms ease forwards;
}
@keyframes sonner-toast-in{
  0%  {opacity:0;transform:translateY(24px) scale(0.92)}
  60% {opacity:1;transform:translateY(-2px) scale(1.01)}
  100%{opacity:1;transform:translateY(0)    scale(1)}
}
#vela-toast.has-action{
  pointer-events:auto;cursor:pointer;
  border-color:rgba(232,74,26,0.3);
}
#vela-toast.has-action:hover{
  border-color:rgba(232,74,26,0.6);
  box-shadow:
    0 1px 2px rgba(14,17,22,0.04),
    0 4px 12px -2px rgba(14,17,22,0.1),
    0 16px 40px -8px rgba(232,74,26,0.22);
}

/* ── Misc ──────────────────────────────────── */
.mu{color:var(--text3)}
.mo{font-family:var(--font-mono)}
.sort-btn{background:none;border:none;color:var(--text3);cursor:pointer;padding:2px;font-size:14px;line-height:1;opacity:.5;transition:opacity .15s,color .15s}
.sort-btn:hover{opacity:1;color:var(--blue)}
.dc.dragging{opacity:.4;transform:scale(.98);box-shadow:0 12px 32px rgba(0,0,0,.18)}
.dc.drag-over{border-top:3px solid var(--blue) !important;transition:border-top .12s}
.cra-inst-remitted{opacity:.45;text-decoration:line-through}
.btn-remit{background:var(--green);color:#fff;border:none;padding:8px 12px;border-radius:var(--radius-xs);font-size:11px;font-weight:700;cursor:pointer;font-family:inherit;white-space:nowrap}
.btn-remit:hover{background:var(--green-dark)}

/* ── Empty state ────────────────────────── */
/* V128 Phase F: legacy .empty-state upgraded to editorial. Every
   `class="empty-state"` callsite across the app (~10 of them in
   History, Plan, Pay, 3-Month, Timeline, etc.) gets the typographic
   treatment for free. Bigger Inter Tight title with italic vermilion
   accent support via <em>, sentence-case body in --ot-t2, calmer
   icon at top. */
.empty-state{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:clamp(60px,8vw,120px) clamp(24px,3vw,56px);
  text-align:center;
  min-height:50vh;
}
.empty-state .es-icon{
  font-size:clamp(40px,5vw,60px);
  margin-bottom:24px;
  opacity:0.55;
}
.empty-state .es-title{
  font-family:var(--ot-font);
  font-size:clamp(26px,3.2vw,40px);
  font-weight:600;
  letter-spacing:-0.025em;
  line-height:1.05;
  color:var(--ot-ink);
  margin:0 0 14px 0;
  text-wrap:balance;
  max-width:20ch;
}
.empty-state .es-title em{
  font-style:italic;
  font-weight:700;
  color:var(--ot-ver);
}
.empty-state .es-body{
  font-size:15px;
  line-height:1.55;
  color:var(--ot-t2);
  margin:0 0 28px 0;
  max-width:50ch;
  text-wrap:pretty;
}
.empty-state .es-body em{
  font-style:italic;
  font-weight:500;
  color:var(--ot-ink);
}
.empty-state .es-body strong{
  font-weight:600;
  color:var(--ot-ink);
}
/* V183 Phase 4A — .empty-state .es-art CSS + emptyArt() helper removed.
   They were leftover from a Phase 2 design-brief iteration that the
   editorial empty states already replaced. emptyArt() was defined but
   never called from anywhere; the CSS class only existed to style its
   output. ~70 lines reclaimed. */

/* ── Onboarding ─────────────────────────── */
/* V131 Phase F: onboarding card converted to editorial. Was a blue
   linear-gradient SaaS-hero with white-on-blue text and a blue-tinted
   drop shadow — the textbook AI-marketing card pattern. Now a clean
   cream surface with Inter Tight italic-accent headline, ash body
   copy, and ink-bordered step buttons that fill in with ink on hover. */
.onboard-card{
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  padding:clamp(24px,3vw,40px);
  margin-bottom:24px;
  color:var(--ot-ink,#0E1116);
  box-shadow:var(--shadow-soft);
}
.onboard-card h2{
  font-family:var(--ot-font);
  font-size:clamp(24px,3vw,36px);
  font-weight:600;
  letter-spacing:-0.025em;
  line-height:1.05;
  margin:0 0 14px 0;
  color:var(--ot-ink,#0E1116);
  text-wrap:balance;
}
.onboard-card h2 em{
  font-style:italic;
  font-weight:700;
  color:var(--ot-ver,#D8431B);
}
.onboard-card p{
  font-size:15px;
  line-height:1.55;
  color:var(--ot-t2,#5F6470);
  margin:0 0 24px 0;
  max-width:50ch;
}
.onboard-steps{display:flex;gap:8px;flex-wrap:wrap}
.onboard-step{
  background:transparent;
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-chip,8px);
  padding:12px 18px;
  font-family:var(--ot-font);
  font-size:13px;
  font-weight:600;
  letter-spacing:0.04em;
  color:var(--ot-ink,#0E1116);
  cursor:pointer;
  transition:background 200ms ease,color 200ms ease,border-color 200ms ease,transform 150ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine){
  .onboard-step:hover{
    background:var(--ot-ink,#0E1116);
    color:var(--ot-bg,#F5F1E8);
    border-color:var(--ot-ink,#0E1116);
  }
}
.onboard-step:active{transform:scale(0.97)}
.onboard-step:focus-visible{
  outline:none;
  box-shadow:0 0 0 3px rgba(232,74,26,0.25),0 0 0 1px rgba(232,74,26,0.6);
}

/* ── Progress bars ──────────────────────── */
.bar{height:6px;border-radius:0;background:var(--border);overflow:hidden;margin:8px 0 4px}
.barf{height:100%;border-radius:0}

/* ── Execute boxes ──────────────────────── */
.ex3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-top:10px}
.exbox{background:var(--surface2);border-radius:var(--radius-sm);padding:11px 13px;border:1px solid var(--border)}
.exlbl{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.07em;margin-bottom:5px;font-weight:700}
.exval{font-size:17px;font-weight:700;font-family:var(--font-mono)}

/* ── 3-Month table ─────────────────────── */
.t3{width:100%;border-collapse:collapse;font-size:12px}
/* On mobile, .t3 becomes a horizontal-scroll block. Cells stay inline
   so the table never breaks the page layout — user swipes sideways to
   see hidden columns. Custom scrollbar so it's visibly draggable. */
@media(max-width:640px){
  .t3{
    display:block;
    overflow-x:auto;
    -webkit-overflow-scrolling:touch;
    white-space:nowrap;
    width:100%;
  }
  .t3::-webkit-scrollbar{height:6px}
  .t3::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:3px}
  .t3::-webkit-scrollbar-track{background:var(--surface2)}
}
.t3 th{padding:9px 10px;text-align:right;font-size:10px;font-weight:700;color:var(--text3);border-bottom:1px solid var(--border);background:var(--surface2);white-space:nowrap;letter-spacing:.05em;text-transform:uppercase}
.t3 th:first-child{text-align:left}
.t3 th.cur{background:rgba(37,99,235,.08);color:var(--blue)}
.t3 th.rem{background:rgba(5,150,105,.08);color:var(--green)}
.t3 td{padding:7px 10px;border-bottom:1px solid var(--border);text-align:right;font-family:var(--font-mono);font-size:12px;vertical-align:middle}
.t3 td:first-child{text-align:left;font-family:inherit;color:var(--text2);font-size:12px}
.t3 td.cur{background:rgba(37,99,235,.04);color:var(--blue);font-weight:600}
.t3 td.rem{background:rgba(5,150,105,.04);color:var(--green);font-weight:600}
.t3 td.rem.red{background:rgba(220,38,38,.04);color:var(--red);font-weight:600}
.t3 .sh td{font-size:10px;text-transform:uppercase;letter-spacing:.07em;color:var(--text3);background:var(--border);padding:6px 10px;font-family:inherit;font-weight:700}
.t3 .tot td{font-weight:700;color:var(--text)}
.t3 .free td{color:var(--green);font-weight:600}
.t3 .neg td{color:var(--red);font-weight:600}
.t3 input{padding:3px 6px;font-size:12px;text-align:right;width:80px;display:inline-block}

/* ── Balance display ──────────────────── */
.bal-row{display:flex;gap:10px;margin:10px 0 8px}
.bal-box{flex:1;background:var(--surface2);border-radius:var(--radius-sm);padding:12px 14px;min-width:0;border:1px solid var(--border)}
.bal-box.stmt{border-color:#fecaca}
.bal-lbl{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.07em;margin-bottom:5px;font-weight:700}
.bal-num{font-size:22px;font-weight:700;font-family:var(--font-mono);line-height:1}
.dbar-wrap{background:var(--surface);border-radius:var(--radius);padding:18px;margin-top:14px;border:1px solid var(--border);box-shadow:var(--shadow)}
.dbar-row{margin-bottom:14px}
.dbar-row:last-child{margin-bottom:0}
.dbar-lbl{display:flex;justify-content:space-between;font-size:12px;margin-bottom:7px;font-weight:500}
.dbar-track{height:10px;border-radius:0;background:var(--border);overflow:hidden;position:relative}
.dbar-bg{height:100%;border-radius:0;position:absolute;top:0;left:0;opacity:.25}
.dbar-fg{height:100%;border-radius:0;position:absolute;top:0;left:0}

/* ── Income rows ──────────────────────── */
.inc-panel{background:var(--surface);border-radius:var(--radius);padding:16px;margin-bottom:12px;border:1px solid var(--border);box-shadow:var(--shadow)}
.inc-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--border)}
.inc-row:last-child{border-bottom:none}
.inc-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}

/* ── Dark mode ──────────────────────────────
   Activated when html[data-theme="dark"] is set.
   Boot script in <head> applies this attribute based on:
     velaTheme = "dark" | "light" | "auto"(default) → mirrors prefers-color-scheme
   ──────────────────────────────────────────── */
html[data-theme="dark"]{
  /* Saava — cinematic fintech dark.
     Pulls the surface palette down toward true ink so the electric-green
     accent reads as a beam, not a UI tint. Original "warm cream" text is
     kept to soften the contrast and give the brand a literary feel
     (Fraunces + cream on graphite, not techy blue on black). */
  --bg:#0A0E14;          /* deep ink page */
  --surface:#10141C;     /* card surface */
  --surface2:#171C26;    /* input bg, muted tiles */
  --border:#1F2530;      /* hairline */
  --border2:#2C3340;     /* stronger hairline for inputs */
  /* text — warm cream, not white */
  --text:#F2EFE6;
  --text2:#A8AEBC;
  --text3:#5C6477;
  /* PRIMARY ACCENT — electric green. The "wow" beam.
     Used in Saava: hero number underline, sign-in CTA, micro-glow on
     key numbers, the 3D torus knot, focus rings. Soft variant for tinted
     surfaces (banners, badges). */
  --blue:#00FF94;
  --blue-bg:#0E1F18;
  --blue-light:#0E1F18;
  --accent:#00FF94;
  --accent-soft:#0E1F18;
  --accent-glow:rgba(0,255,148,.35);
  /* money colors — softened for cinematic dark */
  --green:#3FE0A0;
  --green-bg:#0E1F18;
  --green-light:#13261D;
  --red:#FF6B7E;
  --red-bg:#23121A;
  --red-light:#2D1620;
  --orange:#F2A857;
  --orange-bg:#241910;
  --orange-light:#2D2014;
  --gold:#E5C168;
  --shadow:0 1px 2px rgba(0,0,0,.5),0 12px 36px rgba(0,0,0,.55);
  --shadow-md:0 2px 4px rgba(0,0,0,.55),0 24px 56px rgba(0,0,0,.7);
  /* Brand wordmark — change here to rebrand globally. */
  --brand-name-1:'Saava';
  --brand-name-2:'Savings';
  color-scheme:dark;
}
/* (Saava) The hero base rule above already targets the dark surface
   directly — no per-theme override needed. Block kept empty as a marker
   in case you add another mode later. */
html[data-theme="dark"] .hbox{background:var(--surface2);border-color:var(--border)}
html[data-theme="dark"] input,html[data-theme="dark"] select,html[data-theme="dark"] textarea{background:var(--surface2);border-color:var(--border2);color:var(--text)}
html[data-theme="dark"] input:focus,html[data-theme="dark"] select:focus,html[data-theme="dark"] textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(91,138,191,.25)}
html[data-theme="dark"] .modal{background:var(--surface);border-color:var(--border)}
html[data-theme="dark"] .ov{background:rgba(0,0,0,.8)}
html[data-theme="dark"] .topbar,html[data-theme="dark"] .tabs{border-color:var(--border)}
html[data-theme="dark"] .tab.on{color:#60a5fa;border-bottom-color:#60a5fa}
html[data-theme="dark"] .dc.r{border-left-color:#f87171}
html[data-theme="dark"] .dc.o{border-left-color:#fb923c}
html[data-theme="dark"] .dc.y{border-left-color:#fbbf24}
html[data-theme="dark"] .dc.g{border-left-color:#34d399}
html[data-theme="dark"] .bdg.bm_{background:var(--surface2);color:var(--text2);border-color:var(--border)}
html[data-theme="dark"] .bdg.br_{background:#2e1212;color:#f87171}
html[data-theme="dark"] .bdg.bw_{background:#2e1e0c;color:#fcd34d}
html[data-theme="dark"] .bdg.bg_{background:#0e2e22;color:#4ade80}
html[data-theme="dark"] .bdg.bp_{background:#162040;color:#60a5fa}
html[data-theme="dark"] .btn{border-color:var(--border2);color:var(--text2)}
html[data-theme="dark"] .btn:hover{background:var(--surface2);color:var(--text)}
html[data-theme="dark"] .t3 th{background:var(--surface2);color:var(--text3);border-color:var(--border)}
html[data-theme="dark"] .t3 td{border-color:var(--border);color:var(--text2)}
html[data-theme="dark"] .t3 td:first-child{color:var(--text2)}
html[data-theme="dark"] .t3 .sh td{background:var(--border);color:var(--text3)}
html[data-theme="dark"] .t3 .tot td{color:var(--text)}
html[data-theme="dark"] .t3 th.cur{background:rgba(37,99,235,.18);color:#60a5fa}
html[data-theme="dark"] .t3 td.cur{background:rgba(37,99,235,.1);color:#60a5fa}
html[data-theme="dark"] .t3 th.rem{background:rgba(5,150,105,.18);color:#34d399}
html[data-theme="dark"] .t3 td.rem{background:rgba(5,150,105,.1);color:#34d399}
html[data-theme="dark"] .t3 td.rem.red{background:rgba(220,38,38,.15);color:#f87171}
html[data-theme="dark"] .t3 input{background:var(--surface2);color:var(--text);border-color:var(--border2)}
html[data-theme="dark"] #vela-toast{background:#e4eaf8;color:#0c0f1a}
html[data-theme="dark"] #vela-toast.has-action{background:#d7def0;color:#0c0f1a;border-color:rgba(96,165,250,.35)}
html[data-theme="dark"] .saved-ind{color:var(--text3)}
html[data-theme="dark"] .saved-ind.flash{color:#4ade80}

/* ── Motion baseline (Phase 2 design brief) ───────────────────────────
   Buttons, inputs, cards, modals, tabs all settle into the same easing
   so the app feels "exhaled, not pushed". Existing per-component
   transitions stay where they are; this layer only sets defaults.
   ──────────────────────────────────────────────────────────────────── */
button,a,.btn,.bp,.br2,.bp2,.tab,input,select,textarea{
  transition:background var(--dur-fast) var(--ease),
             color var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease),
             box-shadow var(--dur-fast) var(--ease),
             transform var(--dur-fast) var(--ease);
}
.csm,.dc,.acc-group,details.adv-fold>summary{
  transition:background var(--dur-mid) var(--ease),
             border-color var(--dur-mid) var(--ease),
             box-shadow var(--dur-mid) var(--ease),
             transform var(--dur-mid) var(--ease);
}
button:active,.btn:active,.bp:active,.br2:active,.bp2:active{transform:scale(.97)}
/* Honour OS-level reduce-motion. Brief: durations → 0, transforms off,
   only opacity stays. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
    scroll-behavior:auto!important;
  }
  button:active,.btn:active,.bp:active,.br2:active,.bp2:active{transform:none!important}
}

/* ── Responsive ─────────────────────────── */
@media(max-width:480px){
  .pg{padding:14px 14px 80px}
  .topbar{padding:0 16px;height:60px}
  .logo-mark{width:32px;height:32px;font-size:19px}
  .hn{font-size:48px}
  .hgrid{grid-template-columns:repeat(2,1fr)}
  .g2{grid-template-columns:1fr}
  .ex3{gap:6px}
  .exval{font-size:15px}
}

/* ── Invoice ──────────────────────────────── */
#pg-invoice{padding:0 !important}
.inv-shell{display:grid;grid-template-columns:340px 1fr;min-height:calc(100vh - 90px)}
.inv-panel{background:var(--surface);border-right:1px solid var(--border);padding:20px 18px 48px;overflow-y:auto;height:calc(100vh - 90px);position:sticky;top:90px}
/* Mobile / tablet — stack into a single column. The preview pane sits
   BELOW the form (not in a side rail), and the invoice doc shrinks to
   the viewport so it's actually readable on a phone. */
@media(max-width:900px){
  #pg-invoice{padding:0 !important}
  .inv-shell{display:block;grid-template-columns:1fr;min-height:auto}
  .inv-panel{
    position:static;height:auto;
    border-right:none;border-bottom:1px solid var(--border-strong);
    padding:20px 18px 28px;overflow:visible;
  }
  .inv-preview-pane{
    height:auto;
    padding:20px 16px 40px;
    background:var(--bg);
    align-items:stretch;
  }
  .inv-preview-lbl{width:auto;font-size:9px}
  .inv-doc{
    width:100%;max-width:none;
    padding:24px 18px;
    box-shadow:none;border:1px solid var(--border-strong);
    min-height:0;
  }
  .inv-doc .id-title{font-size:24px}
  .inv-doc table thead th,
  .inv-doc table tbody td{font-size:11px;padding:8px 0}
  .inv-doc .id-parties{grid-template-columns:1fr;gap:18px}
  .inv-doc .id-strip{grid-template-columns:1fr 1fr;gap:8px}
}
.inv-panel .ip-title{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--text3);margin-bottom:14px}
.inv-row2{display:grid;grid-template-columns:1fr 76px;gap:7px;margin-bottom:10px}
/* Line-item row (Phase 10 — Saava editorial) — description, amount, remove */
.inv-line{
  display:grid;grid-template-columns:1fr 110px 32px;
  gap:6px;align-items:center;margin-bottom:6px;
}
.inv-line input.inv-line-desc,
.inv-line input.inv-line-amt{
  font-family:var(--font-sans);font-size:13px;font-weight:500;
  padding:9px 11px;
  border:1px solid var(--border2);
  background:var(--surface);color:var(--navy);
  width:100%;margin:0;
  -webkit-appearance:none;appearance:none;
}
.inv-line input.inv-line-amt{font-family:var(--font-mono);text-align:right}
.inv-line input.inv-line-desc:focus,
.inv-line input.inv-line-amt:focus{
  outline:none;border-color:var(--accent);
}
.inv-line .inv-line-rm{
  width:32px;height:32px;
  border:1px solid var(--border2);background:var(--surface);
  color:var(--text3);cursor:pointer;
  font-size:18px;line-height:1;padding:0;
  font-family:var(--font-sans);
  transition:color 180ms var(--ease),border-color 180ms var(--ease);
}
.inv-line .inv-line-rm:hover{color:var(--red);border-color:var(--red)}
@media(max-width:520px){
  .inv-line{grid-template-columns:1fr 110px 32px;font-size:14px}
}
.inv-field label{display:block;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text3);margin-bottom:5px}
.inv-field select,.inv-field input[type="number"],.inv-field input[type="text"]{width:100%;font-family:inherit;font-size:13px;font-weight:500;color:var(--text);background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-xs);padding:8px 10px;outline:none;transition:border-color .15s}
.inv-field select:focus,.inv-field input:focus{border-color:var(--blue)}
/* V274 — Invoice editor: align legacy form tokens with the editorial system.
   The form markup uses inline var(--surface2)/var(--text) in dozens of places;
   remapping those two tokens at .inv-shell scope warms everything (white fields,
   editorial ink) without touching the inline styles. The collapsible section
   headers (.adv-fold>summary) move from the old tan fill to soft paper. Scoped
   to .inv-shell, so nothing outside the invoice editor is affected; theme-aware
   via the --ot-* tokens. */
.inv-shell{--surface2:var(--ot-surf,#FFFFFF);--text:var(--ot-ink,#0E1116)}
.inv-shell details.adv-fold>summary{background:var(--ot-bg,#F5F1E8)!important;border-color:var(--ot-bd,#E5E0D4)!important;border-radius:var(--r-chip,8px)}
.inv-shell details.adv-fold>summary:hover{background:var(--ot-surf,#FFFFFF)!important}
.half-grid{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-bottom:14px}
.half-btn{border:2px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);padding:11px 10px;cursor:pointer;font-family:inherit;text-align:left;transition:transform .15s var(--ease-out),background .15s ease,border-color .15s ease,color .15s ease;color:var(--text)}
.half-btn.on{background:var(--blue);border-color:var(--blue);color:#fff}
.half-btn .hb-n{font-size:12px;font-weight:700;display:block}
.half-btn .hb-d{font-size:10px;opacity:.6;display:block;margin-top:2px}
.comm-wrap{margin-bottom:12px;display:none}
.comm-wrap.show{display:block}
.comm-box{background:var(--blue-bg);border:1px solid var(--blue-light);border-radius:var(--radius-sm);padding:12px 13px}
.comm-box label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--blue);display:block;margin-bottom:5px}
.comm-box input{width:100%;font-family:var(--font-mono);font-size:18px;font-weight:500;color:var(--blue);background:var(--surface);border:1px solid var(--blue-light);border-radius:var(--radius-xs);padding:8px 11px;outline:none}
.comm-box input:focus{border-color:var(--blue)}
.comm-hint{font-size:11px;color:var(--blue);margin-top:5px}
.inv-totals-panel{background:var(--surface2);border-radius:var(--radius-sm);padding:11px 13px;margin-bottom:13px;font-size:12px;border:1px solid var(--border)}
.itr{display:flex;justify-content:space-between;padding:3px 0;color:var(--text2)}
.itr .mn{font-family:var(--font-mono)}
.itr.big{font-size:14px;font-weight:700;color:var(--text);border-top:1px solid var(--border);margin-top:6px;padding-top:8px}
.btn-inv-preview{width:100%;background:var(--accent);color:#fff;border:none;border-radius:var(--radius-sm);font-family:inherit;font-size:12px;font-weight:700;padding:12px;cursor:pointer;margin-bottom:8px}
.btn-inv-preview:hover{background:var(--navy-hover)}
.btn-inv-dl{width:100%;background:var(--green);color:#fff;border:none;border-radius:var(--radius-sm);font-family:inherit;font-size:12px;font-weight:700;padding:12px;cursor:pointer;margin-bottom:8px;display:none}
.btn-inv-dl:hover{background:var(--green-dark)}
.btn-inv-dl.show{display:block}
.inv-fn{font-size:10px;font-family:var(--font-mono);color:var(--text3);background:var(--surface2);border-radius:5px;padding:5px 8px;word-break:break-all;display:none;margin-bottom:12px}
.inv-fn.show{display:block}
.inv-sec{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text3);margin:16px 0 7px;padding-bottom:5px;border-bottom:1px solid var(--border)}
.inv-saved-row{display:flex;align-items:center;justify-content:space-between;background:var(--surface2);border-radius:var(--radius-xs);padding:7px 10px;margin-bottom:5px;cursor:pointer;border:1px solid transparent;transition:border-color .15s}
.inv-saved-row:hover{border-color:var(--blue)}
.inv-saved-row .isr-lbl{font-size:12px;font-weight:600;color:var(--text)}
.inv-saved-row .isr-amt{font-size:11px;font-family:var(--font-mono);color:var(--text3);margin-top:2px}
.inv-saved-row .isr-del{background:none;border:none;color:var(--text3);cursor:pointer;font-size:14px;padding:0 3px}
.inv-saved-row .isr-del:hover{color:var(--red)}
.btn-inv-save{width:100%;background:none;border:1px dashed var(--border2);border-radius:var(--radius-xs);color:var(--blue);font-family:inherit;font-size:11px;font-weight:600;padding:7px;cursor:pointer;transition:transform .15s var(--ease-out),background .15s ease,border-color .15s ease,color .15s ease;margin-top:3px}
.btn-inv-save:hover{background:var(--blue-bg);border-color:var(--blue)}
.inv-preview-pane{background:var(--ot-bd,#E4DCCD);padding:30px 36px;display:flex;flex-direction:column;align-items:center;overflow-y:auto;height:calc(100vh - 90px)}
.inv-preview-lbl{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ot-t2,#6A655B);align-self:flex-start;width:720px;margin-bottom:12px}
.inv-doc{background:#fff;width:720px;min-height:960px;box-shadow:0 10px 56px rgba(0,0,0,.2);padding:52px 52px 48px;font-family:inherit}
.inv-doc .id-top{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:26px}
.inv-doc .id-title{font-size:30px;font-weight:800;letter-spacing:-.03em;color:#D8431B;line-height:1}
.inv-doc .id-title-sub{font-size:9px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:#8A8578;margin-top:4px}
.inv-doc .id-right{text-align:right}
.inv-doc .id-right-lbl{font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#8A8578;margin-bottom:3px}
.inv-doc .id-right-date{font-size:13px;font-weight:600;color:#0E1116}
.inv-doc .id-rule{height:2px;background:linear-gradient(90deg,#D8431B 0%,#D8431B 55%,#F6DFD5 100%);border-radius:2px;margin-bottom:26px}
.inv-doc .id-parties{display:grid;grid-template-columns:1fr 1fr;gap:32px;margin-bottom:22px}
.inv-doc .id-pty-lbl{font-size:8px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#D8431B;margin-bottom:8px}
.inv-doc .id-pty-name{font-size:13px;font-weight:700;color:#0E1116;margin-bottom:4px}
.inv-doc .id-pty-body{font-size:11px;color:#5F6470;line-height:1.8}
.inv-doc .id-pty-body .mn{font-family:var(--font-mono);font-size:10px}
.inv-doc .id-strip{background:#F7F4EC;border-radius:var(--r-chip,8px);padding:12px 16px;margin-bottom:24px;display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.inv-doc .id-strip-item label{display:block;font-size:8px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#8A8578;margin-bottom:3px}
.inv-doc .id-strip-item span{font-size:12px;font-weight:600;color:#0E1116}
.inv-doc table{width:100%;border-collapse:collapse;margin-bottom:18px}
.inv-doc table thead tr{border-bottom:2px solid #0E1116}
.inv-doc table thead th{font-size:8px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#8A8578;padding:0 0 8px;text-align:left}
.inv-doc table thead th:last-child{text-align:right}
.inv-doc table tbody tr{border-bottom:1px solid #E5E0D4}
.inv-doc table tbody td{padding:12px 0;font-size:12px;color:#0E1116;vertical-align:top}
.inv-doc table tbody td.td-p{font-size:10px;color:#8A8578;padding-right:18px;white-space:nowrap}
.inv-doc table tbody td.td-a{text-align:right;font-family:var(--font-mono);white-space:nowrap}
.inv-doc .id-totals{margin-left:auto;width:240px}
.inv-doc .id-tr{display:flex;justify-content:space-between;align-items:center;padding:6px 0;font-size:12px;color:#5F6470;border-bottom:1px solid #E5E0D4}
.inv-doc .id-tr .mn{font-family:var(--font-mono)}
.inv-doc .id-tf{background:#D8431B;border-radius:var(--r-chip,8px);padding:12px 14px;display:flex;justify-content:space-between;align-items:center;margin-top:9px;color:#fff;font-weight:700;font-size:13px}
.inv-doc .id-tf .mn{font-family:var(--font-mono);font-size:15px}
.inv-doc .id-footer{margin-top:40px;padding-top:16px;border-top:1px solid #E5E0D4;display:flex;justify-content:space-between;align-items:flex-end}
.inv-doc .id-foot-note{font-size:9px;color:#8A8578;line-height:1.9}
.inv-doc .id-foot-bn{text-align:right;font-size:9px;font-family:var(--font-mono);color:#8A8578;line-height:1.9}
.inv-doc .id-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;height:540px;color:#6E6A61;gap:10px}
.inv-doc .id-placeholder .ph-ic{font-size:40px}
.inv-doc .id-placeholder p{font-size:13px;text-align:center}

/* ── Print ──────────────────────────────── */
@media print{
  *{-webkit-print-color-adjust:exact !important;print-color-adjust:exact !important;color-adjust:exact !important}
  html,body{background:#fff !important;margin:0 !important;padding:0 !important}
  .topbar,.tabs,.inv-panel,.inv-preview-lbl,.vela-banner,#vela-toast,.btn-inv-preview,.btn-inv-dl,.btn-inv-save,.inv-fn,.ov,#vela-lock{display:none !important}
  .inv-shell{display:block !important;grid-template-columns:1fr !important;min-height:auto !important}
  .inv-preview-pane{padding:0 !important;background:#fff !important;height:auto !important;overflow:visible !important;display:block !important}
  .inv-doc{width:100% !important;max-width:none !important;box-shadow:none !important;padding:0 !important;min-height:auto !important;margin:0 !important}
  .inv-doc .id-rule{background:#D8431B !important}
  /* Only print the invoice page */
  #wrap > :not(#pg-invoice){display:none !important}
  #pg-invoice{display:block !important;padding:0 !important}
  /* Avoid orphan rows in the items table */
  .inv-doc table tr{page-break-inside:avoid}
  .inv-doc .id-top,.inv-doc .id-parties,.inv-doc .id-strip{page-break-inside:avoid}
}
@page{size:A4;margin:12mm 14mm}

/* ══════ Block 2: Editorial overlay A ══════ */
  #vela-lock{
    position:fixed;inset:0;z-index:800;
    display:flex;align-items:center;justify-content:center;
    overflow:hidden;
    background:var(--bg);
    color:var(--text);
    padding:24px;
  }
  /* The arch — bold red architectural shape behind the wordmark.
     Built from radial gradients so it scales clean at any size. */
  #vela-lock .vl-arch{
    position:absolute;
    top:50%;left:50%;
    transform:translate(-50%, -38%);
    width:min(80vw, 540px);
    height:min(80vw, 540px);
    background:var(--accent);
    border-radius:50% 50% 0 0 / 100% 100% 0 0;
    z-index:1;
    opacity:0;
    animation:saava-arch-rise 1200ms cubic-bezier(0.22,0.61,0.36,1) 80ms forwards;
  }
  /* Inner navy arch nested for depth — like the reference image */
  #vela-lock .vl-arch::before{
    content:'';position:absolute;
    top:8%;left:14%;right:14%;bottom:0;
    background:var(--navy);
    border-radius:50% 50% 0 0 / 100% 100% 0 0;
  }
  #vela-lock .vl-arch::after{
    content:'';position:absolute;
    top:18%;left:26%;right:26%;bottom:0;
    background:var(--accent);
    border-radius:50% 50% 0 0 / 100% 100% 0 0;
  }
  @keyframes saava-arch-rise{
    from{opacity:0;transform:translate(-50%, -28%) scale(.94)}
    to  {opacity:1;transform:translate(-50%, -38%) scale(1)}
  }
  /* Static geometric mark — bottom-left corner.
     Vermilion square overlapping a navy circle — like the reference
     compositions. Pure CSS, no 3D, no blue ball. */
  #vela-lock .vl-mark{
    position:absolute;bottom:80px;left:40px;
    width:130px;height:130px;
    z-index:4;
    pointer-events:none;
  }
  #vela-lock .vl-mark .m-sq{
    position:absolute;top:0;left:0;
    width:78px;height:78px;
    background:var(--accent);
  }
  #vela-lock .vl-mark .m-cir{
    position:absolute;bottom:0;right:0;
    width:96px;height:96px;border-radius:50%;
    background:var(--navy);
  }
  #vela-lock .vl-mark .m-cir::after{
    /* inner square hole — adds depth */
    content:'';position:absolute;
    top:50%;left:50%;transform:translate(-50%,-50%);
    width:36px;height:36px;
    background:var(--bg);
  }
  @media(max-width:640px){
    #vela-lock .vl-mark{width:96px;height:96px;bottom:90px;left:24px}
    #vela-lock .vl-mark .m-sq{width:58px;height:58px}
    #vela-lock .vl-mark .m-cir{width:70px;height:70px}
    #vela-lock .vl-mark .m-cir::after{width:26px;height:26px}
  }
  /* Content stack */
  #vela-lock .vl-stage{
    position:relative;z-index:3;
    width:100%;max-width:560px;text-align:center;
    display:flex;flex-direction:column;align-items:center;gap:14px;
    margin-top:24vh;
  }
  #vela-lock .vl-eyebrow{
    display:inline-flex;align-items:center;gap:10px;
    font-family:var(--font-sans);
    font-size:10px;letter-spacing:.36em;text-transform:uppercase;
    color:var(--accent-text);font-weight:700;
    opacity:0;transform:translateY(8px);
    animation:saava-fade-up 700ms var(--ease) 700ms forwards;
  }
  #vela-lock .vl-eyebrow::before,#vela-lock .vl-eyebrow::after{
    content:'';width:24px;height:1px;background:var(--accent-text);display:inline-block;
  }
  /* V185 — wordmark sized to fit INSIDE the arch shape on mobile. Was
     clamp(56px, 13vw, 132px) which exceeded the arch width on portrait
     phones, clipping the leading "S" and trailing "s" (the cream-on-
     cream text becomes invisible where it overruns the arch). Tightened
     the clamp + max-width so the wordmark always sits cleanly within
     the orange backdrop. */
  #vela-lock .vl-name{
    font-family:var(--font-sans);
    font-size:clamp(40px, 11vw, 110px);
    font-weight:700;
    line-height:.92;letter-spacing:-.04em;
    color:var(--accent-text);
    max-width:90%;
    opacity:0;transform:translateY(14px);
    animation:saava-fade-up 800ms var(--ease) 820ms forwards;
  }
  #vela-lock .vl-name em{
    font-family:var(--font-display);font-style:italic;font-weight:600;
  }
  /* V185 — secondary "continue without signing in" link. Lets people
     explore the app before committing to an account; we set a
     localStorage flag so the bypass persists across reloads. */
  #vela-lock .vl-skip{
    background:none;border:none;
    margin-top:8px;
    font-family:var(--font-sans);
    font-size:12px;letter-spacing:.08em;
    color:var(--accent-text);
    opacity:.75;cursor:pointer;
    padding:8px 14px;
    text-transform:uppercase;font-weight:600;
    transition:opacity 200ms ease,transform 200ms ease;
    animation:saava-fade-up 700ms var(--ease) 1220ms forwards;
    opacity:0;transform:translateY(8px);
  }
  #vela-lock .vl-skip:hover{opacity:1;transform:translateY(-1px)}
  /* V185 — 3-up feature ribbon below the CTAs explaining what Saava is.
     Lifts the lock screen from blank-marketing-page to genuine on-ramp. */
  #vela-lock .vl-feats{
    display:grid;grid-template-columns:repeat(3,1fr);gap:14px;
    margin-top:36px;
    max-width:520px;width:100%;
    opacity:0;transform:translateY(10px);
    animation:saava-fade-up 800ms var(--ease) 1400ms forwards;
  }
  #vela-lock .vl-feat{
    text-align:center;
    padding:14px 10px;
    background:rgba(244,239,230,0.06);
    border:1px solid rgba(244,239,230,0.15);
    border-radius:10px;
    backdrop-filter:blur(8px);
    -webkit-backdrop-filter:blur(8px);
  }
  #vela-lock .vl-feat-lbl{
    font-family:var(--font-sans);
    font-size:9px;letter-spacing:.16em;text-transform:uppercase;
    color:var(--accent-text);opacity:.65;font-weight:600;
    margin-bottom:4px;
  }
  #vela-lock .vl-feat-val{
    font-family:var(--font-display);font-style:italic;
    font-size:14px;color:var(--accent-text);font-weight:500;
    line-height:1.2;
  }
  @media(max-width:500px){
    #vela-lock .vl-feats{grid-template-columns:1fr;max-width:280px;gap:8px}
    #vela-lock .vl-feat{padding:10px 12px;display:flex;align-items:center;justify-content:space-between;text-align:left;gap:12px}
    #vela-lock .vl-feat-lbl{margin-bottom:0;flex-shrink:0}
    #vela-lock .vl-feat-val{text-align:right}
  }
  #vela-lock .vl-name-2{display:none}   /* not needed in this design */
  #vela-lock .vl-tagline{
    font-family:var(--font-display);
    font-size:clamp(15px, 2.4vw, 19px);
    font-style:italic;font-weight:400;
    color:var(--accent-text);max-width:30ch;line-height:1.4;
    margin:6px 0 8px;
    opacity:.9;
    transform:translateY(10px);
    animation:saava-fade-up 700ms var(--ease) 960ms forwards;
  }
  #vela-lock .vl-cta{
    margin-top:14px;
    display:inline-flex;align-items:center;gap:10px;
    padding:16px 28px;
    background:var(--accent-text);color:var(--navy);
    border:none;border-radius:0;
    font-family:var(--font-sans);font-size:13px;font-weight:700;
    letter-spacing:.06em;cursor:pointer;
    text-transform:uppercase;
    transition:transform 220ms var(--ease),background 220ms var(--ease);
    opacity:0;transform:translateY(10px);
    animation:saava-fade-up 700ms var(--ease) 1100ms forwards;
    position:relative;overflow:hidden;
  }
  #vela-lock .vl-cta:hover{transform:translateY(-2px);background:#FFFFFF}
  #vela-lock .vl-cta:active{transform:translateY(0) scale(.98)}
  #vela-lock .vl-cta svg{width:14px;height:14px}
  #vela-lock .vl-status{
    font-size:11px;color:rgba(255,245,238,.7);
    letter-spacing:.08em;min-height:16px;
    margin-top:14px;
    opacity:0;animation:saava-fade-up 700ms var(--ease) 1240ms forwards;
  }
  #vela-lock .vl-foot{
    position:absolute;bottom:24px;left:0;right:0;
    text-align:center;z-index:5;
    font-family:var(--font-sans);
    font-size:10px;letter-spacing:.36em;text-transform:uppercase;
    color:var(--text3);font-weight:700;
    opacity:0;animation:saava-fade-up 800ms var(--ease) 1400ms forwards;
  }
  #vela-lock .vl-foot span{color:var(--accent);font-size:14px;line-height:0}
  @keyframes saava-fade-up{
    to{opacity:1;transform:translateY(0)}
  }
  @media (prefers-reduced-motion: reduce){
    #vela-lock .vl-arch{animation:none;opacity:1}
    #vela-lock .vl-eyebrow,#vela-lock .vl-name,#vela-lock .vl-tagline,
    #vela-lock .vl-cta,#vela-lock .vl-status,#vela-lock .vl-foot{
      animation:none;opacity:1;transform:none;
    }
    #vela-lock .vl-tagline{opacity:.9}
    #vela-lock .vl-status{opacity:.7}
  }

/* ══════ Block 3: Overlay B ══════ */
/* V211 - last of the old-blue palette retired: install banner now ink +
   vermilion like every other floating surface. */
.vela-banner{position:fixed;top:12px;left:50%;transform:translateX(-50%) translateY(-120%);background:#0E1116;color:#F5F1E8;padding:11px 16px;border-radius:14px;font-size:13px;font-weight:500;z-index:9998;box-shadow:0 12px 32px rgba(0,0,0,.22);display:flex;align-items:center;gap:10px;max-width:94vw;opacity:0;transition:opacity .3s ease,transform .35s ease;border:1px solid rgba(255,255,255,.09)}
.vela-banner.show{opacity:1;transform:translateX(-50%) translateY(0)}
.vela-banner .vb-msg{flex:1;line-height:1.4}
.vela-banner .vb-cta{background:#D8431B;color:#fff;border:none;padding:6px 12px;border-radius:var(--r-chip,8px);font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;white-space:nowrap}
.vela-banner .vb-cta:hover{background:#C8351A}
.vela-banner .vb-x{background:none;border:none;color:#B9B4A9;font-size:18px;line-height:1;cursor:pointer;padding:2px 6px}
.vela-banner .vb-x:hover{color:#fff}
@media (max-width:480px){.vela-banner{font-size:12px;padding:9px 12px}.vela-banner .vb-cta{padding:5px 10px;font-size:11px}}

/* ══════ Block 4: Editorial overlay C (v185–v199) ══════ */
  /* Click-ripple ink — coral, scales up + fades. */
  .saava-rip{position:relative;overflow:hidden}
  .saava-rip-ink{
    position:absolute;border-radius:50%;
    background:rgba(255,107,71,.32);pointer-events:none;
    transform:scale(0);opacity:1;
    animation:saava-rip-anim 580ms cubic-bezier(0.22,0.61,0.36,1) forwards;
  }
  @keyframes saava-rip-anim{
    to{transform:scale(2.2);opacity:0}
  }
  @media (prefers-reduced-motion: reduce){
    .saava-rip-ink{display:none}
  }

/* ──────────────────────────────────────────────────────────────────
   Phase 17 — v21 Overview redesign
   All new selectors scoped under .ovr-page so other pages stay intact.
   ────────────────────────────────────────────────────────────────── */
.ovr-page{--ot-font:'Inter Tight','Inter',-apple-system,sans-serif;--ot-bg:var(--bg);--ot-surf:#FFFFFF;--ot-ink:#0E1116;--ot-t2:#5F6470;--ot-t3:#9CA0AA;--ot-ver:#D8431B;--ot-dark:#111418;--ot-bd:#E5E0D4;font-family:var(--ot-font);color:var(--ot-ink);font-feature-settings:'tnum','ss01';line-height:1.45}
.ovr-page *{box-sizing:border-box}
.ovr-page .ovr-reveal{opacity:0;transform:translateY(28px);transition:opacity 700ms cubic-bezier(0.22,0.61,0.36,1),transform 700ms cubic-bezier(0.22,0.61,0.36,1)}
.ovr-page .ovr-reveal.in{opacity:1;transform:translateY(0)}

/* HERO */
.ovr-page .ovr-hero{padding:26px 22px 22px;position:relative;background:var(--ot-bg)}
.ovr-page .ovr-ctx{font-family:var(--ot-font);font-size:11px;font-weight:600;letter-spacing:0.16em;text-transform:uppercase;color:var(--ot-t2);margin-bottom:12px;max-width:200px}
.ovr-page .ovr-num{font-family:var(--ot-font);font-size:66px;font-weight:700;letter-spacing:-0.055em;line-height:0.88;color:var(--ot-ink);font-variant-numeric:tabular-nums;display:flex;align-items:flex-start;white-space:nowrap}
.ovr-page .ovr-num .ovr-cents{font-size:22px;color:var(--ot-t2);font-weight:500;margin-top:7px;margin-left:3px;letter-spacing:-0.01em;line-height:1}
.ovr-page .ovr-mark{position:absolute;top:12px;right:16px;width:38px;height:38px;opacity:0;animation:ovr-markIn 900ms 100ms cubic-bezier(0.22,0.61,0.36,1) forwards;transform:scale(0.5) rotate(-200deg)}
@keyframes ovr-markIn{to{opacity:1;transform:scale(1) rotate(0deg)}}
.ovr-page .ovr-mark svg{width:100%;height:100%;animation:ovr-tilt 8s 1s ease-in-out infinite}
@keyframes ovr-tilt{0%,100%{transform:rotate(-10deg)}50%{transform:rotate(10deg)}}
.ovr-page .ovr-storywrap{position:relative;margin-top:20px}
.ovr-page .ovr-stories{display:flex;gap:8px;padding:0 4px 4px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.ovr-page .ovr-stories::-webkit-scrollbar{display:none}
.ovr-page .ovr-stf{position:absolute;top:0;bottom:4px;width:16px;pointer-events:none;z-index:2}
.ovr-page .ovr-stf.l{left:0;background:linear-gradient(to right,var(--ot-bg),rgba(244,239,230,0))}
.ovr-page .ovr-stf.r{right:0;background:linear-gradient(to left,var(--ot-bg),rgba(244,239,230,0))}
.ovr-page .ovr-story{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer;scroll-snap-align:start;transition:transform 180ms;border:none;background:none;font-family:inherit;padding:0}
.ovr-page .ovr-story:active{transform:scale(0.94)}
.ovr-page .ovr-scir{width:50px;height:50px;border-radius:50%;background:var(--ot-surf);border:0.5px solid var(--ot-bd);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:500;color:var(--ot-ink);font-variant-numeric:tabular-nums;letter-spacing:-0.01em;transition:transform 220ms var(--ease-out),background 220ms ease,border-color 220ms ease,color 220ms ease}
/* Hover effect uses color shift + subtle scale only — no translateY
   because the .ovr-stories container has overflow-x:auto, which
   auto-promotes overflow-y to clipping. A lift would be cut off
   at the container edge. Scale stays inside the bounding box. */
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-story:hover .ovr-scir{
    border-color:var(--ot-ver);
    background:rgba(232,74,26,0.05);
    color:var(--ot-ver);
  }
}
.ovr-page .ovr-story.now .ovr-scir{border:1.5px solid var(--ot-ver);color:var(--ot-ver);font-weight:700}
.ovr-page .ovr-sm{font-size:9px;font-weight:500;letter-spacing:0.14em;color:var(--ot-t3);text-transform:uppercase}
.ovr-page .ovr-story.now .ovr-sm{color:var(--ot-ver)}
.ovr-page .ovr-sub{font-size:13px;font-weight:400;color:var(--ot-t2);margin:18px 22px 0;letter-spacing:-0.01em}
.ovr-page .ovr-sub b{font-weight:500;color:var(--ot-ink)}
.ovr-page .ovr-progbar{height:1px;background:var(--ot-bd);position:relative;margin:8px 22px 0;overflow:hidden}
.ovr-page .ovr-progbar .fill{position:absolute;inset:0;background:var(--ot-ver);transform:scaleX(0);transform-origin:left;animation:ovr-fillbar 700ms 240ms cubic-bezier(0.22,1,0.36,1) forwards}
@keyframes ovr-fillbar{to{transform:scaleX(var(--p,0))}}

/* V146 — Hero stats block. Two cells: Debt-free by + Progress.
   On mobile they sit side-by-side under the number; on desktop they
   stack vertically in the right column. */
.ovr-page .ovr-herostats{
  display:flex;flex-direction:row;flex-wrap:wrap;
  gap:18px 24px;
  margin:16px 22px 0;
}
.ovr-page .ovr-hstat{
  display:flex;flex-direction:column;gap:3px;
  flex:1 1 140px;min-width:130px;
}
.ovr-page .ovr-hslbl{
  font-family:var(--ot-font);
  font-size:10px;font-weight:500;
  letter-spacing:0.16em;text-transform:uppercase;
  color:var(--ot-t2);
}
.ovr-page .ovr-hsval{
  font-family:var(--ot-font);
  font-size:18px;font-weight:600;
  letter-spacing:-0.02em;line-height:1.1;
  color:var(--ot-ink);
  font-variant-numeric:tabular-nums;
}
.ovr-page .ovr-hssub{
  font-size:12px;color:var(--ot-t2);
  letter-spacing:-0.005em;
}

/* V147 — Three orbital rings in the hero empty middle area. Hidden
   on mobile (where the single .ovr-mark in the top-right is enough
   and three rings would crowd the narrow viewport). Desktop styles
   below set positions, sizes, and subtle drift animations. */
.ovr-page .ovr-rings{display:none}
.ovr-page .ovr-ring{position:absolute;aspect-ratio:1;pointer-events:none;transform:translate(-50%,-50%)}
.ovr-page .ovr-ring svg{width:100%;height:100%;display:block}

/* TAKE ACTION header */
.ovr-page .ovr-actsec{padding:26px 22px 14px;display:flex;align-items:center;gap:14px}
.ovr-page .ovr-actglyph{width:38px;height:38px;flex-shrink:0;border-radius:50%;background:#D8431B;color:#FFFFFF;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:transform 300ms cubic-bezier(0.22,0.61,0.36,1);position:relative;overflow:hidden}
.ovr-page .ovr-actglyph::before{content:'';position:absolute;inset:5px;border-radius:50%;border:1px dashed rgba(255,255,255,0.5);animation:ovr-actSpin 9s linear infinite;pointer-events:none}
@keyframes ovr-actSpin{to{transform:rotate(360deg)}}
.ovr-page .ovr-actglyph svg{width:20px;height:20px;position:relative;z-index:1}
.ovr-page .ovr-actglyph:hover{transform:scale(1.1) rotate(6deg)}
.ovr-page .ovr-acttitle{font-family:var(--ot-font);font-size:30px;font-weight:700;letter-spacing:-0.04em;line-height:0.95;color:var(--ot-ink)}
.ovr-page .ovr-acttitle em{font-style:italic;color:var(--ot-ver);font-weight:700}
.ovr-page .ovr-actsub{font-size:11.5px;color:var(--ot-t2);margin-top:3px;letter-spacing:-0.005em;font-weight:400}

/* BENTO actions */
.ovr-page .ovr-qabento{padding:0 22px 14px;display:grid;grid-template-columns:124px 1fr 1fr;grid-template-rows:repeat(3,58px);gap:8px}
.ovr-page .ovr-qab-big{grid-column:1;grid-row:span 3;background:#D8431B !important;background-color:#D8431B !important;color:#FFFFFF !important;border:none;border-radius:var(--r-card,18px);padding:14px;display:flex;flex-direction:column;justify-content:space-between;cursor:pointer;transition:transform 280ms cubic-bezier(0.22,0.61,0.36,1);font-family:inherit;text-align:left;position:relative;overflow:hidden}
.ovr-page .ovr-qab-big:hover{transform:translateY(-3px) rotateX(3deg) rotateY(-3deg)}
.ovr-page .ovr-qic-big{width:42px;height:42px;background:rgba(255,255,255,0.20) !important;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#FFFFFF !important;position:relative;z-index:1}
.ovr-page .ovr-qic-big svg{stroke:#FFFFFF;width:20px;height:20px}
.ovr-page .ovr-qb-eyebrow{font-size:9.5px;font-weight:500;letter-spacing:0.18em;text-transform:uppercase;color:#FFFFFF !important;opacity:0.9;margin-bottom:3px}
.ovr-page .ovr-qb-title{font-family:var(--ot-font);font-size:22px;font-weight:700;letter-spacing:-0.03em;line-height:1.02;position:relative;z-index:1;color:#FFFFFF !important}
.ovr-page .ovr-qab-sm{background:var(--ot-surf);border:0.5px solid var(--ot-bd);border-radius:14px;padding:8px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;cursor:pointer;transition:all 240ms;font-family:inherit;color:var(--ot-ink);text-align:center}
.ovr-page .ovr-qab-sm:hover{background:var(--ot-ink);color:var(--ot-bg);border-color:var(--ot-ink);transform:translateY(-3px)}
.ovr-page .ovr-qab-sm.dark{background:var(--ot-dark);color:#F4EFE6;border-color:var(--ot-dark)}
.ovr-page .ovr-qab-sm.dark:hover{background:var(--ot-ver);color:#fff;border-color:var(--ot-ver)}
.ovr-page .ovr-qab-sm svg{width:17px;height:17px;flex-shrink:0;transition:transform 240ms;stroke:currentColor}
.ovr-page .ovr-qab-sm:hover svg{transform:scale(1.15)}
.ovr-page .ovr-qab-sm span{font-size:10.5px;font-weight:500;letter-spacing:-0.005em;line-height:1;white-space:nowrap}

/* Mini marquee under bento */
.ovr-page .ovr-actfoot{padding:12px 0 22px;overflow:hidden;white-space:nowrap}
.ovr-page .ovr-actmarq-track{display:flex;width:max-content;animation:ovr-actMarq 18s linear infinite;align-items:center}
.ovr-page .ovr-actmarq-seq{display:flex;flex-shrink:0;align-items:center}
/* V116: marquee text demoted from vermilion to ash. This strip is
   decorative tagline copy ("Quick · No menus · Always available");
   vermilion was carrying decorative weight instead of info weight. */
.ovr-page .ovr-actmarq-seq span.t{font-size:15px;font-weight:600;font-style:italic;color:var(--ot-t2);padding-right:14px;letter-spacing:-0.02em;display:inline-block}
.ovr-page .ovr-actmarq-seq span.d{font-size:15px;font-weight:700;color:var(--ot-t3);padding-right:14px;letter-spacing:-0.02em;display:inline-block;font-style:normal}
@keyframes ovr-actMarq{to{transform:translateX(-50%)}}

/* TODAY block */
/* V198 — kept the dark Today banner visible (user reverted the v197
   `display:none` on desktop — they wanted it tuned, not gone). Padding
   reverted to v194 values (28/32) which is the most compact it can be
   while still hosting content. */
.ovr-page .ovr-today{background:var(--ot-dark);color:#F4EFE6;padding:28px 22px 32px;position:relative;cursor:pointer;transition:transform 240ms}
.ovr-page .ovr-today:hover{transform:translateY(-3px)}
.ovr-page .ovr-tctx{font-size:11px;font-weight:500;letter-spacing:0.18em;text-transform:uppercase;color:rgba(244,239,230,0.5);margin-bottom:16px}
.ovr-page .ovr-tmeta{position:absolute;top:44px;right:22px;font-size:11px;font-weight:500;letter-spacing:0.16em;text-transform:uppercase;color:var(--ot-ver)}
.ovr-page .ovr-th{font-family:var(--ot-font);font-size:52px;font-weight:700;line-height:0.9;letter-spacing:-0.055em;margin-bottom:18px}
.ovr-page .ovr-th em{font-style:normal;color:var(--ot-ver)}
.ovr-page .ovr-tam{font-size:23px;font-weight:500;letter-spacing:-0.02em;margin-bottom:26px;font-variant-numeric:tabular-nums}
.ovr-page .ovr-tcta{font-size:12px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:#F4EFE6;border-bottom:1px solid var(--ot-ver);padding-bottom:4px;display:inline-block;transition:color 240ms}
.ovr-page .ovr-today:hover .ovr-tcta{color:var(--ot-ver)}

/* V145 — inline Coming-up list inside the dark Today block. Was a
   separate cream-bg section below the dark Today block that often
   duplicated today's action row. Styled for the dark surface (cream
   text, low-opacity dividers). Individual rows are clickable buttons
   that stop propagation so they don't trigger the parent's onclick. */
.ovr-page .ovr-today-up{
  margin-top:32px;
  padding-top:22px;
  border-top:0.5px solid rgba(244,239,230,0.18);
}
.ovr-page .ovr-today-up-h{
  font-size:11px;font-weight:500;letter-spacing:0.18em;text-transform:uppercase;
  color:rgba(244,239,230,0.5);margin-bottom:14px;
}
.ovr-page .ovr-today-up-row{
  display:grid;grid-template-columns:64px 1fr auto;align-items:baseline;
  gap:12px;padding:14px 0;width:100%;text-align:left;
  background:none;border:none;border-top:0.5px solid rgba(244,239,230,0.10);
  cursor:pointer;font-family:inherit;color:#F4EFE6;
  transition:background 200ms ease;
}
.ovr-page .ovr-today-up-row:first-of-type{border-top:none;padding-top:6px}
.ovr-page .ovr-today-up-row:hover{background:rgba(244,239,230,0.04)}
.ovr-page .ovr-today-up-row .ovr-ud{
  font-size:12px;font-weight:500;font-variant-numeric:tabular-nums;
  letter-spacing:-0.01em;color:rgba(244,239,230,0.55);
}
.ovr-page .ovr-today-up-row .ovr-un{
  font-size:16px;font-weight:500;letter-spacing:-0.01em;color:#F4EFE6;
}
.ovr-page .ovr-today-up-row .ovr-uw{
  font-size:11px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;
  color:rgba(244,239,230,0.5);
}
.ovr-page .ovr-today-up-row .ovr-uw.urg{color:var(--ot-ver)}
@media (min-width:768px){
  .ovr-page .ovr-today-up{margin-top:44px;padding-top:28px}
  .ovr-page .ovr-today-up-row{grid-template-columns:96px 1fr auto;gap:24px;padding:18px 0}
  .ovr-page .ovr-today-up-row .ovr-un{font-size:18px}
}

/* STATS 2x2 */
.ovr-page .ovr-stats{display:grid;grid-template-columns:repeat(2,1fr);background:var(--ot-bg)}
.ovr-page .ovr-st{padding:22px;border-bottom:0.5px solid var(--ot-bd);border-right:0.5px solid var(--ot-bd)}
.ovr-page .ovr-st:nth-child(even){border-right:none}
.ovr-page .ovr-st:nth-child(n+3){border-bottom:none}
.ovr-page .ovr-sl2{font-size:11px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:var(--ot-t2);margin-bottom:10px}
.ovr-page .ovr-sval{font-size:28px;font-weight:700;color:var(--ot-ink);line-height:1;letter-spacing:-0.03em;font-variant-numeric:tabular-nums}
.ovr-page .ovr-sval.ac{color:var(--ot-ver)}

/* Section header (Your debts / Coming up) */
.ovr-page .ovr-sec{padding:26px 22px 12px;display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.ovr-page .ovr-sh{font-size:14px;font-weight:500;letter-spacing:0.18em;text-transform:uppercase;color:var(--ot-t2)}
.ovr-page .ovr-sa-link{font-size:11px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:var(--ot-ver)}

/* Debt cards row (flippable, alternating orange/white) */
.ovr-page .ovr-cardwrap{position:relative}
/* V184 — bumped padding-bottom from 10 to 24 so the gap below the debt
   cards better balances the 60px header gap above. Was: 10+18(minicard
   margin)=28 below vs 60+22=82 above — feels tight at the bottom. */
.ovr-page .ovr-cardrow{display:flex;gap:14px;padding:0 18px 24px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;perspective:1200px;scroll-padding-inline-start:18px;-webkit-overflow-scrolling:touch}
.ovr-page .ovr-cardrow::-webkit-scrollbar{display:none}
.ovr-page .ovr-crf{position:absolute;top:0;bottom:10px;width:22px;pointer-events:none;z-index:2}
.ovr-page .ovr-crf.r{right:0;background:linear-gradient(to left,var(--ot-bg) 10%,rgba(244,239,230,0))}
/* V196 — base (mobile/tablet) reduced 272 → 220 so cards sit tightly
   on phone-sized viewports too. Combined with the v196 flex-start +
   margin-top:auto layout change on .ovr-ff, content stacks at top and
   TAP FOR DETAILS rides the bottom edge without an empty middle. */
.ovr-page .ovr-fcard{flex:0 0 226px;height:220px;perspective:1200px;scroll-snap-align:start;cursor:pointer;transition:transform 600ms cubic-bezier(0.22,0.61,0.36,1)}
.ovr-page .ovr-fin{position:relative;width:100%;height:100%;transition:transform 700ms cubic-bezier(0.22,0.61,0.36,1);transform-style:preserve-3d}
.ovr-page .ovr-fcard.flipped .ovr-fin{transform:rotateY(180deg)}
/* V196 — was `justify-content:space-between` which pushed TAP FOR
   DETAILS to the bottom edge and left a huge empty middle. Now stacks
   content at the top; `.ovr-ftap` uses margin-top:auto below so it
   still rides the bottom edge cleanly without the visible vacuum. */
.ovr-page .ovr-ff,.ovr-page .ovr-fb{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;background:var(--ot-surf);border-radius:var(--r-card,18px);padding:22px 20px;display:flex;flex-direction:column;justify-content:flex-start;gap:14px;border:0.5px solid var(--ot-bd)}
.ovr-page .ovr-ff > .ovr-ftap,
.ovr-page .ovr-fb > button{margin-top:auto}
.ovr-page .ovr-fb{transform:rotateY(180deg);background:var(--ot-dark);color:#F4EFE6;border-color:var(--ot-dark)}
.ovr-page .ovr-ftag{font-size:11px;font-weight:500;letter-spacing:0.16em;text-transform:uppercase;color:var(--ot-t2)}
.ovr-page .ovr-ftap{font-size:10px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:var(--ot-t3);border-top:0.5px solid var(--ot-bd);padding-top:10px}
.ovr-page .ovr-fn{font-family:var(--ot-font);font-size:20px;font-weight:700;letter-spacing:-0.03em;line-height:1.12;margin-bottom:4px;margin-top:12px;color:var(--ot-ink);display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.24em}
.ovr-page .ovr-famt{font-family:var(--ot-font);font-size:30px;font-weight:700;letter-spacing:-0.04em;line-height:0.95;font-variant-numeric:tabular-nums;color:var(--ot-ink);white-space:nowrap}
.ovr-page .ovr-famt .ovr-cn{font-size:0.5em;color:var(--ot-t2);font-weight:500}
.ovr-page .ovr-fmeta{font-size:11px;font-weight:500;color:var(--ot-t2);letter-spacing:-0.01em;margin-top:6px}
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff{background:#D8431B !important;color:#FFFFFF !important;border-color:#D8431B !important}
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-fn,.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-famt{color:#FFFFFF !important}
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-famt .ovr-cn{color:rgba(255,255,255,0.75) !important}
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-ftag,.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-fmeta{color:rgba(255,255,255,0.85) !important}
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-ftap{color:#FFFFFF !important;border-top-color:rgba(255,255,255,0.3) !important}
.ovr-page .ovr-fb h4{font-size:13px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:rgba(244,239,230,0.55);margin-bottom:12px}
.ovr-page .ovr-fb ul{list-style:none;padding:0;margin:0;font-size:13px;display:flex;flex-direction:column;gap:9px}
.ovr-page .ovr-fb li{display:flex;justify-content:space-between;font-variant-numeric:tabular-nums;color:rgba(244,239,230,0.85)}
.ovr-page .ovr-fb li b{font-weight:500;color:#F4EFE6}
.ovr-page .ovr-fb .ovr-pay{margin-top:14px;display:block;text-align:center;font-size:12px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:var(--ot-ver);border:0.5px solid var(--ot-ver);border-radius:999px;padding:10px;background:none;cursor:pointer;font-family:inherit}

/* Insights ticker */
.ovr-page .ovr-insights{background:var(--ot-bg);padding:8px 0 14px;overflow:hidden;white-space:nowrap;border-top:0.5px solid var(--ot-bd);margin-top:32px}
.ovr-page .ovr-itrack{display:flex;width:max-content;animation:ovr-itrack 32s linear infinite}
.ovr-page .ovr-iseq{display:flex;flex-shrink:0}
.ovr-page .ovr-ipill{display:inline-block;padding:14px 22px;margin-right:10px;background:var(--ot-surf);border:0.5px solid var(--ot-bd);border-radius:999px;font-size:12px;font-weight:500;color:var(--ot-ink);white-space:nowrap}
.ovr-page .ovr-ipill b{color:var(--ot-ver);font-weight:500}
@keyframes ovr-itrack{to{transform:translateX(-50%)}}

/* Coming up list */
.ovr-page .ovr-ulist{padding:0;background:var(--ot-bg)}
.ovr-page .ovr-urow{display:grid;grid-template-columns:64px 1fr auto;align-items:baseline;padding:22px;gap:12px;border-top:0.5px solid var(--ot-bd);cursor:pointer;font-family:inherit;width:100%;background:none;border-left:none;border-right:none;color:inherit;text-align:left}
.ovr-page .ovr-urow:last-of-type{border-bottom:0.5px solid var(--ot-bd)}
.ovr-page .ovr-ud{font-size:12px;font-weight:500;color:var(--ot-t2);font-variant-numeric:tabular-nums;letter-spacing:-0.01em}
.ovr-page .ovr-un{font-size:16px;font-weight:500;color:var(--ot-ink);letter-spacing:-0.01em}
.ovr-page .ovr-uw{font-size:11px;font-weight:500;letter-spacing:0.14em;text-transform:uppercase;color:var(--ot-t2)}
.ovr-page .ovr-uw.urg{color:var(--ot-ver)}

/* Big dark marquee */
.ovr-page .ovr-mq{background:var(--ot-dark);padding:42px 0 38px;overflow:hidden;white-space:nowrap;margin-top:36px}
.ovr-page .ovr-mt-track{display:flex;width:max-content;animation:ovr-mqScroll 38s linear infinite}
.ovr-page .ovr-mq-seq{display:flex;flex-shrink:0}
.ovr-page .ovr-mq-item{font-family:var(--ot-font);font-size:36px;font-weight:700;color:#F4EFE6;letter-spacing:-0.05em;padding-right:32px;white-space:nowrap;display:inline-block}
.ovr-page .ovr-mq-item em{font-style:normal;color:var(--ot-ver)}
@keyframes ovr-mqScroll{to{transform:translateX(-50%)}}

/* Counter-marquee */
.ovr-page .ovr-mq2{background:var(--ot-bg);padding:24px 0;overflow:hidden;white-space:nowrap;border-top:0.5px solid var(--ot-bd);border-bottom:0.5px solid var(--ot-bd)}
.ovr-page .ovr-mt2-track{display:flex;width:max-content;animation:ovr-mq2Scroll 28s linear infinite}
.ovr-page .ovr-mq2-seq{display:flex;flex-shrink:0;align-items:center}
/* V116: "Stay focused" strip demoted from vermilion to ash (same
   reason as actmarq above — decorative tagline, not info). */
.ovr-page .ovr-mq2-item{font-family:var(--ot-font);font-size:22px;font-weight:600;color:var(--ot-t2);letter-spacing:-0.04em;padding-right:18px;white-space:nowrap;display:inline-block;font-style:italic}
.ovr-page .ovr-mq2-dot{font-size:22px;font-weight:700;color:var(--ot-ver);padding-right:18px;display:inline-block;font-style:normal}
@keyframes ovr-mq2Scroll{from{transform:translateX(-50%)}to{transform:translateX(0)}}

/* Saava can section */
.ovr-page .ovr-saavacan{padding:28px 0 16px;background:var(--ot-bg)}
.ovr-page .ovr-scintro{padding:0 22px 22px}
.ovr-page .ovr-schead{font-family:var(--ot-font);font-size:36px;font-weight:700;letter-spacing:-0.05em;line-height:0.95;color:var(--ot-ink);margin-bottom:8px}
.ovr-page .ovr-schead em{font-style:italic;color:var(--ot-ver);font-weight:700}
.ovr-page .ovr-scsub{font-size:13px;font-weight:400;color:var(--ot-t2);letter-spacing:-0.01em}
.ovr-page .ovr-canrow{display:flex;gap:14px;padding:0 18px 18px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;perspective:1200px;scroll-padding-inline-start:18px;-webkit-overflow-scrolling:touch}
.ovr-page .ovr-canrow::-webkit-scrollbar{display:none}
.ovr-page .ovr-canc{flex:0 0 250px;height:280px;background:var(--ot-surf);border:0.5px solid var(--ot-bd);border-radius:22px;padding:24px;scroll-snap-align:start;display:flex;flex-direction:column;justify-content:space-between;transition:transform 280ms cubic-bezier(0.22,0.61,0.36,1);position:relative;overflow:hidden;color:var(--ot-ink)}
.ovr-page .ovr-canc.dark{background:#111418 !important;color:#F4EFE6 !important;border-color:#111418}
.ovr-page .ovr-canc.dark .ovr-csub{color:rgba(244,239,230,0.7) !important}
.ovr-page .ovr-canc.dark .ovr-cnum{color:rgba(244,239,230,0.5) !important}
.ovr-page .ovr-canc.red{background:#D8431B !important;color:#FFFFFF !important;border-color:#D8431B}
.ovr-page .ovr-canc.red .ovr-csub{color:rgba(255,255,255,0.85) !important}
.ovr-page .ovr-canc.red .ovr-cnum{color:rgba(255,255,255,0.65) !important}
.ovr-page .ovr-canc.red .ovr-ctitle{color:#FFFFFF !important}
.ovr-page .ovr-canc.dark .ovr-ctitle{color:#F4EFE6 !important}
.ovr-page .ovr-canc:hover{transform:translateY(-4px) rotateX(2deg) rotateY(-3deg)}
.ovr-page .ovr-canhdr{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:auto}
.ovr-page .ovr-cnum{font-size:12px;font-weight:500;letter-spacing:0.16em;color:var(--ot-t3);font-variant-numeric:tabular-nums}
.ovr-page .ovr-cicon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;color:var(--ot-ver)}
.ovr-page .ovr-cicon svg{width:20px;height:20px;stroke:currentColor}
.ovr-page .ovr-canc.red .ovr-cicon{color:#FFFFFF !important}
.ovr-page .ovr-canc.dark .ovr-cicon{color:var(--ot-ver)}
.ovr-page .ovr-ctitle{font-family:var(--ot-font);font-size:26px;font-weight:700;letter-spacing:-0.04em;line-height:1.04;margin:24px 0 10px}
.ovr-page .ovr-csub{font-size:12px;font-weight:400;color:var(--ot-t2);letter-spacing:-0.005em;line-height:1.45}

/* ── Desktop layout — capped 1280px page, ring sits next to number ──
   Phase 19 rebuild: KEEP the 1280px cap from Phase 1 so number + ring
   sit close together. Hero is a flex container so the number and ring
   are natural siblings — no 1fr column pushing the ring to the right
   edge. The supporting items (stories, sublabel, progress) hang under
   the number via a wrapper. */
@media (min-width:768px){
  /* Phase 1 cap is preserved on desktop too — do NOT override .ovr-page width here. */

  /* HERO — tight grid composition. Number anchors left, ring anchors
     right via space-between. Ring spans ONLY the number + stories rows
     (not all 5) so it doesn't force the eyebrow to drift downward. No
     min-height — content drives the hero's height so vertical rhythm
     stays tight. */
  .ovr-page .ovr-hero{
    /* V146 — slightly tighter top/bottom (was 56/56), more focused. */
    padding:44px clamp(40px,6vw,120px) 48px;
    display:grid;
    grid-template-columns:1fr auto;
    grid-template-rows:auto auto auto;
    column-gap:clamp(40px,5vw,96px);
    row-gap:0;
    align-items:start;
    position:relative;
    min-height:0;
  }
  .ovr-page .ovr-ctx{
    grid-column:1;grid-row:1;
    font-size:13px;letter-spacing:0.2em;
    margin:0 0 14px 0;
  }
  .ovr-page .ovr-num{
    grid-column:1;grid-row:2;
    /* V146 — was clamp(108px,11vw,184px). Shrunk ~40% to reduce the
       "you owe this much" anxiety on a wide desktop. Still the
       largest thing on the page, still the protagonist. */
    font-size:clamp(56px,6vw,108px);
    line-height:0.92;letter-spacing:-0.045em;
    margin:0 0 18px 0;
  }
  .ovr-page .ovr-num .ovr-cents{font-size:clamp(20px,1.8vw,32px);margin-top:8px;margin-left:4px}
  /* V146 — Hero stats in column 2, centered vertically against the
     number block. Two stacked cells: Debt-free + Progress. */
  .ovr-page .ovr-herostats{
    grid-column:2;grid-row:1 / span 2;
    align-self:center;
    flex-direction:column;
    gap:clamp(18px,2vw,28px);
    min-width:200px;max-width:280px;
    margin:0;
    position:relative;
    z-index:2;
  }
  .ovr-page .ovr-hstat{flex:0 0 auto;min-width:0}
  .ovr-page .ovr-hslbl{font-size:11px;letter-spacing:0.2em}
  .ovr-page .ovr-hsval{font-size:clamp(20px,1.8vw,28px)}
  .ovr-page .ovr-hssub{font-size:13px}
  /* V146 — Ring is now ambient. Was clamp(340px,32vw,520px) at full
     opacity competing with the number. Now positioned absolutely
     behind the stats block at low opacity — personality without
     stealing the spotlight. */
  .ovr-page .ovr-mark{
    position:absolute !important;
    grid-column:unset !important;grid-row:unset !important;
    align-self:auto !important;justify-self:auto !important;
    right:clamp(20px,3vw,80px) !important;
    top:50% !important;
    transform:translateY(-50%) !important;
    width:clamp(180px,18vw,260px) !important;
    aspect-ratio:1 !important;height:auto !important;
    opacity:0.42 !important;
    animation:none !important;
    pointer-events:none;
    z-index:1;
  }
  .ovr-page .ovr-mark svg{width:100%;height:100%;animation:ovr-tilt 10s ease-in-out infinite}
  .ovr-page .ovr-storywrap{grid-column:1;grid-row:3;margin:24px 0 0;max-width:560px}
  .ovr-page .ovr-stories{padding:0 4px 4px}
  .ovr-page .ovr-scir{width:60px;height:60px;font-size:12px}

  /* Sections — tighter padding now that .ovr-page caps at 1280px.
     7vw was meant for full-bleed; with a cap we want consistent gutters. */
  /* V142 — base desktop: section top 60→32, heading 56→40 (max), glyph 54→44 */
  .ovr-page .ovr-actsec{padding:32px clamp(32px,5vw,80px) 14px}
  .ovr-page .ovr-acttitle{font-size:clamp(26px,2.8vw,40px)}
  .ovr-page .ovr-actglyph{width:44px;height:44px}
  .ovr-page .ovr-actglyph svg{width:22px;height:22px}
  .ovr-page .ovr-actsub{font-size:13px;margin-top:4px}

  /* Bento — 4 columns, big tile spans 2 rows */
  .ovr-page .ovr-qabento{
    /* V142 — bottom 22→10, gap 14→10 */
    padding:0 clamp(32px,5vw,80px) 10px;
    grid-template-columns:minmax(220px,1fr) repeat(3,1fr);
    grid-template-rows:repeat(2,clamp(88px,9vw,120px));
    gap:10px;
  }
  .ovr-page .ovr-qab-big{grid-row:span 2;padding:24px}
  .ovr-page .ovr-qb-title{font-size:clamp(28px,2.6vw,40px)}
  .ovr-page .ovr-qb-eyebrow{font-size:11px}
  .ovr-page .ovr-qic-big{width:60px;height:60px}
  .ovr-page .ovr-qic-big svg{width:28px;height:28px}
  .ovr-page .ovr-qab-sm{padding:14px}
  .ovr-page .ovr-qab-sm span{font-size:13px}
  .ovr-page .ovr-qab-sm svg{width:22px;height:22px}

  .ovr-page .ovr-actfoot{padding:10px 0 18px} /* V142 — was 18px 0 36px */
  .ovr-page .ovr-actmarq-seq span.t,.ovr-page .ovr-actmarq-seq span.d{font-size:20px}

  /* Today — capped, scaled so text never overflows
     V194 — reduced 64→40 vertical padding so banner is more compact. */
  .ovr-page .ovr-today{padding:40px clamp(32px,5vw,80px)}
  .ovr-page .ovr-tctx{font-size:13px}
  .ovr-page .ovr-tmeta{top:64px;right:clamp(32px,5vw,80px);font-size:13px}
  .ovr-page .ovr-th{font-size:clamp(48px,5.5vw,88px);line-height:1}
  .ovr-page .ovr-tam{font-size:clamp(24px,2.2vw,34px);margin-bottom:30px}
  .ovr-page .ovr-tcta{font-size:13px}

  /* Stats — 4 across, capped width */
  .ovr-page .ovr-stats{grid-template-columns:repeat(4,1fr);padding:0 clamp(32px,5vw,80px)}
  .ovr-page .ovr-st{padding:32px;border-bottom:none !important;border-right:0.5px solid var(--ot-bd) !important}
  .ovr-page .ovr-st:last-child{border-right:none !important}
  .ovr-page .ovr-sl2{font-size:12px}
  .ovr-page .ovr-sval{font-size:clamp(28px,2.8vw,42px)}

  .ovr-page .ovr-sec{padding:60px clamp(32px,5vw,80px) 22px}
  .ovr-page .ovr-sh{font-size:14px}

  /* Debt cards — still horizontal scroll (works for >4 cards) */
  .ovr-page .ovr-cardrow{
    padding-left:clamp(32px,5vw,80px);
    padding-right:clamp(32px,5vw,80px);
    scroll-padding-inline-start:clamp(32px,5vw,80px);
  }
  /* V196 — further reduced desktop card height 320 → 240 so the front
     face actually sits tight to its content. Combined with the v196
     justify-content:flex-start change on .ovr-ff (line ~4119), the
     empty middle is finally gone — TAP FOR DETAILS sits right under
     the status meta. */
  .ovr-page .ovr-fcard{flex-basis:340px;height:240px}
  .ovr-page .ovr-fn{font-size:24px}
  .ovr-page .ovr-famt{font-size:38px}
  .ovr-page .ovr-ctitle{font-size:30px}
  .ovr-page .ovr-cnum{font-size:13px}

  /* Saava-can — convert horizontal scroll to a 4-column grid on desktop
     so no card gets clipped on a capped 1280px canvas. */
  .ovr-page .ovr-canrow{
    display:grid !important;
    grid-template-columns:repeat(4,1fr);
    gap:14px;
    padding:0 clamp(32px,5vw,80px);
    overflow:visible !important;
  }
  .ovr-page .ovr-canc{flex-basis:auto;width:auto;height:clamp(280px,26vw,360px)}

  .ovr-page .ovr-ulist{padding:0 clamp(32px,5vw,80px)}
  .ovr-page .ovr-urow{padding:30px 0;grid-template-columns:96px 1fr auto;gap:24px}
  .ovr-page .ovr-ud{font-size:14px}
  .ovr-page .ovr-un{font-size:20px}
  .ovr-page .ovr-uw{font-size:13px}

  .ovr-page .ovr-insights{margin-top:56px}
  .ovr-page .ovr-mq{padding:88px 0 80px}
  .ovr-page .ovr-mq-item{font-size:clamp(44px,5vw,72px);padding-right:48px}
  .ovr-page .ovr-mq2{padding:40px 0}
  .ovr-page .ovr-mq2-item,.ovr-page .ovr-mq2-dot{font-size:clamp(24px,2.4vw,34px);padding-right:24px}

  .ovr-page .ovr-saavacan{padding:48px 0 24px}
  .ovr-page .ovr-scintro{padding:0 clamp(32px,5vw,80px) 32px}
  .ovr-page .ovr-schead{font-size:clamp(36px,4.5vw,64px)}
  .ovr-page .ovr-scsub{font-size:15px}
}

/* ── Flip cards (Phase 3) ────────────────────────────────────────
   Generic 3D flip surface. The host keeps its existing dimensions;
   .flip-inner does the rotation; .flip-front/.flip-back overlay
   absolutely with backface-visibility:hidden so only one face shows
   at a time. Applied to Saava-can cards on Overview — click a card,
   it flips to reveal a "why this matters" detail. */
.flip-card{perspective:1200px;cursor:pointer}
.flip-card .flip-inner{
  position:relative;width:100%;height:100%;
  transform-style:preserve-3d;
  transition:transform 720ms cubic-bezier(.7,0,.2,1);
}
.flip-card.flipped .flip-inner{transform:rotateY(180deg)}
.flip-card .flip-front,
.flip-card .flip-back{
  position:absolute;inset:0;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:24px;border-radius:inherit;
}
.flip-card .flip-back{transform:rotateY(180deg)}
/* Back-face palette inversion — keeps each card visually distinct
   from its front face so the flip feels like a reveal, not a re-skin. */
.ovr-canc.flip-card .flip-back{background:#D8431B;color:#FFFFFF;border:none}
.ovr-canc.flip-card.dark .flip-back{background:#D8431B;color:#FFFFFF}
.ovr-canc.flip-card.red  .flip-back{background:#111418;color:#F4EFE6}
.flip-card .flip-back .fb-eyebrow{font-size:11px;letter-spacing:.16em;text-transform:uppercase;font-weight:600;opacity:.75;margin-bottom:auto}
.flip-card .flip-back .fb-body{font-size:17px;line-height:1.42;font-weight:500;letter-spacing:-0.005em}
.flip-card .flip-back .fb-hint{font-size:11px;letter-spacing:.16em;text-transform:uppercase;font-weight:600;opacity:.75}
@media (min-width:768px){
  .flip-card .flip-back .fb-body{font-size:19px}
}

/* ── Page transitions (Phase 4) ─────────────────────────────────
   Slide-up + fade entry for every page swap. Replaces the older
   simple opacity fade. Reduced motion strips the transform; the
   page still appears, just without the slide. */
/* V166 — page-swap animation killed. Sub-tab switches felt like a "glitch"
   to users because the 480ms enter animation overlapped with mast/content
   layout calc and count-up animations, producing a visible flicker. Plain
   instant swap is calmer and feels more like a SPA route change. */
.pg.on{display:block}
@keyframes pg-enter{
  from{opacity:0;transform:translateY(28px)}
  to{opacity:1;transform:translateY(0)}
}
@media (prefers-reduced-motion: reduce){
  .pg.on{animation:none}
}

/* ──────────────────────────────────────────────────────────────────
   Phase 20 — fit-to-page + cinematic 3D pass
   Goals (from user feedback):
     1. Content actually fills the desktop viewport — no 1280px cap,
        no fat 7vw gutters. Lateral padding capped at 56px.
     2. "Way more obvious 3D features" — Saava-can cards sit tilted
        at rest with depth, lift dramatically on hover, flip into
        their back face on click.
     3. "Scroll transitions" — sections enter the viewport with a
        scroll-driven 3D animation (rotateX from 22deg + translateY
        + scale), and the hero number gets a parallax drift as you
        scroll past it. Uses CSS scroll-timeline (Chromium 115+).
        Falls back to the existing opacity-fade reveal elsewhere.
   ────────────────────────────────────────────────────────────────── */

/* 1. Full-bleed Overview on desktop — kill the 1280px cap so the
   composition can use the entire canvas. Tight lateral padding
   everywhere; sections breathe with the viewport. */
@media (min-width:768px){
  #pg-overview .ovr-page{max-width:none !important;margin:0 !important;padding:0 0 96px 0 !important}
  .ovr-page .ovr-hero{padding:56px clamp(24px,3vw,56px) 56px}
  .ovr-page .ovr-actsec{padding:60px clamp(24px,3vw,56px) 18px}
  .ovr-page .ovr-qabento{padding:0 clamp(24px,3vw,56px) 22px}
  /* V194 — matched the desktop 40px reduction so Today banner stays compact at all sizes. */
  .ovr-page .ovr-today{padding:40px clamp(24px,3vw,56px)}
  .ovr-page .ovr-stats{padding:0 clamp(24px,3vw,56px)}
  .ovr-page .ovr-sec{padding:60px clamp(24px,3vw,56px) 22px}
  .ovr-page .ovr-canrow{padding:0 clamp(24px,3vw,56px) !important}
  .ovr-page .ovr-cardrow{
    padding-left:clamp(24px,3vw,56px) !important;
    padding-right:clamp(24px,3vw,56px) !important;
    scroll-padding-inline-start:clamp(24px,3vw,56px) !important;
  }
  .ovr-page .ovr-ulist{padding:0 clamp(24px,3vw,56px) !important}
  .ovr-page .ovr-scintro{padding:0 clamp(24px,3vw,56px) 32px !important}
}

/* 2. Scroll-driven depth (V207 — slimmed).
   The section entry animation that used to live here ran IN ADDITION
   to the JS IntersectionObserver reveal — two systems driving the same
   opacity/transform. In scroll-timeline browsers they overlapped
   (double animation); during full-page capture and at certain zoom
   states the scroll timeline sat at frame 0 with fill:both, pinning
   whole sections at opacity:0 even after JS marked them .in. One
   system now: the JS reveal (with its V207 fail-open). Only the hero
   parallax keeps a scroll timeline — it's a progressive enhancement
   that can't hide content. */
@supports (animation-timeline: view()){
  /* Hero number parallax — drifts up + shrinks slightly as you
     scroll past the hero, creating a sense of depth (the ring
     stays put, so the number appears to recede behind it). */
  .ovr-page .ovr-num{
    animation:ovr-num-parallax linear both;
    animation-timeline:view();
    animation-range:exit -20% exit 100%;
    will-change:transform;
  }
  @keyframes ovr-num-parallax{
    from{transform:translateY(0) scale(1)}
    to  {transform:translateY(-80px) scale(0.92)}
  }
}

/* ── Emil Kowalski polish pass (Phase 22) ──────────────────────
   Replaces Phase 20's maximalist 3D tilts with Emil's signature
   restraint + precision. The motion philosophy:
     - Hover: subtle vertical lift (2-4px), soft layered shadow,
       NEVER rotation or aggressive scale. Hover signals interest,
       not panic.
     - Press: scale(0.97) for 120ms with spring ease-back. Every
       interactive element responds to touch like a physical button.
     - Easing: ease-out spring `cubic-bezier(0.32, 0.72, 0, 1)` for
       all transitions. The exit is soft, the entry is precise.
     - Shadows: layered, soft, never blasted. Use multiple
       low-opacity shadows stacked rather than one big blurred one.
   ────────────────────────────────────────────────────────────── */

/* Saava-can cards — flat at rest (no rotation), subtle hover lift */
.ovr-page .ovr-canrow{perspective:none;transform-style:flat}
.ovr-page .ovr-canc.flip-card{
  transform:none;
  transition:transform 240ms var(--ease-out),box-shadow 240ms var(--ease-out);
  /* V111: switched from neutral rgba(0,0,0,...) shadows to OKLCH
     ink-tinted tokens. Reads as a subtle warm dark, not generic
     black. The redesign-skill audit called this out as one of the
     most common AI-design tells. */
  box-shadow:var(--shadow-soft);
}
/* Override the nth-child rest tilts from Phase 20 */
.ovr-page .ovr-canc.flip-card:nth-child(2n),
.ovr-page .ovr-canc.flip-card:nth-child(3n),
.ovr-page .ovr-canc.flip-card:nth-child(5n){transform:none}
/* Refined hover — vertical lift only, soft stacked shadow.
   Gated to pointer:fine devices so it doesn't fire on tap. */
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-canc.flip-card:hover{
    transform:translateY(-4px) !important;
    box-shadow:var(--shadow-hover) !important;
  }
}
/* Press feedback — Emil's hallmark. Scales to 0.985 on active. */
.ovr-page .ovr-canc.flip-card:active{
  transform:translateY(-2px) scale(0.97) !important;
  /* Blueprint: 150ms ease-out for press release */
  transition:transform 150ms var(--ease-out) !important;
}
/* Flipped state — handled by .flip-inner rotation, outer stays flat */
.ovr-page .ovr-canc.flip-card.flipped{
  transform:none !important;
  box-shadow:
    0 2px 4px rgba(14,17,22,0.04),
    0 12px 24px -8px rgba(14,17,22,0.12),
    0 24px 48px -16px rgba(14,17,22,0.08) !important;
}

/* Bento tiles — refined hover, no rotation */
.ovr-page .ovr-qabento{perspective:none}
.ovr-page .ovr-qab-big{
  transition:transform 240ms var(--ease-out),box-shadow 240ms var(--ease-out);
  /* V111: vermilion-tinted shadow for the accent surface (was inline
     rgba). Reads as a true vermilion bloom under the tile, not a
     muddy black wash. */
  box-shadow:var(--shadow-accent);
}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-qab-big:hover{
    transform:translateY(-4px) !important;
    box-shadow:var(--shadow-accent-hover) !important;
  }
}
.ovr-page .ovr-qab-big:active{
  transform:translateY(-1px) scale(0.97) !important;
  transition:transform 150ms var(--ease-out) !important;
}
.ovr-page .ovr-qab-sm{
  transition:transform 240ms var(--ease-out),
             box-shadow 240ms var(--ease-out),
             background 220ms ease,color 220ms ease,border-color 220ms ease;
  box-shadow:var(--shadow-soft);
}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-qab-sm:hover{
    transform:translateY(-3px) !important;
    box-shadow:var(--shadow-hover) !important;
  }
}
.ovr-page .ovr-qab-sm:active{
  transform:translateY(-1px) scale(0.97) !important;
  transition:transform 150ms var(--ease-out) !important;
}

/* Today block — refined hover */
.ovr-page .ovr-today{perspective:none}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-today:hover{transform:translateY(-3px);box-shadow:var(--shadow-hover)}
}
.ovr-page .ovr-today:active{transform:translateY(-1px) scale(0.97);transition:transform 150ms var(--ease-out)}

/* ── Universal Emil-style polish across the app ──────────────────
   Blueprint mapping:
     - transform (press / hover lift) → ease-out, responsive feel
     - background/color/border (hover) → built-in `ease`, gentler */
.tab,.bn-item,.btn,.profile-btn,.ovr-story,
.ovr-fcard,.ovr-acttitle,.ovr-tcta,
button:not([disabled]){
  transition:transform 200ms var(--ease-out),
             background 200ms ease,color 200ms ease,
             border-color 200ms ease,opacity 200ms ease;
}
.tab:active,.bn-item:active,.btn:active,.profile-btn:active,
.ovr-story:active,.ovr-fcard:active,button:not([disabled]):active{
  /* Blueprint spec: scale(0.97) with 150ms ease-out. Exactly the
     values from Emil's article. 0.98 is too subtle to register as
     "the interface heard me"; 0.97 is the sweet spot. */
  transform:scale(0.97);
  transition:transform 150ms var(--ease-out);
}
/* Refined focus rings — soft vermilion halo, not OS default */
.tab:focus-visible,.bn-item:focus-visible,.btn:focus-visible,
.profile-btn:focus-visible,.ovr-story:focus-visible,
.ovr-canc:focus-visible,.ovr-qab-big:focus-visible,.ovr-qab-sm:focus-visible,
.flip-card:focus-visible,
button:focus-visible{
  outline:none;
  box-shadow:0 0 0 3px rgba(232,74,26,0.25),
             0 0 0 1px rgba(232,74,26,0.6);
  border-radius:var(--r-chip,8px);
}
/* Override box-shadow merge for elements that already have shadows */
.ovr-page .ovr-canc.flip-card:focus-visible,
.ovr-page .ovr-qab-big:focus-visible,
.ovr-page .ovr-qab-sm:focus-visible{
  box-shadow:
    0 0 0 3px rgba(232,74,26,0.25),
    0 0 0 1px rgba(232,74,26,0.6),
    0 12px 24px -8px rgba(14,17,22,0.12) !important;
}

/* ──────────────────────────────────────────────────────────────────
   Phase 21 — Cinematic hero rebuild
   Goals: this is the first thing people see. Massive Inter Tight
   number on the left, real Three.js 3D ring (rotating torus stack)
   on the right, hero takes ~80vh on desktop so it dominates the
   first viewport. The 3D ring is in a dedicated host (#ovr-3d-host)
   with a SVG fallback inside that paints if WebGL fails.
   ────────────────────────────────────────────────────────────────── */
/* Hero keeps the page's cream surface — the drama comes from scale,
   italic accents, and a warm peach glow behind the ring, NOT from
   a dark box. Stays cohesive with the rest of the page. */
.ovr-page .ovr-hero{
  background:transparent !important;
  position:relative;
  overflow:hidden;
}
/* Soft warm glow behind the ring — peach + vermilion, blends into
   the cream rather than fighting it. */
.ovr-page .ovr-hero::before{
  content:'';
  position:absolute;
  top:50%;right:0%;
  width:55%;height:130%;
  background:radial-gradient(circle at center,
    rgba(232,74,26,0.18) 0%,
    rgba(232,74,26,0.08) 30%,
    rgba(255,210,180,0.10) 50%,
    transparent 75%);
  filter:blur(30px);
  transform:translateY(-50%);
  pointer-events:none;
  z-index:0;
  animation:hero-glow-pulse 9s ease-in-out infinite;
}
@keyframes hero-glow-pulse{
  0%,100%{opacity:0.85;transform:translateY(-50%) scale(1)}
  50%{opacity:1;transform:translateY(-50%) scale(1.06)}
}
.ovr-page .ovr-hero > *{position:relative;z-index:1}
/* Italic accent in the eyebrow — turns "Total owed" into editorial */
.ovr-page .ovr-ctx em{
  font-style:italic;
  font-weight:600;
  color:#D8431B;
}
/* Vermilion blink dot before the date — live, current */
.ovr-page .ovr-ctx::before{
  content:'';
  display:inline-block;
  width:7px;height:7px;
  border-radius:50%;
  background:#D8431B;
  margin-right:10px;
  margin-bottom:1px;
  vertical-align:middle;
  animation:hero-blink 1.8s ease-in-out infinite;
}
@keyframes hero-blink{
  0%,100%{opacity:1;transform:scale(1)}
  50%{opacity:0.35;transform:scale(0.85)}
}
/* Italic "savings" accent inside the sub — single vermilion italic
   word that pulls the eye, like Mendo / Cash App. */
.ovr-page .ovr-sub em{
  font-style:italic;
  font-weight:500;
  color:#D8431B;
}

@media (min-width:768px){
  .ovr-page .ovr-hero{
    /* V146 — was min-height:clamp(560px,82vh,860px) (filled most of the
       viewport). Now sized by its content with a sane min so it doesn't
       collapse below the stats block. Smaller hero = less "WHAT YOU OWE"
       shouting on every visit. */
    min-height:clamp(320px,42vh,440px) !important;
    align-items:center !important;
    padding:48px clamp(32px,4vw,72px) !important;
  }
  /* V146 — number shrunk ~45%. Was clamp(140px,16vw,280px) which was
     anxiety-inducing on a wide desktop. Now clamp(56px,7vw,112px) —
     still the protagonist, no longer screaming. */
  .ovr-page .ovr-num{
    font-size:clamp(56px,7vw,112px) !important;
    letter-spacing:-0.045em !important;
    line-height:0.92 !important;
    font-weight:700 !important;
    margin:0 0 18px 0 !important;
  }
  .ovr-page .ovr-num .ovr-cents{
    font-size:clamp(20px,1.8vw,32px) !important;
    margin-top:10px !important;
  }
  /* V147 — single .ovr-mark hidden on desktop; replaced by the
     .ovr-rings constellation in the empty middle area. The single
     ring lives on for mobile (handled in base CSS). */
  .ovr-page .ovr-mark{display:none !important}
  .ovr-page .ovr-mark canvas{display:block;width:100% !important;height:100% !important}
  .ovr-page .ovr-mark:has(canvas) .ovr-mark-fallback{display:none}
  .ovr-page .ovr-mark-fallback{width:100%;height:100%;animation:ovr-tilt 10s ease-in-out infinite}

  /* V148 — Rings reworked. V147 was washed out (30-38% opacity, thin
     hairline strokes, clustered right). Now: opacity 70-90%, stroke
     widths 1.6-2.4, three different ellipse aspect ratios in the SVG
     (flat orbital / medium / rounder), each ring rotated to a
     different tilt angle so they don't read as identical stamps.
     Spread horizontally across 50-82% so the empty area actually
     fills, with clear gaps from the number (ends ~45%) and the
     stats block (starts ~86%). Vertical staggering kept subtle. */
  .ovr-page .ovr-rings{
    display:block !important;
    position:absolute !important;
    inset:0 !important;
    pointer-events:none !important;
    z-index:1 !important;
  }
  /* V150 → V153 evolution of the hero ring.
     V150: static single orbital.
     V152: added rotateY spin + center dot pulse + outer drift.
     V153: larger, shifted left, layered animations —
       (1) outer wobble: rotateX nods ±9deg over 18s, so the ring
           tilts toward/away from the viewer like a wobbling top
       (2) inner spin: rotateY 360° over 22s linear (faster than V152's
           26s so the motion is more visible)
       (3) glow halo: soft vermilion radial-gradient behind the ring,
           pulses scale + opacity in 5s ease-in-out
       (4) center dot pulse: 2.4s heartbeat, slightly more dramatic
       (5) outer drift: kept from V150 for breathing
     Five durations chosen to be relatively prime so the composite
     never resyncs into a mechanical pattern. */
  .ovr-page .ovr-ring-solo{
    left:58%;top:50%;
    /* V153 — bigger. was clamp(380,28vw,540). */
    width:clamp(440px,34vw,680px);
    /* V155 — fully opaque container (was 0.88). With hairline strokes
       at zero transparency, the ring reads sleek-bright rather than
       chunky. */
    opacity:1;
    transform:translate(-50%,-50%) rotate(-4deg);
    animation:ovr-ring-wobble 10s ease-in-out infinite; /* V278 — faster, clearly alive */
    perspective:1600px;
    perspective-origin:center center;
    transform-style:preserve-3d;
  }
  /* V153 — wobble replaces the V150 vertical drift. Adds rotateX
     (forward/backward tilt) for axial-tilt feel. */
  @keyframes ovr-ring-wobble{
    0%,100%{transform:translate(-50%,-50%) rotate(-4deg) rotateX(0deg)   translateY(0)}
    25%    {transform:translate(-50%,-50%) rotate(-4deg) rotateX(9deg)   translateY(-6px)}
    50%    {transform:translate(-50%,-50%) rotate(-4deg) rotateX(0deg)   translateY(-10px)}
    75%    {transform:translate(-50%,-50%) rotate(-4deg) rotateX(-9deg)  translateY(-4px)}
  }
  /* V155 — halo dropped. Sleek doesn't have an aura. The ring stands
     on its own as a fine-line mark on cream. (Pseudo-element kept as
     a hidden hook in case we want to restore it later.) */
  .ovr-page .ovr-ring-solo::before{display:none}
  .ovr-page .ovr-ring-solo svg{
    display:block;width:100%;height:100%;
    transform-origin:center center;
    transform-style:preserve-3d;
    animation:ovr-ring-3d-spin 12s linear infinite; /* V278 — faster orbital spin */
    will-change:transform;
  }
  @keyframes ovr-ring-3d-spin{
    from{transform:rotateY(0deg)}
    to  {transform:rotateY(360deg)}
  }
  /* Center dot pulse — slightly more dramatic than V152 */
  .ovr-page .ovr-ring-solo svg circle{
    transform-origin:center;
    transform-box:fill-box;
    animation:ovr-ring-pulse 2.4s ease-in-out infinite;
  }
  @keyframes ovr-ring-pulse{
    0%,100%{transform:scale(1);  opacity:1}
    50%    {transform:scale(1.5);opacity:0.65}
  }
  @media (prefers-reduced-motion: reduce){
    .ovr-page .ovr-ring-solo,
    .ovr-page .ovr-ring-solo::before,
    .ovr-page .ovr-ring-solo svg,
    .ovr-page .ovr-ring-solo svg circle{
      animation:none !important;
    }
  }
  @media (prefers-reduced-motion: reduce){
    .ovr-page .ovr-ring{animation:none !important}
  }
  /* Eyebrow */
  .ovr-page .ovr-ctx{
    font-size:13px !important;
    letter-spacing:0.2em !important;
    margin-bottom:14px !important;
    font-weight:600 !important;
  }
  /* V146 — Hero stats placement on desktop. Stacked vertically in
     column 2, vertically centered against the number block. */
  .ovr-page .ovr-herostats{
    flex-direction:column !important;
    gap:clamp(20px,2.2vw,32px) !important;
    margin:0 !important;
    min-width:200px !important;
    max-width:280px !important;
    z-index:2 !important;
  }
  .ovr-page .ovr-hslbl{font-size:11px !important;letter-spacing:0.2em !important}
  .ovr-page .ovr-hsval{font-size:clamp(20px,1.8vw,28px) !important}
  .ovr-page .ovr-hssub{font-size:13px !important}
  /* Sublabel (legacy; V146 removed .ovr-sub render but rule kept harmless) */
  .ovr-page .ovr-sub{margin-top:40px !important;font-size:16px !important;letter-spacing:-0.005em !important}
  /* Story circles bigger */
  .ovr-page .ovr-scir{width:64px !important;height:64px !important;font-size:13px !important}
}

/* Scrollable bottom nav (v21 pattern) */
.bottom-nav.bn-scroll{padding:0}
.bottom-nav.bn-scroll .bottom-nav-inner{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;padding:8px 16px 12px;scroll-padding-inline-start:16px;gap:2px}
.bottom-nav.bn-scroll .bottom-nav-inner::-webkit-scrollbar{display:none}
.bottom-nav.bn-scroll .bn-item{flex:0 0 auto;width:auto;min-width:64px;padding:6px 12px;scroll-snap-align:start;display:flex;flex-direction:column;align-items:center;gap:3px;position:relative}
.bottom-nav.bn-scroll .bn-item::before{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);width:14px;height:1px;background:transparent;transition:background 280ms}
.bottom-nav.bn-scroll .bn-item.on::before{background:var(--ot-ver,#D8431B)}
.bottom-nav.bn-scroll .bn-item .bn-icon{width:18px;height:18px}
.bottom-nav.bn-scroll .bn-item span:last-child{font-size:10px;font-weight:500;letter-spacing:0.06em;text-transform:none}
.bottom-nav.bn-scroll-wrap{position:relative}
.bottom-nav.bn-scroll-wrap::after{content:'';position:absolute;top:0;bottom:0;right:0;width:24px;background:linear-gradient(to right,rgba(255,255,255,0),rgba(255,255,255,0.95));pointer-events:none;z-index:2}

/* ── V117: Phase 3 — consistency tokens ──────────────────────────
   Three named radius values, one section-padding token. Applied
   uniformly across card-class surfaces so the design system stops
   drifting toward random border-radius values. */
:root{
  --r-chip:8px;
  --r-card:18px;
  --r-slab:0;
  --section-py:clamp(56px,7vw,88px);
  --section-px:clamp(24px,3vw,56px);
}
.ovr-page .ovr-canc,
.ovr-page .ovr-actile,
.ovr-page .ovr-can-primary,
.ovr-page .ovr-fcard{border-radius:var(--r-card) !important}
.ovr-page .ovr-today{border-radius:var(--r-slab) !important}

/* ── V118: Phase 5 — apply --section-py / --section-px uniformly
   Every major Overview section now uses the same vertical rhythm
   (clamp 56-88px) and lateral gutter (clamp 24-56px). Was a mix of
   48 / 56 / 60 / 64 px verticals and 22 / 24 / 32 / 48 / 56 / 80
   lateral. The rhythm now reads as deliberate, not ad-hoc. */
@media (min-width:768px){
  .ovr-page .ovr-actsec{
    /* V142 — was padding-top:var(--section-py) [56-88px], padding-bottom:24px.
       Take Action section was sitting at the top of clamp(56-88px) of empty
       space above the heading. Trimmed by ~50% so the section starts faster. */
    padding-top:clamp(28px,3vw,44px) !important;
    padding-bottom:14px !important;
    padding-left:var(--section-px) !important;
    padding-right:var(--section-px) !important;
  }
  .ovr-page .ovr-today{
    padding:var(--section-py) var(--section-px) !important;
  }
  .ovr-page .ovr-stats{
    padding-left:var(--section-px) !important;
    padding-right:var(--section-px) !important;
    margin-top:var(--section-py) !important;
  }
  .ovr-page .ovr-sec{
    padding:var(--section-py) var(--section-px) 22px !important;
  }
  .ovr-page .ovr-saavacan{padding:var(--section-py) 0 24px !important}
  .ovr-page .ovr-scintro{padding:0 var(--section-px) 32px !important}
  .ovr-page .ovr-canrow{padding:0 var(--section-px) !important}
  .ovr-page .ovr-cardrow{padding-left:var(--section-px) !important;padding-right:var(--section-px) !important;scroll-padding-inline-start:var(--section-px) !important}
  .ovr-page .ovr-qabento{padding:0 var(--section-px) 22px !important}
  .ovr-page .ovr-ulist{padding:0 var(--section-px) !important}
  .ovr-page .ovr-insights,
  .ovr-page .ovr-mq,
  .ovr-page .ovr-mq2{margin-top:var(--section-py) !important;margin-bottom:0 !important}
}

/* ── V117: Phase 3 — banner italic accent (italic-as-voice rhythm)
   The "Saving roughly $90.73 a month in interest" banner had its
   em element styled font-style:normal + vermilion. Now italic +
   vermilion + weight 600 — matches the italic-as-voice rule across
   the rest of the page. */
.ovr-page .ovr-mq-item em{
  font-style:italic !important;
  font-weight:600 !important;
  color:var(--ot-ver) !important;
}

/* ── V118: Mobile hero — hide the 3 inner SVG rings on narrow
   viewports. The .ovr-mark is just 38×38 there (absolute top-right);
   all 5 rings clustered into that tiny cell read as a smudge. Keep
   the 2 outermost rings + center dot. Hidden on desktop (>=768px)
   where the host is 420–640px wide and the full system reads fine. */
@media (max-width: 767px){
  .ovr-page .ovr-mark-fallback ellipse:nth-of-type(3),
  .ovr-page .ovr-mark-fallback ellipse:nth-of-type(4),
  .ovr-page .ovr-mark-fallback ellipse:nth-of-type(5){display:none}
}

/* ── V117: Phase 4 — accessibility hardening ─────────────────────
   1. Skip-to-content link for keyboard users (hidden until focused)
   2. Darker tertiary ash for AA Large contrast (was 2.2:1, now ~3.2)
   3. Story circle mobile touch target bumped 50px → 56px
   4. Focus rings include .ovr-fcard (debt cards were previously
      uncovered because they use .ovr-fcard, not .flip-card) */
.skip-link{
  position:absolute;
  top:-100px;left:8px;
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  padding:14px 22px;
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:14px;
  font-weight:600;
  letter-spacing:0.04em;
  z-index:9999;
  border-radius:var(--r-chip,8px);
  text-decoration:none;
  transition:top 150ms cubic-bezier(0.16,1,0.3,1);
}
.skip-link:focus,
.skip-link:focus-visible{top:8px;outline:none;box-shadow:0 0 0 3px rgba(232,74,26,0.35)}
.ovr-page{--ot-t3:#63636C !important} /* V219 a11y — was #696973 (3.4:1) */
@media (max-width:767px){
  .ovr-page .ovr-scir{width:56px !important;height:56px !important;font-size:12px !important}
  .ovr-page .ovr-story{min-height:44px}
}
.ovr-fcard:focus-visible,
.ovr-fcard.flip-card:focus-visible{
  outline:none;
  box-shadow:
    0 0 0 3px rgba(232,74,26,0.25),
    0 0 0 1px rgba(232,74,26,0.6),
    var(--shadow-soft);
}

/* ── V117: Phase 4 — inline empty-state row ──────────────────────
   Used by "Coming up", "Your debts", and other sections that
   render zero items. Sits below the section header as a single
   honest line of prose, no card, no skeleton. */
.ovr-page .ovr-empty-row{
  display:block;
  padding:24px clamp(24px,3vw,56px) 28px;
  color:var(--ot-t2);
  font-size:15px;
  line-height:1.55;
  max-width:60ch;
}
.ovr-page .ovr-empty-row em{
  font-style:italic;
  font-weight:600;
  color:var(--ot-ver);
}

/* ──────────────────────────────────────────────────────────────────
   Phase A — Foundation primitives (V121)

   Reusable editorial classes available to every .pg surface. The
   Overview's .ovr-* classes were one-off and surface-scoped; these
   .pg-* / .ed-* primitives are the canonical kit every subsequent
   phase (B–F) consumes when redesigning Plan, Pay, History, etc.

   Phase A is additive only — no existing tab visually changes.
   ────────────────────────────────────────────────────────────────── */

/* V138 auto-widen — any .pg that contains a .pg-mast editorial header
   automatically gets full-bleed canvas. Was: opt-in `.pg.wide` class
   that nobody ever added. Result: Plan / Pay / History / Timeline /
   3-Month / HST / Income Tax / Settings were all rendering their
   editorial mast (designed for clamp(56-88px) padding and clamp(40-
   80px) titles) inside a 700px column with 20px lateral inset — text
   wrapped weirdly, sub-copy crammed at 65ch in a 660px column, huge
   empty gutters. `:has()` selector handles tabs without a masthead
   correctly: they keep the narrow 700px cage. */
.pg.wide,
.pg:has(.pg-mast){max-width:none !important;padding:0 0 96px 0 !important}

/* V166 — Plan / Pay / History / Savings were rendering flush to the
   viewport edges on large monitors (the .pg:has(.pg-mast) rule above
   killed all max-width and padding). Overview gets centered via its
   own .ovr-page inner container; these pages had no equivalent, so
   their hero numbers and cards stretched to the screen edges and
   looked unbalanced next to Overview. Constrain them to the same
   1280px content cage and add lateral padding so they read like
   peer pages, not full-bleed dashboards. */
/* V166 / V167 / V168 — every sub-tab page except Invoice gets the same
   1280px centered cage. Invoice keeps its own full-bleed layout because
   the document is designed to print edge-to-edge on A4 (the existing
   `#pg-invoice{padding:0 !important}` rules above handle that).
   V168 adds the five new Settings sub-pages to the same cage. */
#pg-plan,
#pg-execute,
#pg-history,
#pg-savings,
#pg-cra,
#pg-income_tax,
#pg-timeline,
#pg-3mo,
#pg-profile,
#pg-setup,
:is(#pg-sources, #pg-sync, #pg-advanced),
#pg-sync,
#pg-advanced,
#pg-cashflow{
  max-width:1280px !important;
  margin-left:auto !important;
  margin-right:auto !important;
  padding:32px 24px 96px !important;
}
@media(max-width:640px){
  #pg-plan,#pg-execute,#pg-history,#pg-savings,
  #pg-cra,#pg-income_tax,#pg-timeline,#pg-3mo,
  #pg-profile,#pg-setup,:is(#pg-sources, #pg-sync, #pg-advanced),#pg-sync,#pg-advanced,
  #pg-cashflow{padding:20px 16px 96px !important}
}

/* ── Page header (V140) ──
   Was a large editorial masthead (clamp 40-80px title + italic vermilion
   accent + eyebrow with live blink dot + 65ch sub-copy + clamp 56-88px
   padding). User feedback: "i hate the new heading formatting. its boxy
   things. so ugly". Stripped to a simple compact H1 — eyebrow and sub
   hidden, italic accent reverted to normal type. Page title now reads
   as a quiet label, not a magazine spread. */
.pg-mast{
  padding:28px 24px 12px;
}
.pg-mast-eyebrow,
.pg-mast-sub{display:none}
.pg-mast-title{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:24px;
  font-weight:700;
  letter-spacing:-0.01em;
  line-height:1.3;
  color:var(--ot-ink,#0E1116);
  margin:0;
  text-wrap:balance;
}
.pg-mast-title em{
  font-style:normal;
  font-weight:700;
  color:inherit;
}

/* ── Editorial card ── Standard surface for grouped content. */
.ed-card{
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  padding:clamp(20px,2.4vw,28px);
  box-shadow:var(--shadow-soft);
  transition:transform 240ms var(--ease-out),box-shadow 240ms var(--ease-out);
}
.ed-card.dark{
  background:var(--ot-dark,#111418);
  color:#F4EFE6;
  border-color:var(--ot-dark,#111418);
}
.ed-card.accent{
  background:var(--ot-ver,#D8431B);
  color:#FFFFFF;
  border-color:var(--ot-ver,#D8431B);
  box-shadow:var(--shadow-accent);
}
@media (hover: hover) and (pointer: fine){
  .ed-card.interactive:hover{
    transform:translateY(-3px);
    box-shadow:var(--shadow-hover);
  }
}
.ed-card.interactive:active{
  transform:scale(0.985);
  transition:transform 100ms var(--ease-out);
}

/* ── Editorial list row ── Numeral/icon, content, chevron. */
.ed-list-row{
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;
  gap:clamp(16px,2vw,32px);
  padding:18px 4px;
  border:none;
  border-bottom:0.5px solid var(--ot-bd,#E5E0D4);
  background:transparent;
  color:var(--ot-ink,#0E1116);
  font-family:inherit;
  text-align:left;
  width:100%;
  cursor:default;
  transition:opacity 200ms ease;
}
.ed-list-row:last-child{border-bottom:none}
.ed-list-row.tappable{
  cursor:pointer;
  transition:transform 150ms var(--ease-out),opacity 200ms ease;
}
.ed-list-row.tappable:active{transform:scale(0.985)}
@media (hover: hover) and (pointer: fine){
  .ed-list-row.tappable:hover{background:rgba(232,74,26,0.03)}
}

/* ── Editorial inline primitives ── */
.ed-eyebrow{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:12px;
  font-weight:600;
  letter-spacing:0.16em;
  text-transform:uppercase;
  color:var(--ot-t2,#5F6470);
}
/* V193 — eyebrow accent now uses Inter Tight italic (real italic now
   that v191 loaded the italic axis). Bumped to 600 weight + a touch
   negative tracking to give it presence without uppercasing — the
   "& credits", "soon", etc. accents read as warm editorial flourishes. */
.ed-eyebrow em{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-style:italic;
  font-weight:600;
  color:var(--ot-ver,#D8431B);
  text-transform:none;
  letter-spacing:-0.01em;
}
.ed-headline{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:clamp(22px,2.4vw,32px);
  font-weight:600;
  letter-spacing:-0.025em;
  line-height:1.1;
  color:var(--ot-ink,#0E1116);
  text-wrap:balance;
  margin:0;
}
.ed-headline em{font-style:italic;font-weight:600;color:var(--ot-ver,#D8431B)}

/* V192 — modal h2 titles unified to Inter Tight to match the page-title
   typography. Several modal headers (Import, Receipt OCR, T4/T5, Auto
   Bank) had inline `font-family:Fraunces` styles which now clash with
   the unified Inter Tight pages. Override here so the modal h2 reads
   in the same brand voice. */
.modal h2{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif !important;
  font-size:clamp(22px,2.4vw,28px) !important;
  font-weight:700 !important;
  letter-spacing:-0.025em !important;
  line-height:1.1 !important;
  color:var(--ot-ink,#0E1116) !important;
  margin:0 0 10px !important;
  text-wrap:balance;
}
.modal h2 em{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif !important;
  font-style:italic !important;
  font-weight:700 !important;
  color:var(--ot-ver,#D8431B) !important;
  letter-spacing:-0.03em !important;
}
.ed-divider{
  height:0;
  border:0;
  border-top:0.5px solid var(--ot-bd,#E5E0D4);
  margin:clamp(24px,3vw,40px) 0;
}

/* ── Form primitives ── Label above input, vermilion focus glow. */
.ed-field{
  display:flex;
  flex-direction:column;
  gap:8px;
  margin-bottom:18px;
}
.ed-label{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:13px;
  font-weight:500;
  color:var(--ot-ink,#0E1116);
}
.ed-input{
  background:transparent;
  border:1px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-chip,8px);
  padding:12px 14px;
  font-size:16px;  /* iOS won't zoom-on-focus at ≥16px */
  font-family:inherit;
  color:var(--ot-ink,#0E1116);
  width:100%;
  transition:border-color 200ms ease,background 200ms ease,box-shadow 200ms ease;
}
.ed-input:focus,
.ed-input:focus-visible{
  outline:none;
  border-color:var(--ot-ver,#D8431B);
  box-shadow:0 0 0 3px rgba(232,74,26,0.15);
}
.ed-input::placeholder{color:var(--ot-t3,#9CA0AA)}
.ed-input.has-error{border-color:var(--ot-ver,#D8431B);box-shadow:0 0 0 3px rgba(232,74,26,0.10)}

/* V160 — Editorial inheritance for raw inputs inside Settings/History/HST
   forms. Touching ~46 raw <input>/<select>/<textarea> callsites with class
   swaps would be invasive; instead, inputs INSIDE legacy .csm rows and
   inputs that explicitly lack the .ed-input class but live inside the
   Settings sub-page surface inherit the editorial chrome. Preserves all
   existing form behaviour. */
.csm input:not(.ed-input):not([type="checkbox"]):not([type="radio"]),
.csm select:not(.ed-input),
.csm textarea:not(.ed-input),
#pg-settings input:not(.ed-input):not([type="checkbox"]):not([type="radio"]):not([type="file"]),
#pg-settings select:not(.ed-input),
#pg-settings textarea:not(.ed-input),
#pg-history input[type="search"]:not(.ed-input),
#pg-history input[type="date"]:not(.ed-input),
#pg-history select:not(.ed-input),
#pg-cra input:not(.ed-input):not([type="checkbox"]):not([type="radio"]),
#pg-cra select:not(.ed-input),
#pg-cra textarea:not(.ed-input),
#pg-income_tax input:not(.ed-input):not([type="checkbox"]):not([type="radio"]),
#pg-income_tax select:not(.ed-input){
  background:transparent;
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-chip,8px);
  padding:10px 12px;
  font-size:14px;
  font-family:inherit;
  color:var(--ot-ink,#0E1116);
  transition:border-color 180ms ease,box-shadow 180ms ease;
}
.csm input:not(.ed-input):focus,
.csm select:not(.ed-input):focus,
.csm textarea:not(.ed-input):focus,
#pg-settings input:not(.ed-input):focus,
#pg-settings select:not(.ed-input):focus,
#pg-settings textarea:not(.ed-input):focus,
#pg-history input:not(.ed-input):focus,
#pg-history select:not(.ed-input):focus,
#pg-cra input:not(.ed-input):focus,
#pg-cra select:not(.ed-input):focus,
#pg-cra textarea:not(.ed-input):focus,
#pg-income_tax input:not(.ed-input):focus,
#pg-income_tax select:not(.ed-input):focus{
  outline:none;
  border-color:var(--ot-ver,#D8431B);
  box-shadow:0 0 0 3px rgba(232,74,26,0.12);
}
.csm input::placeholder,
#pg-settings input::placeholder,
#pg-history input::placeholder,
#pg-cra input::placeholder,
#pg-income_tax input::placeholder{
  color:var(--ot-t3,#9CA0AA);
}
.ed-helper{
  font-size:12px;
  color:var(--ot-t2,#5F6470);
  line-height:1.4;
}
.ed-error{
  font-size:12px;
  color:var(--ot-ver,#D8431B);
  font-weight:500;
  line-height:1.4;
}

/* ── Editorial buttons ── */
.ed-btn-primary{
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  border:none;
  padding:14px 32px;
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:14px;
  font-weight:600;
  letter-spacing:0.06em;
  text-transform:uppercase;
  border-radius:var(--r-card,18px);
  cursor:pointer;
  transition:transform 150ms var(--ease-out),background 200ms ease,color 200ms ease;
}
@media (hover: hover) and (pointer: fine){
  .ed-btn-primary:hover{background:var(--ot-ver,#D8431B)}
}
.ed-btn-primary:active{transform:scale(0.97)}
.ed-link{
  background:transparent;
  border:none;
  color:var(--ot-ink,#0E1116);
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:15px;
  font-weight:500;
  text-decoration:underline;
  text-decoration-color:var(--ot-bd,#E5E0D4);
  text-underline-offset:3px;
  padding:0;
  cursor:pointer;
  transition:color 200ms ease,text-decoration-color 200ms ease;
}
@media (hover: hover) and (pointer: fine){
  .ed-link:hover{color:var(--ot-ver,#D8431B);text-decoration-color:var(--ot-ver,#D8431B)}
}

/* ── Empty-state page ── Whole-tab zero-data state. */
.empty-state-page{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:clamp(64px,10vw,140px) var(--section-px,clamp(24px,3vw,56px));
  text-align:center;
  min-height:60vh;
}
.empty-state-page-mark{
  width:clamp(80px,8vw,120px);
  height:clamp(80px,8vw,120px);
  margin-bottom:32px;
  color:var(--ot-t3,#9CA0AA);
}
/* V192 — aligned with the unified page-title scale + weight. */
.empty-state-page-title{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-size:clamp(32px,3.6vw,46px);
  font-weight:700;
  letter-spacing:-0.035em;
  line-height:1.05;
  color:var(--ot-ink,#0E1116);
  margin:0 0 14px 0;
  text-wrap:balance;
  max-width:22ch;
}
.empty-state-page-title em{
  font-family:'Inter Tight','Inter',-apple-system,sans-serif;
  font-style:italic;
  font-weight:700;
  color:var(--ot-ver,#D8431B);
  letter-spacing:-0.04em;
}
.empty-state-page-body{
  font-size:16px;
  line-height:1.55;
  color:var(--ot-t2,#5F6470);
  margin:0 0 32px 0;
  max-width:48ch;
}
.empty-state-page-body em{
  font-style:italic;
  font-weight:500;
  color:var(--ot-ink,#0E1116);
}

/* Token availability — the ovr-* tokens were scoped to .ovr-page.
   Expose them at :root so .ed-* and .pg-mast primitives can find
   the same values outside Overview. Mirrors Phase 17's palette. */
:root{
  --ot-bg:#F5F1E8;
  --ot-surf:#FFFFFF;
  --ot-ink:#0E1116;
  --ot-t2:#5F6470;
  --ot-t3:#63636C; /* V219 a11y */
  --ot-ver:#D8431B;
  --ot-dark:#111418;
  --ot-bd:#E5E0D4;
  --ot-font:'Inter Tight','Inter',-apple-system,sans-serif;
}

/* ── Global reduced-motion guard (animation-skill mandate) ──────
   "Always respect prefers-reduced-motion. Not optional."
   Collapses every animation and transition to ~instant for users
   who've enabled reduced motion in their OS. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:0.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.01ms !important;
    scroll-behavior:auto !important;
  }
}

/* ── V110: Redesign-skill audit findings, high-priority items ───────
   1. Smooth scroll for anchor jumps (anchor jumps were abrupt).
   2. text-wrap: balance on display type so big headings don't break
      with a single orphaned word.
   3. Sentence case for stats labels (editorial warmth, was tracked
      uppercase which felt like a bank dashboard).
   4. Tinted shadow tokens. Black-alpha shadows were the AI-design
      tell flagged in the redesign skill audit. Now ink-tinted for
      neutral surfaces, vermilion-tinted under accent surfaces.
   5. Honest empty state for the progress rail. The "0.0% paid off"
      bar with a flat rail was sad. Now hidden until there's actual
      progress to show. */
html{scroll-behavior:smooth}
.ovr-page .ovr-th,
.ovr-page .ovr-acttitle,
.ovr-page .ovr-schead,
.ovr-page .ovr-num{
  text-wrap:balance;
}
.ovr-page .ovr-tam,
.ovr-page .ovr-csub,
.ovr-page .ovr-sub{
  text-wrap:pretty;
}
.ovr-page .ovr-sl2{
  text-transform:none !important;
  letter-spacing:0 !important;
  font-size:13px !important;
  font-weight:500 !important;
  color:var(--ot-t2) !important;
}
/* Tinted shadow tokens (V110). All custom box-shadows on Overview
   should reach for these instead of declaring rgba(0,0,0,...). */
:root{
  --shadow-soft:    0 1px 2px oklch(15% 0.015 270 / 0.06), 0 4px 12px oklch(15% 0.015 270 / 0.08);
  --shadow-hover:   0 2px 4px oklch(15% 0.015 270 / 0.06), 0 12px 24px oklch(15% 0.015 270 / 0.12), 0 24px 48px oklch(15% 0.015 270 / 0.08);
  --shadow-accent:  0 1px 2px oklch(67% 0.20 35 / 0.12), 0 4px 12px oklch(67% 0.20 35 / 0.20);
  --shadow-accent-hover: 0 2px 4px oklch(67% 0.20 35 / 0.14), 0 12px 28px oklch(67% 0.20 35 / 0.30), 0 24px 56px oklch(67% 0.20 35 / 0.20);
}
/* Empty progress state — when origTotal == curTotal, show no rail
   instead of asserting a sad zero. The --p variable is set on the
   .ovr-progbar itself, not on .fill. V110 had the selector wrong. */
.ovr-page .ovr-progbar[style*="--p:0.000"]{
  background:transparent !important;
}
.ovr-page .ovr-progbar[style*="--p:0.000"] .fill{
  display:none;
}

/* ── V115: Saava-can → primary + editorial list ──
   Format swap with Take action. The differentiator (Predict your
   debt-free date) gets the spotlight as a vermilion editorial
   card on the left; remaining 5 capabilities stack vertically on
   the right as a list with italic verb accents and a subtitle. */
.ovr-page .ovr-canrow{
  display:block !important;
  perspective:none !important;
  padding:0 clamp(24px,3vw,56px) !important;
}
@media (min-width:768px){
  .ovr-page .ovr-canrow{
    display:grid !important;
    grid-template-columns:clamp(360px,40%,540px) 1fr !important;
    gap:clamp(28px,4vw,56px) !important;
    align-items:stretch !important;
  }
}
.ovr-page .ovr-can-primary{
  /* V116: was vermilion, demoted to dark ink so it stops competing
     with the hero number for the page's loudest moment. Italic
     accent on the verb keeps the editorial signature. */
  background:var(--ot-dark);
  color:#F4EFE6;
  border-radius:var(--r-card,18px);
  padding:clamp(28px,3vw,40px);
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  gap:clamp(24px,3vw,40px);
  min-height:clamp(320px,32vw,440px);
  box-shadow:var(--shadow-soft);
}
.ovr-page .ovr-can-primary-eyebrow{
  font-size:12px;
  font-weight:500;
  letter-spacing:0.16em;
  text-transform:uppercase;
  color:rgba(244,239,230,0.55);
}
.ovr-page .ovr-can-primary-title{
  font-family:var(--ot-font);
  font-size:clamp(32px,3.4vw,48px);
  font-weight:600;
  letter-spacing:-0.025em;
  line-height:1.05;
  color:#FFFFFF;
  text-wrap:balance;
}
.ovr-page .ovr-can-primary-title em{
  font-style:italic;
  font-weight:600;
  /* Vermilion italic accent against the dark surface — the one
     vermilion moment in this section. */
  color:var(--ot-ver);
}
.ovr-page .ovr-can-primary-body{
  font-size:16px;
  line-height:1.55;
  color:rgba(244,239,230,0.78);
  max-width:48ch;
}
.ovr-page .ovr-can-list{
  display:flex;
  flex-direction:column;
  margin-top:24px;
}
@media (min-width:768px){.ovr-page .ovr-can-list{margin-top:0}}
.ovr-page .ovr-can-row{
  display:grid;
  grid-template-columns:auto 1fr;
  align-items:start;
  gap:clamp(16px,2vw,32px);
  padding:20px 4px;
  border-bottom:0.5px solid var(--ot-bd);
}
.ovr-page .ovr-can-row:last-child{border-bottom:none}
.ovr-page .ovr-can-num{
  font-family:var(--ot-font);
  font-size:13px;
  font-weight:500;
  color:var(--ot-t3);
  font-variant-numeric:tabular-nums;
  letter-spacing:0.04em;
  min-width:28px;
  padding-top:6px;
}
.ovr-page .ovr-can-text{
  display:flex;
  flex-direction:column;
  gap:6px;
}
.ovr-page .ovr-can-name{
  font-family:var(--ot-font);
  font-size:clamp(20px,2.2vw,28px);
  font-weight:500;
  letter-spacing:-0.02em;
  line-height:1.15;
  color:var(--ot-ink);
  text-wrap:balance;
}
.ovr-page .ovr-can-name em{
  font-style:italic;
  font-weight:600;
  /* V116: was always vermilion. Demoted to ink at rest; vermilion
     only on row hover so each list item earns the accent on demand. */
  color:var(--ot-ink);
  transition:color 200ms ease;
}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-can-row:hover .ovr-can-name em{color:var(--ot-ver)}
}
.ovr-page .ovr-can-sub{
  font-size:14px;
  line-height:1.5;
  color:var(--ot-t2);
  text-wrap:pretty;
}

/* ── V115: Take action → asymmetric 4-col grid ──
   Format swap with Saava-can. Action tiles in an asymmetric grid:
   Log charge primary spans 2 cols (top-left), See history spans
   2 cols (bottom-right). Diagonal balance, no equal-card row. */
.ovr-page .ovr-qabento{
  display:grid !important;
  grid-template-columns:1fr 1fr !important;
  grid-template-rows:auto !important;
  gap:12px !important;
  padding:0 clamp(24px,3vw,56px) 22px !important;
  perspective:none !important;
}
@media (min-width:768px){
  .ovr-page .ovr-qabento{
    grid-template-columns:repeat(4,1fr) !important;
    gap:14px !important;
  }
}
.ovr-page .ovr-actile{
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  gap:10px;
  background:var(--ot-surf);
  border:0.5px solid var(--ot-bd);
  border-radius:var(--r-card,18px);
  /* V141 shrink — was padding:clamp(20px,2.4vw,28px) + min-height:140px.
     On wide desktop the section was eating ~250px+ of vertical space
     per row. Trimmed to feel like quick actions, not hero panels. */
  padding:clamp(14px,1.6vw,18px);
  cursor:pointer;
  font-family:inherit;
  text-align:left;
  color:var(--ot-ink);
  min-height:88px;
  transition:transform 240ms var(--ease-out),box-shadow 240ms var(--ease-out),background 220ms ease,color 220ms ease,border-color 220ms ease;
  box-shadow:var(--shadow-soft);
}
.ovr-page .ovr-actile.primary{
  background:var(--ot-ver) !important;
  border-color:var(--ot-ver) !important;
  color:#FFFFFF !important;
  grid-column:span 2;
  /* V141 shrink — was clamp(180px,18vw,220px). Primary still reads as
     primary via the vermilion fill + larger title, doesn't need 220px
     of height to do so. */
  min-height:clamp(120px,11vw,140px);
  box-shadow:var(--shadow-accent);
}
.ovr-page .ovr-actile.dark{
  background:var(--ot-dark) !important;
  border-color:var(--ot-dark) !important;
  color:#F4EFE6 !important;
}
.ovr-page .ovr-actile.wide{grid-column:span 2}
@media (max-width:767px){
  .ovr-page .ovr-actile.primary,
  .ovr-page .ovr-actile.wide{grid-column:span 2}
}
.ovr-page .ovr-actile-eyebrow{
  font-size:11px;
  font-weight:500;
  letter-spacing:0.18em;
  text-transform:uppercase;
  opacity:0.8;
}
.ovr-page .ovr-actile-num{
  font-family:var(--ot-font);
  font-size:13px;
  font-weight:500;
  letter-spacing:0.04em;
  font-variant-numeric:tabular-nums;
  color:currentColor;
  opacity:0.55;
}
.ovr-page .ovr-actile-name{
  font-family:var(--ot-font);
  /* V141 shrink — was clamp(22px,2.4vw,34px) */
  font-size:clamp(17px,1.6vw,22px);
  font-weight:500;
  letter-spacing:-0.025em;
  line-height:1.05;
}
.ovr-page .ovr-actile.primary .ovr-actile-name{
  /* V141 shrink — was clamp(32px,3.4vw,48px) */
  font-size:clamp(22px,2.2vw,30px);
}
.ovr-page .ovr-actile-name em{
  font-style:italic;
  font-weight:600;
}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-actile:hover{
    transform:translateY(-4px) !important;
    box-shadow:var(--shadow-hover) !important;
  }
  .ovr-page .ovr-actile.primary:hover{box-shadow:var(--shadow-accent-hover) !important}
}
.ovr-page .ovr-actile:active{
  transform:scale(0.985) !important;
  transition:transform 100ms var(--ease-out) !important;
}

/* ── V115: Stats row → 2×2 stacked grid ──
   V114's full-width vertical list had labels pinned far-left and
   values pinned far-right, creating a huge dead space across wide
   screens. Now a compact 2×2 grid: each cell stacks label above
   value, hairline dividers between cells. Editorial, scannable,
   no wasted horizontal space. */
/* V157 — Stats upgraded from flat hairline-divided grid to elevated
   cards with hover lift + subtle 3D tilt + entry stagger.
   - Each cell is now a card surface (white on cream, soft shadow,
     hairline border, ed-card radius)
   - Cards lift on hover and tilt forward slightly via perspective
     on the container (rotateX gives the depth)
   - Each card animates in with a 80ms stagger when scroll-revealed
   - Numbers count up from 0 via JS in _ovrInit (data-stat-target)
   - Plan remaining gets an inline progress bar (paid/planned ratio) */
.ovr-page .ovr-stats{
  display:grid !important;
  grid-template-columns:1fr 1fr !important;
  background:transparent !important;
  padding:0 clamp(24px,3vw,56px) !important;
  margin-top:24px !important;
  gap:12px !important;
  perspective:1200px;
}
@media (min-width:900px){
  .ovr-page .ovr-stats{
    grid-template-columns:repeat(4,1fr) !important;
    gap:14px !important;
  }
}
.ovr-page .ovr-st{
  display:flex !important;
  flex-direction:column !important;
  align-items:flex-start !important;
  justify-content:flex-start !important;
  padding:20px 22px !important;
  gap:12px;
  background:var(--ot-surf,#FFFFFF) !important;
  border:0.5px solid var(--ot-bd,#E5E0D4) !important;
  border-radius:var(--r-card,18px) !important;
  box-shadow:var(--shadow-soft);
  transition:transform 280ms var(--ease-out), box-shadow 280ms var(--ease-out);
  position:relative;
  transform-origin:center bottom;
  transform-style:preserve-3d;
}
@media (min-width:768px){
  .ovr-page .ovr-st{padding:24px 26px !important}
}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-st:hover{
    transform:translateY(-4px) translateZ(8px) rotateX(2deg);
    box-shadow:var(--shadow-hover);
  }
}
.ovr-page .ovr-st .ovr-sl2{
  margin-bottom:0 !important;
  display:flex;
  align-items:center;
  gap:8px;
}
.ovr-page .ovr-st .ovr-sl2 svg{
  color:var(--ot-ver,#D8431B);
  opacity:0.6;
  width:13px;height:13px;
  flex-shrink:0;
}
.ovr-page .ovr-st .ovr-sval{
  font-family:var(--ot-font);
  font-size:clamp(26px,3vw,40px) !important;
  font-weight:600 !important;
  letter-spacing:-0.025em !important;
  line-height:1.05 !important;
  font-variant-numeric:tabular-nums;
}
.ovr-page .ovr-st .ovr-sval.ac{color:var(--ot-ver) !important}
/* Plan-remaining inline progress bar */
.ovr-page .ovr-st-prog{
  width:100%;
  height:3px;
  background:var(--ot-bd,#E5E0D4);
  margin-top:4px;
  overflow:hidden;
  border-radius:2px;
}
.ovr-page .ovr-st-prog-fill{
  height:100%;
  background:var(--ot-ver,#D8431B);
  transform:scaleX(var(--p,0));
  transform-origin:left center;
  transition:transform 700ms 500ms cubic-bezier(0.22,1,0.36,1);
}

/* Stagger entry — each stat fades-up with a slight delay when the
   .ovr-stats section enters the viewport (via .in class added by the
   IntersectionObserver in _ovrInit). */
.ovr-page .ovr-stats .ovr-st{
  opacity:0;
  transform:translateY(16px) scale(0.97);
}
.ovr-page .ovr-stats.in .ovr-st{
  animation:ovr-stat-rise 540ms cubic-bezier(0.22,1,0.36,1) both;
}
.ovr-page .ovr-stats.in .ovr-st:nth-child(1){animation-delay:0ms}
.ovr-page .ovr-stats.in .ovr-st:nth-child(2){animation-delay:90ms}
.ovr-page .ovr-stats.in .ovr-st:nth-child(3){animation-delay:180ms}
.ovr-page .ovr-stats.in .ovr-st:nth-child(4){animation-delay:270ms}
@keyframes ovr-stat-rise{
  from{opacity:0;transform:translateY(16px) scale(0.97)}
  to  {opacity:1;transform:translateY(0)    scale(1)}
}
@media (prefers-reduced-motion: reduce){
  .ovr-page .ovr-stats .ovr-st{opacity:1;transform:none}
  .ovr-page .ovr-stats.in .ovr-st{animation:none}
  .ovr-page .ovr-st:hover{transform:none}
  .ovr-page .ovr-st-prog-fill{transition:none}
}

/* ─────────────────────────────────────────────────────────────────
   V158 — Plan page treatment (matches Overview vibes)
   ─────────────────────────────────────────────────────────────── */

/* The Payment Plan hero card on Plan tab. ed-card surface with the
   ambient orbital ring tucked top-right, and CSS transition on the
   progress fill so it draws in after the card rises. */
.plan-hero{
  position:relative;
  overflow:hidden;
}
.plan-hero-ring{
  position:absolute;
  top:-30px;right:-40px;
  width:240px;height:240px;
  opacity:0.32;
  pointer-events:none;
  transform:rotate(-6deg);
  z-index:1;
}
.plan-hero-ring svg{
  width:100%;height:100%;
  display:block;
  animation:plan-ring-drift 22s ease-in-out infinite;
}
@keyframes plan-ring-drift{
  0%,100%{transform:rotate(0deg) translateY(0)}
  50%    {transform:rotate(4deg) translateY(-6px)}
}
@media (min-width:768px){
  .plan-hero-ring{width:340px;height:340px;top:-60px;right:-60px;opacity:0.34}
}

/* Animate the progress fill from 0 to its inline width on reveal */
.plan-hero-fill{transform-origin:left center}
.plan-hero.ovr-reveal.in .plan-hero-fill,
.ovr-reveal.in .plan-hero-fill{
  transform:scaleX(1) !important;
}

/* Month tabs — elevated cards with hover lift + 3D tilt, stagger entry */
.plan-mtabs{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:10px;
  margin-bottom:24px;
  perspective:1200px;
}
@media (min-width:768px){
  .plan-mtabs{gap:14px}
}
.plan-mtab{
  display:flex;flex-direction:column;
  gap:6px;
  padding:16px 16px;
  background:var(--ot-surf,#FFFFFF);
  border:0.5px solid var(--ot-bd,#E5E0D4);
  border-radius:var(--r-card,18px);
  color:var(--ot-ink);
  cursor:pointer;
  font-family:var(--ot-font);
  text-align:left;
  box-shadow:var(--shadow-soft);
  transition:transform 280ms var(--ease-out), box-shadow 280ms var(--ease-out), background 200ms ease, color 200ms ease;
  transform-style:preserve-3d;
  min-height:96px;
}
.plan-mtab.on{
  background:var(--ot-ink,#0E1116);
  color:var(--ot-bg,#F5F1E8);
  border-color:var(--ot-ink,#0E1116);
}
@media (hover: hover) and (pointer: fine){
  .plan-mtab:hover{
    transform:translateY(-4px) translateZ(8px) rotateX(2deg);
    box-shadow:var(--shadow-hover);
  }
}
.plan-mtab-lbl{
  font-size:13px;font-weight:600;
  letter-spacing:0.08em;
}
.plan-mtab-now{
  font-size:10px;font-style:italic;font-weight:600;
  letter-spacing:0.04em;
  color:var(--ot-ver,#D8431B);
}
.plan-mtab.on .plan-mtab-now{color:rgba(244,239,230,0.95)}
.plan-mtab-spacer{height:14px}
.plan-mtab-amt{
  margin-top:auto;
  font-size:13px;font-weight:600;
  font-variant-numeric:tabular-nums;
  letter-spacing:-0.005em;
}
.plan-mtab-amt.empty{
  color:var(--ot-t3);
  font-weight:500;
}
.plan-mtab.on .plan-mtab-amt{color:var(--ot-bg)}
.plan-mtab-paid{
  font-weight:500;
  color:var(--ot-t2);
}
.plan-mtab.on .plan-mtab-paid{color:rgba(244,239,230,0.65)}

/* Stagger entry on month tabs — fades + rises in sequence */
.plan-mtabs.ovr-reveal .plan-mtab{
  opacity:0;
  transform:translateY(14px) scale(0.97);
}
.plan-mtabs.ovr-reveal.in .plan-mtab{
  animation:plan-mtab-rise 480ms cubic-bezier(0.22,1,0.36,1) both;
}
.plan-mtabs.ovr-reveal.in .plan-mtab:nth-child(1){animation-delay:0ms}
.plan-mtabs.ovr-reveal.in .plan-mtab:nth-child(2){animation-delay:80ms}
.plan-mtabs.ovr-reveal.in .plan-mtab:nth-child(3){animation-delay:160ms}
@keyframes plan-mtab-rise{
  from{opacity:0;transform:translateY(14px) scale(0.97)}
  to  {opacity:1;transform:translateY(0)    scale(1)}
}

@media (prefers-reduced-motion: reduce){
  .plan-hero-ring svg{animation:none}
  .plan-mtabs.ovr-reveal .plan-mtab{opacity:1;transform:none}
  .plan-mtabs.ovr-reveal.in .plan-mtab{animation:none}
  .plan-mtab:hover{transform:none}
  .plan-hero-fill{transition:none}
}

/* ── V114: Saava-can → asymmetric grid (kill 6-equal-cards) ──
   Was a 4-col / 3-col grid of equal-sized feature cards. Now an
   asymmetric 4-col layout where cards 1 and 6 span two columns,
   anchoring opposite corners with diagonal balance. */
@media (min-width:768px){
  .ovr-page .ovr-canrow{
    display:grid !important;
    grid-template-columns:repeat(4,1fr) !important;
    grid-auto-flow:row !important;
    gap:16px !important;
    overflow:visible !important;
  }
  .ovr-page .ovr-canrow .ovr-canc:nth-child(1){grid-column:span 2 !important}
  .ovr-page .ovr-canrow .ovr-canc:nth-child(6){grid-column:span 2 !important}
  /* Cards 2-5 take single columns automatically.
     Layout: [1 wide][2][3] / [4][5][6 wide] */
  .ovr-page .ovr-canrow .ovr-canc{
    flex-basis:auto !important;
    width:auto !important;
    height:clamp(300px,28vw,400px) !important;
  }
}

/* ── V113: Editorial action list ──
   Replaces the banned 3-column equal-card row. Primary stays as
   the big vermilion tile on the left. Secondary actions are a
   vertical list with italic verbs and hairline dividers — no
   boxes, no card grid. The redesign skill and design-taste skill
   both explicitly ban the 3-column-equal-card layout. */
.ovr-page .ovr-qabento{
  display:grid !important;
  grid-template-columns:1fr !important;
  grid-template-rows:auto !important;
  gap:16px !important;
  padding:0 clamp(24px,3vw,56px) 22px !important;
}
@media (min-width:768px){
  .ovr-page .ovr-qabento{
    grid-template-columns:clamp(280px,30%,380px) 1fr !important;
    gap:clamp(28px,4vw,56px) !important;
    align-items:stretch !important;
  }
}
.ovr-page .ovr-qab-big{
  grid-row:auto !important;
  min-height:300px !important;
}
.ovr-page .ovr-actlist{
  display:flex;
  flex-direction:column;
  align-self:stretch;
}
.ovr-page .ovr-actrow{
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;
  gap:clamp(16px,2vw,32px);
  padding:18px 4px;
  background:transparent;
  border:none;
  border-bottom:0.5px solid var(--ot-bd);
  color:var(--ot-ink);
  font-family:inherit;
  text-align:left;
  width:100%;
  cursor:pointer;
  transition:opacity 200ms ease,transform 150ms var(--ease-out);
}
.ovr-page .ovr-actrow:last-child{border-bottom:none}
.ovr-page .ovr-actrow:active{transform:scale(0.985)}
@media (hover: hover) and (pointer: fine){
  .ovr-page .ovr-actrow:hover .ovr-actarr{
    transform:translateX(6px);
    color:var(--ot-ver);
  }
  .ovr-page .ovr-actrow:hover .ovr-actname em{color:var(--ot-ver)}
}
.ovr-page .ovr-actnum{
  font-family:var(--ot-font);
  font-size:13px;
  font-weight:500;
  color:var(--ot-t3);
  font-variant-numeric:tabular-nums;
  letter-spacing:0.04em;
  min-width:28px;
}
.ovr-page .ovr-actname{
  font-family:var(--ot-font);
  font-size:clamp(20px,2.2vw,30px);
  font-weight:500;
  letter-spacing:-0.02em;
  line-height:1.1;
}
.ovr-page .ovr-actname em{
  font-style:italic;
  font-weight:600;
  color:var(--ot-ink);
  transition:color 200ms ease;
}
.ovr-page .ovr-actarr{
  font-size:20px;
  color:var(--ot-t2);
  font-family:var(--ot-font);
  transition:transform 200ms var(--ease-out),color 200ms ease;
}

/* ── V112: Eyebrow editorial restyle ──
   "TOTAL OWED · MAY 17" was the first thing on the page and was
   tracked uppercase. Redesign-skill audit flagged this as a tell.
   Switch to sentence case, drop the tracking, bump the size so it
   has presence as a real masthead label, keep the italic vermilion
   accent on "owed". */
.ovr-page .ovr-ctx{
  text-transform:none !important;
  letter-spacing:0 !important;
  font-size:15px !important;
  font-weight:500 !important;
  font-style:italic !important;
  color:var(--ot-t2) !important;
  max-width:none !important;
  margin-bottom:18px !important;
}
.ovr-page .ovr-ctx em{
  font-style:italic !important;
  font-weight:600 !important;
  color:var(--ot-ver) !important;
}
/* Live-state dot stays vermilion solid */
@media (min-width:768px){
  .ovr-page .ovr-ctx{
    /* V116: bumped from 17px → 22px so the eyebrow reads bigger
       than the .13 cents subscript on the hero number. Previously
       they were the same scale and felt unintentional. */
    font-size:22px !important;
    margin-bottom:28px !important;
  }
}

/* ══════ V208 — Overview rhythm: one content column ══════
   User feedback (v207 demo): debt cards sat left-aligned in a full-width
   row while the notice/cash-flow minis centered at 980px — two competing
   columns read as "weird centering + squished cards". The hero and the
   dark Today slab stay full-bleed (intentional editorial contrast); all
   WHITE content below shares one centered 1040px column. On desktop the
   card row becomes a grid inside that column (no stranded right
   whitespace, wraps cleanly at 4+ debts); mobile keeps the swipeable
   row. Card height +16px so the type breathes. */
@media (min-width:1024px){
  .ovr-page .ovr-stats,
  .ovr-page .ovr-sec,
  .ovr-page .ovr-cardwrap,
  .ovr-page .ovr-canrow,
  .ovr-page .ovr-ulist,
  .ovr-page .ovr-scintro{
    max-width:var(--ovr-col,1200px);
    margin-left:auto !important;
    margin-right:auto !important;
  }
  .ovr-page .ovr-sec{padding-left:24px !important;padding-right:24px !important}
  .ovr-page .ovr-stats{padding-left:24px !important;padding-right:24px !important}
  .ovr-page .ovr-cardrow{
    display:grid !important;
    grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
    gap:16px;
    overflow:visible !important;
    padding:0 24px 24px !important;
  }
  .ovr-page .ovr-fcard{flex:none;width:auto;flex-basis:auto;height:256px}
}

/* ══════ V210 — Overview column scales with the viewport ══════
   User feedback: at wide windows the 1040px column left too much side
   space. The shared column now grows to fill (capped 1280px, 48px
   gutters), and everything that aligns to it — stats, section headers,
   debt cards, minis — follows via --ovr-col. Cards get +8px height at
   the larger width. */
@media (min-width:1024px){
  .ovr-page{--ovr-col:min(1280px,calc(100vw - 96px))}
  .ovr-page .ovr-stats,
  .ovr-page .ovr-sec,
  .ovr-page .ovr-cardwrap,
  .ovr-page .ovr-canrow,
  .ovr-page .ovr-ulist,
  .ovr-page .ovr-scintro{max-width:var(--ovr-col)}
  .ovr-page .ovr-fcard{height:264px}
}
/* Quiet caption under empty stat values — "—" alone read as broken. */
.ovr-page .ovr-ssub{font-size:11px;color:var(--ot-t3);margin-top:6px;letter-spacing:.01em}

/* V212 — on small screens the FAB used to sit on top of the next-action
   bar's CTA (both live at the bottom edge). When the bar is visible the
   FAB now hops above it. */
@media(max-width:900px){
  body.na-visible .fab{bottom:calc(146px + env(safe-area-inset-bottom))}
}


/* ══════ V219 — WCAG 2.1 AA layer ══════
   Findings from the runtime contrast crawler (47 unique failures).
   Brand vermilion #D8431B is 3.35:1 on cream — fine for LARGE text and
   graphics, fails for small text. --accent-text (#B43A10, 5.1:1) now
   carries every small vermilion text role; fills and large display
   accents keep the brighter brand hue. */
:root{ --accent-ink:#B43A10; /* V219 — vermilion for SMALL TEXT (5.1:1 on cream). --accent-text stays cream-on-fill. */ }
.pg-mast-eyebrow,
.ed-eyebrow,
.ed-eyebrow em,
.logo-tag,
.logo:hover .logo-tag,
.ovr-sa-link,
.ed-link{ color:var(--accent-ink) !important; }
.ovr-page .ovr-story.now .ovr-scir{ color:var(--accent-ink); border-color:var(--accent-ink); }
.ovr-page .ovr-story.now .ovr-sm{ color:var(--accent-ink); }

/* Vermilion debt cards: white is only 3.9:1 on #D8431B — passes for the
   big name/amount (large text) but not the small meta lines. Those go
   deep-ink (#2A1006, 4.6:1) and the cents go bold so they qualify as
   large text. Editorial side-effect: looks sharper, not worse. */
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-ftag,
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-fmeta,
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-ftap{ color:#2A1006 !important; }
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-cn{ font-weight:700; font-size:0.5em; }

/* Hero cents on the cream hero: was rgba(255,255,255,.75) artifact on
   some themes; ensure ink-muted everywhere. */
.ovr-page .ovr-num .ovr-cn{ color:var(--ot-t2); }

/* Touch targets (WCAG 2.5.5): tiny text-links and icon buttons get an
   invisible 44px hit area on coarse pointers; small buttons get height. */
@media (pointer:coarse){
  .ed-link,.na-close,.isr-del,#buildChip,.ovr-tcta,
  .ovr-today-up-h button,[onclick*="ismiss"]{ position:relative; }
  .ed-link::after,.na-close::after,.isr-del::after,#buildChip::after,
  .ovr-tcta::after,.ovr-today-up-h button::after,[onclick*="ismiss"]::after{
    content:''; position:absolute; inset:-12px;
  }
  .btn,.bp,.br2{ min-height:40px; }
  .ovr-today-up-row{ min-height:44px; }
}


/* V219 round 2 — remaining crawler findings. */
/* Inline small vermilion text (spans/ems written with var(--ot-ver)). */
[style*="color:var(--ot-ver"]{ color:var(--accent-ink) !important; }
/* Hero eyebrow accent ("Total owed") — 22px regular needs 4.5:1. */
.ovr-page .ovr-eyebrow em{ color:var(--accent-ink) !important; }
/* Desktop section-nav active label (10px vermilion). */
.sec-tab.on,.sec-tab.on span{ color:var(--accent-ink) !important; }
/* Plan goal-card display figures: 20-22px weight-600 misses the bold
   large-text bar; push to 700 so 3:1 applies (vermilion passes). */
.plan-hero ~ * [data-stat-target]{ font-weight:700; }
/* Action-bar + invoice CTA fills: white 12px text needs a darker fill. */
.next-action-bar .na-cta{ background:var(--accent-ink) !important; }
.btn-inv-preview{ background:var(--accent-ink) !important; }
/* Vermilion card cents: full white + bold (large-text rule, 3.9:1 ≥ 3). */
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-cn{ color:#FFFFFF !important; opacity:1 !important; }
/* Dark Today slab: muted token is tuned for cream — re-tune inside the
   slab so secondary text reads against ink (#A9A498 ≈ 5.8:1). */
.ovr-page .ovr-today{ --ot-t3:#A9A498; --ot-t2:#C6C1B5; }
/* Invoice preview-pane label sits on the slate strip. */
.inv-preview-lbl{ color:#FFFFFF !important; }


/* V219 round 3 — final crawler stragglers. */
.ovr-page .ovr-ctx em{ color:var(--accent-ink) !important; }              /* hero "owed" 22px */
.bn-item.on{ color:var(--accent-ink) !important; }                        /* bottom-nav active 10px label */
.ovr-page .ovr-cardrow .ovr-fcard:nth-child(odd) .ovr-ff .ovr-famt .ovr-cn{
  color:#FFFFFF !important; font-weight:700; font-size:0.5em;             /* scales with the amount */
}
/* Inside the dark Today slab the BRIGHT vermilion is the accessible one
   (4.9:1 on ink) — exempt it from the global small-vermilion darkening. */
.ovr-page .ovr-today [style*="color:var(--ot-ver"],
.ovr-page .ovr-today .ovr-brief span{ color:var(--ot-ver,#D8431B) !important; }
/* Invoice preview label sits on the light pane after all — dark ink. */
.inv-preview-lbl{ color:#4A453C !important; }


/* ══════ App left sidebar (☰ menu) — v251 ══════ */
.app-drawer{position:fixed;inset:0;z-index:1000;visibility:hidden;opacity:0;transition:opacity .25s,visibility .25s}
.app-drawer.open{visibility:visible;opacity:1}
.app-drawer .ad-scrim{position:absolute;inset:0;background:rgba(14,17,22,.45)}
.app-drawer .ad-panel{position:absolute;top:0;left:0;bottom:0;width:min(86vw,300px);background:var(--bg);border-right:1px solid var(--border);transform:translateX(-100%);transition:transform .28s ease-out;display:flex;flex-direction:column;padding:16px 18px calc(16px + env(safe-area-inset-bottom));overflow-y:auto}
.app-drawer.open .ad-panel{transform:none}
.app-drawer .ad-h{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.app-drawer .ad-wm{font-size:17px;font-weight:600;color:var(--ink)}
.app-drawer .ad-wm em{font-family:'Newsreader',serif;font-style:italic;color:var(--accent);font-weight:500}
.app-drawer .ad-x{width:40px;height:40px;border:none;background:transparent;font-size:26px;line-height:1;color:var(--ink);cursor:pointer}
.app-drawer .ad-nav{display:flex;flex-direction:column}
.app-drawer .ad-nav button,.app-drawer .ad-nav a{text-align:left;font:500 16px/1.2 var(--ot-font,'Inter Tight',sans-serif);color:var(--ink);background:none;border:none;border-bottom:1px solid var(--border);padding:15px 4px;cursor:pointer;text-decoration:none;width:100%}
.app-drawer .ad-nav button:hover,.app-drawer .ad-nav a:hover{color:var(--accent)}
.app-drawer .ad-sep{height:14px}

/* ════════════════════════════════════════════════════════════════════
   V277 — "More motion" pass: premium-but-lively micro-interactions.
   All transforms/idle motion are gated behind hover capability and
   prefers-reduced-motion so the Calm Authority baseline is preserved
   for users who opt out. Nothing here changes layout at rest.
   ════════════════════════════════════════════════════════════════════ */

@media (hover: hover) and (prefers-reduced-motion: no-preference){
  /* Dominant editorial card — the transform transition was already wired
     but had no :hover target, so cards never moved. Give them a gentle
     lift + deeper shadow so content feels tactile across every tab. */
  .ed-card{transition:transform 240ms var(--ease-out),box-shadow 240ms var(--ease-out)}
  .ed-card:hover{transform:translateY(-3px);box-shadow:0 16px 34px rgba(20,20,20,.10),0 4px 10px rgba(20,20,20,.05)}

  /* Buttons — primary buttons lift on hover (press-scale already exists). */
  .btn{transition:background 180ms ease,border-color 180ms ease,color 180ms ease,transform 160ms var(--ease-out),box-shadow 180ms ease}
  .btn:hover{transform:translateY(-1px)}
  .bp{transition:background 180ms ease,transform 150ms var(--ease-out,ease),box-shadow 200ms ease}
  .bp:hover{transform:translateY(-1px);box-shadow:0 8px 18px rgba(216,67,27,.28)}

  /* Topbar icon buttons (search / inbox / settings / menu) — quiet lift. */
  .topbar > button{transition:transform 160ms var(--ease-hover,ease),background 160ms ease}
  .topbar > button:hover{transform:translateY(-1px)}

  /* Overview month chips already scale their circle on hover; add a small
     lift to the whole chip so the row feels alive end-to-end. */
  .ovr-page .ovr-story{transition:transform 200ms var(--ease-out)}
  .ovr-page .ovr-story:hover{transform:translateY(-2px)}
}

/* Soft focus ring on form controls — a calm glow that fades in/out.
   Works in both themes via the vermilion accent at low alpha. */
@media (prefers-reduced-motion: no-preference){
  input,select,textarea{transition:border-color 150ms ease,box-shadow 200ms var(--ease-out)}
}
input:focus,select:focus,textarea:focus,
.inv-field input:focus,.inv-field select:focus{
  box-shadow:0 0 0 3px rgba(216,67,27,.14);
}

/* FAB — springy entrance, then a continuous "ready" pulse: an expanding
   vermilion halo ring radiates outward on a loop so the primary action is
   always visibly alive. The FAB itself also gently breathes. */
@media (prefers-reduced-motion: no-preference){
  .fab{
    position:fixed; /* keep stacking context for ::after */
    animation:fab-pop 460ms var(--ease-bounce,cubic-bezier(0.34,1.56,0.64,1)) both,
              fab-breathe 3.2s ease-in-out 0.6s infinite;
  }
  .fab::after{
    content:'';position:absolute;inset:0;border-radius:50%;
    border:2px solid var(--accent,#D8431B);
    animation:fab-halo 2.4s ease-out infinite;
    pointer-events:none;
  }
  @keyframes fab-pop{
    from{opacity:0;transform:scale(.4) translateY(12px)}
    60%{opacity:1}
    to{opacity:1;transform:scale(1) translateY(0)}
  }
  @keyframes fab-breathe{
    0%,100%{transform:scale(1)}
    50%{transform:scale(1.06)}
  }
  @keyframes fab-halo{
    0%{transform:scale(1);opacity:.55}
    70%{opacity:0}
    100%{transform:scale(1.9);opacity:0}
  }
}

/* Respect the opt-out: strip every motion this pass introduced. */
@media (prefers-reduced-motion: reduce){
  .ed-card:hover,.btn:hover,.bp:hover,.topbar > button:hover{transform:none}
  .fab{animation:none}
  .fab::after{display:none}
  input:focus,select:focus,textarea:focus{box-shadow:0 0 0 3px rgba(216,67,27,.14)}
}

/* ════════════════════════════════════════════════════════════════════
   V279 — "Maximal" pass: hero sheen + full page cross-fade/slide.
   Default-on, stripped under prefers-reduced-motion.
   ════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: no-preference){
  /* Hero number — a soft light "sheen" sweeps across on a loop. Overlay
     pseudo-element only, so the number's color/weight is untouched in both
     light and dark themes. */
  .ovr-page .ovr-num{position:relative;overflow:hidden}
  .ovr-page .ovr-num::after{
    content:'';position:absolute;top:0;bottom:0;left:0;width:60%;
    background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,.0) 30%,rgba(255,255,255,.65) 50%,rgba(255,255,255,.0) 70%,transparent 100%);
    transform:translateX(-120%) skewX(-18deg);
    animation:hero-sheen 4.5s ease-in-out 0.6s infinite;
    pointer-events:none;
  }
  html[data-theme="dark"] .ovr-page .ovr-num::after{
    background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,0) 30%,rgba(255,255,255,.30) 50%,rgba(255,255,255,0) 70%,transparent 100%);
  }
  @keyframes hero-sheen{
    0%{transform:translateX(-120%) skewX(-18deg)}
    /* sweep happens in the first ~26% of the cycle, then rests off-screen */
    26%,100%{transform:translateX(230%) skewX(-18deg)}
  }

  /* Full page transition — the whole page cross-fades and zooms in as a
     unit on every tab switch, layered over the per-section vertical
     stagger. Scale stays <=1 so it can never create horizontal overflow
     (a translateX slide would flash a scrollbar on narrow screens). */
  .pg.on{animation:pg-cross 460ms var(--ease-out,cubic-bezier(0.16,1,0.3,1)) both}
  @keyframes pg-cross{
    from{opacity:0;transform:scale(.985)}
    to{opacity:1;transform:scale(1)}
  }
}

@media (prefers-reduced-motion: reduce){
  .ovr-page .ovr-num::after{display:none}
  .pg.on{animation:none}
}

/* ════════════════════════════════════════════════════════════════════
   V281 — universal in-page content cascade. Every app tab/subtab: the
   cards (debt, savings goals) and table rows rise in with a stagger on
   each render, so no page is ever static. Nested elements only, so they
   don't collide with the top-level .pg.on > * section stagger.
   ════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference){
  .pg.on .crd{animation:vfx-rise .55s cubic-bezier(.16,1,.3,1) both}
  .pg.on .crd:nth-child(1){animation-delay:.03s}
  .pg.on .crd:nth-child(2){animation-delay:.10s}
  .pg.on .crd:nth-child(3){animation-delay:.17s}
  .pg.on .crd:nth-child(4){animation-delay:.24s}
  .pg.on .crd:nth-child(5){animation-delay:.31s}
  .pg.on .crd:nth-child(6){animation-delay:.38s}
  .pg.on .crd:nth-child(n+7){animation-delay:.45s}

  .pg.on tbody tr{animation:vfx-rowin .5s cubic-bezier(.16,1,.3,1) both}
  .pg.on tbody tr:nth-child(1){animation-delay:.05s}
  .pg.on tbody tr:nth-child(2){animation-delay:.10s}
  .pg.on tbody tr:nth-child(3){animation-delay:.15s}
  .pg.on tbody tr:nth-child(4){animation-delay:.20s}
  .pg.on tbody tr:nth-child(5){animation-delay:.25s}
  .pg.on tbody tr:nth-child(6){animation-delay:.30s}
  .pg.on tbody tr:nth-child(7){animation-delay:.35s}
  .pg.on tbody tr:nth-child(n+8){animation-delay:.40s}

  @keyframes vfx-rise{from{opacity:0;transform:translateY(26px)}to{opacity:1;transform:none}}
  @keyframes vfx-rowin{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
}
@media (prefers-reduced-motion: reduce){
  .pg.on .crd,.pg.on tbody tr{animation:none}
}
