/* ==========================================================================
   CroSum — shared design system
   --------------------------------------------------------------------------
   One stylesheet for every page on crosum.app. Linked, not inlined, because
   the site is now multi-page and this file is heavily cached (see _headers).

   Built on the brand marks: navy #2E597C, cream #F4EAD5, gold #C8A565.
   Ramps were derived in OKLCH at each brand colour's native hue
   (navy h=245.1, cream h=85.6, gold h=81.6) so every tint stays on-brand,
   then written back as hex for universal support.

   Two rules that shape everything below:
     1. Light surfaces carry the CREAM hue; dark surfaces carry the NAVY hue.
        Neutral grey is what made the old palette read as a template.
     2. Elevation is hairlines + a navy-tinted micro-shadow, never a large
        soft black drop shadow. In dark mode shadows are dropped entirely and
        the border ladder does the work — a black shadow on a near-black
        page is invisible.
   ========================================================================== */

/* ---------------------------------------------------------------- fonts --
   Self-hosted OFL variable faces, latin subset, WOFF2 only.
   Fraunces is instanced: SOFT=40 and WONK=0 are pinned (CroSum is
   trustworthy, not quirky) and opsz is pinned to 72, which takes the file
   from 121 KB to 37.5 KB. Only wght still varies.

   The two *Fallback* faces exist so the swap from system font to webfont
   causes zero layout shift. size-adjust values are measured — average glyph
   advance over a real sample string of site copy versus the fallback — and
   the ascent/descent overrides are the real font metrics divided by that
   size-adjust.
   ------------------------------------------------------------------------ */
@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/fraunces-v38-latin.woff2') format('woff2-variations'),
       url('/fonts/fraunces-v38-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('/fonts/instrumentsans-v4-latin.woff2') format('woff2-variations'),
       url('/fonts/instrumentsans-v4-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('/fonts/instrumentsans-v4-latin-ext.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Metrics-matched fallbacks — measured, see header note. */
@font-face {
  font-family: 'Fraunces Fallback';
  src: local('Georgia'), local('Times New Roman'), local('Nimbus Roman');
  size-adjust: 107.28%;
  ascent-override: 91.16%;
  descent-override: 23.77%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Instrument Fallback';
  src: local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans');
  size-adjust: 102.62%;
  ascent-override: 94.52%;
  descent-override: 24.36%;
  line-gap-override: 0%;
}

/* ---------------------------------------------------------------- tokens -- */
:root {
  /* --- brand ramps (fixed, never themed) --- */
  --navy-50:  #e7f0f7;
  --navy-100: #d1e0ed;
  --navy-200: #a6c1d9;
  --navy-300: #7ea3c3;
  --navy-400: #5b85a9;
  --navy-500: #3a688d;
  --navy-600: #2e597c;  /* brand */
  --navy-700: #1f4664;
  --navy-800: #133047;
  --navy-900: #0b2133;
  --navy-950: #071521;

  --gold-50:  #f9f1e3;
  --gold-100: #eddcbd;
  --gold-200: #dbc090;
  --gold-300: #c8a565;  /* brand */
  --gold-400: #ac8947;
  --gold-500: #8b6c32;  /* the only gold that passes as TEXT on light */
  --gold-600: #695124;
  --gold-700: #423315;

  --cream-50:  #faf6ee;
  --cream-100: #f4ead5;  /* brand */
  --cream-200: #e6d9bf;

  /* --- semantic: light (cream-hued neutrals) --- */
  --bg:            #fbf9f5;
  --bg-alt:        #f3efe4;
  --surface:       #ffffff;
  --surface-2:     #faf6ee;
  --surface-sunk:  #f7f3e9;
  --border:         #e5ded0;  /* decorative hairline */
  --border-strong:  #d5c6a7;  /* decorative, heavier */
  --border-control: #978869;  /* interactive boundaries — 3.03:1, WCAG 1.4.11 */
  --fg:            #0b2133;
  --fg-muted:      #5c6470;
  --fg-subtle:     #646c78;  /* 4.62:1 on the lightest surface */
  --link:          #1f4664;
  --gold-text:     #7e6129;  /* gold-500 darkened: 4.9:1 on every light surface */

  /* On navy bands (hero, CTA, footer). Alphas are contrast-solved against
     navy-600: .86 = 4.98:1, .82 = 4.76:1. The old file used .70/.72/.75,
     all of which failed. */
  --on-navy:        #f4ead5;
  --on-navy-muted:  rgba(244, 234, 213, 0.86);
  --on-navy-subtle: rgba(244, 234, 213, 0.82);

  /* --- type scale: six fluid steps replace 17 ad-hoc sizes --- */
  --step--1: clamp(0.875rem, 0.84rem + 0.18vw, 0.95rem);
  --step-0:  clamp(1.0625rem, 1.03rem + 0.2vw, 1.125rem);
  --step-1:  clamp(1.25rem, 1.18rem + 0.35vw, 1.375rem);
  --step-2:  clamp(1.5rem, 1.35rem + 0.75vw, 2rem);
  --step-3:  clamp(2rem, 1.7rem + 1.5vw, 3rem);
  --step-4:  clamp(2.5rem, 1.9rem + 3vw, 4.5rem);

  --font-display: 'Fraunces', 'Fraunces Fallback', Georgia, 'Times New Roman', serif;
  --font-ui: 'Instrument Sans', 'Instrument Fallback', -apple-system,
             BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* --- space: 4px base, 8pt rhythm --- */
  --sp-1: 4px;  --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px;  --sp-7: 48px;  --sp-8: 64px;
  --sp-9: 96px; --sp-10: 128px;
  --section-y: clamp(72px, 10vw, 160px);

  /* One container width. The old file had the hero at 1040 and every
     section at 980, so the hero copy sat 30px outside everything below. */
  --container: 1100px;
  --container-narrow: 760px;

  /* --- radii: two, not ten --- */
  --r-card: 12px;
  --r-pill: 999px;

  /* --- elevation: hairline + navy-tinted micro-shadow --- */
  --ring: 1px solid var(--border);
  --shadow-sm: 0 1px 2px rgba(46, 89, 124, 0.06);
  --shadow:    0 1px 2px rgba(46, 89, 124, 0.06), 0 8px 24px rgba(46, 89, 124, 0.05);
  --shadow-lift: 0 2px 4px rgba(46, 89, 124, 0.07), 0 14px 34px rgba(46, 89, 124, 0.08);
  --focus-ring: var(--navy-600);
  /* Must track the ACTUAL theme, not just advertise support for both.
     Declaring "light dark" lets the browser pick from the OS, so a visitor on
     a dark OS who forces the light theme got dark-scheme native controls on
     our light surfaces — which rendered the date picker's calendar glyph
     white on a white input. This also governs scrollbars and select popups. */
  color-scheme: light;
}

/* --- semantic: dark (navy-hued ink). Applied via media query AND the
   data-theme attribute so an explicit toggle wins in both directions. --- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg:            #0d151d;
    --bg-alt:        #101921;
    --surface:       #19232c;
    --surface-2:     #222d36;
    --surface-sunk:  #0a1118;
    --border:         #39444e;
    --border-strong:  #4b5762;
    --border-control: #6f7c89;
    color-scheme: dark;
    --focus-ring:    var(--cream-100);
    --fg:            #e9e3d6;
    --fg-muted:      #a8b0ba;
    --fg-subtle:     #939ba6;
    --link:          #a6c1d9;
    --gold-text:     #dbc090;
    /* The --on-navy-* tokens are deliberately NOT redeclared here. The band
       is navy-600 in both themes, so theming them means two sources of truth
       — and the copy in this block had already drifted to a failing alpha. */
    --shadow-sm: none;
    --shadow: none;
    --shadow-lift: none;
  }
}
:root[data-theme='dark'] {
  --bg:            #0d151d;
  --bg-alt:        #101921;
  --surface:       #19232c;
  --surface-2:     #222d36;
  --surface-sunk:  #0a1118;
  --border:         #39444e;
  --border-strong:  #4b5762;
  --border-control: #6f7c89;
  color-scheme: dark;
  --focus-ring:    var(--cream-100);
  --fg:            #e9e3d6;
  --fg-muted:      #a8b0ba;
  --fg-subtle:     #939ba6;
  --link:          #a6c1d9;
  --gold-text:     #dbc090;
  --shadow-sm: none;
  --shadow: none;
  --shadow-lift: none;
}

