/* getxfin.com
   ============================================================================
   Built from the app, not from an impression of it.

   - Type is Inter 400/500/600/700 — the exact four weights ios/Xfin/Info.plist
     registers under UIAppFonts, subset from the same @expo-google-fonts/inter
     files the build ships, so the site and the app render in one typeface.
   - Every colour below is a literal value from components/design-system/theme.ts.
   - Light only. The app reads light and airy and that is the brand, so the site
     does not follow the visitor's OS preference; `color-scheme: light` stops
     the browser force-darkening controls and scrollbars.
   ========================================================================== */

@font-face { font-family: Inter; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/inter-400.woff2) format("woff2"); }
@font-face { font-family: Inter; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/inter-500.woff2) format("woff2"); }
@font-face { font-family: Inter; font-style: normal; font-weight: 600; font-display: swap; src: url(/fonts/inter-600.woff2) format("woff2"); }
@font-face { font-family: Inter; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/inter-700.woff2) format("woff2"); }

:root {
  color-scheme: light;

  /* theme.ts — brand */
  --brand: #554B8A;            /* actionSecondary600 */
  --brand-deep: #3E2D7A;       /* purple700 */
  --brand-100: #D8D3EE;        /* actionSecondary100 */
  --brand-300: #9488C0;        /* actionSecondary300 */
  --brand-tint: #EEEDFE;
  --g1: #A78BFA; --g2: #7C3AED; --g3: #6D28D9;   /* BRAND_GRADIENT_STOPS */

  /* theme.ts — surfaces */
  --bg: #FBFBFC;               /* surfaceBase */
  --card: #FFFFFF;             /* surfaceCard */
  --muted: #F0F0F6;            /* surfaceMuted */
  --line: #EDEEF1;
  --line-strong: #E5E7EB;      /* gray200 */
  --gray300: #D1D5DB;
  --ink-dark: #14141A;

  /* theme.ts — text */
  --ink: #1A1D23;              /* textGrayscale900 */
  --ink-700: #495057;
  --ink-600: #4B5563;
  --ink-soft: #6B7280;         /* textGrayscale500 */
  --ink-faint: #9CA3AF;

  /* theme.ts — semantic */
  --pos: #16A34A;              /* flowIncome / alertSuccess400 */
  --warn: #D85F18;             /* alertWarning400 */
  --neg: #B91C1C;              /* alertCritical400 */
  --blue: #1D71D8;             /* actionTertiary400 */

  --radius-card: 20px;
  --radius-tile: 16px;
  --shadow-sm: 0 1px 3px rgba(26,29,35,.07);
  --shadow: 0 1px 2px rgba(26,29,35,.04), 0 8px 28px rgba(26,29,35,.06);
  --shadow-lg: 0 2px 6px rgba(26,29,35,.05), 0 26px 60px rgba(26,29,35,.11);
  --measure: 46rem;
  --ease: cubic-bezier(.16, 1, .3, 1);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 400 17px/1.65 Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "kern" 1, "liga" 1;
}
.wrap { max-width: var(--measure); margin: 0 auto; padding-left: 1.5rem; padding-right: 1.5rem; }
.wide { max-width: 70rem; }
.mid { max-width: 58rem; }

/* ── scroll reveal ─────────────────────────────────────────────────
   One primitive, used everywhere. Elements start displaced and settle;
   the observer adds .in once and never removes it, so nothing re-animates
   on scroll-back. --d staggers siblings. */
.reveal { opacity: 0; transform: translateY(26px); }
.reveal.in {
  opacity: 1; transform: none;
  transition: opacity .85s var(--ease) var(--d, 0s), transform .85s var(--ease) var(--d, 0s);
}
/* .in is added by script. With no scripting there is nothing to add it, and
   the headline would stay at opacity 0 forever — so hand the page back. */
@media (scripting: none) {
  .reveal { opacity: 1; transform: none; }
}

/* ── header ───────────────────────────────────────────────────────── */
/* The app runs a TRANSPARENT floating header over HeaderGradientGlow — an
   indigo wash from the very top, rgba(90,75,180,.65) fading to nothing at the
   header's bottom edge. Same hue and direction here, carried at a lower alpha
   because the site's header spans a desktop width rather than a 393pt screen,
   where .65 would read as a purple band instead of a glow. The frosted plate
   only appears once you scroll, so the glow is what you see at the top. */
