/* AutoPortfolios — the public site's design system.
 *
 * ONE stylesheet for every public page (landing, sign-in, the legal set). Not a build output:
 * there is no bundler in this service on purpose, so what you read here is what ships. That
 * also means a stale class name is a silently unstyled element rather than a build error,
 * which is why tests/test_deploy.py walks every reference these pages make.
 *
 * NOTHING HERE MAY FETCH FROM ANOTHER ORIGIN. No @import from a CDN, no Google Fonts, no
 * remote background-image. A visitor's first request should reach this box and nowhere else —
 * it is a privacy property, it is why the site works behind a corporate proxy, and
 * test_no_new_page_fetches_anything_off_this_origin walks the url() and @import references in
 * this file to enforce it.
 *
 * The dark application at /dashboard and the operator page at /admin keep their own dark
 * palette. The seam is deliberate and the sentence below is the whole test — they are a trading
 * interface, this is a brochure, and pretending otherwise produced the half-and-half page this
 * replaces.
 *
 * /portfolios MOVED to this side on 2026-08-17, which is the same rule applied more honestly:
 * the catalogue is something you read before deciding, not something you trade in. Sign-in
 * merged into it at the same time, so /login now redirects there.
 *
 * Fonts: Geist and Geist Mono, SIL OFL 1.1, subset copies vendored in assets/fonts/.
 *
 * WHAT SATISFIES THE LICENCE IS assets/fonts/OFL.txt, and nothing else. Condition 2 requires
 * that each copy of the font software carries the copyright notice and the licence, and it
 * accepts a stand-alone text file for exactly that — which is what the file beside the woff2s
 * is. The OFL asks for no credit in the interface: there was a line in every page footer for a
 * while, and it was courtesy rather than compliance, so it has gone. Deleting OFL.txt would be
 * a licence breach; deleting a footer line was not.
 *
 * Georgia — a system font, no download — is the serif that sets the emphasised clause in every
 * headline, and is the strongest single brand signature here; do not replace it with an
 * italic sans.
 */

/* --------------------------------------------------------------------- fonts
 * unicode-range values copied VERBATIM from the upstream subset manifests. Hand-typing them
 * is how latin-ext silently stops loading and half the punctuation falls back to Arial.
 * The filenames keep upstream's content hash, which is what makes `immutable` honest in the
 * Caddyfile: a different font is a different URL. */
@font-face {
  font-family: Geist;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fonts/geist-latin-98bbbccb.woff2) format("woff2");
  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: Geist;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fonts/geist-latin-ext-001175b1.woff2) format("woff2");
  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;
}
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fonts/geist-mono-latin-013b2f2f.woff2) format("woff2");
  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;
}

/* --------------------------------------------------------------------- tokens */
:root {
  /* brand */
  --ink: #132219;
  --muted: #5f6d63;
  --paper: #f4f2e9;
  --cream: #fbfaf5;
  --lime: #c8f05b;
  --green: #1f6b49;
  --line: rgba(19, 34, 25, .15);

  /* text scale on light ground, darkest to lightest */
  --ink-2: #33473a;
  --muted-2: #68746c;
  --muted-3: #829087;

  /* text on the dark bands */
  --on-dark: #a9b6ac;
  --on-dark-2: #9caaa0;
  --line-dark: #46554a;
  --line-dark-2: #253129;

  /* surfaces */
  --stage: #dfe8da;
  --panel: #e5eadf;
  --sunk: #f0f0e9;
  --band-green: #1d4831;
  --band-pale: #e3eadd;
  --footer: #0c1510;
  --code: #0d1811;
  --line-2: #e1e5de;
  --line-3: #dce1da;
  --chip-ok-bg: #e4eee6;
  --chip-ok-ink: #3c6a4a;
  --chip-warn-bg: #edf5c8;
  --chip-warn-ink: #5d6818;
  --bar-muted: #8e9c91;
  /* The one red on the site, used to emphasise a headline figure — NOT a status colour. If
     something ever needs to signal loss or error, give it its own token rather than reusing
     this one, or the two meanings will collide on the same page. */
  --accent-red: #b3341f;
  /* The ✗ on the comparison grid. Its own token because the one above says, in terms, that it is
     an emphasis colour and not a status colour — reusing it would collide the two meanings on the
     same page, which is exactly what its comment tells you not to do. Slightly deeper than the
     headline red so a 13px glyph still reads on cream. */
  --mark-no: #a32d19;

  --font-sans: Geist, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
    sans-serif;
  --font-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-serif: Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }
/* `hidden` must actually hide. The browser's own rule is `[hidden] { display: none }`, and ANY
 * author rule setting `display` beats it — so `.form-result { display: flex }` left the
 * early-access success card on the page from the moment it loaded: an empty rectangle with a
 * tick in it, under the form, before anyone had submitted anything. The hero's benchmark
 * circle was one edit away from the same fate, since it is hidden the same way and styled
 * `display: grid`. This is the one place !important is the correct tool. */
[hidden] { display: none !important; }

/* `.hide` has to live HERE, not only in account.html's own style block, and this is a bug fix.
   The plan chooser ships on the landing page and on every portfolio page as
   `<div id="chooser" class="hide" style="...display:flex...">`. Those two pages load only this
   stylesheet, where `.hide` did not exist — so the class did nothing, the inline `display:flex`
   won, and the modal was visible from page load and IMPOSSIBLE TO DISMISS: `close()` adds a class,
   and a class cannot override an inline style without `!important`. It worked on account.html for
   the single reason that that page defines the rule itself.

   `!important` for the same reason `[hidden]` above needs it: the elements carrying this are the
   ones with an inline display to beat. */
.hide { display: none !important; }
/* iOS inflates text on rotation to landscape unless told not to. The hero runs 9–10.5px type
 * inside fixed-width rings, so inflation there is not a nicety — it bursts the circles. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
button { color: inherit; }
button, summary, a { -webkit-tap-highlight-color: transparent; }
/* Split in two ON PURPOSE. A selector list is invalid as a WHOLE if any selector in it is
 * unparseable, and :focus-visible only reached iOS in 15.4 — so writing this as one rule meant
 * every iPhone before that had NO focus ring anywhere on the site, keyboard or otherwise. The
 * plain :focus rule below is the fallback; the :focus-visible rule then narrows it on browsers
 * that understand it, so a mouse click does not leave a ring behind. */
button:focus, input:focus, summary:focus, a:focus {
  outline: 3px solid rgba(40, 114, 76, .35);
  outline-offset: 3px;
}
button:focus:not(:focus-visible), input:focus:not(:focus-visible),
summary:focus:not(:focus-visible), a:focus:not(:focus-visible) {
  outline: none;
}
button:focus-visible, input:focus-visible, summary:focus-visible, a:focus-visible {
  outline: 3px solid rgba(40, 114, 76, .35);
  outline-offset: 3px;
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* Someone who asked not to be moved should not be. The reference honours this and nothing
 * else — no colour-scheme query, because this site is light by design. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}