/* ------------------------------------------------------------------ base -- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* 62px sticky header + breathing room, so a focused or linked
     heading never lands underneath it. */
  scroll-padding-top: 84px;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-ui);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: 'SOFT' 40, 'WONK' 0;
  letter-spacing: -0.02em;
  line-height: 1.05;
  text-wrap: balance;
  /* text-wrap: balance distributes lines but cannot rescue a single word
     that is wider than its box. Long compounds ("Recommendations",
     "Aanbevelingen") must break rather than bleed out of a card. */
  overflow-wrap: break-word;
  margin: 0 0 var(--sp-4);
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); line-height: 1.15; }
h4 { font-size: var(--step-1); line-height: 1.25; }

p { margin: 0 0 var(--sp-4); max-width: 68ch; }
a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: none;
  border-radius: 6px;
}
/* On navy bands the ring must be light in BOTH themes. */
.band :focus-visible { outline-color: var(--cream-100); }
/* The gold CTA keeps a navy ring in both themes — cream on gold is 1.7:1,
   navy-950 on gold is 7.93:1, the same pairing the label already uses. */
.btn--primary:focus-visible { outline-color: var(--navy-950); }
img, svg, video { max-width: 100%; height: auto; display: block; }
hr { border: 0; border-top: var(--ring); margin: var(--sp-7) 0; }
small { font-size: var(--step--1); }
code, kbd { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
            font-size: 0.92em; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 200;
  background: var(--gold-300); color: var(--navy-950);
  padding: 10px 16px; border-radius: var(--r-pill); font-weight: 600;
  transition: top .15s ease;
}
.skip-link:focus { top: 8px; }

/* ---------------------------------------------------------------- layout -- */
.container { width: min(100% - 2 * var(--sp-5), var(--container)); margin-inline: auto; }
.container--narrow { width: min(100% - 2 * var(--sp-5), var(--container-narrow)); }
.section { padding-block: var(--section-y); }
.section--alt { background: var(--bg-alt); }
.section--sunk { background: var(--surface-sunk); }
.section-head { max-width: 62ch; margin-bottom: var(--sp-8); }
.section-head.center { margin-inline: auto; text-align: center; }
.eyebrow {
  display: inline-block; font-size: var(--step--1); font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--gold-text); margin-bottom: var(--sp-3);
}
.lede { font-size: var(--step-1); color: var(--fg-muted); line-height: 1.5; }

/* --- the navy band: hero, CTA, footer share this treatment --- */
.band {
  position: relative;
  background: var(--navy-600);
  color: var(--on-navy);
  overflow: hidden;
  isolation: isolate;
}
.band::before {
  content: ''; position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(60% 70% at 78% 18%, rgba(244, 234, 213, 0.14), transparent 60%),
    radial-gradient(50% 60% at 12% 90%, rgba(200, 165, 101, 0.18), transparent 60%);
}
/* Grain. Inlined as a data-URI, not a live filter: url(), because a live
   SVG filter on a large element re-rasterises on every paint. Makes the
   navy read as printed rather than as a flat digital fill. */