header {
  position: sticky; top: 0; z-index: 50;
  background: transparent; border-bottom: 1px solid transparent;
  transition: background .35s var(--ease), border-color .3s, backdrop-filter .35s;
}
header::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 132px; z-index: -1;
  background: linear-gradient(180deg, rgba(90,75,180,.28) 0%, rgba(90,75,180,0) 100%);
  pointer-events: none;
}
header.stuck {
  background: rgba(251,251,252,.78); backdrop-filter: saturate(180%) blur(20px);
  border-bottom-color: var(--line);
}
header.stuck::before { opacity: 0; transition: opacity .35s var(--ease); }
.bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; height: 56px; }
.brand { display: inline-flex; align-items: center; gap: .55rem; text-decoration: none; }
.brand img { display: block; height: 27px; width: 27px; }
.brand span { font-weight: 600; font-size: 1.08rem; color: var(--ink); letter-spacing: -.02em; }
nav { display: flex; align-items: center; gap: 1.4rem; }
nav a { color: var(--ink-600); text-decoration: none; font-size: .92rem; font-weight: 500; }
nav a:hover { color: var(--ink); }
nav .btn { color: #fff; background: var(--brand); padding: .48rem 1.05rem; border-radius: 999px; font-weight: 600; }
nav .btn:hover { color: #fff; filter: brightness(1.08); }
@media (max-width: 620px) { nav a.hide-s { display: none; } }

/* ── hero ─────────────────────────────────────────────────────────── */
.hero { text-align: center; padding: 5rem 0 1rem; position: relative; overflow: hidden; }
.hero::before {
  content: ""; position: absolute; inset: -30% 0 auto; height: 70vh; z-index: -1;
  background: radial-gradient(58% 52% at 50% 0%, rgba(167,139,250,.30), rgba(167,139,250,0) 70%);
}
/* The real 1024pt App Store icon, at the squircle radius iOS gives it. */
.appicon {
  width: 96px; height: 96px; border-radius: 22px; display: block; margin: 0 auto 2rem;
  background: #fff;
  box-shadow: 0 1px 2px rgba(26,29,35,.10), 0 20px 48px rgba(85,75,138,.26);
}
h1 {
  font-size: clamp(2.9rem, 8.2vw, 6.2rem); line-height: .96; font-weight: 700;
  letter-spacing: -.045em; margin: 0 0 1.25rem; text-wrap: balance;
}
.lede {
  font-size: clamp(1.1rem, 1.9vw, 1.42rem); line-height: 1.5; color: var(--ink-soft);
  margin: 0 auto 2.4rem; max-width: 34rem; font-weight: 400; text-wrap: pretty;
}
.cta {
  display: inline-flex; align-items: center; gap: .5rem; background: var(--brand); color: #fff;
  padding: .95rem 1.9rem; border-radius: 999px; text-decoration: none; font-weight: 600;
  font-size: 1.03rem; box-shadow: 0 2px 5px rgba(85,75,138,.2), 0 14px 34px rgba(85,75,138,.22);
  transition: transform .3s var(--ease), filter .3s;
}
.cta:hover { filter: brightness(1.09); transform: translateY(-2px); }
.cta-note { display: block; margin-top: 1rem; color: var(--ink-faint); font-size: .89rem; }

/* ── section rhythm ───────────────────────────────────────────────── */
section.band { padding: 7rem 0; }
section.band.tight { padding: 4.5rem 0; }
section.band.alt { background: #F7F7FA; }
section.band.dark { background: var(--ink-dark); color: #fff; }
.eyebrow {
  font-size: .78rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase;
  color: var(--brand); margin: 0 0 1rem;
}
.dark .eyebrow { color: var(--g1); }
h2.section {
  font-size: clamp(2rem, 4.4vw, 3.3rem); line-height: 1.06; font-weight: 700;
  letter-spacing: -.038em; margin: 0 0 1.1rem; text-wrap: balance;
}
.section-sub {
  font-size: clamp(1.02rem, 1.5vw, 1.2rem); color: var(--ink-soft); margin: 0 0 3rem;
  max-width: 38rem; line-height: 1.55; text-wrap: pretty;
}
.dark .section-sub { color: #A9AAB4; }
.center { text-align: center; }
.center .section-sub { margin-left: auto; margin-right: auto; }

/* the gradient "fin" wordmark, set inline in running text */
.finword { height: .92em; width: auto; vertical-align: -.06em; }

/* ── iPhone renders ─────────────────────────────────────────────────
   Each screen is authored at true iPhone logical points (393 × 852, an
   iPhone 15/16) using the app's own type scale from
   components/design-system/theme.ts — displayXl 44/52, bodyLgSemibold
   14/22, captionSm 12/16, captionXs 11/14 — and then the whole screen
   is scaled as one unit. Authoring at real point size is why these read
   as the device rather than as an approximation of it: every gap, radius
   and font size below is the number the app actually uses. */

.shots {
  /* Scale factor for the 393pt canvas. It has to stay unitless — CSS cannot
     divide a length by a length, so a calc() against the viewport here just
     yields an invalid value and collapses every screen to nothing. */
  --s: .68;
  display: flex; flex-wrap: wrap; gap: 2.75rem 1.75rem;
  justify-content: center; align-items: flex-start;
  padding: 0 1.5rem 3.5rem;
}
.device { margin: 0; display: flex; flex-direction: column; align-items: center; }
.device-body {
  position: relative; padding: 11px;
  border-radius: calc(56px * var(--s) + 11px);
  background: linear-gradient(147deg, #7d7d86 0%, #2a2a30 20%, #17171b 52%, #45454d 86%, #6e6e77 100%);
  box-shadow: 0 22px 44px rgba(26,29,35,.24), 0 2px 6px rgba(26,29,35,.14);
}
/* right side: power. left side: action button over the volume pair. */
.device-body::before, .device-body::after {
  content: ""; position: absolute; width: 3px; border-radius: 3px;
  background: linear-gradient(90deg, #2b2b31, #5c5c66);
}
.device-body::before { right: -1px; top: 27%; height: calc(86px * var(--s)); }
.device-body::after {
  left: -1px; top: 17%; height: calc(196px * var(--s));
  background:
    linear-gradient(90deg, #2b2b31, #5c5c66) 0 0 / 3px calc(30px * var(--s)) no-repeat,
    linear-gradient(90deg, #2b2b31, #5c5c66) 0 calc(66px * var(--s)) / 3px calc(58px * var(--s)) no-repeat,
    linear-gradient(90deg, #2b2b31, #5c5c66) 0 calc(138px * var(--s)) / 3px calc(58px * var(--s)) no-repeat;
}
.device-screen {
  position: relative; overflow: hidden; background: var(--bg);
  width: calc(393px * var(--s)); height: calc(852px * var(--s));
  border-radius: calc(56px * var(--s));
}
/* the 393 × 852 canvas everything below is drawn on */
.ios {
  position: absolute; top: 0; left: 0; width: 393px; height: 852px;
  transform: scale(var(--s)); transform-origin: top left;
  display: flex; flex-direction: column;
  font-size: 14px; line-height: 22px; color: var(--ink);
  /* .hero centres its column; the phone is a device canvas and must not
     inherit that. Screen 1 lives in .shots and never did, which is why only
     the hero render came out centred. */
  text-align: left;
}
.island {
  position: absolute; z-index: 6; top: 11px; left: 50%; transform: translateX(-50%);
  width: 124px; height: 36px; border-radius: 18px; background: #000;
}
.homebar {
  position: absolute; z-index: 6; bottom: 8px; left: 50%; transform: translateX(-50%);
  width: 140px; height: 5px; border-radius: 3px; background: rgba(0,0,0,.82);
}
.sb {
  flex: 0 0 auto; height: 59px; display: flex; align-items: center;
  justify-content: space-between; padding: 0 22px 0 32px;
}
.sb b { font-size: 16px; font-weight: 640; letter-spacing: -.2px; }
.sb svg { width: 68px; height: 13px; }

/* Ionicons glyphs, extracted from the app's own font. They are filled
   outlines, so no stroke — stroking them doubles every edge. */
.i { width: 20px; height: 20px; fill: currentColor; stroke: none; }
.device figcaption { margin-top: 1rem; font-size: .9rem; color: var(--ink-soft); text-align: center; max-width: 22rem; }

/* ── app surfaces ─────────────────────────────────────────────────── */
.wash { padding: 0 12px 18px; background: transparent; }
.ios::before {
  content: ""; position: absolute; z-index: 0; top: 0; left: 0; right: 0; height: 115px;
  background: linear-gradient(180deg, rgba(90,75,180,.65) 0%, rgba(90,75,180,0) 100%);
  pointer-events: none;
}
/* Lift the screen content above the header gradient — but NOT the island
   or the home bar, which are absolute overlays. Making them relative put
   them in flow and pushed the status bar 36pt down the screen. */
.ios > *:not(.island):not(.homebar) { position: relative; z-index: 1; }
.chrome { display: flex; align-items: center; justify-content: space-between; gap: 8px; height: 48px; margin-bottom: 8px; }
.hbub {
  width: 38px; height: 38px; flex: 0 0 auto; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.5); border: 1px solid rgba(255,255,255,.55);
  font-size: 15px; font-weight: 700;
}
/* building-bank, size 18, actionSecondary600 — cash-flow-dashboard.tsx */
.hbub .i { width: 18px; height: 18px; color: #554B8A; }
.hbub.grad {
  background-image: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.h-caprow { display: flex; align-items: center; gap: 6px; }
.h-chev {
  width: 22px; height: 22px; flex: 0 0 auto; border-radius: 999px; position: relative;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
}
.h-chev { display: flex; align-items: center; justify-content: center; }
/* chevron-down at 14px in white, inside the 22px brand-gradient circle. */
.h-chev .i { width: 14px; height: 14px; color: #fff; }
/* Cash + Income − Bills − Goals */
.h-formula { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 4px; }
.fc { font-size: 11px; line-height: 14px; font-weight: 600; padding: 2px 6px; border-radius: 8px; white-space: nowrap; }
.fo { font-size: 11px; line-height: 14px; font-weight: 500; color: #DEE2E6; }
.body { flex: 1; min-height: 0; padding: 0 12px; display: flex; flex-direction: column; gap: 11px; }

.seg { display: flex; gap: 2px; background: rgba(255,255,255,.55); border-radius: 999px; padding: 3px; width: fit-content; }
.seg span { font-size: 13px; font-weight: 600; padding: 6px 16px; border-radius: 999px; color: #3E2D7A; }
.seg span.on { background: #fff; box-shadow: 0 1px 3px rgba(26,29,35,.14); }

/* the twin hero: Cash Reserve leads on the left, Current Cash on the right */
.twin { display: flex; gap: 14px; }
.twin > div { flex: 1; min-width: 0; }
/* Phase 450hz-fin120: the window pills sit TOP-RIGHT of the hero, in a row
   with the title — not under the number. And in RESERVE mode the formula
   chips REPLACE the caption; the gradient chevron rides the end of the
   formula row, never the caption. */
.h-toprow { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
.h-toprow .chips { flex: 0 0 auto; margin-left: 8px; }
.h-frow { display: flex; align-items: center; gap: 4px; margin-top: 4px; }
.h-frow .h-formula { flex: 1 1 auto; margin-top: 0; }
.h-frow .h-chev { flex: 0 0 auto; }
[hidden] { display: none !important; }
.h-title { font-size: 18px; line-height: 28px; font-weight: 600; color: #495057; }
.h-num { font-size: 44px; line-height: 52px; font-weight: 700; letter-spacing: -1px; margin-top: 2px; }
.h-num.soft { opacity: .6; }
.h-cap { font-size: 12px; line-height: 16px; font-weight: 500; color: #6B7280; }
.pos { color: #16A34A; }

.chips { display: flex; gap: 4px; }
.chipw { font-size: 11px; line-height: 14px; font-weight: 600; padding: 2px 8px; border-radius: 16px; border: 1px solid #E5E7EB; color: #6B7280; }
.chipw.on { background: #D8D3EE; border-color: #9488C0; color: #554B8A; }

.dowith { font-size: 16px; font-weight: 700; letter-spacing: -.3px; margin: 4px 0 -2px; }
.dowith em { font-style: normal; font-weight: 700; background: linear-gradient(90deg, #1D71D8, #8B5CF6); -webkit-background-clip: text; background-clip: text; color: transparent; }

.card { background: #fff; border-radius: 16px; box-shadow: 0 1px 3px rgba(26,29,35,.07); }
.afford { padding: 13px 15px; display: flex; align-items: center; justify-content: space-between; border: 1.5px solid #554B8A; }
.afford b { display: block; font-size: 14px; font-weight: 600; color: #3E2D7A; }
.afford i { font-style: normal; font-size: 12px; line-height: 16px; color: #6B7280; }

.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.tile { padding: 14px; }
.tile.alert { background: #FEF6F1; }
.tile-top { display: flex; align-items: center; justify-content: space-between; }
.chipic { width: 34px; height: 34px; border-radius: 11px; display: flex; align-items: center; justify-content: center; }
.chipic .i { width: 18px; height: 18px; }
.tile b { display: block; font-size: 14px; line-height: 22px; font-weight: 600; margin-top: 8px; }
.tile .v { font-size: 12px; line-height: 16px; color: #6B7280; }
.tile .v.warn { color: #D85F18; }
.tile .h { font-size: 11px; line-height: 14px; color: #9CA3AF; margin-top: 5px; }

/* category + account rows */
.crow { padding: 12px 14px; display: flex; align-items: center; gap: 11px; }
.rw { flex: 1; min-width: 0; }
.rw b { display: block; font-size: 14px; line-height: 22px; font-weight: 600; }
.rw i { display: block; font-style: normal; font-size: 12px; line-height: 16px; color: #6B7280; margin-top: 1px; }
.rw i.warn { color: #D85F18; }
.rw i.bad { color: #B91C1C; }
.amt { font-size: 14px; font-weight: 600; letter-spacing: -.2px; flex: 0 0 auto; }

.bucket { display: flex; align-items: center; justify-content: space-between; margin: 6px 0 -2px; }
.bucket-l { display: flex; align-items: center; gap: 8px; }
.dot { width: 8px; height: 8px; border-radius: 999px; }
.bucket-k { font-size: 11px; line-height: 14px; font-weight: 600; color: #6B7280; letter-spacing: .4px; }
.bucket-s { font-size: 12px; line-height: 16px; color: #4B5563; }
.bucket-t { font-size: 12px; line-height: 16px; font-weight: 600; color: #4B5563; }

/* the focus bar: only a category the user has put a focus on gets graded */
.focus { display: flex; align-items: center; gap: 8px; margin-top: 7px; }
.track { flex: 1; height: 6px; border-radius: 999px; background: #B91C1C22; overflow: hidden; }
.track > i { display: block; height: 6px; border-radius: 999px; background: #B91C1C; }
.pct { font-size: 11px; font-weight: 600; color: #B91C1C; min-width: 34px; text-align: right; }

.stepper { display: flex; align-items: center; justify-content: center; gap: 14px; color: #495057; }
.stepper b { font-size: 14px; font-weight: 600; }
.stepper .i { width: 18px; height: 18px; color: #9CA3AF; }

.filters { display: flex; gap: 6px; overflow: hidden; }

/* net worth spark */
.spark { height: 84px; margin: 2px 0 4px; }
.spark svg { width: 100%; height: 100%; display: block; }

.eyebrow { font-size: 12px; font-weight: 600; color: #554B8A; letter-spacing: .4px; }
.display { font-size: 28px; line-height: 36px; font-weight: 700; letter-spacing: -.6px; margin: 4px 0 0; }

/* fin chat */
.finhead { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 2px 12px 12px; }
.finhead .mark { font-size: 17px; font-weight: 700; background: linear-gradient(90deg, #1D71D8, #8B5CF6); -webkit-background-clip: text; background-clip: text; color: transparent; }
.finhead .ctx { font-size: 11px; font-weight: 600; color: #554B8A; background: #EEEDFE; border-radius: 999px; padding: 4px 10px; }
.finhead .x { width: 28px; height: 28px; border-radius: 999px; background: #F0F0F6; display: flex; align-items: center; justify-content: center; color: #6B7280; }
.finhead .x .i { width: 15px; height: 15px; }
.me { align-self: flex-end; max-width: 76%; background: #554B8A; color: #fff; border-radius: 18px; padding: 10px 14px; font-size: 14px; line-height: 20px; }
.fin { font-size: 14px; line-height: 21px; }
.fin.soft { color: #4B5563; }
.confirm { padding: 13px 15px; font-size: 13px; font-weight: 600; border: 1px solid #E5E7EB; }
.confirm.primary { border: 1.5px solid #554B8A; color: #554B8A; }
.disclaim { margin-top: auto; font-size: 11px; line-height: 15px; color: #9CA3AF; margin-bottom: 0; }
.composer {
  flex: 0 0 auto; margin: 0 20px 30px; padding: 12px 14px;
  background: #fff; border: 1px solid #E5E7EB; border-radius: 999px;
  display: flex; align-items: center; justify-content: space-between;
  font-size: 14px; color: #9CA3AF; box-shadow: 0 2px 10px rgba(26,29,35,.06);
}
.composer em { font-style: normal; width: 26px; height: 26px; border-radius: 999px; background: #554B8A; color: #fff; display: flex; align-items: center; justify-content: center; }
.composer em .i { width: 15px; height: 15px; }

/* Fin's inline commentary on Home: sparkle, the line, a dismiss, a trace
   label naming where the figure came from, and an optional action row. */
.insight { padding: 13px 15px; }
.insight-top { display: flex; gap: 9px; align-items: flex-start; }
.insight-top p { margin: 0; font-size: 12px; line-height: 17px; color: #4B5563; flex: 1; }
.insight .sp { width: 16px; height: 16px; color: #8B5CF6; flex: 0 0 auto; margin-top: 1px; }
.insight .xs { width: 14px; height: 14px; color: #9CA3AF; flex: 0 0 auto; margin-top: 2px; }
.insight .trace { display: block; font-size: 11px; color: #9CA3AF; margin: 6px 0 0 25px; }
.insight-cta {
  margin-top: 10px; padding-top: 9px; border-top: 1px solid #F0F0F6;
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
  font-size: 12px; font-weight: 600; color: #554B8A;
}
.insight-cta .xs { width: 14px; height: 14px; }

/* PlanWithFinButton: a 1.5pt brand-gradient border around a white card. */
.planwithfin { border-radius: 16px; padding: 1.5px; background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9); box-shadow: 0 1px 3px rgba(26,29,35,.08); }
.pwf-inner { border-radius: 14.5px; background: #fff; padding: 11px 13px; display: flex; align-items: center; gap: 10px; }
.pwf-ic { width: 26px; height: 26px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.pwf-ic .i { width: 22px; height: 22px; color: #554B8A; }
.pwf-inner .rw b { color: #453C73; }


/* ── chrome pieces shared by the renders ─────────────────────────── */
.hbub.ghost { background: transparent; border-color: transparent; }
.titlebub {
  height: 40px; padding: 0 16px; border-radius: 20px; display: inline-flex; align-items: center;
  background: rgba(255,255,255,.5); border: 1px solid rgba(255,255,255,.55);
}
.finmark { height: 17px; width: auto; display: block; }
.titlebub .finmark { height: 20px; }

/* "Do it with" is gradient text; the fin beside it is the real wordmark. */
.dowith { display: flex; align-items: center; gap: 4px; margin: 4px 0 -2px; }
.gt {
  font-size: 17px; line-height: 20px; font-weight: 600;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* TodayCard / PlanWithFinButton: 1.5pt brand-gradient border, white inner. */
.gradcard { border-radius: 16px; padding: 1.5px; background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9); box-shadow: 0 1px 3px rgba(26,29,35,.08); }
.gradcard-in { border-radius: 14.5px; background: #fff; padding: 10px 16px; display: flex; align-items: center; gap: 12px; }
.pwf-ic { width: 24px; height: 24px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.pwf-ic .i { width: 22px; height: 22px; color: #554B8A; }

/* Fin home */
.h3 { font-size: 18px; line-height: 24px; font-weight: 600; margin: 0; letter-spacing: -.2px; }
.h3sub { font-size: 12px; line-height: 16px; color: #6B7280; margin: 4px 0 0; }
.pillgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pill {
  background: #fff; border: 1px solid #E5E7EB; border-radius: 16px;
  padding: 11px 12px; min-height: 52px; display: flex; align-items: center;
}
.pic { width: 30px; height: 30px; border-radius: 9px; margin-right: 10px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; }
.pic .i { width: 17px; height: 17px; }
.pill b { font-size: 14px; line-height: 18px; font-weight: 600; }
.secthead { font-size: 14px; font-weight: 600; margin: 6px 0 0; }
.recent { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; color: #4B5563; margin: 0; }
.recent span { color: #9CA3AF; font-size: 11px; flex: 0 0 auto; }

/* the floating iOS tab bar */
.tabbar {
  flex: 0 0 auto; margin: 0 20px 30px; padding: 13px 0; border-radius: 999px;
  background: rgba(255,255,255,.92); backdrop-filter: blur(14px);
  display: flex; justify-content: space-around; color: #9CA3AF;
  box-shadow: 0 4px 18px rgba(26,29,35,.13);
}
.tabbar .i { width: 23px; height: 23px; }
/* The four tab icons are template-rendered xcassets in the app — iOS uses the
   alpha as a mask and tints it. Same thing here, so the shapes are the app's
   own and the tint is ours. */
.tabbar .tb {
  width: 26px; height: 26px; background: currentColor;
  /* Longhands, not the `mask:` shorthand — the shorthand resets mask-image to
     none, and at this specificity it would beat the per-icon rules below. */
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain;    mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.tabbar .tb-home  { -webkit-mask-image: url(/brand/tabs/home.png);  mask-image: url(/brand/tabs/home.png); }
.tabbar .tb-clock { -webkit-mask-image: url(/brand/tabs/clock.png); mask-image: url(/brand/tabs/clock.png); }
.tabbar .tb-arrow { -webkit-mask-image: url(/brand/tabs/arrow.png); mask-image: url(/brand/tabs/arrow.png); }
.tabbar .tb-fin   { -webkit-mask-image: url(/brand/tabs/xfin.png);  mask-image: url(/brand/tabs/xfin.png); }
.tabbar .on { color: #554B8A; }
.caption { text-align: center; font-size: .88rem; color: var(--ink-soft); margin-top: .85rem; }

/* ── the live reserve demo ────────────────────────────────────────────
   A working copy of the Cash Flow hero. The chips run the same rule the
   app runs: reserve = cash − bills in the window − what goals hold. Income
   is never folded in until it lands, which is why 30 days can go negative
   while a paycheque sits three days away. */
.demo {
  background: var(--card); border-radius: 26px; box-shadow: var(--shadow-lg);
  padding: 2.25rem 2.25rem 2rem; max-width: 44rem; margin: 0 auto;
}
/* HeaderGradientGlow, verbatim: rgba(90,75,180,.65) to fully transparent,
   ending at the bottom edge of the header chrome rather than washing the page. */
.demo-wash {
  margin: -2.25rem -2.25rem 1.75rem; padding: 1.5rem 2.25rem 1.75rem;
  border-radius: 26px 26px 0 0;
  background:
    linear-gradient(180deg, rgba(90,75,180,.65) 0%, rgba(90,75,180,0) 132px),
    var(--card);
}

/* The header chrome the app actually has: an initials bubble that opens
   Settings, the Cash Flow / Net Worth selector, and a connect-a-bank bubble,
   all sitting on the indigo header wash. */
.demo-chrome { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 2rem; }
.bub {
  width: 40px; height: 40px; border-radius: 999px; display: flex; align-items: center;
  justify-content: center; background: rgba(255,255,255,.55); backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.6); font-weight: 700; font-size: .95rem;
  background-clip: padding-box;
}
.bub:first-child { color: transparent; background-image: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9); -webkit-background-clip: text; background-clip: text; }
.bub svg { width: 21px; height: 21px; stroke: #1A1D23; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.seg-pill {
  display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px;
  background: rgba(255,255,255,.5); backdrop-filter: blur(10px);
}
.seg-pill b, .seg-pill i {
  font-style: normal; font-size: .82rem; font-weight: 600; padding: .4rem .9rem;
  border-radius: 999px; color: #3E2D7A;
}
.seg-pill b { background: #fff; box-shadow: 0 1px 3px rgba(26,29,35,.14); }
.seg-pill i { opacity: .62; }
.demo-hero { min-width: 0; }
.demo-caprow { display: flex; align-items: center; gap: .5rem; }
.chev {
  width: 22px; height: 22px; border-radius: 999px; flex: 0 0 auto;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9); position: relative;
}
.chev::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 7px; height: 7px;
  border-right: 2px solid #fff; border-bottom: 2px solid #fff; transform: translateY(-2px) rotate(45deg);
}
/* Cash + Income − Bills − Goals */
.formula { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; margin-top: 1rem; }
.fchip { font-size: .74rem; font-weight: 600; padding: .22rem .55rem; border-radius: 8px; white-space: nowrap; }
.fop { font-size: .74rem; color: var(--ink-faint); }
.demo-label { font-size: .95rem; font-weight: 600; color: var(--ink-700); }
.demo-num {
  font-size: clamp(2.6rem, 6vw, 3.6rem); font-weight: 700; letter-spacing: -.04em;
  line-height: 1.05; margin-top: .15rem; font-variant-numeric: tabular-nums;
  transition: color .4s var(--ease);
}
.demo-num.soft { opacity: .6; }
.demo-cap { font-size: .92rem; color: var(--ink-soft); min-height: 1.4em; }
.pos { color: var(--pos); } .neg { color: var(--neg); } .warn { color: var(--warn); }

.chiprow { display: flex; gap: .5rem; margin-top: 1.5rem; flex-wrap: wrap; }
.chip {
  font: 600 .84rem/1 Inter, sans-serif; padding: .5rem 1rem; border-radius: 999px;
  border: 1px solid var(--line-strong); background: transparent; color: var(--ink-soft);
  cursor: pointer; transition: all .25s var(--ease);
}
.chip:hover { border-color: var(--brand-300); color: var(--ink); }
.chip[aria-pressed="true"] { background: var(--brand-100); border-color: var(--brand-300); color: var(--brand); }
.chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* the maths, shown rather than asserted */
.ledger { margin-top: .5rem; border-top: 1px solid var(--line); }
.ledger-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: .8rem 0; border-bottom: 1px solid var(--line); font-size: .96rem;
}
.ledger-row b { font-weight: 500; color: var(--ink-600); }
.ledger-row i { font-style: normal; font-size: .84rem; color: var(--ink-faint); display: block; margin-top: .1rem; }
.ledger-row span { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ledger-row.total { border-bottom: 0; font-size: 1.06rem; }
.ledger-row.total b { color: var(--ink); font-weight: 600; }
.ledger-note {
  margin: 1.1rem 0 0; font-size: .9rem; line-height: 1.55; color: var(--ink-soft);
  background: var(--muted); border-radius: 12px; padding: .85rem 1rem;
}

/* ── the affordability calculator ─────────────────────────────────── */
.calc { max-width: 44rem; margin: 0 auto; background: var(--card);
  border-radius: 26px; box-shadow: var(--shadow-lg); padding: 2.25rem; }
.calc-amount {
  font-size: clamp(2.8rem, 7vw, 4rem); font-weight: 700; letter-spacing: -.045em;
  text-align: center; font-variant-numeric: tabular-nums; line-height: 1;
}
.calc-hint { text-align: center; color: var(--ink-faint); font-size: .9rem; margin: .5rem 0 1.75rem; }
input[type=range] {
  -webkit-appearance: none; appearance: none; width: 100%; height: 6px; border-radius: 999px;
  background: var(--muted); outline: none; margin: 0 0 1.5rem;
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 28px; height: 28px; border-radius: 50%;
  background: #fff; border: 1px solid var(--line-strong); cursor: grab;
  box-shadow: 0 1px 3px rgba(26,29,35,.16), 0 4px 12px rgba(26,29,35,.12);
}
input[type=range]::-moz-range-thumb {
  width: 28px; height: 28px; border-radius: 50%; background: #fff;
  border: 1px solid var(--line-strong); cursor: grab;
  box-shadow: 0 1px 3px rgba(26,29,35,.16), 0 4px 12px rgba(26,29,35,.12);
}
input[type=range]:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }
.verdict {
  border-radius: var(--radius-tile); padding: 1.1rem 1.25rem; font-size: 1rem; line-height: 1.55;
  border: 1px solid var(--line-strong); background: var(--muted); color: var(--ink-600);
  transition: background .35s var(--ease), border-color .35s var(--ease);
}
.verdict b { color: var(--ink); font-weight: 600; }
.verdict.safe  { background: #ECFAF0; border-color: #BFE8CC; }
.verdict.tight { background: #FDF3EA; border-color: #F3D6BC; }
.verdict.over  { background: #FDECEC; border-color: #F2C7C7; }
.verdict-tag { display: block; font-size: .74rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; margin-bottom: .4rem; }
.verdict.safe .verdict-tag { color: var(--pos); }
.verdict.tight .verdict-tag { color: var(--warn); }
.verdict.over .verdict-tag { color: var(--neg); }

/* ── Fin, answering ───────────────────────────────────────────────── */
.chat { max-width: 40rem; margin: 0 auto; }
.asks { display: flex; flex-wrap: wrap; gap: .55rem; justify-content: center; margin-bottom: 2rem; }
.ask {
  font: 500 .93rem/1 Inter, sans-serif; padding: .68rem 1.1rem; border-radius: 999px;
  border: 1px solid var(--line-strong); background: var(--card); color: var(--ink-600);
  cursor: pointer; transition: all .25s var(--ease); box-shadow: var(--shadow-sm);
}
.ask:hover { border-color: var(--brand-300); color: var(--ink); transform: translateY(-1px); }
.ask[aria-pressed="true"] { background: var(--brand); border-color: var(--brand); color: #fff; }
.ask:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.thread {
  background: var(--card); border-radius: 24px; box-shadow: var(--shadow-lg);
  padding: 1.75rem; display: flex; flex-direction: column; gap: .9rem; min-height: 15rem;
}
.bubble-me {
  align-self: flex-end; max-width: 82%; background: var(--brand); color: #fff;
  border-radius: 20px 20px 5px 20px; padding: .7rem 1.05rem; font-size: .98rem; line-height: 1.45;
}
.bubble-fin { font-size: 1rem; line-height: 1.6; color: var(--ink-600); margin: 0; }
.bubble-fin b { color: var(--ink); font-weight: 600; }
.act {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  border: 1px solid var(--line-strong); border-radius: var(--radius-tile);
  padding: .85rem 1.1rem; font-size: .95rem; font-weight: 500; color: var(--ink);
}
.act.primary { border: 1.5px solid var(--brand); color: var(--brand); font-weight: 600; }
.act span.k { font-size: .78rem; color: var(--ink-faint); font-weight: 500; }
.caret { width: 8px; height: 8px; border-right: 2px solid var(--gray300);
  border-bottom: 2px solid var(--gray300); transform: rotate(-45deg); flex: 0 0 auto; }
.finfoot {
  display: flex; align-items: center; gap: .5rem; margin-top: .3rem;
  font-size: .8rem; color: var(--ink-faint);
}
.typing { display: inline-flex; gap: 4px; align-items: center; height: 1.6em; }
.typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--gray300);
  animation: blink 1.3s infinite both; }
.typing i:nth-child(2) { animation-delay: .18s; }
.typing i:nth-child(3) { animation-delay: .36s; }
@keyframes blink { 0%,60%,100% { opacity: .28 } 30% { opacity: 1 } }

/* ── feature grid ─────────────────────────────────────────────────── */
.grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr)); }
.feat {
  background: var(--card); border-radius: var(--radius-card); padding: 1.6rem;
  box-shadow: var(--shadow-sm); border: 1px solid var(--line);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.feat:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.feat .ic {
  width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center;
  justify-content: center; margin-bottom: 1rem; background: var(--brand-tint); color: var(--brand);
}
.feat .ic svg { width: 21px; height: 21px; stroke: currentColor; fill: none;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.feat h3 { font-size: 1.02rem; font-weight: 600; margin: 0 0 .4rem; letter-spacing: -.015em; }
.feat p { margin: 0; font-size: .93rem; line-height: 1.55; color: var(--ink-soft); }

/* ── the dark honesty beat ────────────────────────────────────────── */
.dark h2.section, .dark h3 { color: #fff; }
.wont { display: grid; gap: 0; max-width: 46rem; margin: 0 auto; }
.wont > div { padding: 1.6rem 0; border-top: 1px solid rgba(255,255,255,.11); }
.wont > div:last-child { border-bottom: 1px solid rgba(255,255,255,.11); }
.wont h3 { font-size: 1.1rem; font-weight: 600; margin: 0 0 .4rem; letter-spacing: -.015em; }
.wont p { margin: 0; color: #9EA0AB; font-size: .97rem; line-height: 1.6; }
.wont code {
  font: 500 .88em/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  background: rgba(255,255,255,.09); padding: .15em .45em; border-radius: 5px; color: #D8D3EE;
}

/* ── privacy receipt ──────────────────────────────────────────────── */
.receipt { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); max-width: 52rem; margin: 0 auto; }
.receipt > div { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 1.5rem; }
.receipt h3 { font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 1rem; }
.receipt .on-device h3 { color: var(--pos); }
.receipt .on-server h3 { color: var(--ink-faint); }
.receipt ul { margin: 0; padding: 0; list-style: none; }
.receipt li { font-size: .93rem; color: var(--ink-600); padding: .38rem 0 .38rem 1.4rem; position: relative; }
.receipt li::before { content: ""; position: absolute; left: 0; top: .78em; width: 7px; height: 7px;
  border-radius: 50%; background: var(--line-strong); }
.receipt .on-device li::before { background: var(--pos); }
.receipt p.foot { margin: 1rem 0 0; font-size: .86rem; color: var(--ink-faint); line-height: 1.55; }

/* ── screen gallery captions ──────────────────────────────────────── */
.caption { text-align: center; font-size: .93rem; color: var(--ink-soft); margin-top: 1rem;
  max-width: 21rem; line-height: 1.55; }

/* ── waitlist ─────────────────────────────────────────────────────── */
.signup { display: flex; gap: .6rem; max-width: 27rem; margin: 0 auto; flex-wrap: wrap; }
.signup input {
  flex: 1 1 13rem; font: 400 1rem/1 Inter, sans-serif; padding: .95rem 1.15rem;
  border-radius: 999px; border: 1px solid var(--line-strong); background: var(--card); color: var(--ink);
}
.signup input:focus { outline: 2px solid var(--brand); outline-offset: 1px; border-color: transparent; }
.signup button {
  font: 600 1rem/1 Inter, sans-serif; padding: .95rem 1.6rem; border-radius: 999px;
  border: 0; background: var(--brand); color: #fff; cursor: pointer;
  transition: filter .25s, transform .25s var(--ease);
}
.signup button:hover { filter: brightness(1.09); transform: translateY(-1px); }

@media (max-width: 700px) {
  section.band { padding: 4.5rem 0; }
  .demo, .calc { padding: 1.5rem; border-radius: 20px; }
  .demo-wash { margin: -1.5rem -1.5rem 1.4rem; padding: 1.5rem; border-radius: 20px 20px 0 0; }
  .thread { padding: 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .typing i { animation: none; opacity: .5; }
  .cta:hover, .feat:hover, .ask:hover, .signup button:hover { transform: none; }
}

/* ── legal ─────────────────────────────────────────────────────── */
.doc { padding-top: 2.5rem; padding-bottom: 1rem; }
.doc h1 { font-size: clamp(1.9rem,5vw,2.3rem); letter-spacing: -.032em; margin: 0 0 .4rem; font-weight: 660; }
.doc .updated { color: var(--ink-faint); font-size: .9rem; margin: 0 0 2.4rem; }
.doc h2 { font-size: 1.16rem; margin: 2.3rem 0 .55rem; letter-spacing: -.018em; font-weight: 640; }
.doc h3 { font-size: 1rem; margin: 1.5rem 0 .4rem; font-weight: 620; }
.doc p, .doc li { color: var(--ink-soft); }
.doc li { margin-bottom: .4rem; }
.doc strong { color: var(--ink); font-weight: 620; }
.doc a { color: var(--brand); }
table { border-collapse: collapse; width: 100%; margin: 1.2rem 0; font-size: .94rem; }
th, td { text-align: left; padding: .65rem .7rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--ink); font-weight: 620; }
td { color: var(--ink-soft); }
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.callout { border-left: 3px solid var(--brand); background: var(--card); padding: .95rem 1.15rem; margin: 1.5rem 0; border-radius: 0 var(--radius-tile) var(--radius-tile) 0; box-shadow: var(--shadow); }
.callout p { margin: 0; }

footer { border-top: 1px solid var(--line); padding: 2.5rem 0 3rem; color: var(--ink-faint); font-size: .9rem; }
footer .cols { display: flex; flex-wrap: wrap; gap: 2rem 3rem; margin-bottom: 1.75rem; }
footer .col p { margin: 0 0 .5rem; font-weight: 620; color: var(--ink); font-size: .85rem; }
footer .col a { display: block; color: var(--ink-soft); text-decoration: none; margin-bottom: .35rem; }
footer .col a:hover { color: var(--ink); }
footer .legal { line-height: 1.6; border-top: 1px solid var(--line); padding-top: 1.5rem; }

/* The standalone centred pages — the 404 and the Plaid OAuth hand-off — put
   this on <main>. It used to be an unscoped `.center`, which also matched the
   landing page's `.wrap mid center` section headers: it gave every one of them
   min-height 74vh and squeezed their `.section-sub` to the 25rem meant for a
   one-line status message. Scoped to main, so only those two pages get it. */
main.center { min-height: 74vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
main.center h1 { font-size: 1.5rem; margin: 1.2rem 0 .5rem; letter-spacing: -.02em; }
main.center p { color: var(--ink-soft); max-width: 25rem; margin: 0 0 1.5rem; }
.spinner { width: 28px; height: 28px; border-radius: 50%; border: 3px solid var(--line-strong); border-top-color: var(--brand); animation: spin .9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; } html { scroll-behavior: auto; } }

/* 393 × .68 + 22px of bezel is 289px, which clears a 375pt phone with its
   1.5rem gutters. Below that, step down rather than overflow. */
@media (max-width: 360px) { .shots { --s: .58; } }

/* ══════════════════════════════════════════════════════════════════════
   v2 — hero, the formula story, and the reserve demo

   One animation language for all three: things rise once and settle, and
   financial figures count up. Nothing loops, nothing floats, nothing
   moves after it has arrived.

   The staging is opt-IN. Every animated element renders in its finished
   state by default and JS adds .staged to hide it before animating, so a
   failed script or a blocked file leaves a correct page rather than a
   column of $0.00. Reduced motion never gets .staged at all.
   ══════════════════════════════════════════════════════════════════ */

/* ── hero ─────────────────────────────────────────────────────────────
   The claim on the left, the product on the right, so a visitor sees both
   without scrolling. Stacks to headline → phone below 980px, which is the
   order the story needs on a phone. */
.hero-split { display: grid; gap: 3rem; align-items: center; justify-items: center; text-align: center; }
.hero-copy { min-width: 0; }
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 1rem 1.5rem; }
.cta-ghost {
  color: var(--brand); text-decoration: none; font-weight: 600; font-size: 1rem;
  display: inline-flex; align-items: center; gap: .4rem;
}
.cta-ghost i { font-style: normal; display: inline-block; transition: transform .35s var(--ease); }
.cta-ghost:hover i { transform: translateY(3px); }

@media (min-width: 980px) {
  .hero { padding-top: 4rem; }
  .hero-split { grid-template-columns: 1fr auto; gap: 4.5rem; text-align: left; justify-items: stretch; }
  .hero-split h1 { font-size: clamp(2.9rem, 5vw, 4.5rem); }
  .hero-split .appicon { margin-left: 0; width: 76px; height: 76px; margin-bottom: 1.5rem; }
  .hero-split .lede { margin-left: 0; }
  .hero-cta { justify-content: flex-start; }
}

/* The phone is the existing 393 × 852 chassis. It scales up with the
   viewport so the product holds its own against the headline rather than
   sitting beside it as a thumbnail. */
.hero-stage { --s: .72; display: flex; justify-content: center; }
@media (max-width: 360px) { .hero-stage { --s: .62; } }
@media (min-width: 560px) and (max-width: 979px) { .hero-stage { --s: .60; } }
@media (min-width: 980px)  { .hero-stage { --s: .68; } }
@media (min-width: 1200px) { .hero-stage { --s: .74; } }
.hero-stage.staged .device-body { opacity: 0; transform: translateY(50px); }
.hero-stage.staged.in .device-body {
  opacity: 1; transform: none;
  transition: opacity .9s var(--ease), transform 1.05s var(--ease);
}

/* Formula chips arrive one at a time as the number resolves, so the
   arithmetic reads as cause → effect rather than as a finished sum. */
.h-formula.staged .fc, .h-formula.staged .fo { opacity: 0; transform: translateY(5px); }
.h-formula.staged .fc.on, .h-formula.staged .fo.on {
  opacity: 1; transform: none;
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.h-num, .demo-num { font-variant-numeric: tabular-nums; }
.chips.staged .chipw { opacity: 0; }
.chips.staged.on .chipw { opacity: 1; transition: opacity .5s var(--ease); }

/* The window chips, drawn at the app's size inside the phone rather than
   at page size. Same buttons, same behaviour — just the app's proportions. */
.wash .chiprow { display: flex; gap: 4px; flex-wrap: wrap; }
.wash .chiprow .chip {
  font: 600 11px/14px Inter, sans-serif; padding: 2px 8px; border-radius: 16px;
  border: 1px solid #E5E7EB; background: transparent; color: #6B7280;
  cursor: pointer; transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.wash .chiprow .chip:hover { border-color: #9488C0; color: #1A1D23; }
.wash .chiprow .chip[aria-pressed="true"] { background: #D8D3EE; border-color: #9488C0; color: #554B8A; }

/* ── the formula story ────────────────────────────────────────────────
   Section 2. Bank balance → commitments → what is actually left, one line
   at a time. Figures carry cents because this is the section a sceptical
   reader will check: 2,838.18 + 1,336.36 − 740.00 − 407.00 = 3,027.54. */
.fml { max-width: 36rem; margin: 0 auto; }
.fml-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem;
  padding: .95rem 0; border-bottom: 1px solid var(--line);
}
.fml.staged .fml-row { opacity: 0; transform: translateY(16px); }
.fml.staged .fml-row.in {
  opacity: 1; transform: none;
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.fml-row b { font-weight: 500; color: var(--ink-600); font-size: 1rem; }
.fml-row i { font-style: normal; display: block; font-size: .85rem; color: var(--ink-faint); margin-top: .15rem; }
.fml-row .v { font-weight: 600; font-size: 1.15rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fml-row .v.add { color: var(--blue); }
.fml-row .v.sub { color: var(--warn); }
.fml-row .v.hold { color: var(--brand); }
.fml-row.sum {
  border-bottom: 0; border-top: 2px solid var(--ink);
  margin-top: .5rem; padding-top: 1.15rem;
}
.fml-row.sum b { color: var(--ink); font-weight: 600; font-size: 1.08rem; }
.fml-row.sum .v { font-size: clamp(1.7rem, 4vw, 2.3rem); letter-spacing: -.035em; color: var(--pos); }
.fml-note {
  margin: 1.5rem auto 0; max-width: 36rem; font-size: .92rem; line-height: 1.6;
  color: var(--ink-soft); text-align: center;
}
.fml-note strong { color: var(--ink); font-weight: 600; }

/* ── the reserve demo ─────────────────────────────────────────────────
   Section 3. The phone holds the live number; the ledger sits beside it so
   the maths is legible at page type size rather than at 10px. */
.rdemo { display: grid; gap: 2.75rem; align-items: center; justify-items: center; }
.rdemo-phone { --s: .70; display: flex; justify-content: center; }
.rdemo-side { width: 100%; min-width: 0; max-width: 34rem; }
.rdemo-side .ledger { margin-top: 0; }
@media (min-width: 980px) {
  .rdemo { grid-template-columns: auto 1fr; gap: 3.5rem; justify-items: stretch; }
}
@media (max-width: 360px) { .rdemo-phone { --s: .62; } }

/* ── reduced motion ───────────────────────────────────────────────────
   Nothing here needs an override: JS withholds .staged entirely, so every
   element keeps the finished state it renders with. This only stops the
   two hover nudges. */
@media (prefers-reduced-motion: reduce) {
  .cta-ghost i, .cta-ghost:hover i { transform: none; transition: none; }
  .wash .chiprow .chip { transition: none; }
}

/* ── the Activity feed ────────────────────────────────────────────────
   Screen 2. transaction.tsx's renderItem: a date header (captionSmSemibold
   on textGrayscale700, uppercase, +1 tracking, with the day's signed total
   in captionSmMedium on textGrayscale600) followed by rows on surfaceCard.
   A row is name (bodyLgSemibold) over subtitle "Category · Account"
   (captionSm on textGrayscale600), with the amount in headingMd — green
   for a credit, textGrayscale900 for a debit — using a real U+2212 minus. */
.fd-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 0 16px; margin: 24px 0 8px;
}
.fd-head:first-child { margin-top: 8px; }
.fd-head b { font-size: 12px; line-height: 16px; font-weight: 600; color: #495057;
  letter-spacing: 1px; text-transform: uppercase; }
.fd-head span { font-size: 12px; line-height: 16px; font-weight: 500; color: #4B5563; }
.fd-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 16px; background: #fff;
}
.fd-row + .fd-row { border-top: 1px solid #EDEEF1; }
.fd-l { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* the 32pt merchant avatar; logo-less rows fall back to the category icon */
.fd-av {
  width: 32px; height: 32px; border-radius: 999px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
}
.fd-av .i { width: 17px; height: 17px; }
.fd-t { min-width: 0; }
.fd-t b { display: block; font-size: 14px; line-height: 22px; font-weight: 600; color: #1A1D23;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fd-t i { display: block; font-style: normal; font-size: 12px; line-height: 16px;
  font-weight: 500; color: #4B5563; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fd-badge {
  display: inline-block; margin-left: 8px; vertical-align: 1px;
  font-size: 10px; font-weight: 600; padding: 2px 8px; border-radius: 999px;
}
.fd-amt { font-size: 14px; line-height: 22px; font-weight: 500; color: #1A1D23;
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.fd-amt.in { color: #16A34A; }

/* ── Categories: MoneyInOutHero ───────────────────────────────────────
   components/categories/MoneyInOutHero.tsx — the top of the Categories
   screen, which the renders were skipping entirely. An uppercase eyebrow,
   two totals split by a hairline (money in on flowIncome, money out on
   flowExpenses, both at 26/32), a 6pt ratio bar weighted by the raw
   amounts, and the Plan-with-Fin gradient CTA. */
.mio { padding: 6px 16px 6px; }
.mio-eyebrow { font-size: 12px; line-height: 16px; font-weight: 500; color: #6B7280;
  text-transform: uppercase; letter-spacing: .5px; margin: 0 0 10px; }
.mio-pair { display: flex; align-items: stretch; }
.mio-col { flex: 1; min-width: 0; }
.mio-k { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.mio-dot { width: 6px; height: 6px; border-radius: 999px; flex: 0 0 auto; }
.mio-k span { font-size: 12px; line-height: 16px; font-weight: 500; color: #6B7280; }
.mio-v { font-size: 26px; line-height: 32px; font-weight: 600; letter-spacing: -.4px;
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.mio-rule { width: 1px; align-self: stretch; margin: 0 16px; background: #E5E7EB; flex: 0 0 auto; }
.mio-bar { display: flex; height: 6px; border-radius: 999px; overflow: hidden;
  margin-top: 8px; background: #F0F0F6; }
.mio-bar i { display: block; }
.mio-bar i + i { margin-left: 2px; }
/* PlanWithFinButton — the shared brand-gradient glass button. */
.pwf { margin-top: 10px; border-radius: 16px; padding: 1.5px;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
  box-shadow: 0 1px 3px rgba(26,29,35,.08); }
.pwf-in { border-radius: 14.5px; background: #fff; padding: 10px 14px;
  display: flex; align-items: center; gap: 11px; }
.pwf-ic { width: 30px; height: 30px; border-radius: 10px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: #554B8A1A; color: #554B8A; }
.pwf-ic .i { width: 16px; height: 16px; }
.pwf-t { min-width: 0; flex: 1; }
.pwf-t b { display: block; font-size: 14px; line-height: 22px; font-weight: 600; color: #3E2D7A; }
.pwf-t i { display: block; font-style: normal; font-size: 12px; line-height: 16px;
  font-weight: 500; color: #4B5563; }

/* ── connecting an account ────────────────────────────────────────────
   Three ways in, because the app has three: Plaid Link, telling Fin, or a
   PDF statement. Plaid is the automatic one, not the only one — and it is
   an independent controller, which the card says rather than buries. */
.ways { display: grid; gap: 1.25rem; margin-top: 2.5rem; }
@media (min-width: 780px) { .ways { grid-template-columns: repeat(3, 1fr); } }
.way {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card);
  padding: 1.5rem 1.4rem; box-shadow: var(--shadow-sm);
}
.way .ic {
  width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center;
  justify-content: center; margin-bottom: 1rem; background: var(--brand-tint); color: var(--brand);
}
.way .ic .i { width: 21px; height: 21px; }
.way h3 { font-size: 1.02rem; font-weight: 600; margin: 0 0 .4rem; letter-spacing: -.015em; }
.way p { margin: 0; font-size: .93rem; line-height: 1.55; color: var(--ink-soft); }
.way .tag {
  display: inline-block; margin-bottom: .7rem; font-size: .72rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--brand);
}
.plaid-note {
  margin: 2.5rem auto 0; max-width: 44rem; background: var(--muted);
  border-radius: var(--radius-tile); padding: 1.25rem 1.4rem;
  font-size: .95rem; line-height: 1.6; color: var(--ink-soft);
}
.plaid-note strong { color: var(--ink); font-weight: 600; }
.plaid-note a { color: var(--brand); }

/* ── say it ───────────────────────────────────────────────────────────
   VoiceCaptureSheet + VoiceConfirmPanel. Recognition is requested
   on-device (requiresOnDeviceRecognition), so the audio never leaves the
   phone; the transcript runs the deterministic creation path rather than
   the model, so it cannot invent a write that did not happen. Nothing is
   saved until the tile is tapped. */
.say { display: grid; gap: 1.25rem; margin-top: 2.5rem; }
@media (min-width: 900px) { .say { grid-template-columns: repeat(3, 1fr); align-items: start; } }
.sheet {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card);
  padding: 1.4rem 1.35rem; box-shadow: var(--shadow);
}
.sheet-k { font-size: .72rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 .9rem; display: flex; align-items: center; gap: .5rem; }
.sheet-k .dot { width: 7px; height: 7px; border-radius: 999px; background: var(--neg); flex: 0 0 auto; }
.mic {
  width: 54px; height: 54px; border-radius: 999px; margin: 0 auto .9rem;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
  box-shadow: 0 6px 20px rgba(85,75,138,.32);
}
.mic .i { width: 21px; height: 21px; color: #fff; }
.sheet-hint { text-align: center; font-size: .93rem; color: var(--ink-soft); margin: 0; }
.sheet-lab { font-size: .78rem; font-weight: 500; color: var(--ink-soft); margin: 0 0 .15rem; }
.sheet-said { font-size: 1rem; font-weight: 600; color: var(--ink); margin: 0 0 1.1rem; }
.sheet-fin { font-size: .78rem; font-weight: 600; color: var(--ink-soft); margin: 0 0 .5rem; }
.sheet-heard { font-size: 1.02rem; font-weight: 600; color: var(--ink); margin: 0 0 1.1rem; line-height: 1.45; }
.sheet-lead { font-size: .97rem; color: var(--ink); margin: 0 0 1.1rem; line-height: 1.5; }
.sheet .tile {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  border: 1px solid var(--line-strong); border-radius: 12px; background: #fff;
  padding: .62rem .8rem; margin-bottom: .5rem;
  font-size: .93rem; font-weight: 500; color: var(--ink-600); text-align: left;
}
.sheet .tile .i { width: 16px; height: 16px; flex: 0 0 auto; color: var(--ink-faint); }
.sheet .tile.primary { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.sheet .tile.primary .i { color: #fff; }
.say-note {
  margin: 2.25rem auto 0; max-width: 44rem; text-align: center;
  font-size: .95rem; line-height: 1.6; color: var(--ink-soft);
}
.say-note strong { color: var(--ink); font-weight: 600; }

/* ── Fin's bottom bar ─────────────────────────────────────────────────
   FinComposerAccessory: [mic 44] [camera 44] [ Ask Fin anything ..... ]
   Both icon buttons are 44pt gradient circles with a 21pt white glyph; the
   field takes the remaining width, gradient-filled at radius 26 with the
   arrow-up on its right. */
.finbar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; margin: 0 12px 10px; }
.fb-ic {
  width: 44px; height: 44px; border-radius: 999px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
}
.fb-ic .i { width: 21px; height: 21px; color: #fff; }
.fb-ask {
  flex: 1; min-height: 44px; border-radius: 26px; padding: 0 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: linear-gradient(135deg,#A78BFA,#7C3AED 55%,#6D28D9);
  color: #fff; font-size: 15px; font-weight: 500;
}
.fb-ask .i { width: 20px; height: 20px; color: #fff; flex: 0 0 auto; }
/* transaction.tsx renders the filter summary above the list — the count, the
   active window, and the grouping — with a Clear action on the right. */
.fd-filter {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 16px 10px;
}
.fd-filter span { font-size: 12px; line-height: 16px; font-weight: 500; color: #4B5563; }
.fd-filter b { font-size: 12px; line-height: 16px; font-weight: 600; color: #554B8A; }
/* Keyboard users land on the header nav on every page; this jumps past it.
   Visible only when focused, and it lands on <main>. */
.skip {
  position: absolute; left: 1rem; top: -3rem; z-index: 100;
  background: var(--brand); color: #fff; padding: .6rem 1rem;
  border-radius: 0 0 10px 10px; text-decoration: none; font-weight: 600; font-size: .92rem;
  transition: top .2s var(--ease);
}
.skip:focus { top: 0; }

/* ── Activity: the search row ─────────────────────────────────────────
   transaction.tsx puts a 44pt search field at radius 22 beside a 44pt
   filter button, above the filter summary. */
.fd-search { display: flex; align-items: center; gap: 8px; padding: 6px 16px 8px; }
.fd-field {
  flex: 1; min-width: 0; height: 44px; border-radius: 22px; background: #fff;
  border: 1px solid var(--line); display: flex; align-items: center; gap: 8px; padding: 0 14px;
  box-shadow: 0 1px 3px rgba(26,29,35,.07);
}
.fd-field .i { width: 20px; height: 20px; color: #4B5563; flex: 0 0 auto; }
.fd-field i { font-style: normal; font-size: 14px; color: #9CA3AF; }
.fd-filterbtn {
  width: 44px; height: 44px; border-radius: 22px; flex: 0 0 auto; background: #fff;
  border: 1px solid var(--line); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 3px rgba(26,29,35,.07);
}
.fd-filterbtn .i { width: 19px; height: 19px; color: #4B5563; }

/* ── Cash Flow: the by-month section under the tiles ──────────────────
   The dashboard does not end at the tile grid — a "CASH FLOW" eyebrow and
   the inline six-month CashFlowByMonthSheet follow it, money in against
   paid from, with the current month selected. */
.cf-eyebrow { font-size: 12px; line-height: 16px; font-weight: 600; color: #6B7280;
  letter-spacing: .4px; margin: 4px 0 4px 4px; flex: 0 0 auto; }
/* .body is a column flex container, so the chart shrinks unless it is told
   not to — the bars collapsed to a few pixels without this. */
.cf-chart { display: flex; align-items: flex-end; justify-content: space-between;
  gap: 6px; height: 28px; flex: 0 0 28px; padding: 0 2px; }
.cf-bar { flex: 1; display: flex; align-items: flex-end; justify-content: center; gap: 3px;
  height: 100%; position: relative; }
.cf-bar i { display: block; width: 9px; border-radius: 3px 3px 0 0; }
.cf-bar i.in { background: #16A34A; }
.cf-bar i.out { background: #D85F18; }
.cf-bar b { position: absolute; bottom: -16px; left: 0; right: 0; text-align: center;
  font-size: 10px; font-weight: 500; color: #9CA3AF; }
.cf-bar.on b { color: #554B8A; font-weight: 600; }
.cf-legend { display: flex; gap: 14px; margin-top: 18px; margin-bottom: 4px; flex: 0 0 auto; }
.cf-legend span { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #6B7280; }
.cf-legend b { width: 8px; height: 8px; border-radius: 2px; }
.cf-legend b.in { background: #16A34A; }
.cf-legend b.out { background: #D85F18; }
.cf-legend em { font-style: normal; font-weight: 600; color: #1A1D23; font-variant-numeric: tabular-nums; }

/* ── Goals: GoalCard ──────────────────────────────────────────────────
   GoalsList.tsx: name over its target date on the left, saved over
   "of <target>" stacked on the right, then an 8pt momentum bar with
   "N% saved" and "$X left" beneath it. */
.goalcard { padding: 14px; border-radius: 16px; }
.goal-top { display: flex; align-items: center; gap: 12px; }
.goal-id { flex: 1; min-width: 0; }
.goal-id b { display: block; font-size: 14px; line-height: 22px; font-weight: 500; color: #1A1D23;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.goal-id i { display: block; font-style: normal; font-size: 12px; line-height: 16px; color: #6B7280; }
.goal-amt { text-align: right; flex: 0 0 auto; }
.goal-amt b { display: block; font-size: 14px; line-height: 22px; font-weight: 600; color: #1A1D23;
  font-variant-numeric: tabular-nums; }
.goal-amt i { display: block; font-style: normal; font-size: 12px; line-height: 16px; color: #6B7280;
  font-variant-numeric: tabular-nums; }
.goal-bar { display: block; height: 8px; border-radius: 999px; background: #F0F0F6;
  overflow: hidden; margin-top: 12px; }
.goal-bar i { display: block; height: 100%; border-radius: 999px; }
.goal-foot { display: flex; justify-content: space-between; margin-top: 4px; }
.goal-foot span { font-size: 11px; line-height: 14px; color: #6B7280; }
/* NetWorthHero's eyebrow is captionSm on textGrayscale500 — a label above the
   number, not an 18pt screen title. */
.nw-eyebrow { font-size: 12px; line-height: 16px; font-weight: 500; color: #6B7280; }
.nw-delta { font-size: 12px; line-height: 16px; font-weight: 600; color: #16A34A; }

/* ── the curtain footer ───────────────────────────────────────────────
   Above 900px the page ends and the footer is revealed from underneath it:
   main sits above on its own background, the footer is fixed behind, and a
   spacer inside main is what uncovers it. Pure CSS, no scroll listener.

   Everything dark is scoped INSIDE the media query. The first cut set the
   text colours globally, so below the breakpoint — where the footer is a
   normal light footer — the wordmark and column headings were white on
   white and simply vanished. */
footer.curtain .wordmark {
  font-size: clamp(2.6rem, 9vw, 6.5rem); font-weight: 700; letter-spacing: -.045em;
  line-height: .95; margin: 0 0 .4rem; color: var(--ink);
}
footer.curtain .tagline {
  font-size: 1.05rem; color: var(--ink-soft); margin: 0 0 2.5rem; letter-spacing: -.01em;
}
.curtain-space { display: none; }

@media (min-width: 900px) {
  /* No dark body: the fixed footer paints its own background, and a dark
     body showed through the transparent sticky header at the top of the
     page, turning the whole masthead near-black. */
  .home main { position: relative; z-index: 2; background: var(--bg); }
  .curtain-space { display: block; height: 520px; }

  footer.curtain {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 1;
    background: var(--ink-dark); color: #fff; border-top: 0;
    display: flex; align-items: center;
    min-height: 520px; padding: 4rem 0 3rem;
  }
  footer.curtain .wordmark { color: #fff; }
  footer.curtain .tagline  { color: #8E8FA0; margin-bottom: 3rem; }
  footer.curtain .cols     { margin-bottom: 2.25rem; }
  footer.curtain .col p    { color: #fff; }
  footer.curtain .col a    { color: #8E8FA0; }
  footer.curtain .col a:hover { color: #fff; }
  footer.curtain .legal    { color: #6D6E7C; border-top-color: rgba(255,255,255,.12); }
}

/* Fixed positioning and a reveal are motion. Reduced motion gets a plain
   footer in normal flow. */
@media (prefers-reduced-motion: reduce) {
  footer.curtain { position: static; min-height: 0; }
  .curtain-space { display: none; }
}

/* ── large screens ────────────────────────────────────────────────────
   At 1920 the interactive pieces were the NARROWEST things on the page —
   the ledger sat at 30% of the viewport, the chat at 33% — so the demos
   that carry the argument read as small while plain text blocks read as
   wide. That is backwards.

   Running text stays near 65 characters, because that is a readability
   limit and not a layout one. Everything that is UI rather than prose
   grows, and the phones grow with it, so the page fills the screen by
   getting BIGGER rather than by stretching paragraphs. */
@media (min-width: 1440px) {
  .wide { max-width: 78rem; }
  .fml { max-width: 44rem; }
  .calc { max-width: 52rem; }
  .chat { max-width: 48rem; }
  .receipt { max-width: 60rem; }
  .rdemo-side { max-width: 40rem; }
  .hero-stage { --s: .82; }
  .rdemo-phone { --s: .78; }
  .shots { --s: .76; }
  h2.section { font-size: clamp(2.2rem, 3.2vw, 3.6rem); }
}

@media (min-width: 1800px) {
  .wide { max-width: 86rem; }
  .fml { max-width: 48rem; }
  .calc { max-width: 58rem; }
  .chat { max-width: 52rem; }
  .receipt { max-width: 66rem; }
  .rdemo-side { max-width: 44rem; }
  .hero-stage { --s: .90; }
  .rdemo-phone { --s: .84; }
  .shots { --s: .82; }
  /* The six screens wrap 3-up rather than sprawling into a single row. */
  .shots { max-width: 96rem; margin: 0 auto; }
}

/* ── the pinned ledger ────────────────────────────────────────────────
   The section is tall; the phone and the ledger stick inside it, and the
   scroll through that height is what reveals the arithmetic a line at a
   time while the phone's number counts to each running subtotal.

   Desktop only. Below 900px a 260vh section that pins is a lot of thumb
   work for the same information, so the ledger just reveals on sight the
   way it did before. Sticky is used rather than fixed so it cannot fight
   the fixed curtain footer — they never share a stacking context. */
.pin-phone { display: none; }

@media (min-width: 900px) and (prefers-reduced-motion: no-preference) {
  .pin-stage { min-height: 240vh; position: relative; }
  .pin-sticky {
    position: sticky; top: 0; min-height: 100vh;
    display: grid; grid-template-columns: auto 1fr; gap: 4rem;
    align-items: center; justify-items: center;
  }
  .pin-phone { display: block; --s: .72; }
  .pin-sticky .fml { margin: 0; width: 100%; }
  .pin-stage .fml-note { margin-top: 1.75rem; text-align: left; }

  /* Rows wait for the scroll to reach them. */
  .pin-stage .fml-row { opacity: .18; transform: translateY(8px); transition: opacity .45s var(--ease), transform .45s var(--ease); }
  .pin-stage .fml-row.lit { opacity: 1; transform: none; }
  .pin-stage .fml-row.sum { opacity: .12; }
  .pin-stage .fml-row.sum.lit { opacity: 1; }
  .pin-stage .fml-note { opacity: 0; transition: opacity .5s var(--ease); }
  .pin-stage .fml-note.lit { opacity: 1; }

  /* Formula chips arrive with their line. */
  .pin-phone .h-formula .fc, .pin-phone .h-formula .fo { opacity: 0; transform: translateY(4px); transition: opacity .35s var(--ease), transform .35s var(--ease); }
  .pin-phone .h-formula .fc.on, .pin-phone .h-formula .fo.on { opacity: 1; transform: none; }
}
@media (min-width: 1440px) { .pin-phone { --s: .80; } }

/* ── the affordability calculator page ────────────────────────────────
   Its own inputs, so the visitor can answer the question with their own
   figures rather than reading about someone else's. */
.calc .fields { display: grid; gap: .9rem; margin-bottom: 1.5rem; }
@media (min-width: 640px) { .calc .fields { grid-template-columns: 1fr 1fr; gap: 1rem 1.25rem; } }
.calc label { display: flex; flex-direction: column; gap: .35rem;
  font-size: .92rem; font-weight: 500; color: var(--ink-600); }
.calc label span { color: var(--ink-faint); font-weight: 400; }
.calc input[type="number"] {
  font: 600 1.05rem/1.4 Inter, sans-serif; color: var(--ink);
  padding: .7rem .85rem; border: 1px solid var(--line-strong); border-radius: 12px;
  background: #fff; width: 100%; font-variant-numeric: tabular-nums;
}
.calc input[type="number"]:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; border-color: var(--brand-300); }
.calc-out { display: flex; flex-wrap: wrap; gap: 1rem 2.5rem; padding: 1.1rem 0 1.25rem;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin-bottom: 1.25rem; }
.calc-figure { display: flex; flex-direction: column; gap: .15rem; }
.calc-figure span { font-size: .85rem; color: var(--ink-soft); }
.calc-figure b { font-size: 1.6rem; font-weight: 700; letter-spacing: -.03em;
  color: var(--ink); font-variant-numeric: tabular-nums; }
.calc .verdict p { margin: 0; }
.doc .calc { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-card);
  padding: 1.5rem 1.4rem; box-shadow: var(--shadow); margin: 2rem 0 2.5rem; max-width: none; }
.calc-more { margin: 1.25rem 0 0; text-align: center; font-size: .95rem; }
.calc-more a { color: var(--brand); font-weight: 600; text-decoration: none; }
.calc-more a:hover { text-decoration: underline; }