/* --------------------------------------------------------------------- header */
.site-header {
  width: min(1420px, calc(100% - 48px));
  height: 88px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--line);
  position: relative;
  z-index: 5;
}
.brand { display: flex; align-items: center; gap: 11px; font-weight: 720; letter-spacing: -.03em; font-size: 19px; }
.brand-mark {
  width: 34px; height: 34px; display: grid; place-items: center; border-radius: 10px;
  background: var(--ink); color: var(--lime); font-size: 11px; font-weight: 800;
  letter-spacing: -.04em;
}
.desktop-nav { display: flex; align-items: center; gap: 34px; font-size: 14px; color: var(--ink-2); }
.desktop-nav a, .header-cta { transition: opacity .2s ease; }
.desktop-nav a:hover, .header-cta:hover { opacity: .65; }
.header-cta {
  min-height: 44px; display: inline-flex; align-items: center; background: var(--ink);
  color: #fff; padding: 0 18px; border-radius: 999px; font-size: 13px; font-weight: 650;
}
.mobile-menu { display: none; position: relative; }
.mobile-menu summary {
  width: 44px; height: 44px; padding: 12px; display: grid; align-content: center; gap: 4px;
  border: 1px solid var(--line); border-radius: 50%; list-style: none; cursor: pointer;
}
.mobile-menu summary::-webkit-details-marker { display: none; }
.mobile-menu summary i { height: 1px; display: block; background: var(--ink); }
.mobile-menu nav {
  width: min(260px, calc(100vw - 30px)); position: fixed; top: 74px; right: 24px; z-index: 20;
  padding: 10px; display: grid; border: 1px solid var(--line); border-radius: 16px;
  background: var(--cream); box-shadow: 0 20px 45px rgba(19, 34, 25, .18);
}
.mobile-menu nav a {
  min-height: 46px; padding: 0 13px; display: flex; align-items: center; border-radius: 10px;
  font-size: 13px;
}
.mobile-menu nav a:hover { background: #e8ece4; }

/* --------------------------------------------------------------------- headings */
.section { width: min(1420px, calc(100% - 48px)); margin: 0 auto; padding: 140px 0; }
h1 {
  margin: 0; max-width: 680px; font-size: clamp(54px, 5.65vw, 88px); line-height: .93;
  letter-spacing: -.07em; font-weight: 600;
}
h1 em, h2 em { font-family: var(--font-serif); font-weight: 400; font-style: italic; color: var(--green); }
.section-heading h2, .band-heading h2, .split-heading h2 {
  margin: 0; font-size: clamp(48px, 5vw, 74px); line-height: .98; letter-spacing: -.06em;
  font-weight: 590;
}
.on-dark h2 em { color: var(--lime); }
.section-tag {
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 24px; color: var(--green);
  font-size: 10px; font-weight: 800; letter-spacing: .17em; text-transform: uppercase;
}
.section-tag::before { content: ""; width: 22px; height: 1px; background: currentColor; }
.on-dark .section-tag { color: var(--lime); }
.split-heading { display: grid; grid-template-columns: 1.15fr .65fr; align-items: end; gap: 80px; }
.split-heading > p {
  max-width: 500px; margin: 0 0 6px; color: var(--muted); font-size: 17px; line-height: 1.7;
  letter-spacing: -.02em;
}
.on-dark .split-heading > p { color: var(--on-dark); }

/* --------------------------------------------------------------------- buttons */
.button {
  min-height: 52px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0 22px; border: 0; border-radius: 999px; font-size: 14px; font-weight: 680;
  cursor: pointer; transition: transform .2s ease, background .2s ease;
}
.button:hover { transform: translateY(-2px); }
.button-primary { background: var(--ink); color: #fff; }
.button-secondary { border: 1px solid var(--line); background: rgba(255, 255, 255, .35); gap: 10px; }

.text-link {
  display: inline-flex; gap: 16px; align-items: center; padding-bottom: 4px;
  border-bottom: 1px solid rgba(255, 255, 255, .25); font-size: 13px; font-weight: 650;
}
.text-link span { color: var(--lime); }

/* --------------------------------------------------------------------- hero */
.hero {
  width: min(1420px, calc(100% - 48px)); min-height: 640px; margin: 0 auto; display: grid;
  grid-template-columns: .92fr 1.08fr; align-items: center; gap: 64px; padding: 64px 0 58px;
}
.hero-copy { padding-left: clamp(0px, 2vw, 32px); }
.eyebrow {
  display: flex; align-items: center; gap: 9px; margin-bottom: 24px; font-size: 12px;
  line-height: 1; letter-spacing: .12em; font-weight: 720; text-transform: uppercase;
  color: var(--green);
}
.eyebrow span {
  width: 7px; height: 7px; border-radius: 50%; background: var(--lime);
  box-shadow: 0 0 0 5px rgba(200, 240, 91, .2);
}
.hero-lede {
  max-width: 585px; margin: 30px 0 0; color: var(--muted); font-size: 18px; line-height: 1.65;
  letter-spacing: -.018em;
}
.hero-actions { display: flex; align-items: center; gap: 12px; margin-top: 34px; }
.trust-row { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 28px; color: var(--muted-2); font-size: 11px; }
.trust-row span { display: flex; gap: 6px; align-items: center; }
.trust-row b { color: var(--green); }

.product-stage {
  min-height: 540px; position: relative; display: grid; place-items: center; overflow: hidden;
  border-radius: 34px; background: var(--stage); isolation: isolate;
}
.product-stage::before {
  content: ""; position: absolute; inset: 0; z-index: -3;
  background: radial-gradient(circle at 48% 47%, rgba(200, 240, 91, .75), transparent 32%),
    radial-gradient(circle at 88% 10%, rgba(255, 255, 255, .7), transparent 28%);
}
/* Centred explicitly rather than by the grid parent's place-items. Aligning an absolutely
 * positioned child that way is correct per spec and was buggy in Safari before 16, and the
 * failure mode is a ring pinned to a corner rather than a ring. */
.stage-orbit {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  border: 1px solid rgba(19, 34, 25, .09); border-radius: 50%; z-index: -2;
}
.orbit-one { width: 610px; height: 610px; }
.orbit-two { width: 430px; height: 430px; }
.stage-badge {
  position: absolute; left: 18px; top: 18px; z-index: 3; padding: 7px 10px;
  border: 1px solid rgba(19, 34, 25, .1); border-radius: 99px; background: rgba(251, 250, 245, .9);
  color: #536259; font-size: 9px; font-weight: 700; letter-spacing: .04em;
}
/* The comparison stage. Two circles, the portfolio's return and its benchmark's over the same
 * window, because that pairing is the entire proposition and a single number is not evidence
 * of anything. The window caption underneath is not decoration: an unqualified cumulative
 * figure over a curve that starts in a backtest is what made these look wrong. */
.vs-stage {
  width: min(560px, calc(100% - 64px)); padding: 30px 28px 26px; display: grid;
  justify-items: center; gap: 16px; border: 1px solid rgba(255, 255, 255, .7);
  border-radius: 26px; background: rgba(251, 250, 245, .93);
  box-shadow: 0 32px 70px rgba(32, 59, 42, .16);
  /* -webkit- first: unprefixed backdrop-filter only reached iOS in 18, so every iPhone
     before that needs the prefixed form or the blur is silently dropped. */
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.vs-kicker {
  margin: 0; color: #516057; font-size: 10px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; text-align: center;
}
.vs-pair { display: flex; align-items: center; justify-content: center; gap: 14px; }
.vs-circle {
  width: clamp(128px, 15vw, 168px); height: clamp(128px, 15vw, 168px); aspect-ratio: 1;
  flex: 0 0 auto; display: grid; place-content: center;
  padding: 12px; border: 7px solid var(--green); border-radius: 50%; background: var(--cream);
  text-align: center; box-shadow: 0 14px 32px rgba(32, 59, 42, .14);
}
.vs-circle.bench {
  width: clamp(104px, 12vw, 138px); height: clamp(104px, 12vw, 138px);
  border-color: var(--bar-muted);
  box-shadow: 0 10px 24px rgba(32, 59, 42, .1);
}
/* The figure alone, with room to breathe inside the ring. It used to carry its unit inline —
 * "+46.3%/year" — which at this size is far wider than the circle and overflowed it. */
.vs-circle b {
  display: block; font-size: clamp(21px, 2.3vw, 31px); line-height: 1; letter-spacing: -.05em;
  font-variant-numeric: tabular-nums; color: var(--green);
}
.vs-circle.bench b { font-size: clamp(16px, 1.8vw, 24px); color: var(--ink); }
/* Set by renderHero when the figure runs long — a cumulative total on a decade-old book
 * reaches "+1443.5%", which is wider than the ring at the size above. */
.vs-circle.long b { font-size: clamp(17px, 1.9vw, 25px); }
.vs-circle.bench.long b { font-size: clamp(14px, 1.6vw, 20px); }
.vs-unit {
  display: block; margin-top: 3px; color: var(--muted-2); font-style: normal; font-size: 9px;
  font-weight: 750; letter-spacing: .1em; text-transform: uppercase;
}
.vs-circle small {
  display: block; margin-top: 5px; color: var(--muted); font-size: 9.5px; line-height: 1.3;
  overflow-wrap: anywhere;
}
.vs-word { color: var(--muted-2); font-size: 11px; font-weight: 750; letter-spacing: .1em; }
.vs-caption {
  margin: 0; max-width: 440px; color: var(--muted-2); font-size: 10.5px; line-height: 1.6;
  text-align: center;
}
/* The cumulative figure and how long it took, pulled out of the caption and given weight — it
 * is the line that makes the rate above it concrete. Red is a deliberate marketing choice
 * rather than a status colour; nothing else on this site uses it, so it does not collide with
 * a loss indicator anywhere. Warm brick rather than pure red, to sit inside the palette. */
.vs-headline {
  color: var(--accent-red); font-size: 13px; font-weight: 750; letter-spacing: -.01em;
}
.vs-spark { width: 100%; height: 92px; }
.vs-stats {
  width: 100%; display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line-2); padding-top: 14px;
}
/* `min-width: 0` is what actually stops a long value blowing the track out — a grid `1fr` is
 * `minmax(auto, 1fr)`, so without it the column floors at its content's min-content width.
 * `overflow-wrap` alone was carrying that job, and it is not supported before iOS 15.4. The
 * padding gives the dividers a gutter; they were sitting flush against the glyphs. */
.vs-stats div { min-width: 0; display: grid; gap: 4px; text-align: center; padding: 0 7px; }
.vs-stats div + div { border-left: 1px solid var(--line-2); }
.vs-stats b { font-size: 12px; overflow-wrap: anywhere; }
.vs-stats span { color: var(--muted-2); font-size: 9.5px; }

/* The same pairing at card scale. */
.headline-pair { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-2); }
.hp-main { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; }
.hp-main > b {
  font-size: 30px; line-height: 1; letter-spacing: -.05em; color: var(--green);
  font-variant-numeric: tabular-nums;
}
.hp-bench { color: var(--muted); font-size: 11px; }
.hp-bench i { font-style: normal; color: var(--muted-2); }
.hp-bench b { color: var(--ink); font-variant-numeric: tabular-nums; }
.hp-window {
  margin: 7px 0 0; color: var(--muted-2); font-size: 9.5px; letter-spacing: .06em;
  text-transform: uppercase;
}
.hp-extra {
  display: flex; align-items: baseline; gap: 8px; margin-top: 12px; padding-top: 10px;
  border-top: 1px dashed var(--line); color: var(--muted); font-size: 11px;
}
.hp-extra b { color: var(--green); font-variant-numeric: tabular-nums; }
.hp-extra em { font-style: normal; color: var(--muted-2); }

/* The hero curve and every catalogue sparkline are inline SVG drawn from the published series.
 * The reference draws its chart with a clip-path polygon of hardcoded percentages, which is
 * fine for a mockup and would be a fabricated track record here. */
.spark { display: block; width: 100%; height: 100%; }
.spark path { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.spark .model { stroke: var(--green); stroke-width: 2; }
.spark .bench { stroke: var(--bar-muted); stroke-width: 1.5; stroke-dasharray: 3 3; }

/* --------------------------------------------------------------------- proof strip */
.proof-strip {
  min-height: 80px; padding: 20px max(24px, calc((100% - 1420px) / 2)); display: flex;
  align-items: center; justify-content: space-between; gap: 24px; background: var(--ink);
  color: #fff;
}
.proof-strip > span { color: #aebbaf; font-size: 12px; }
.proof-strip > div { display: flex; align-items: center; gap: 18px; font-size: 10px; letter-spacing: .14em; }
.proof-strip i { width: 46px; height: 1px; background: var(--line-dark); }

/* --------------------------------------------------------------------- catalogue */
.catalogue-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 18px;
  margin-top: 60px;
}
/* The line that stands in for the rest of the catalogue. Centred and quiet: it is a way past a
   shortlist, not a call to action competing with the ones that matter. */
.catalogue-more { margin-top: 22px; text-align: center; }
.catalogue-more-btn {
  padding: 13px 24px; border: 1px solid var(--line); border-radius: 99px;
  background: var(--cream); color: var(--ink); font: inherit; font-size: 13px; cursor: pointer;
  transition: background .2s ease;
}
.catalogue-more-btn:hover { background: var(--stage); }
.catalogue-more-btn:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
@media (max-width: 620px) { .catalogue-more-btn { width: 100%; min-height: 48px; } }
.model-card {
  min-width: 0; display: flex; flex-direction: column; padding: 26px;
  border: 1px solid var(--line); border-radius: 22px; background: var(--cream);
}
.model-card-head { display: flex; align-items: flex-start; gap: 12px; }
.model-mark {
  width: 40px; height: 40px; flex: 0 0 auto; display: grid; place-items: center;
  border-radius: 12px; background: var(--ink); color: var(--lime); font-size: 12px;
  font-weight: 800; letter-spacing: -.02em;
}
.model-card-head > div { min-width: 0; display: grid; gap: 4px; }
.model-card h3 { margin: 0; font-size: 19px; letter-spacing: -.035em; overflow-wrap: anywhere; }
.model-byline { color: #516057; font-size: 9px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; }
.model-card > p { margin: 18px 0 0; color: var(--muted); font-size: 13px; line-height: 1.6; }
.model-facts {
  display: flex; flex-wrap: wrap; gap: 7px; margin-top: 18px;
}
.model-facts span {
  padding: 5px 9px; border: 1px solid var(--line); border-radius: 99px; color: #526158;
  font-size: 10px;
}
.model-spark { height: 96px; margin: 20px 0 0; }
.model-returns {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 14px;
  margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-2);
}
.model-returns div { display: grid; gap: 4px; }
.model-returns span { color: #536259; font-size: 9px; letter-spacing: .06em; text-transform: uppercase; }
.model-returns b { color: var(--green); font-size: 17px; letter-spacing: -.035em; }
.model-returns b.bench { color: var(--ink); font-size: 13px; }
.model-foot {
  margin-top: auto; padding-top: 18px; color: var(--muted-2); font-size: 10px; line-height: 1.6;
}

/* --------------------------------------------------------------------- one portfolio
 * /portfolios/{public_id} — where a card's "Request access" used to point at a route that did
 * not exist. Deliberately narrower than the marketing sections: this is a page somebody READS
 * before deciding, so it is a column of prose and one large chart, not a full-bleed band.
 *
 * It shows no holdings, and cannot: the payload behind it is PUBLIC_FIELDS_DETAIL, which has
 * no holdings key for the page to render even by mistake. */
.model-detail { max-width: 760px; padding: 72px 0 120px; }
.detail-back { margin: 0 0 34px; font-size: 12px; }
.detail-head { display: flex; align-items: flex-start; gap: 16px; }
.detail-head > div { min-width: 0; display: grid; gap: 8px; }
.detail-head h1 { font-size: clamp(34px, 4.6vw, 52px); line-height: 1.02; letter-spacing: -.05em; }
.detail-panel {
  margin-top: 44px; padding: 30px; border: 1px solid var(--line); border-radius: 22px;
  background: var(--cream);
}
.detail-chart { height: 320px; margin-bottom: 14px; }
.detail-legend {
  display: flex; flex-wrap: wrap; gap: 18px; margin: 0; color: var(--muted-2); font-size: 10px;
  letter-spacing: .06em; text-transform: uppercase;
}
/* The key is drawn from the same strokes as the chart, so the dashed benchmark is recognisable
   as the dashed benchmark rather than named in prose beside it. */
.detail-legend b, .detail-legend em {
  display: inline-flex; align-items: center; gap: 7px; font-style: normal; font-weight: 600;
  color: var(--ink-2);
}
.detail-legend b::before, .detail-legend em::before {
  content: ""; width: 18px; height: 0; border-top: 2px solid var(--green);
}
.detail-legend em::before { border-top: 1.5px dashed var(--bar-muted); }
.detail-meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 20px;
  margin-top: 34px; padding-top: 26px; border-top: 1px solid var(--line-2);
}
.detail-meta div { display: grid; gap: 5px; }
.detail-meta span {
  color: var(--muted-2); font-size: 9px; letter-spacing: .09em; text-transform: uppercase;
}
.detail-meta b { font-size: 14px; letter-spacing: -.02em; }
/* The holdings answer, given where the question is asked. A panel rather than a footnote
   because it carries the two doors — the sentence and the offer are one thing. */
.detail-lock {
  margin-top: 34px; padding: 20px 22px;
  border: 1px dashed var(--line); border-radius: 14px; background: var(--cream);
}
.detail-lock > span { display: block; margin-top: 10px; color: var(--ink-2); font-size: 14px;
  line-height: 1.65; }
.detail-lock .lockhead { display: block; font-size: 16px; color: var(--ink); }
.detail-lock .detail-cta { margin-top: 20px; }
.detail-cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 38px; }
.detail-cta .button { min-height: 48px; }
.detail-note {
  margin: 26px 0 0; color: var(--muted-2); font-size: 11.5px; line-height: 1.7;
}
@media (max-width: 640px) {
  .model-detail { padding: 48px 0 88px; }
  .detail-panel { padding: 20px; }
  .detail-chart { height: 220px; }
}

/* Every card ends in an action. The cards are the most persuasive object on the page — real
 * figures, benchmark beaten, window stated — and they used to be dead ends. */
.card-cta { width: 100%; margin-top: 18px; min-height: 46px; font-size: 13px; }
.calc-cta { width: 100%; margin-top: 22px; }

/* The one thumb-reach action on a long phone page. Desktop never sees it. */
.sticky-cta {
  display: none; position: fixed; left: 16px; right: 16px; z-index: 30;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 12px 32px rgba(19, 34, 25, .28);
}

/* The state that must exist and must never be a zero. An absent curve is absent, not flat. */
.empty-state {
  padding: 34px; border: 1px dashed var(--line); border-radius: 18px; background: transparent;
  color: var(--muted); font-size: 13px; line-height: 1.65; text-align: center;
}
.empty-state b { display: block; margin-bottom: 6px; color: var(--ink); font-size: 15px; }

/* --------------------------------------------------------------------- dark band */
/* ---------------------------------------------------------------- custody and liquidity

   A three-column grid rather than a <table>: the question, what a fund does, what happens here.
   One grid for the whole block so every column lines up across rows — per-row flex boxes drift
   as soon as one answer wraps to a different number of lines.

   On a phone it becomes stacked pairs, and the "A managed fund" / "AutoPortfolios" header row is
   hidden there because a header two screens above its data labels nothing; each cell carries its
   own label from a ::before instead. */
.custody-table { margin-top: 56px; border-top: 1px solid var(--line); }
.custody-head, .custody-row {
  display: grid; grid-template-columns: .8fr 1fr 1.25fr; gap: 40px;
  padding: 22px 0; border-bottom: 1px solid var(--line);
}
.custody-head { padding: 14px 0; border-bottom: 1px solid var(--ink); }
.custody-head p {
  margin: 0; font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted-2);
}
.custody-head .custody-us { color: var(--ink); }
.custody-row p { margin: 0; font-size: 14.5px; line-height: 1.6; }
.custody-q { font-weight: 500; color: var(--ink); }
/* The fund column is deliberately quieter than ours — same information hierarchy the eye already
   reads as "this is the old way". */