.band::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  opacity: 0.08; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
.band h1, .band h2, .band h3 { color: var(--on-navy); }
.band p { color: var(--on-navy-muted); }
.band a { color: var(--gold-100); }  /* 5.3:1 on navy-600; gold-200 was 4.22 */

/* --------------------------------------------------------------- header --- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border-bottom: var(--ring);
}
.site-header__inner {
  display: flex; align-items: center; gap: var(--sp-5);
  min-height: 62px; padding-block: var(--sp-2);
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none;
         color: var(--fg); font-weight: 600; letter-spacing: -0.01em; }
.brand:hover { text-decoration: none; }
.brand svg { width: 30px; height: 30px; flex: none; }
.brand span { font-family: var(--font-display); font-size: 1.2rem;
              font-variation-settings: 'SOFT' 40, 'WONK' 0; }
.site-nav { display: flex; gap: var(--sp-5); margin-inline: auto; }
.site-nav a {
  color: var(--fg-muted); text-decoration: none; font-size: 0.95rem;
  font-weight: 500; padding: 6px 2px; border-bottom: 2px solid transparent;
  white-space: nowrap;   /* never break "Hoe het werkt" across two lines */
}
.site-nav a:hover { color: var(--fg); border-bottom-color: var(--gold-300); }
.header-actions { display: flex; align-items: center; gap: var(--sp-3); }

/* Language switch. A segmented control showing BOTH codes rather than just
   the other one, because "NL" alone is ambiguous — it could mean "you are
   reading Dutch" or "switch to Dutch". Showing the pair with the current one
   marked removes the guess, and a two-letter code plus a globe needs no
   English to understand, which is the entire point: a Dutch speaker has to
   spot this before they give up on an English page. Lives in
   .header-actions, not the nav, so it survives the mobile collapse. */
.lang-switch {
  display: inline-flex; align-items: center;
  border: 1px solid var(--border-control); border-radius: var(--r-pill);
  overflow: hidden; flex: none;
}
.lang-switch__globe {
  display: grid; place-items: center; padding-inline: 7px 3px;
  color: var(--fg-subtle);
}
.lang-switch__globe svg { width: 14px; height: 14px; display: block; }
.lang-switch a,
.lang-switch span[aria-current] {
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.04em;
  padding: 10px 9px; line-height: 1; text-decoration: none;
  color: var(--fg-muted);
}
.lang-switch a:hover { color: var(--fg); background: var(--surface-2); text-decoration: none; }
.lang-switch span[aria-current] { color: var(--navy-950); background: var(--gold-300); }

/* On the navy bands the header is still on --bg, so no band overrides are
   needed here — the sticky header keeps the page background. */
/* The CTA moves INTO the menu on mobile rather than being dropped — a
   sub-page like /vs/ynab has no store badge above the fold to fall back on.
   Hidden on desktop, where the header CTA is already present. */
/* Two-class selector on purpose: the element also carries .btn, which is
   declared later in this file and would otherwise win on source order and
   leave a duplicate CTA on desktop. */
.site-nav .nav-cta { display: none; }
@media (max-width: 1100px) {
  .site-nav .nav-cta { display: inline-flex; margin-top: var(--sp-4); border-bottom: 0; }
  .site-nav .nav-cta:hover { color: var(--navy-950); }
}
@media (max-width: 420px) {
  /* Below this the row cannot hold brand + language + menu + theme + CTA.
     The CTA is the one that has a home elsewhere (see .nav-cta above);
     language and menu must survive. */
  .header-actions .btn--primary { display: none; }
}

/* Hamburger. Hidden on desktop, where the nav is already inline. */
.nav-toggle {
  display: none; width: 38px; height: 38px; padding: 0;
  border-radius: var(--r-pill); place-items: center;
  background: transparent; border: 1px solid var(--border-control);
  color: var(--fg-muted); cursor: pointer;
}
.nav-toggle:hover { color: var(--fg); border-color: var(--fg-muted); }
.nav-toggle svg { width: 18px; height: 18px; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded='true'] .icon-close { display: block; }
.nav-toggle[aria-expanded='true'] .icon-open { display: none; }

@media (max-width: 1100px) {
  /* The nav becomes a disclosure panel rather than disappearing. Without
     this, every section anchor AND every content page was reachable only
     from the footer on a phone.
     Breakpoint is 1100px, not a round 960 or 1024, because it is set by
     CONTENT: with six items the Dutch header needs 1024px of content, i.e.
     a 1072px viewport, measured. Dutch labels run ~25% longer than English
     ("Hoe het werkt" vs "How it works"), so English collapses earlier than
     it strictly needs to — which is the right trade for never overflowing. */
  .site-nav {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 0;
    padding: var(--sp-2) var(--sp-5) var(--sp-5);
    background: var(--bg);
    border-bottom: var(--ring);
    box-shadow: var(--shadow-lift);
  }
  .site-nav.is-open { display: flex; }
  .site-nav a {
    padding: 13px 0; font-size: 1.05rem; color: var(--fg);
    border-bottom: 1px solid var(--border);
  }
  .site-nav a:last-child { border-bottom: 0; }
  .site-nav a:hover { border-bottom-color: var(--border); color: var(--gold-text); }
  .nav-toggle { display: grid; }
  .site-header__inner { justify-content: space-between; }
}
/* Scroll-progress hairline under the sticky header. Progressive enhancement
   only — no support means no line, which is a fine failure mode. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .scroll-progress {
      position: fixed; top: 0; left: 0; height: 2px; width: 100%; z-index: 101;
      transform-origin: 0 50%; background: var(--gold-300);
      animation: grow-progress linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes grow-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  }
}

/* -------------------------------------------------------------- buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px; min-height: 44px;
  border-radius: var(--r-pill); border: 1px solid transparent;
  font-family: var(--font-ui); font-size: 0.975rem; font-weight: 600;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform .15s ease, background-color .15s ease, border-color .15s ease;
}
.btn:hover { text-decoration: none; }
@media (prefers-reduced-motion: no-preference) { .btn:active { transform: translateY(1px); } }

/* The primary CTA. gold-300 fill with navy-950 text is 7.93:1 — it passes
   AAA and reads identically in light and dark, which is why gold finally
   becomes structural here instead of decorative. Deliberately no inset top
   highlight: over a saturated gold fill a 60%-white 1px line reads as a seam
   across the top of the button rather than as lighting. */
.btn--primary { background: var(--gold-300); color: var(--navy-950); }
.btn--primary:hover { background: var(--gold-200); }
.btn--secondary { background: transparent; color: var(--fg); border-color: var(--border-control); }
.btn--secondary:hover { border-color: var(--fg-muted); background: var(--surface-2); }
.btn--onnavy { background: var(--gold-300); color: var(--navy-950); }
.btn--onnavy:hover { background: var(--gold-200); }
.btn--ghost-onnavy { background: transparent; color: var(--on-navy);
                     border-color: rgba(244, 234, 213, 0.4); }
.btn--ghost-onnavy:hover { border-color: var(--on-navy); background: rgba(244, 234, 213, 0.08); }
.btn--sm { padding: 8px 16px; min-height: 38px; font-size: 0.9rem; }

/* ---------------------------------------------------------------- chips --- */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); list-style: none;
         margin: 0; padding: 0; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border-radius: var(--r-pill);
  font-size: var(--step--1); font-weight: 500;
  background: var(--surface-2); color: var(--fg-muted); border: var(--ring);
}
.band .chip { background: rgba(244, 234, 213, 0.1); color: var(--on-navy-muted);
              border-color: rgba(244, 234, 213, 0.22); }

/* The native picker button. color-scheme above already gives it the right
   colour; this is purely affordance — it is a button, so it should look
   clickable and have a visible focus ring like everything else. */
input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.7;
  padding: 2px;
  border-radius: 4px;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
input[type="date"]::-webkit-calendar-picker-indicator:focus-visible {
  outline: 2px solid var(--focus-ring); outline-offset: 1px;
}

/* ---------------------------------------------------------------- cards --- */
.card {
  background: var(--surface);
  border: var(--ring);
  border-radius: var(--r-card);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
}
.card h3 { margin-bottom: var(--sp-2); }
.card p:last-child { margin-bottom: 0; }
.card__icon {
  width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--gold-300) 16%, var(--surface));
  color: var(--gold-text); margin-bottom: var(--sp-4);
  transition: background-color 160ms ease, color 160ms ease;
}
.card__icon svg { width: 20px; height: 20px; }

/* Hover: the grid was completely inert, which read as printed rather than
   built. Deliberately quiet — the border warms, the shadow gains a little
   depth, the icon picks up its gold. No lift, no scale, no glow, no text
   colour change: this is a finance site and movement reads as noise.
   Applied to every bento cell rather than only the linked ones, because one
   card of seven responding looks like a defect. The cursor is untouched, so
   nothing here promises a click. */
/* Bento cards also carry .reveal, whose transition shorthand would replace
   this one — CSS cannot merge two shorthands, so the reveal's own properties
   are restated here rather than fighting over specificity. Keep the .5s
   timings in step with the .reveal rule near the bottom of this file. */
@media (prefers-reduced-motion: no-preference) {
  .bento .card {
    transition: opacity .5s ease,
                transform .5s cubic-bezier(.22, .61, .36, 1),
                border-color 160ms ease,
                box-shadow 160ms ease;
  }
}
.bento .card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow);
}
.bento .card:hover .card__icon {
  background: color-mix(in srgb, var(--gold-300) 26%, var(--surface));
  color: var(--gold-500);
}
/* Dark mode: --gold-500 is too dark to read on a raised surface, so step the
   icon UP the ramp instead of down. */
:root[data-theme='dark'] .bento .card:hover .card__icon { color: var(--gold-200); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .bento .card:hover .card__icon { color: var(--gold-200); }
}

/* --------------------------------------------------------- proof strip --- */
.proof {
  border-block: var(--ring);
  background: var(--surface-2);
  padding-block: var(--sp-4);
}
.proof ul { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-7);
            list-style: none; margin: 0; padding: 0; justify-content: center; }
.proof li { display: flex; align-items: center; gap: 8px;
            font-size: var(--step--1); color: var(--fg-muted); }
.proof svg { width: 16px; height: 16px; color: var(--gold-text); flex: none; }

/* ---------------------------------------------------------------- steps --- */
.steps { display: grid; gap: var(--sp-5); grid-template-columns: repeat(3, 1fr); }
@media (max-width: 800px) { .steps { grid-template-columns: 1fr; } }
.step__num {
  width: 34px; height: 34px; border-radius: var(--r-pill);
  display: grid; place-items: center; margin-bottom: var(--sp-4);
  background: var(--navy-600); color: var(--cream-100);
  font-weight: 600; font-size: 0.95rem;
}

/* --------------------------------------------------- alternating rows ---- */
.feature-row {
  display: grid; grid-template-columns: 1fr auto; gap: clamp(32px, 6vw, 88px);
  align-items: center; padding-block: var(--sp-8);
}
.feature-row + .feature-row { border-top: var(--ring); }
.feature-row:nth-child(even) .feature-row__media { order: -1; }
.feature-row__copy > :last-child { margin-bottom: 0; }
@media (max-width: 900px) {
  .feature-row { grid-template-columns: 1fr; gap: var(--sp-6); }
  .feature-row:nth-child(even) .feature-row__media { order: 0; }
}