.custody-them { color: var(--muted-2); }
.custody-us { color: var(--ink); }
.custody-us b { font-weight: 600; }
.custody-us i { font-style: normal; color: var(--muted-2); }
.custody-note, .custody-brokers {
  max-width: 900px; margin: 32px 0 0; font-size: 14.5px; line-height: 1.7; color: var(--ink-2);
}
.custody-note b, .custody-brokers b { color: var(--ink); }
.custody-cta { margin-top: 40px; }

/* The marks. A comparison is read by scanning one column against the other, and a ✗/✓ pair does
   that faster than any amount of prose — which is why they live at EVERY width, not just where
   there is room. In ::before, so no row markup changes: the equal-row guard counts the exact
   strings `class="custody-them"` and `class="custody-us"`, and a wrapper span carrying those
   names would break the count while looking harmless. */
.custody-row .custody-them::before, .custody-row .custody-us::before {
  font-weight: 700; margin-right: 7px;
}
.custody-row .custody-them::before { content: "\2717"; color: var(--mark-no); }
.custody-row .custody-us::before { content: "\2713"; color: var(--green); }

@media (max-width: 860px) {
  /* Side by side, at every width. Stacked, the two halves of a comparison were never on screen
     together — which is the entire point of the device, so the phone layout was showing the
     content and losing the argument. The question spans both columns above its own pair, and the
     header strip comes back to label them (it had been hidden, with the labels repeated into
     every cell from a ::before — the slot the marks now need). */
  .custody-head, .custody-row { grid-template-columns: 1fr 1fr; gap: 6px 14px; }
  .custody-head { display: grid; padding: 10px 0; }
  .custody-head .custody-q { display: none; }
  .custody-head .custody-them, .custody-head .custody-us { font-size: 9px; letter-spacing: .1em; }
  .custody-row .custody-q { grid-column: 1 / -1; font-size: 14px; margin-bottom: 2px; }
  .custody-row p { font-size: 12.5px; line-height: 1.5; }
  .custody-row .custody-them::before, .custody-row .custody-us::before { margin-right: 4px; }
  .custody-note, .custody-brokers { font-size: 13.5px; }
  .custody-cta { width: 100%; }
}