/* -------------------------------------------------------- device frame --- */
.device {
  position: relative; flex: none;
  width: clamp(212px, 26vw, 268px);
  padding: 8px;
  border-radius: 34px;
  background: linear-gradient(160deg, var(--navy-700), var(--navy-900));
  box-shadow: var(--shadow-lift);
  border: 1px solid var(--navy-800);
}
.device img { width: 100%; border-radius: 27px; display: block; }
.device--hero { width: clamp(224px, 30vw, 284px); }

/* Real-HTML UI fragments floating beside the phone. These are markup, not
   image crops — legible at any width, themeable, and zero image bytes. */
.frag {
  position: absolute; z-index: 2;
  background: var(--surface); color: var(--fg);
  border: var(--ring); border-radius: var(--r-card);
  box-shadow: var(--shadow-lift);
  padding: var(--sp-4) var(--sp-5);
  width: max-content; max-width: 250px;
}
.frag__label { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em;
               text-transform: uppercase; color: var(--fg-subtle); }
.frag__value { font-family: var(--font-display); font-size: 1.9rem;
               font-variation-settings: 'SOFT' 40, 'WONK' 0;
               font-weight: 600; line-height: 1.1; margin-top: 2px; }
.frag__meta { font-size: 0.82rem; color: var(--fg-muted); margin-top: 4px; }
.frag--tl { top: 8%; left: -18%; }
.frag--br { bottom: 12%; right: -22%; }
.frag--amber {
  background: color-mix(in srgb, var(--gold-300) 16%, var(--surface));
  border-color: color-mix(in srgb, var(--gold-400) 40%, var(--border));
}
.frag__bar { height: 6px; border-radius: var(--r-pill); background: var(--border);
             margin-top: 10px; overflow: hidden; }
.frag__bar i { display: block; height: 100%; border-radius: var(--r-pill);
               background: var(--gold-400); }
@media (max-width: 620px) { .frag { display: none; } }

/* ----------------------------------------------------------- bento grid --- */
.bento {
  display: grid; gap: var(--sp-4);
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(150px, auto);
}
.bento > * { container-type: inline-size; }
.bento .card { display: flex; flex-direction: column; height: 100%; }
.cell-2x2 { grid-column: span 2; grid-row: span 2; }
.cell-2x1 { grid-column: span 2; }
@container (min-width: 380px) {
  .card__icon { width: 44px; height: 44px; }
}
/* A bento cell ranges from a quarter of the grid (~263px) to half of it,
   so the heading has to answer to the CELL, not the viewport — a media
   query cannot express that. Narrow cells step the display face down. */
.bento .card h3 { font-size: var(--step-1); }
@container (min-width: 340px) {
  .bento .card h3 { font-size: var(--step-2); }
}
@media (max-width: 980px) { .bento { grid-template-columns: repeat(2, 1fr); }
                            .cell-2x2 { grid-row: span 1; } }
@media (max-width: 620px) { .bento { grid-template-columns: 1fr; }
                            .cell-2x2, .cell-2x1 { grid-column: span 1; } }

/* -------------------------------------------------------------- pricing --- */
.plans { display: grid; gap: var(--sp-5); grid-template-columns: repeat(2, 1fr);
         align-items: start; }
@media (max-width: 800px) { .plans { grid-template-columns: 1fr; } }
.plan { position: relative; }
.plan--featured { border-color: var(--gold-300); box-shadow: var(--shadow); }
.plan__price { font-family: var(--font-display); font-size: clamp(2.1rem, 1.6rem + 2vw, 2.9rem);
               font-variation-settings: 'SOFT' 40, 'WONK' 0;
               font-weight: 600; line-height: 1; margin: var(--sp-3) 0 var(--sp-1); }
.plan__period { color: var(--fg-muted); font-size: var(--step--1); }
.plan__badge {
  display: inline-block; padding: 4px 12px; border-radius: var(--r-pill);
  background: var(--gold-300); color: var(--navy-950);
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; margin-bottom: var(--sp-2);
}
.plan ul { list-style: none; margin: var(--sp-4) 0; padding: 0; display: grid; gap: 10px; }
.plan li { display: flex; gap: 10px; align-items: flex-start; font-size: 0.97rem; }
.plan li svg { width: 18px; height: 18px; flex: none; margin-top: 3px; color: var(--gold-text); }
.plan li.is-off { color: var(--fg-subtle); }
.plan li.is-off svg { color: var(--fg-subtle); }

/* ------------------------------------------------------------------ FAQ --- */
.faq { display: grid; gap: var(--sp-3); }
.faq details {
  background: var(--surface); border: var(--ring); border-radius: var(--r-card);
  padding: var(--sp-4) var(--sp-5);
}
.faq details:has(> summary:focus-visible) {
  outline: 3px solid var(--focus-ring); outline-offset: 2px; }
.faq details[open] { border-color: var(--border-strong); }
.faq summary {
  cursor: pointer; font-weight: 600; list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4);
  min-height: 32px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; font-size: 1.5rem; line-height: 1; color: var(--fg-subtle); flex: none;
  transition: transform .18s ease;
}
.faq details[open] summary::after { content: '\2212'; }
.faq details > :not(summary) { margin-top: var(--sp-3); color: var(--fg-muted); }
.faq details p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- table --- */
.table-wrap { overflow-x: auto; border: var(--ring); border-radius: var(--r-card);
              background: var(--surface); }
table { border-collapse: collapse; width: 100%; font-size: 0.95rem; }
th, td { text-align: left; padding: 12px 16px; border-bottom: var(--ring); vertical-align: top; }
thead th { background: var(--surface-2); font-weight: 600; white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }

/* ----------------------------------------------------------- callout ----- */
.note {
  border-left: 3px solid var(--gold-300);
  background: var(--surface-2);
  border-radius: 0 var(--r-card) var(--r-card) 0;
  padding: var(--sp-4) var(--sp-5);
  margin-block: var(--sp-5);
}
.note :last-child { margin-bottom: 0; }
.note--quiet { border-left-color: var(--border-strong); }

/* --------------------------------------------------------- store badges --- */
/* align-items: flex-start so the captioned pending badge doesn't stretch
   the Play badge to match its height. */
.store-badges { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4);
                align-items: flex-start; }
.store-badge img { height: 52px; width: auto; }

/* App Store badge before the listing is live. Apple's artwork is shown
   unaltered — no dimming, no recolouring — per their badge guidelines; the
   caption underneath carries the state instead. Not a link yet, so it is a
   <span> rather than an <a> with a dead href. */
.store-badge--pending { display: inline-flex; flex-direction: column;
                        align-items: center; gap: 5px; }
.store-badge--pending small { font-size: 0.78rem; letter-spacing: 0.01em;
                              color: var(--fg-subtle); }
.band .store-badge--pending small { color: var(--on-navy-subtle); }

/* --------------------------------------------------------------- footer --- */
.site-footer { background: var(--navy-800); color: var(--on-navy); padding-block: var(--sp-8) var(--sp-6); }
.site-footer::before { background:
  radial-gradient(50% 80% at 20% 0%, rgba(200, 165, 101, 0.15), transparent 65%); }
.footer-grid { display: grid; gap: var(--sp-6); grid-template-columns: 1.5fr repeat(4, 1fr); }
@media (max-width: 1000px) { .footer-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer h3 { font-family: var(--font-ui); font-size: 0.8rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--on-navy-subtle);
  margin-bottom: var(--sp-3); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
/* inline-block + padding so each standalone link clears the 24x24 CSS px
   minimum of WCAG 2.5.8. In-sentence links are exempt; these are not. */
.site-footer a { color: var(--on-navy-muted); text-decoration: none; font-size: 0.95rem;
                 display: inline-block; padding: 5px 0; }
.site-footer a:hover { color: var(--on-navy); text-decoration: underline; }
.footer-legal {
  margin-top: var(--sp-7); padding-top: var(--sp-5);
  border-top: 1px solid rgba(244, 234, 213, 0.16);
  display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  justify-content: space-between; align-items: center;
  font-size: var(--step--1); color: var(--on-navy-subtle);
}
.footer-legal p { margin: 0; color: var(--on-navy-subtle); max-width: none; }

/* --------------------------------------------------------- theme toggle --- */
.theme-toggle {
  width: 38px; height: 38px; padding: 0; border-radius: var(--r-pill);
  display: grid; place-items: center; background: transparent;
  border: 1px solid var(--border-control); color: var(--fg-muted); cursor: pointer;
}
.theme-toggle:hover { color: var(--fg); border-color: var(--fg-muted); }
.theme-toggle svg { width: 17px; height: 17px; }
.theme-toggle .icon-dark { display: none; }
:root[data-theme='dark'] .theme-toggle .icon-dark { display: block; }
:root[data-theme='dark'] .theme-toggle .icon-light { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .theme-toggle .icon-dark { display: block; }
  :root:not([data-theme='light']) .theme-toggle .icon-light { display: none; }
}

/* --------------------------------------------------------------- prose --- */
.prose { max-width: 68ch; }
.prose h2 { margin-top: var(--sp-8); }
.prose h3 { margin-top: var(--sp-6); }
.prose ul, .prose ol { padding-left: 1.25em; margin: 0 0 var(--sp-4); }
.prose li { margin-bottom: var(--sp-2); }
.prose li::marker { color: var(--gold-text); }

/* ------------------------------------------------- confirmation banner --- */
/* Shown when Supabase redirects a newly-confirmed user back to /. */
.confirm-banner {
  display: none; text-align: center; padding: 14px 20px;
  font-size: var(--step--1); font-weight: 500;
  background: #e6f6ed; color: #16603a; border-bottom: 1px solid #b6e0c8;
}
.confirm-banner.visible { display: block; }
:root[data-theme='dark'] .confirm-banner { background: #10291d; color: #86d6a8; border-bottom-color: #1e4632; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .confirm-banner { background: #10291d; color: #86d6a8; border-bottom-color: #1e4632; }
}

/* ----------------------------------------------------------------- hero --- */
.hero { padding-block: clamp(56px, 8vw, 104px) clamp(64px, 9vw, 120px); }
.hero__inner {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(32px, 6vw, 80px); align-items: center;
}
.hero__kicker {
  font-family: var(--font-display); font-size: var(--step-0);
  font-variation-settings: 'SOFT' 40, 'WONK' 0;
  color: var(--on-navy-subtle); margin: 0 0 var(--sp-3); font-style: italic;
}
.hero h1 { margin-bottom: var(--sp-5); max-width: 15ch; }
.hero__sub { font-size: var(--step-1); line-height: 1.5; max-width: 46ch; }
/* The best line on the old site was buried at 16px and failing contrast.
   Give it real prominence. */
.hero__hook {
  border-left: 3px solid var(--gold-300);
  padding-left: var(--sp-4); margin: var(--sp-5) 0 var(--sp-6);
  color: var(--on-navy) !important; font-size: var(--step-0); max-width: 44ch;
}
.hero .store-badges { margin-bottom: var(--sp-5); }
.hero__chips { margin-top: var(--sp-2); }
.hero__stage { position: relative; display: flex; justify-content: center; }
@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; }
  .hero h1 { max-width: none; }
  .hero__stage { margin-top: var(--sp-5); }
}

/* --------------------------------------------------------------- steps --- */
.step__honest {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: var(--ring); font-size: 0.94rem; color: var(--fg-muted);
}

/* -------------------------------------------------------- feature rows --- */
.row-note {
  display: inline-block; margin-top: var(--sp-2); margin-bottom: 0;
  font-size: var(--step--1); color: var(--fg-subtle);
}
.feature-row__media { display: flex; justify-content: center; }