.band {
  padding: 140px max(24px, calc((100% - 1420px) / 2)); background: var(--ink); color: #f3f4ee;
}
.band-inner { display: grid; grid-template-columns: .85fr 1.15fr; gap: 110px; }
.band-heading > p { max-width: 500px; margin: 28px 0; color: var(--on-dark); font-size: 16px; line-height: 1.7; }
/* The two tracks stack inside the band's content column, so nothing at any breakpoint needs to
   know there are two of them — `.band-inner` is still heading | content, and `.step-list` is
   unchanged so both inherit the same bordered rows. */
.tracks { display: grid; gap: 54px; }
.track-label {
  margin: 0 0 14px; color: var(--lime); font-size: 10px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase;
}
.track-label b { color: var(--on-dark-2); font-weight: 500; letter-spacing: .06em; }
.step-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid rgba(255, 255, 255, .15); }
.step-list li {
  min-height: 140px; display: grid; grid-template-columns: 48px 1fr; gap: 25px;
  align-items: center; border-bottom: 1px solid rgba(255, 255, 255, .15);
}
.step-list li > span { color: var(--lime); font-family: var(--font-mono); font-size: 10px; }
.step-list h3 { margin: 0 0 8px; font-size: 21px; letter-spacing: -.035em; }
.step-list p { max-width: 540px; margin: 0; color: var(--on-dark-2); font-size: 13px; line-height: 1.6; }