/* ------------------------------------------------------- honest section -- */
.honest-list { list-style: none; margin: 0 0 var(--sp-5); padding: 0; display: grid; gap: var(--sp-3); }
.honest-list li { padding-left: 0; color: var(--fg); }
.honest-note { margin-bottom: 0; color: var(--fg-muted); padding-top: var(--sp-4); border-top: var(--ring); }

/* ------------------------------------------------------------- pricing --- */
.plan__permo { font-family: var(--font-ui); font-size: 1rem; font-weight: 500; color: var(--fg-muted); }

/* --------------------------------------------------------- data flow ----- */
.flow {
  display: grid; grid-template-columns: 1fr auto 1fr auto 1fr;
  gap: var(--sp-4); align-items: stretch; margin-bottom: var(--sp-6);
}
.flow__node {
  background: var(--surface); border: var(--ring); border-radius: var(--r-card);
  padding: var(--sp-5); box-shadow: var(--shadow-sm);
}
.flow__node h3 { margin-bottom: var(--sp-2); }
.flow__node p { margin: 0; font-size: 0.95rem; color: var(--fg-muted); }
.flow__node--muted { background: var(--surface-sunk); border-style: dashed; }
.flow__arrow { align-self: center; color: var(--gold-text); font-size: 1.5rem; }
@media (max-width: 820px) {
  .flow { grid-template-columns: 1fr; }
  .flow__arrow { transform: rotate(90deg); justify-self: center; }
}

/* ------------------------------------------------------------- two-col --- */
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 820px) { .two-col { grid-template-columns: 1fr; } }
.tick-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.tick-list li { position: relative; padding-left: 26px; font-size: 0.97rem; }
.tick-list li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 8px; height: 8px; border-radius: 50%; background: var(--gold-300);
}
.tick-list--neutral li::before { background: var(--border-control); }

/* ------------------------------------------------------------ CTA band --- */
.cta-band { text-align: center; padding-block: clamp(64px, 8vw, 112px); }
.cta-band h2 { margin-bottom: var(--sp-3); }
.cta-band p { margin-inline: auto; }
.cta-band .store-badges { justify-content: center; margin-top: var(--sp-5); }

/* -------------------------------------------------------------- footer --- */
.brand--footer { color: var(--on-navy); }
.brand--footer span { color: var(--on-navy); }
.footer-tag { margin-top: var(--sp-3); font-style: italic;
              color: var(--on-navy-subtle) !important; font-size: 0.95rem; }

/* --------------------------------------------------------------- motion --- */
/* Section reveals use IntersectionObserver + a class toggle as the safe
   default; animation-timeline is layered on where supported. Content is
   never made *visible* by an animation — .reveal starts visible and is only
   hidden once JS has confirmed it can un-hide it (see the inline script). */
@media (prefers-reduced-motion: no-preference) {
  .js-reveal .reveal { opacity: 0; transform: translateY(18px); }
  .reveal { transition: opacity .5s ease, transform .5s cubic-bezier(.22,.61,.36,1); }
  .reveal.is-in { opacity: 1; transform: none; }
}

/* Cross-document view transitions — two lines, Chrome/Safari get a soft
   cross-fade between pages, Firefox gets a normal navigation. */
@view-transition { navigation: auto; }