/* --------------------------------------------------------------------- calculator */
.performance-section {
  padding: 140px max(24px, calc((100% - 1220px) / 2)); background: var(--band-green); color: #fff;
}
.performance-heading { max-width: 850px; margin: 0 auto 62px; text-align: center; }
.performance-heading .section-tag { justify-content: center; }
.performance-heading > p { max-width: 650px; margin: 24px auto 0; color: #b5c3b9; font-size: 16px; line-height: 1.65; }
.calculator-shell {
  display: grid; grid-template-columns: .78fr 1.22fr; overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .16); border-radius: 26px; background: var(--cream);
  color: var(--ink); box-shadow: 0 35px 80px rgba(0, 0, 0, .2);
}
.calculator-controls { padding: 34px; border-right: 1px solid #dfe4dc; background: var(--sunk); }
.control-group { margin: 0 0 28px; padding: 0 0 28px; border: 0; border-bottom: 1px solid #d8ded5; }
.control-group:last-child { margin: 0; padding: 0; border: 0; }
.control-group label, .control-group legend {
  display: block; margin-bottom: 12px; color: #66756b; font-size: 10px; font-weight: 750;
  letter-spacing: .08em; text-transform: uppercase;
}
.money-input {
  height: 57px; display: flex; align-items: center; gap: 8px; padding: 0 16px;
  border: 1px solid #cbd3c8; border-radius: 12px; background: #fff;
}
.money-input span { color: #708078; font-size: 20px; }
.money-input input {
  min-width: 0; width: 100%; border: 0; outline: 0; background: transparent; color: var(--ink);
  font-size: 24px; font-weight: 700; letter-spacing: -.04em;
}
.amount-presets { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 9px; }
.amount-presets button, .range-picker button {
  min-height: 44px; border: 1px solid #d2d9d0; border-radius: 8px; background: transparent;
  color: #6b776f; font-size: 10px; cursor: pointer;
}
.amount-presets button.active, .range-picker button.active {
  border-color: var(--green); background: #dce9dc; color: var(--green); font-weight: 750;
}
.range-picker { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
.strategy-picker { display: grid; gap: 8px; max-height: 320px; overflow-y: auto; }
.strategy-option {
  width: 100%; min-height: 58px; padding: 9px 11px; display: flex; align-items: center;
  gap: 11px; border: 1px solid #d4dbd2; border-radius: 12px; background: transparent;
  text-align: left; cursor: pointer;
}
.strategy-option > span { min-width: 0; display: grid; gap: 3px; }
.strategy-option b { font-size: 12px; overflow-wrap: anywhere; }
.strategy-option small { color: #758179; font-size: 9px; }
.strategy-option > i { width: 13px; height: 13px; flex: 0 0 auto; margin-left: auto; border: 1px solid #aeb9b0; border-radius: 50%; }
.strategy-option.active { border-color: #7aa287; background: #e5eee3; }
.strategy-option.active > i { border: 4px solid var(--green); }
.calculator-results { min-width: 0; padding: 42px; }
.result-topline {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 20px;
  padding-bottom: 30px; border-bottom: 1px solid var(--line-2);
}
.result-topline small { color: #526158; font-size: 10px; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; }
.result-topline h3 { margin: 6px 0 0; font-size: clamp(36px, 4vw, 54px); letter-spacing: -.06em; }
.result-topline > span {
  padding: 7px 9px; border: 1px solid #dde2da; border-radius: 99px; color: #4f6055;
  font-size: 10px; white-space: nowrap;
}
.result-bars { display: grid; gap: 27px; padding: 36px 0 32px; }
.result-row-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; font-size: 11px; }
.result-row-head b { color: var(--green); }
.result-row + .result-row .result-row-head b { color: #66746a; }
.result-track { height: 35px; border-radius: 7px; background: #e8eae5; overflow: hidden; }
.result-track > i {
  min-width: 112px; height: 100%; display: flex; align-items: center; justify-content: flex-end;
  padding: 0 10px; border-radius: inherit; font-style: normal; transition: width .35s ease;
}
.result-track > i span { color: #fff; font-size: 10px; font-weight: 750; }
.strategy-bar { background: var(--green); }
.benchmark-bar { background: var(--bar-muted); }
.difference-card {
  padding: 20px; display: flex; align-items: center; gap: 15px; border-radius: 15px;
  background: #eaf4ca;
}
.difference-icon {
  width: 42px; height: 42px; flex: 0 0 auto; display: grid; place-items: center;
  border-radius: 12px; background: var(--ink); color: var(--lime); font-size: 20px;
}
.difference-card > div { display: grid; gap: 3px; }
.difference-card small { color: #4f5a31; font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.difference-card strong { font-size: 25px; letter-spacing: -.04em; }
.difference-card p { margin: 0; color: #4f5a31; font-size: 10px; }
/* No top border, and a smaller gap. The bars and the benchmark card used to sit between the
   headline and these figures; with the projection they are gone, so the topline's bottom border
   and this one bracketed 52px of empty space — two rules with nothing between them, which is
   what it looked like on a phone. One divider is enough. */
.result-metrics {
  display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 26px;
}
.result-metrics div { display: grid; gap: 6px; }
.result-metrics div + div { padding-left: 20px; border-left: 1px solid var(--line-2); }
.result-metrics span { color: #536259; font-size: 10px; }
.result-metrics b { font-size: 12px; }
/* The horizon slider. A range input rather than a row of buttons: 1–30 is too many to list, and
   dragging makes the shape of compounding something you feel rather than read. The marks under
   the track are also buttons, because hitting exactly 15 by dragging on a phone is unpleasant.

   Both vendor thumbs are styled explicitly. `appearance: none` removes the platform control
   ENTIRELY, so a thumb that is only defined for one engine leaves an invisible one on the other —
   a slider you cannot see is a slider you cannot use. */
.years-readout { display: block; margin-bottom: 10px; font-size: 22px; letter-spacing: -.03em; }
.years-slider {
  -webkit-appearance: none; appearance: none; width: 100%; height: 4px; margin: 6px 0;
  border-radius: 99px; background: var(--line-2); cursor: pointer;
}
.years-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--green); border: 3px solid var(--cream); cursor: grab;
  box-shadow: 0 1px 5px rgba(19, 34, 25, .3);
}
.years-slider::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%; background: var(--green);
  border: 3px solid var(--cream); cursor: grab; box-shadow: 0 1px 5px rgba(19, 34, 25, .3);
}
.years-slider:focus-visible { outline: 2px solid var(--green); outline-offset: 6px; }
/* A positioning context for the marks, which are placed at their own value's fraction of the
   track rather than spread evenly — see renderControls for why that distinction is the whole
   thing. Height is reserved explicitly because the children are absolute and would otherwise
   collapse the row to nothing. */
.years-ticks { position: relative; height: 26px; margin-top: 9px; }
.years-ticks button {
  position: absolute; top: 0; transform: translateX(-50%);
  padding: 3px 7px; border: 0; border-radius: 6px; background: none; cursor: pointer;
  color: var(--muted-2); font: inherit; font-size: 11px;
}
.years-ticks button:hover { color: var(--ink); }
.years-ticks button.active { color: var(--ink); font-weight: 600; }
/* Measured at 375px: the marks came out 21x20px, well under a thumb. They are the fast way to a
   common horizon, so on a phone they get a real target — taller, not wider, so five of them still
   fit the track without crowding. */
@media (max-width: 620px) {
  .years-ticks { height: 44px; }
  .years-ticks button { padding: 12px 8px; font-size: 12px; }
  .years-readout { font-size: 20px; }
}

.calculator-disclosure {
  max-width: 1060px; margin: 25px auto 0; display: flex; gap: 11px; color: #d4ded6;
  font-size: 11px; line-height: 1.65;
}
.calculator-disclosure > span {
  width: 17px; height: 17px; flex: 0 0 auto; display: grid; place-items: center;
  border: 1px solid #738a79; border-radius: 50%; font-family: var(--font-serif);
}
.calculator-disclosure p { margin: 0; }
.calculator-disclosure b { color: #fff; }
.attribution { max-width: 1060px; margin: 10px auto 0; color: #c3d0c6; font-size: 10px; line-height: 1.6; }

/* --------------------------------------------------------------------- pricing */
.pricing-section { padding: 140px max(24px, calc((100% - 1220px) / 2)); background: var(--band-pale); }
.pricing-heading { max-width: 800px; margin: 0 auto; text-align: center; }
.pricing-heading .section-tag { justify-content: center; }
.pricing-heading > p { max-width: 620px; margin: 24px auto 0; color: var(--muted); font-size: 16px; line-height: 1.65; }
.pricing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-top: 65px; align-items: stretch; }
.price-card {
  min-width: 0; position: relative; display: flex; flex-direction: column; padding: 31px;
  border: 1px solid rgba(19, 34, 25, .14); border-radius: 22px; background: var(--cream);
}
.featured-price { border: 2px solid var(--green); box-shadow: 0 24px 55px rgba(32, 78, 50, .11); }
.popular-label {
  position: absolute; top: -13px; left: 50%; transform: translateX(-50%); padding: 6px 11px;
  border-radius: 99px; background: var(--green); color: #fff; font-size: 7px; font-weight: 800;
  letter-spacing: .11em; white-space: nowrap;
}
.plan-tag { color: var(--green); font-size: 8px; font-weight: 800; letter-spacing: .14em; }
.price-card h3 { margin: 16px 0 7px; font-size: 26px; letter-spacing: -.04em; }
.price-card > p { min-height: 62px; margin: 0; color: #69766d; font-size: 12px; line-height: 1.55; }
.price {
  min-height: 90px; margin: 25px 0; display: grid; align-content: center; gap: 4px;
  border-top: 1px solid #e0e4dd; border-bottom: 1px solid #e0e4dd;
}
.price strong { font-size: 28px; letter-spacing: -.04em; }
.price span { color: #78837c; font-size: 9px; }
.price-button { width: 100%; border: 1px solid #ccd4c9; background: #f5f5ef; }
.dark-price-button { border-color: var(--ink); background: var(--ink); color: #fff; }
.price-card ul { margin: 27px 0 0; padding: 0; display: grid; gap: 13px; list-style: none; }
/* NOT a flex container, and that is the whole point of this rule.
   As `display: flex` the tick and the text were two flex items — and so was any <b> inside the
   text, because a flex container turns each child into an item and wraps the loose text between
   them in anonymous ones. "…with our software — our <b>Basket Trader</b>" therefore rendered as
   two blocks side by side with a gap down the middle, and "Access to <b>every</b> signal and
   portfolio" would have scattered into three. Reported from a phone, where the narrow column made
   it obvious.
   A hanging indent instead: the tick is taken out of flow and the bullet is ordinary inline text,
   so emphasis inside it flows like emphasis. */
.price-card li {
  position: relative; padding-left: 19px; color: #536259; font-size: 11px; line-height: 1.4;
}
.price-card li i {
  position: absolute; left: 0; top: 0; color: var(--green); font-style: normal; font-weight: 800;
}
.pricing-note { max-width: 780px; margin: 24px auto 0; color: #536259; font-size: 11px; line-height: 1.6; text-align: center; }

/* --------------------------------------------------------------------- faq */
.faq-section { display: grid; grid-template-columns: .8fr 1.2fr; gap: 110px; }
.faq-intro { position: sticky; top: 40px; align-self: start; }
.faq-intro > p { max-width: 440px; margin: 25px 0 0; color: var(--muted); font-size: 15px; line-height: 1.65; }
.faq-list { border-top: 1px solid var(--line); }
.faq-list details { border-bottom: 1px solid var(--line); }
.faq-list summary {
  min-height: 84px; display: flex; align-items: center; justify-content: space-between;
  gap: 22px; cursor: pointer; list-style: none; font-size: 17px; font-weight: 650;
  letter-spacing: -.025em;
}
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary i {
  width: 29px; height: 29px; flex: 0 0 auto; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: 50%; color: var(--green); font-size: 15px;
  font-style: normal; transition: transform .2s ease;
}
.faq-list details[open] summary i { transform: rotate(45deg); }
.faq-list details p { max-width: 650px; margin: -5px 55px 28px 0; color: var(--muted); font-size: 13px; line-height: 1.7; }

/* ---------------------------------------------------------------------- start
   The page's close. The same dark orbital shell as before, holding two links instead of the
   email form it was built for: `.access-form`, `.form-note` and `.form-result` went with the
   waiting list, and nothing else on any page used them. */
.start-section {
  min-height: 560px; position: relative; padding: 120px 24px; overflow: hidden; display: flex;
  flex-direction: column; align-items: center; justify-content: center; background: var(--ink);
  color: #fff; text-align: center; isolation: isolate;
}
.start-section::before {
  content: ""; position: absolute; width: 490px; height: 490px; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(200, 240, 91, .22), transparent 66%);
}
.start-orbit { position: absolute; border: 1px solid rgba(200, 240, 91, .09); border-radius: 50%; z-index: -1; }
.orbit-large { width: 790px; height: 790px; }
.orbit-small { width: 560px; height: 560px; }
.start-section > p { max-width: 620px; margin: 23px auto 32px; color: #abb8ae; font-size: 16px; line-height: 1.65; }
.start-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px; }
/* `.button-primary` is ink-on-white, which is this section's own background: without the swap the
   main call to action is a dark shape on a dark field. The retired form's button was lime for the
   same reason. */
.start-section .button-primary { background: var(--lime); color: var(--ink); }
.start-section .button-secondary { border-color: rgba(255, 255, 255, .3); background: transparent; color: #fff; }
/* Scoped `.start-section > .start-note` and not `.start-note`: `.start-section > p` above is a
   class-plus-element selector, so a bare class would lose to it and inherit 16px and 32px of
   margin. */
.start-section > .start-note { max-width: 460px; margin: 18px auto 0; color: #b5c2b8; font-size: 12px; line-height: 1.6; }
.start-section > .start-note a { color: #cfe0d2; text-decoration: underline; }

/* --------------------------------------------------------------------- auth */
.auth-page { min-height: 100vh; display: grid; grid-template-rows: auto 1fr auto; }
.auth-main {
  width: min(1420px, calc(100% - 48px)); margin: 0 auto; padding: 70px 0 100px; display: grid;
  grid-template-columns: 1fr 1fr; align-items: center; gap: 80px;
}
.auth-card {
  width: min(430px, 100%); padding: 36px; border: 1px solid var(--line); border-radius: 24px;
  background: var(--cream); box-shadow: 0 24px 55px rgba(32, 78, 50, .08);
}
.auth-card h1 { font-size: clamp(34px, 4vw, 44px); line-height: 1.02; letter-spacing: -.05em; }
.auth-card > p { margin: 16px 0 28px; color: var(--muted); font-size: 14px; line-height: 1.6; }
.field { display: grid; gap: 8px; margin-bottom: 16px; }
.field label { color: #66756b; font-size: 10px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
.field input {
  min-height: 52px; padding: 0 15px; border: 1px solid #cbd3c8; border-radius: 12px;
  background: #fff; color: var(--ink); font-size: 15px;
}
.auth-card .button { width: 100%; margin-top: 10px; }
.auth-error {
  margin: 16px 0 0; padding: 13px 15px; border: 1px solid #e0c3c3; border-radius: 12px;
  background: #f8eeee; color: #7d3a3a; font-size: 12px; line-height: 1.5;
}
.auth-aside { max-width: 480px; }
.auth-aside h2 { margin: 0 0 18px; font-size: clamp(28px, 3vw, 38px); line-height: 1.05; letter-spacing: -.045em; font-weight: 590; }
.auth-aside p { margin: 0 0 20px; color: var(--muted); font-size: 15px; line-height: 1.7; }
.auth-aside ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 12px; }
.auth-aside li { display: flex; gap: 10px; align-items: flex-start; color: var(--muted); font-size: 13px; line-height: 1.6; }
.auth-aside li i { color: var(--green); font-style: normal; font-weight: 800; }

/* --------------------------------------------------------------------- legal */
.legal-main { width: min(820px, calc(100% - 48px)); margin: 0 auto; padding: 80px 0 120px; }
.legal-main h1 { font-size: clamp(40px, 5vw, 62px); line-height: 1; letter-spacing: -.055em; }
.legal-updated { margin: 20px 0 46px; color: var(--muted-2); font-size: 12px; letter-spacing: .04em; }
.legal-main h2 {
  margin: 52px 0 14px; font-size: 24px; line-height: 1.2; letter-spacing: -.035em; font-weight: 650;
}
.legal-main h3 { margin: 30px 0 10px; font-size: 17px; letter-spacing: -.02em; font-weight: 650; }
.legal-main p, .legal-main li { color: var(--muted); font-size: 15px; line-height: 1.75; }
.legal-main ul, .legal-main ol { padding-left: 22px; display: grid; gap: 10px; }
.legal-main strong { color: var(--ink); }
.legal-main a { color: var(--green); text-decoration: underline; text-underline-offset: 2px; }
.legal-callout {
  margin: 34px 0; padding: 22px 24px; border-left: 3px solid var(--green); border-radius: 0 14px 14px 0;
  background: var(--cream);
}
.legal-callout p { margin: 0; }
.legal-toc { margin: 0 0 44px; padding: 22px 24px; border: 1px solid var(--line); border-radius: 16px; background: var(--cream); }
.legal-toc b { display: block; margin-bottom: 12px; color: var(--green); font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.legal-toc ul { margin: 0; padding: 0; list-style: none; gap: 8px; }
.legal-toc a { color: var(--ink); text-decoration: none; font-size: 13px; }
.legal-toc a:hover { color: var(--green); }

/* --------------------------------------------------------------------- footer */
footer { padding: 75px max(24px, calc((100% - 1420px) / 2)) 35px; background: var(--footer); color: #fff; }
.footer-main { display: grid; grid-template-columns: .7fr .8fr 1.5fr; gap: 70px; padding-bottom: 65px; }
.footer-brand { align-self: start; }
.footer-main > p { margin: 4px 0 0; color: #89998d; font-size: 12px; line-height: 1.65; }
.footer-links { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.footer-links > div { display: flex; flex-direction: column; gap: 12px; }
.footer-links b { margin-bottom: 5px; color: #66766a; font-size: 8px; letter-spacing: .13em; text-transform: uppercase; }
.footer-links a { color: #a8b5ab; font-size: 11px; }
.footer-links a:hover { color: #fff; }
.footer-disclosure { padding-top: 30px; border-top: 1px solid var(--line-dark-2); }
.footer-disclosure p { max-width: 1100px; margin: 0 0 20px; color: #9aaaa0; font-size: 10px; line-height: 1.7; }
.footer-disclosure div { display: flex; justify-content: space-between; gap: 20px; color: #9aaaa0; font-size: 10px; }

/* --------------------------------------------------------------------- responsive */
@media (max-width: 1100px) {
  .section { padding: 110px 0; }
  .band-inner { gap: 70px; }
  .faq-section { gap: 70px; }
  .footer-main { grid-template-columns: .65fr .7fr 1.65fr; gap: 40px; }
}
@media (max-width: 960px) {
  .desktop-nav { display: none; }
  .mobile-menu { display: block; }
  .hero { grid-template-columns: 1fr; padding-top: 56px; }
  .product-stage { min-height: 500px; }
  /* The 2vw left padding is a desktop nicety that never got reset, so the centred column sat
     ~8px right of the stage beneath it — visible as the whole hero being slightly off-axis. */
  .hero-copy { text-align: center; padding-left: 0; }
  .eyebrow, .hero-actions, .trust-row { justify-content: center; }
  .hero-lede { margin-left: auto; margin-right: auto; }
  .auth-main { grid-template-columns: 1fr; gap: 48px; padding-top: 48px; }
  .auth-card { margin: 0 auto; }
  .auth-aside { margin: 0 auto; }
}
@media (max-width: 820px) {
  .section { width: min(100% - 34px, 1420px); }
  .split-heading { grid-template-columns: 1fr; gap: 28px; align-items: start; }

  .band { padding: 110px 17px; }
  .band-inner { grid-template-columns: 1fr; gap: 65px; }
  .calculator-shell { grid-template-columns: 1fr; }
  .calculator-controls { border-right: 0; border-bottom: 1px solid #dfe4dc; }
  .pricing-grid { grid-template-columns: 1fr; max-width: 560px; margin-left: auto; margin-right: auto; gap: 24px; }
  .price-card > p { min-height: 0; }
  .faq-section { grid-template-columns: 1fr; }
  .faq-intro { position: static; }
  .footer-main { grid-template-columns: 1fr; }
  .footer-links { max-width: 580px; }
  .legal-main { width: min(100% - 34px, 820px); }
}
@media (max-width: 620px) {
  .site-header, .hero, .auth-main { width: min(100% - 30px, 1420px); }
  .site-header { height: 72px; }
  .brand { font-size: 16px; }
  .header-cta { padding: 0 12px; font-size: 11px; }
  .hero { gap: 42px; padding: 46px 0; }
  h1 { font-size: clamp(44px, 13vw, 62px); }
  .hero-lede { font-size: 16px; }
  .hero-actions { flex-direction: column; }
  .hero-actions .button { width: 100%; }
  .trust-row { gap: 10px 16px; }
  /* THE HERO ON A PHONE. Everything below is one problem: the stage was designed as a
   * decorative FRAME sitting behind a card, and on a 375px screen there is no room for a
   * frame. Measured on the live page before the fix — the numbers are the reason for each
   * rule, not decoration:
   *
   *   - the "Live from the catalogue" badge is absolutely positioned at top-left of the stage,
   *     and with the card taller than the stage's min-height there is no vertical slack, so the
   *     card's first line — the portfolio's name — started underneath it. Overlap measured at
   *     47px wide by 13px tall: the word ALPHA was behind the badge. The badge says the same
   *     thing as the kicker it was covering, so on a phone it simply goes.
   *   - the frame measured 32px left, 32px right, 0 top, 0 bottom: a green stripe down each
   *     side of a cream card, which reads as a mistake rather than a design. Worse, the card's
   *     drop shadow was being clipped away by the stage's `overflow: hidden`, flattening it.
   *     So on a phone the stage stops being a frame: no tint, no orbits (a fixed 610px ring
   *     inside a 345px box is two vertical smudges anyway), no clipping, and the card goes
   *     full-bleed to the hero's own gutters.
   *   - the two rings needed 275px on a 223px content box, stretching the card's grid column
   *     and squeezing the padding to 2px. They are sized down here so the row fits honestly.
   */
  /* THE NUMBERS GO ABOVE THE FOLD. In source order the phone showed eyebrow, a huge H1, a
   * six-line lede, two buttons and the trust row before the comparison card — the strongest
   * thing on the page sat two screens down. `display: contents` dissolves .hero-copy so its
   * children and the stage share one grid, and `order` puts the card straight after the
   * headline: claim, then proof, then the explanation and the buttons. */
  .hero { gap: 0; }
  .hero-copy { display: contents; }
  .eyebrow { order: 1; margin-bottom: 16px; }
  .hero h1 { order: 2; margin-bottom: 22px; }
  .product-stage { order: 3; }
  .hero-lede { order: 4; margin: 26px auto 0; }
  .hero-actions { order: 5; margin-top: 26px; }
  .trust-row { order: 6; margin-top: 22px; }

  .sticky-cta { display: inline-flex; }

  .product-stage {
    min-height: 0;
    border-radius: 0;
    background: none;
    overflow: visible;          /* the card's shadow was being clipped to nothing */
  }
  .product-stage::before, .stage-orbit, .stage-badge { display: none; }
  .vs-stage { width: 100%; padding: 26px 16px 22px; }
  .vs-pair { gap: 8px; }
  .vs-circle { width: 116px; height: 116px; border-width: 5px; }
  .vs-circle.bench { width: 94px; height: 94px; }
  .vs-circle b { font-size: 24px; }
  .vs-circle.bench b { font-size: 19px; }
  .vs-spark { height: 76px; }
  .vs-stats b { font-size: 11px; }

  .proof-strip { justify-content: center; }
  .proof-strip > span { display: none; }
  .proof-strip > div { gap: 8px; }
  .proof-strip i { width: 18px; }
  .section { padding: 88px 0; }
  .section-heading h2, .band-heading h2, .split-heading h2 { font-size: clamp(40px, 12vw, 54px); }
  .split-heading > p { font-size: 15px; }
  .catalogue-grid { margin-top: 45px; }
  .catalogue-grid { grid-template-columns: 1fr; }
  .model-card { padding: 21px; }
  .step-list li { min-height: 155px; grid-template-columns: 35px 1fr; gap: 13px; }
  .step-list p { font-size: 12px; }
  .performance-section { padding: 95px 15px; }
  .performance-heading { margin-bottom: 42px; }
  .calculator-shell { border-radius: 20px; }
  .calculator-controls, .calculator-results { padding: 24px 19px; }
  .result-topline { flex-direction: column; align-items: flex-start; }
  .result-topline h3 { overflow-wrap: anywhere; }
  .result-topline > span { white-space: normal; text-align: left; line-height: 1.4; }
  .result-metrics div + div { padding-left: 10px; }
  .result-metrics b { font-size: 10px; }
  .pricing-section { padding: 95px 17px; }
  .pricing-grid { margin-top: 48px; }
  .faq-list summary { min-height: 76px; font-size: 15px; }
  .faq-list details p { margin-right: 18px; }
  .start-section { min-height: 520px; padding: 90px 17px; }
  /* Full-width and stacked, like every other pair of buttons on a phone (`.hero-actions`). */
  .start-actions { flex-direction: column; align-self: stretch; }
  .start-actions .button { width: 100%; }
  .auth-card { padding: 26px 21px; }
  footer { padding: 58px 17px 28px; }
  .footer-main { gap: 35px; }
  .footer-links { grid-template-columns: repeat(2, 1fr); row-gap: 35px; }
  .footer-disclosure div { flex-direction: column; gap: 8px; }
}
@media (max-width: 380px) {
  .site-header .brand > span:last-child { display: none; }
  .mobile-menu nav { right: 15px; }
  .proof-strip > div { gap: 13px; flex-wrap: wrap; justify-content: center; }
  .proof-strip > div i { display: none; }
}


/* Both doors on the landing page. Early access is the loud one; signing in is quiet but present
   — a visitor who has been told to sign up needs somewhere to do it, and the header CTA alone
   sent them to a form that only writes a lead row. */
.header-cta-quiet {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
  margin-left: 8px;
}
.header-cta-quiet:hover { background: var(--cream); }
.hero-alt {
  margin: 14px 0 0;
  font-size: 14px;
  color: var(--muted);
}
.hero-alt a { color: var(--green); text-decoration: underline; }