@media print {
  .site-header, .site-footer, .store-badges, .scroll-progress { display: none; }
  body { background: #fff; color: #000; }
}

/* ============================================== the amortisation figure ====
   The site's one drawing, and the only one it gets: a real amortisation
   schedule — the interest part of each payment falling, the principal part
   rising, crossing where each is half the payment. It is literally what the
   app computes, and nothing else in this category draws it.

   Given the furniture of a figure in a printed book (baseline, five-year
   ordinates, a ringed crossing, no axis labels, no fill, no grid) so it reads
   as a diagram and not as a dashboard chart competing with the screenshots.

   Inlined as a data-URI MASK rather than an <img> or a live filter: url(),
   for three reasons. The ink is then a token, so ONE asset themes itself in
   both directions with no second copy to drift; a mask cannot re-rasterise on
   every paint the way a live SVG filter does; and aspect-ratio reserves the
   box at first layout, so no CLS is possible even in theory.

   The geometry is computed, not eyeballed: 300,000 at 4.50% over 360 months,
   sampled once a year, interest_m = pay - pay*(1+i)^(m-1-n). Interest plus
   principal equals the payment in EVERY month, so the two curves are exact
   reflections about the mid-line — which is why one <path> plus one mirrored
   <use> is the definition of an annuity rather than a shortcut. It crosses at
   month 176. Both href and xlink:href are present because older WebKit
   ignores the SVG2 form inside an image. NOTE: a 60-month consumer loan
   cannot cross at all (it needs n*i > ln 2), so this figure IS a mortgage —
   hence it is captioned as one where it is content and left unlabelled where
   it is decoration. Never describe it as a five-year loan.
   -------------------------------------------------------------------------- */
:root {
  --ledger-fig: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='484' height='139' viewBox='-2 -3 484 139'%3E%3Cdefs%3E%3Cpath id='a' d='M0 34.3L16 35.9L32.1 37.5L48.1 39.3L64.2 41.1L80.2 42.9L96.3 44.9L112.3 47L128.4 49.1L144.4 51.4L160.4 53.8L176.5 56.2L192.5 58.8L208.6 61.5L224.6 64.3L240.7 67.3L256.7 70.4L272.8 73.6L288.8 77L304.8 80.5L320.9 84.2L336.9 88.1L353 92.2L369 96.4L385.1 100.8L401.1 105.4L417.2 110.3L433.2 115.4L449.2 120.7L465.3 126.2L480 131.5'/%3E%3C/defs%3E%3Cg fill='none' stroke='%23fff' stroke-width='1.5'%3E%3Cuse href='%23a' xlink:href='%23a' stroke-dasharray='5 4'/%3E%3Cuse href='%23a' xlink:href='%23a' transform='matrix(1 0 0 -1 0 132)'/%3E%3Cpath d='M0 132h480M79 132v-6M159 132v-6M239 132v-6M320 132v-6M400 132v-6M233.7 132v-66' stroke-opacity='.5'/%3E%3Ccircle cx='233.7' cy='66' r='3.2' stroke-opacity='.85'/%3E%3C/g%3E%3C/svg%3E");
}
/* No mask support means no ink, so the figure must not reserve space or leave
   its caption orphaned. These defaults MUST stay above the @supports. */
.ledger-fig, figure.ledger-figure { display: none; }
@supports (mask-image: url("#")) or (-webkit-mask-image: url("#")) {
  .ledger-fig {
    display: block; width: min(480px, 100%); aspect-ratio: 484 / 139;
    margin-inline: auto; background: var(--border-strong);
    -webkit-mask: var(--ledger-fig) center / 100% 100% no-repeat;
            mask: var(--ledger-fig) center / 100% 100% no-repeat;
  }
  /* One value, not two: .band is navy-600 in BOTH themes — the same reasoning
     the --on-navy-* tokens are given. */
  .band .ledger-fig { background: var(--cream-100); opacity: 0.42; }
  .hero .ledger-fig { margin-top: var(--sp-8); }
  figure.ledger-figure { display: block; max-width: 560px;
                         margin: var(--sp-6) auto var(--sp-7); }
  /* Where the figure is CONTENT rather than decoration it needs real ink.
     --border-strong measured 1.47:1 on the alt background in light — the page
     tells the reader to look at the crossover and then draws it invisibly.
     --fg-muted is 5.20:1 light / 8.10:1 dark, clears 1.4.11's 3:1 for a
     graphical object in both themes, and drawing a figure in the same ink as
     its own caption is what a printed book does anyway. The decorative copy in
     the hero stays soft on purpose — it is aria-hidden and must not compete
     with the headline. */
  .ledger-figure .ledger-fig { background: var(--fg-muted); }
  .ledger-figure figcaption { margin-top: var(--sp-4); text-align: center;
    font-size: var(--step--1); color: var(--fg-muted); }
}

/* -------------------------------------------------------------- the sum rule
   A printed ledger closes a total with a DOUBLE rule, and 3px double is
   exactly that: 1px, 1px gap, 1px. This is the half of the motif that
   RECURS. It needs no aspect ratio, cannot be cropped, works at any width,
   and asserts only "this is bookkeeping" — true on all 25 pages, unlike a
   curve, which asserts something about interest on pages where no loan is
   discussed. It attaches to hooks every page already has, so there is nothing
   to add to any file. The figure's own baseline is this line at figure scale.
   -------------------------------------------------------------------------- */
hr, .rule-sum { border-top: 3px double var(--border-strong); }
.proof { border-block: 3px double var(--border-strong); }
thead th { border-bottom: 3px double var(--border-strong); }
.cta-band, .site-footer { border-top: 3px double rgba(244, 234, 213, 0.3); }
/* Money in a column has to align. Proportional figures were making the
   pricing column and the comparison tables shimmer. */
table, .plan__price, .frag__value, .mini { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------- bento fragments
   The hero's .frag cards are the best-looking thing on the homepage and the
   technique was used nowhere else. These are the same idea in flow at the
   foot of a bento cell: real markup, zero image bytes, themed by the page.
   A well (--surface-sunk) inside a raised card, which reads as sunk in both
   themes. margin-top: auto works because .bento .card is already
   flex-direction: column; height: 100% — and it bottom-aligns all three
   fragments across the row whatever the copy length.
   -------------------------------------------------------------------------- */
.mini { margin-top: auto; overflow: hidden; font-size: 0.82rem;
        background: var(--surface-sunk); border: var(--ring); border-radius: 10px; }
.mini__row { display: flex; align-items: center; gap: var(--sp-3);
             padding: 9px var(--sp-3); border-top: var(--ring); }
.mini__row:first-child { border-top: 0; }
/* min-width: 0 or the name block refuses to shrink and the row overflows in a
   one-column bento on a phone. */
.mini__name { flex: 1; min-width: 0; line-height: 1.3; }
.mini__name em { display: block; font-style: normal; font-size: 0.72rem;
                 color: var(--fg-subtle); }
.mini__dot { flex: none; width: 8px; height: 8px; border-radius: 50%;
             background: var(--d, var(--border-control)); }
.mini__amt { flex: none; min-width: 88px; text-align: right; font-weight: 600; }
.mini__amt--in { color: var(--gold-text); }  /* the only gold that reads as text */
/* The fragment's total row, closed by the sum rule: the motif at 1/20 scale. */
.mini__foot { display: flex; flex-wrap: wrap; justify-content: space-between;
              gap: 2px var(--sp-3); padding: 8px var(--sp-3); font-size: 0.75rem;
              color: var(--fg-subtle); background: var(--surface-2);
              border-top: 3px double var(--border-strong); }
.mini__foot .mini__amt { min-width: 0; color: var(--fg); }
/* The report fragment is a sheet of paper: --surface with the gold rule a
   printed report carries across page one. Its columns have no axis of their
   own — the sum rule under them IS the baseline, so one line serves as both
   the chart's axis and the report's total. */
.mini--paper { background: var(--surface); border-top: 3px solid var(--gold-300); }
.mini__pad { padding: var(--sp-3); }
.mini__bars { display: flex; align-items: flex-end; gap: 5px; height: 40px;
              margin-top: var(--sp-3); }
.mini__bars i { flex: 1; border-radius: 2px 2px 0 0; background: var(--border-strong); }
.mini__bars i:last-child { background: var(--gold-300); }
