:root {
  /* Surfaces */
  --white: #ffffff;
  --surface-warm: #faf8f5;
  --surface-warm-2: #f3f1ee;

  /* Brand — deep plum */
  --plum: #5b365d;
  --plum-dark: #3e2541;
  --plum-soft: #eee7ef;
  --plum-light: #f7f2f7;

  /* Neutral text */
  --text-primary: #202124;
  --text-secondary: #64666b;
  /* Darkened from #8a8d92 in the Stage 7 QA pass: the old value measured
     ~3.1-3.3:1 on white, below the WCAG 2.2 AA 4.5:1 floor for the small
     label/caption text it's used on. #6a6d72 is ~5:1 on white and ~4.8:1
     on the warm surface. */
  --text-muted: #6a6d72;

  /* Lines */
  --border: #e8e8e8;
  --divider: #f0f0f0;

  /* Spacing scale */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-12: 48px;

  /* Radius */
  --r-btn: 14px;
  --r-tile: 18px;
  --r-input: 14px;
  --r-pill: 999px;

  --page-pad: 20px;
  --nav-h: 72px;

  /* ---------- Phase 3 — Warm Editorial Journey design tokens ---------- */
  /* Additive only: every token above is untouched, so Home/Journey/Search/
     Profile/Category/Guide (which reference --plum, --sp-*, --r-* etc.
     directly) render exactly as before. These new tokens back the Phase-3
     redesign of the onboarding-shell screens only (see the ".app.onboarding"
     rules near the end of this file) — see DESIGN_SYSTEM.md Section K. */

  /* Brand (aliases onto the existing plum family — no new hues introduced) */
  --brand-primary: var(--plum);
  --brand-deep: var(--plum-dark);
  --brand-muted: var(--plum-soft);
  --brand-soft: var(--plum-light);

  /* Background layers */
  --bg-page: var(--surface-warm);
  --bg-alt: var(--surface-warm-2);
  --bg-surface: var(--white);

  /* Borders */
  --line-subtle: var(--divider);
  --line-default: var(--border);
  --line-strong: #d9d5d1;

  /* Status (new — not previously tokenised; --status-danger refines the
     inline #a33 previously hardcoded on .auth-error into a documented,
     reusable value of the same hue) */
  --status-success: #2f6f4e;
  --status-success-soft: #eaf3ee;
  --status-danger: #a3352f;
  --status-danger-soft: #fbeceb;
  --status-info: var(--brand-primary);
  --status-info-soft: var(--brand-muted);

  /* Interaction */
  --interactive-hover: var(--plum-dark);
  --interactive-active: #2f1c31;

  /* Typography scale — used only within .app.onboarding in this phase */
  --font-display: "Familjen Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  --fs-eyebrow: 12.5px;
  --fs-caption: 12.5px;
  --fs-label: 13px;
  --fs-body-sm: 14px;
  --fs-body: 15.5px;
  --fs-body-lg: 17.5px;
  --fs-h4: 19px;
  --fs-h3: 22px;
  --fs-h2: 27px;
  --fs-h1: 31px;
  --fs-display: 36px;
  --lh-tight: 1.2;
  --lh-snug: 1.35;
  --lh-normal: 1.55;
  --lh-relaxed: 1.65;
  --tracking-tight: -0.01em;
  --tracking-wide: 0.03em;

  /* Motion */
  --ease-out-warm: cubic-bezier(0.16, 1, 0.3, 1);
  --motion-fast: 150ms;
  --motion-base: 220ms;

  /* Shadow — one soft level, used sparingly */
  --shadow-soft: 0 2px 20px rgba(62, 37, 65, 0.08);
}

/* Familjen Grotesk — self-hosted, per Phase 3.7 (DESIGN_SYSTEM.md Section T).
   Single variable-font file (wght 400-700), ~18.4KB, SIL OFL 1.1 licensed
   (see assets/fonts/OFL.txt) — no Google Fonts CDN request in production.
   Used only for brand/display headings (see the ".app.onboarding" rules
   further down); Inter remains the only font for functional UI, forms, and
   all 31 guides. font-display:swap avoids a render-blocking wait; no
   preload — display headings aren't the LCP element on any of these
   screens, so a preload isn't justified (see Section T for the measurement
   that backs this). */
@font-face {
  font-family: "Familjen Grotesk";
  src: url("assets/fonts/familjen-grotesk-variable.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* Inter — self-hosted too, as of the Stage 7 QA pass. Previously pulled from
   the Google Fonts CDN (fonts.googleapis.com / fonts.gstatic.com), which is
   an external request DESIGN_SYSTEM.md Section T rules out and a privacy /
   offline-resilience concern. Two variable subsets: latin (~48KB, the LCP
   text) and latin-ext (~85KB, only fetched when macron / accented text is on
   screen — matters for te reo Māori place names). SIL OFL 1.1, see
   assets/fonts/inter-OFL.txt. */
@font-face {
  font-family: "Inter";
  src: url("assets/fonts/inter-variable-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  src: url("assets/fonts/inter-variable-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--white);
  color: var(--text-primary);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
  line-height: 1.6;
}

button {
  font-family: inherit;
}

a {
  color: inherit;
}

/* Visually hidden but available to screen readers (Stage 7). */
.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;
}

/* One consistent keyboard-focus treatment for every interactive control —
   subtle, brand-coloured, never relies on color alone since it's a visible
   ring, not a color swap.
   Stage 7: the old ring was var(--plum) on a 2px offset. On the primary
   CTAs (which are themselves var(--plum)) that outline was effectively
   invisible — a WCAG 2.4.7 failure. Now: a deep-plum outline PLUS a 2px
   white halo hugging the element, so the ring reads on both the light
   surfaces and the plum/stage-coloured buttons. */
button:focus-visible,
a:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--plum-dark);
  outline-offset: 3px;
  box-shadow: 0 0 0 2px var(--white);
  border-radius: 4px;
}

.app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  position: relative;
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px) + var(--sp-4));
}

#view-root {
  padding: var(--sp-6) var(--page-pad) var(--sp-8);
}

/* ---------- Typography ---------- */
h1,
h2,
h3 {
  font-weight: 600;
  margin: 0;
  color: var(--text-primary);
}

.page-heading {
  font-size: 26px;
  font-weight: 600;
  margin: 0 0 var(--sp-1);
}

.page-sub {
  font-size: 15px;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-6);
}

.section-heading {
  font-size: 20px;
  font-weight: 600;
  margin: 0 0 var(--sp-3);
}

/* ---------- Page header (back + title) ---------- */
.page-header {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}

.back-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-btn);
  border: none;
  background: var(--surface-warm);
  color: var(--text-primary);
  cursor: pointer;
  flex-shrink: 0;
}

.back-btn:hover {
  background: var(--surface-warm-2);
}

.page-header h1 {
  font-size: 22px;
}

/* ---------- Home header ---------- */
.home-brand-mark {
  height: 20px;
  width: auto;
  display: block;
  margin: 0 0 var(--sp-3);
}

.home-header {
  margin-bottom: var(--sp-6);
}

.greeting {
  font-size: 26px;
  font-weight: 600;
  margin: 0 0 2px;
}

.greeting-sub {
  font-size: 15px;
  color: var(--text-secondary);
  margin: 0;
}

/* ---------- Progress ---------- */
.progress-block {
  margin: var(--sp-6) 0;
}

.progress-block .row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--sp-2);
}

.progress-block .label {
  font-size: 14px;
  color: var(--text-secondary);
  font-weight: 500;
}

.progress-block .pct {
  font-size: 14px;
  font-weight: 600;
  color: var(--plum);
}

.progress-track {
  height: 8px;
  border-radius: var(--r-pill);
  background: var(--plum-soft);
  overflow: hidden;
}

.progress-track > .fill {
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--plum);
  transition: width 0.4s ease;
}

/* ---------- Featured task ---------- */
.featured-task {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--plum-light);
  border: none;
  border-radius: var(--r-tile);
  padding: var(--sp-6);
  cursor: pointer;
  margin-bottom: var(--sp-6);
}

.featured-task .eyebrow {
  font-size: 13px;
  font-weight: 600;
  color: var(--plum);
  margin: 0 0 var(--sp-2);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.featured-task h3 {
  font-size: 19px;
  margin: 0 0 var(--sp-2);
}

.featured-task p {
  font-size: 14.5px;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-4);
  line-height: 1.55;
}

.featured-task .foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.time-chip {
  font-size: 13px;
  color: var(--plum-dark);
  background: var(--plum-soft);
  padding: 4px 10px;
  border-radius: var(--r-pill);
  font-weight: 500;
}

.cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--plum);
  color: var(--white);
  font-size: 14px;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: var(--r-btn);
  border: none;
}

.all-caught-up {
  background: var(--surface-warm);
  border-radius: var(--r-tile);
  padding: var(--sp-6);
  margin-bottom: var(--sp-6);
  text-align: center;
}

.all-caught-up h3 {
  font-size: 18px;
  margin-bottom: var(--sp-1);
}

.all-caught-up p {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 0;
}

/* ---------- Secondary next steps (rows) ---------- */
.next-steps {
  margin-bottom: var(--sp-8);
}

.step-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  background: none;
  border: none;
  border-bottom: 1px solid var(--divider);
  padding: var(--sp-4) 0;
  text-align: left;
  cursor: pointer;
}

.step-row:last-child {
  border-bottom: none;
}

.step-row .icon-wrap {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  background: var(--surface-warm);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--plum);
  flex-shrink: 0;
}

.step-row .txt {
  flex: 1;
  min-width: 0;
}

.step-row .txt .t {
  font-size: 15px;
  font-weight: 500;
  margin: 0;
}

.step-row .txt .m {
  font-size: 13px;
  color: var(--text-muted);
  margin: 2px 0 0;
}

.step-row .chev {
  color: var(--text-muted);
  flex-shrink: 0;
}

/* ---------- Big tiles (Explore by area) ---------- */
.tile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
}

.tile {
  display: block;
  text-align: left;
  border: none;
  border-radius: var(--r-tile);
  padding: var(--sp-4);
  cursor: pointer;
  min-height: 128px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.tile.v-white {
  background: var(--white);
  border: 1px solid var(--border);
}

.tile.v-warm {
  background: var(--surface-warm);
}

.tile.v-plum {
  background: var(--plum-light);
}

.tile .icon-wrap {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--plum);
  margin-bottom: var(--sp-6);
}

.tile.v-white .icon-wrap {
  background: var(--surface-warm);
}

.tile .name {
  font-size: 15.5px;
  font-weight: 600;
  margin: 0 0 3px;
}

.tile .desc {
  font-size: 12.5px;
  color: var(--text-secondary);
  margin: 0;
  line-height: 1.4;
}

.tile .tile-progress {
  margin-top: var(--sp-3);
  height: 4px;
  border-radius: var(--r-pill);
  background: rgba(91, 54, 93, 0.12);
  overflow: hidden;
}

.tile .tile-progress > .fill {
  height: 100%;
  background: var(--plum);
  border-radius: var(--r-pill);
}

/* Reference-only categories (no tracked tasks) show a neutral count instead
   of a progress bar — a 0% bar would falsely read as unfinished. */
.tile .tile-meta {
  margin-top: var(--sp-3);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-muted);
}

/* ---------- Category detail: item rows ---------- */
.item-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4) 0;
  border-bottom: 1px solid var(--divider);
}

.item-row:last-child {
  border-bottom: none;
}

.item-row input[type="checkbox"] {
  appearance: none;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  border: 1.5px solid var(--border);
  flex-shrink: 0;
  margin-top: 1px;
  cursor: pointer;
  display: grid;
  place-content: center;
  background: var(--white);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.item-row input[type="checkbox"]::after {
  content: "";
  width: 12px;
  height: 12px;
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  background: var(--white);
  transform: scale(0);
  transition: transform 0.12s ease;
}

.item-row input[type="checkbox"]:checked {
  background: var(--plum);
  border-color: var(--plum);
}

.item-row input[type="checkbox"]:checked::after {
  transform: scale(1);
}

.item-row .txt {
  flex: 1;
  min-width: 0;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
}

.item-row .txt h3 {
  font-size: 16px;
  font-weight: 600;
  margin: 0;
}

.item-row.done .txt h3 {
  color: var(--text-muted);
  text-decoration: line-through;
  font-weight: 500;
}

.item-row .txt p {
  font-size: 14px;
  color: var(--text-secondary);
  margin: var(--sp-1) 0 0;
  line-height: 1.5;
}

.item-row .txt .meta-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}

.item-row .txt .meta-row .mins {
  font-size: 12.5px;
  color: var(--text-muted);
}

.item-row .txt .view-steps {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 12.5px;
  color: var(--plum);
  font-weight: 600;
}

.category-blurb {
  font-size: 14.5px;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-6);
}

/* ---------- Item detail (guide) ---------- */
.item-eyebrow {
  font-size: 13px;
  font-weight: 600;
  color: var(--plum);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 var(--sp-2);
}

/* Journey-stage eyebrow. Stage 7: was inline-styled with the raw stage
   colour (e.g. #c9622b ~3.4:1 on white — fails AA). Uses the deep plum
   instead; stage identity is still carried by the trail, step numbers and
   the "Stage N · name" text itself. */
.item-eyebrow--stage {
  color: var(--plum-dark);
}

.item-title {
  font-size: 24px;
  font-weight: 600;
  margin: 0 0 var(--sp-3);
  line-height: 1.3;
}

.item-intro {
  font-size: 15.5px;
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0 0 var(--sp-8);
}

.step-list {
  margin-bottom: var(--sp-6);
}

.step {
  display: flex;
  gap: var(--sp-3);
  padding-bottom: var(--sp-6);
  position: relative;
}

.step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 30px;
  bottom: 4px;
  width: 1px;
  background: var(--divider);
}

.step-num {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--stage-soft, var(--plum-soft));
  /* Stage 7: was var(--stage-color) — the raw stage hue on the pale
     stage-soft tint fell below 4.5:1. Deep plum on the tint is ~8:1. */
  color: var(--plum-dark);
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.step-body h2 {
  font-size: 15.5px;
  font-weight: 600;
  margin: 2px 0 4px;
}

.step-body p {
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.55;
  margin: 0;
}

.step-body ul {
  margin: var(--sp-2) 0 0;
  padding-left: 18px;
}

.step-body ul li {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin-bottom: 3px;
}

.fact-list {
  margin-bottom: var(--sp-6);
}

.fact-row {
  padding: 10px 0;
  border-bottom: 1px solid var(--divider);
  font-size: 14px;
}

.fact-row:last-child {
  border-bottom: none;
}

.fact-row .fact-label {
  display: block;
  color: var(--text-muted);
  font-size: 12.5px;
  margin-bottom: 3px;
}

.fact-row > span:last-child {
  color: var(--text-primary);
  font-weight: 500;
  line-height: 1.5;
}

.trust-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--surface-warm);
  border-radius: var(--r-input);
  padding: var(--sp-3) var(--sp-4);
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: var(--sp-6);
}

.trust-row.verified {
  background: var(--plum-light);
}

.trust-row svg {
  color: var(--text-muted);
  flex-shrink: 0;
}

.trust-row.verified svg {
  color: var(--plum);
}

.trust-row a {
  color: var(--plum-dark);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  /* Stage 7: was undecorated and the same colour as the body text — not
     clearly a link. Deep plum + underline reads as interactive; the small
     vertical padding gives it a taller tap target (it also sits inline in
     the "Verified information: …" sentence, so the WCAG 2.5.8 inline
     exception applies regardless). */
  display: inline-block;
  padding: 3px 0;
}

.mark-complete-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  background: var(--plum);
  color: var(--white);
  border: none;
  font-size: 15px;
  font-weight: 600;
  padding: 14px;
  border-radius: var(--r-btn);
  cursor: pointer;
}

.mark-complete-btn.done {
  background: var(--plum-soft);
  color: var(--plum-dark);
}

/* ---------- Plan view rows ---------- */
.plan-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  background: none;
  border: none;
  border-bottom: 1px solid var(--divider);
  padding: var(--sp-4) 0;
  text-align: left;
  cursor: pointer;
}

.plan-row:last-child {
  border-bottom: none;
}

.plan-row .icon-wrap {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--surface-warm);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--plum);
  flex-shrink: 0;
}

.plan-row.complete .icon-wrap {
  background: var(--plum-soft);
}

.plan-row .txt {
  flex: 1;
  min-width: 0;
}

.plan-row .txt .t {
  font-size: 15.5px;
  font-weight: 600;
  margin: 0 0 5px;
}

.plan-row .txt .track {
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--surface-warm-2);
  overflow: hidden;
}

.plan-row .txt .track > .fill {
  height: 100%;
  background: var(--plum);
  border-radius: var(--r-pill);
}

.plan-row .frac {
  font-size: 13px;
  color: var(--text-muted);
  flex-shrink: 0;
  min-width: 30px;
  text-align: right;
}

/* ---------- Ask view ---------- */
.ask-input {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--surface-warm);
  border-radius: var(--r-input);
  padding: var(--sp-3) var(--sp-4);
  color: var(--text-muted);
  margin-bottom: var(--sp-6);
}

.ask-input input {
  border: none;
  background: none;
  outline: none;
  font-size: 15px;
  flex: 1;
  color: var(--text-primary);
  font-family: inherit;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}

.chip {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  /* Stage 7: min tap target (was ~34px tall). */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  font-size: 13.5px;
  color: var(--text-primary);
  cursor: pointer;
}

/* ---------- Account / auth ---------- */
.auth-input {
  width: 100%;
  max-width: 320px;
  margin-bottom: var(--sp-4);
}

.auth-input input {
  border: none;
  background: none;
  outline: none;
  font-size: 15px;
  flex: 1;
  min-width: 0;
  color: var(--text-primary);
  font-family: inherit;
}

.auth-hint {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.5;
  margin: var(--sp-2) 0 var(--sp-4);
  max-width: 320px;
}

.auth-error {
  font-size: 13.5px;
  color: #a33;
  margin: 0 0 var(--sp-3);
  max-width: 320px;
}

.account-block {
  background: var(--surface-warm);
  border-radius: var(--r-tile);
  padding: var(--sp-4);
  margin-bottom: var(--sp-4);
}

.account-label {
  font-size: 12.5px;
  color: var(--text-muted);
  margin: 0 0 2px;
}

.account-email {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 var(--sp-2);
  word-break: break-word;
}

.account-status {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--plum);
  margin: 0;
  line-height: 1.5;
}

.account-status.muted {
  color: var(--text-secondary);
  font-weight: 400;
}

/* ---------- Search results ---------- */
.step-row.search-result {
  align-items: flex-start;
  padding: var(--sp-4) 0;
}

.step-row.search-result .icon-wrap {
  margin-top: 2px;
}

.result-eyebrow {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 3px;
}

.step-row.search-result .txt .t {
  font-size: 15.5px;
  font-weight: 600;
  margin: 0;
}

.result-desc {
  font-size: 13.5px;
  color: var(--text-secondary);
  line-height: 1.45;
  margin: 3px 0 0;
}

#search-popular .section-label {
  margin-bottom: var(--sp-3);
}

.ask-note {
  background: var(--surface-warm);
  border-radius: var(--r-tile);
  padding: var(--sp-4);
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.6;
}

/* ---------- Profile view ---------- */
.profile-summary {
  background: var(--surface-warm);
  border-radius: var(--r-tile);
  padding: var(--sp-6);
  margin-bottom: var(--sp-6);
  text-align: center;
}

.profile-summary .big-pct {
  font-size: 36px;
  font-weight: 600;
  color: var(--plum);
  margin: 0;
}

.profile-summary .lbl {
  font-size: 14px;
  color: var(--text-secondary);
  margin: var(--sp-1) 0 0;
}

.profile-note {
  background: var(--plum-light);
  border-radius: var(--r-tile);
  padding: var(--sp-4);
  font-size: 14px;
  color: var(--plum-dark);
  line-height: 1.6;
  margin-bottom: var(--sp-6);
}

.text-btn {
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 14px;
  text-decoration: underline;
  cursor: pointer;
  /* Stage 7: give standalone text buttons a real ~44px tap target
     (they were ~17px tall). Inline-flex keeps them sitting like text. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
}

/* ---------- Bottom nav ---------- */
.bottom-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--white);
  border-top: 1px solid var(--divider);
  display: flex;
  max-width: 480px;
  margin: 0 auto;
  z-index: 20;
}

.nav-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 8px 0 12px;
}

.nav-btn .label {
  font-size: 11px;
  font-weight: 500;
}

.nav-btn.active {
  color: var(--plum);
}

/* Home uses the real AfterLanding brand mark (raster, true colors) instead of
   the outline icon set. Sized by height only so its natural aspect ratio
   (~0.79) is preserved — never stretched to a square like the other icons. */
.brand-home-icon {
  height: 29px;
  width: auto;
  display: block;
  filter: grayscale(1) opacity(0.55);
}

.nav-btn.active .brand-home-icon {
  filter: none;
}

/* ---------- Onboarding shell ---------- */
.app.onboarding {
  padding-bottom: var(--sp-6);
}

.onboard-shell {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-top: var(--sp-8);
  min-height: calc(100vh - var(--sp-12));
}

.brand-mark {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: var(--plum-soft);
  color: var(--plum);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--sp-6);
}

/* ---------- Consistent small AfterLanding branding ---------- */
/* Centred-column screens (onboarding/payoff/paywall/auth/checkout): a tiny
   mark above the screen's own status icon. Deliberately small — see
   brandTopmark() in app.js. Sits above .brand-mark, which had its own
   bottom margin trimmed slightly so this doesn't add much net height on
   space-tight screens (paywall, OTP entry). */
.brand-topmark {
  height: 18px;
  width: auto;
  display: block;
  margin: 0 auto var(--sp-2);
}

/* Row-header screens (Journey/category/guide/Search/Profile, via
   renderHomeBtn()): sits beside the existing "Home" pill at the top-right,
   adding no new row/height at all. */
.topbar-brand-group {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.topbar-brand-mark {
  height: 20px;
  width: auto;
  flex-shrink: 0;
}

.brand-mark.done-mark {
  background: var(--plum);
  color: var(--white);
}

.welcome-logo {
  width: min(72%, 260px);
  height: auto;
  margin-bottom: var(--sp-8);
}

.onboard-illustration {
  margin-bottom: var(--sp-8);
}

.onboard-heading {
  font-size: 30px;
  font-weight: 600;
  line-height: 1.25;
  margin: 0 0 var(--sp-3);
  max-width: 320px;
}

.onboard-sub {
  font-size: 16px;
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0 0 var(--sp-8);
  max-width: 320px;
}

.cta-full {
  display: block;
  width: 100%;
  background: var(--plum);
  color: var(--white);
  border: none;
  font-size: 16px;
  font-weight: 600;
  padding: 15px;
  border-radius: var(--r-btn);
  cursor: pointer;
  margin-bottom: var(--sp-3);
  text-align: center;
  text-decoration: none;
  box-sizing: border-box;
  transition: opacity 0.15s ease;
}

.cta-full:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.action-primary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: var(--sp-2);
}

/* ---------- Guide detail sections ---------- */
.who-block {
  margin-bottom: var(--sp-4);
}

.who-block p {
  font-size: 14.5px;
  color: var(--text-secondary);
  margin: 0 0 4px;
  line-height: 1.55;
}

.who-block .eligibility {
  color: var(--text-muted);
  font-size: 13.5px;
}

.need-list {
  list-style: none;
  margin: 0 0 var(--sp-6);
  padding: 0;
}

.need-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: 14.5px;
  color: var(--text-primary);
  padding: 7px 0;
}

.need-list li svg {
  color: var(--plum);
  flex-shrink: 0;
  margin-top: 2px;
}

.where-block {
  font-size: 14.5px;
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0 0 var(--sp-6);
}

.section-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 var(--sp-2);
}

.other-actions {
  margin-bottom: var(--sp-6);
}

.action-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
  margin-bottom: 8px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--text-primary);
  text-decoration: none;
}

.action-row svg {
  color: var(--text-muted);
  flex-shrink: 0;
}

.trouble-list {
  margin-bottom: var(--sp-2);
}

.trouble-row {
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--divider);
}

.trouble-row:last-child {
  border-bottom: none;
}

.trouble-row .q {
  font-size: 14.5px;
  font-weight: 600;
  margin: 0 0 4px;
}

.trouble-row .a {
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.55;
  margin: 0;
}

.next-note {
  font-size: 14px;
  color: var(--text-secondary);
  line-height: 1.6;
  margin: 0 0 var(--sp-6);
}

.next-note .fact-label {
  display: block;
  font-size: 12.5px;
  color: var(--text-muted);
  margin-bottom: 3px;
}

/* ---------- Questionnaire ---------- */
.q-header {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-bottom: var(--sp-8);
}

.q-progress {
  flex: 1;
}

.q-count {
  font-size: 13px;
  color: var(--text-muted);
  font-weight: 500;
  display: block;
  margin-bottom: 6px;
}

.q-track {
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--divider);
  overflow: hidden;
}

.q-track > .fill {
  height: 100%;
  background: var(--plum);
  border-radius: var(--r-pill);
  transition: width 0.3s ease;
}

.q-prompt {
  font-size: 26px;
  font-weight: 600;
  line-height: 1.3;
  margin: 0 0 var(--sp-2);
}

.q-sub {
  font-size: 15px;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-6);
}

.option-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  /* Generous bottom clearance so the fixed .q-cta-bar (~100px + safe-area)
     never covers the last option — better a little extra whitespace than a
     hidden choice. */
  margin: var(--sp-6) 0 140px;
}

.option-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: var(--r-btn);
  padding: 16px 18px;
  font-size: 16px;
  font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.option-row.selected {
  border-color: var(--plum);
  background: var(--plum-light);
  color: var(--plum-dark);
}

.option-row.selected svg {
  color: var(--plum);
}

/* Reveals the less-common options on a long question — deliberately plainer
   than .option-row so it doesn't read as a selectable choice itself. */
.option-more-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  background: none;
  border: 1.5px dashed var(--border);
  border-radius: var(--r-btn);
  padding: 12px 18px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
}

.option-more-btn svg {
  transform: rotate(90deg);
}

/* Continue stays fixed to the viewport bottom so it's never something the
   user has to scroll to discover — the question/options above scroll
   normally underneath it if they don't fit. Same fixed+max-width+centred
   technique as .bottom-nav, so it lines up identically on wide screens. */
.q-cta-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-width: 480px;
  margin: 0 auto;
  background: var(--white);
  border-top: 1px solid var(--divider);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06);
  padding: var(--sp-4) var(--page-pad) calc(var(--sp-4) + env(safe-area-inset-bottom, 0px));
  /* Above .bottom-nav's z-index (20): that element stays in the DOM with its
     own solid background even when emptied out during onboarding/paywall
     screens (render() sets its innerHTML to "", not display:none), so
     without this these bars would be covered by it. */
  z-index: 25;
}

.q-cta-bar .cta-full {
  margin-bottom: 0;
}

/* ---------- Generating ---------- */
.spinner {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 3px solid var(--plum-soft);
  border-top-color: var(--plum);
  animation: spin 0.8s linear infinite;
  margin-bottom: var(--sp-4);
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.generating-text {
  font-size: 15px;
  color: var(--text-secondary);
}

/* ---------- Payoff ---------- */
.payoff-section {
  width: 100%;
  max-width: 320px;
  text-align: left;
  margin-bottom: var(--sp-6);
}

.payoff-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 var(--sp-3);
}

.payoff-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: 15px;
  font-weight: 500;
  padding: 10px 0;
  border-bottom: 1px solid var(--divider);
}

.payoff-row:last-child {
  border-bottom: none;
}

.payoff-row.done {
  color: var(--text-muted);
  font-weight: 400;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.dot.todo {
  background: var(--plum);
}

.dot.done {
  background: var(--border);
}

.profile-divider {
  height: 1px;
  background: var(--divider);
  margin: var(--sp-4) 0;
}

/* ---------- Paywall / preview / locked guide ---------- */
.unlock-shell .mini-trail {
  margin: var(--sp-2) 0 var(--sp-6);
}

/* The purchase block now lives in normal flow, right under the headline/
   context line (see renderUnlockScreen in app.js), so price + CTA are
   visible on a normal mobile screen without scrolling at all — no fixed/
   sticky positioning needed. Reuses the plain .unlock-card styling already
   defined below (shared with the locked-guide inline prompt). */

/* "Already purchased?" — a plain-language nudge toward sign-in, not a scary
   account-recovery message. Visible, but clearly secondary to the purchase
   CTA above it. */
.returning-customer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 14px;
  color: var(--text-secondary);
}

.returning-customer .text-btn {
  font-weight: 600;
  color: var(--plum-dark);
}

.unlock-benefits {
  text-align: left;
}

.locked-highlight-list {
  list-style: none;
  margin: 0;
  padding: 0;
  text-align: left;
}

.locked-highlight-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: 14.5px;
  color: var(--text-primary);
  padding: 7px 0;
  line-height: 1.4;
}

.locked-highlight-list li svg {
  color: var(--plum);
  flex-shrink: 0;
  margin-top: 2px;
}

.locked-guide-card {
  background: var(--surface-warm);
  border-radius: var(--r-tile);
  padding: var(--sp-4) var(--sp-4) var(--sp-2);
  margin-bottom: var(--sp-6);
}

.unlock-card {
  /* Calm hairline card, not a filled block — matches the paywall screen's
     Phase 3.7 treatment, now applied everywhere .unlock-card appears
     (including the locked-guide preview), per Phase 4 §H "use the same
     premium paywall language already approved." */
  background: var(--bg-surface);
  border: 1px solid var(--line-default);
  border-radius: var(--r-tile);
  padding: var(--sp-6) var(--sp-6) var(--sp-4);
  margin: var(--sp-2) 0 var(--sp-3);
  text-align: center;
}

.unlock-card-price {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--plum-dark);
  margin: 0 0 2px;
}

.unlock-card-sub {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-4);
}

.unlock-card .cta-full {
  margin-bottom: var(--sp-3);
}

.unlock-card-note {
  font-size: 12.5px;
  color: var(--text-secondary);
  margin: 0;
  line-height: 1.5;
}

.unlock-trust-line {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: 12.5px;
  color: var(--text-secondary);
  margin: var(--sp-2) 0 0;
}

.unlock-trust-line a {
  color: var(--text-secondary);
  text-decoration: underline;
}

/* Home's single, subtle unlock prompt for preview users */
.preview-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  width: 100%;
  background: var(--plum-light);
  border: none;
  border-radius: var(--r-input);
  padding: 12px 14px;
  margin-bottom: var(--sp-3);
  cursor: pointer;
  text-align: left;
}

.preview-banner-txt {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--plum-dark);
}

.preview-badge {
  flex-shrink: 0;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--white);
  background: var(--plum);
  border-radius: var(--r-pill);
  padding: 3px 8px;
}

.preview-banner-price {
  flex-shrink: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--plum-dark);
}

/* Sparing lock indicator on category rows — never a large overlay */
.lock-indicator {
  display: flex;
  color: var(--text-muted);
  flex-shrink: 0;
}

/* ==================================================
   The settlement journey — stage hero, path, nodes
   ================================================== */

.stage-hero {
  background: linear-gradient(180deg, var(--stage-soft) 0%, var(--white) 100%);
  border-radius: 0 0 28px 28px;
  margin: calc(-1 * var(--sp-6)) calc(-1 * var(--page-pad)) var(--sp-6);
  padding: var(--sp-6) var(--page-pad) var(--sp-6);
}

.stage-hero-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
}

.stage-eyebrow {
  font-size: 13px;
  font-weight: 600;
  /* Stage 7: stage-hue label text failed AA on the hero tint. Stage identity
     is carried by the hero gradient, the trail nodes and the "Stage N" text
     itself; the label reads in deep plum. */
  color: var(--plum-dark);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 6px;
}

.stage-name {
  font-size: 30px;
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 6px;
}

.stage-tagline {
  font-size: 15px;
  color: var(--text-secondary);
  margin: 0;
  max-width: 92%;
  line-height: 1.5;
}

.stage-illus {
  flex-shrink: 0;
  margin-left: var(--sp-3);
}

.stage-progress-row {
  margin-top: var(--sp-6);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stage-dashes {
  display: flex;
  gap: 4px;
}

.dash {
  flex: 1;
  height: 5px;
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, 0.08);
}

.dash.completed {
  background: var(--stage-color);
}

.dash.current {
  background: var(--stage-color);
  height: 7px;
}

.dash.doLater {
  background: var(--text-muted);
  opacity: 0.35;
}

.stage-progress-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
}

.deferred-note {
  font-size: 13.5px;
  color: var(--text-secondary);
  background: var(--surface-warm);
  padding: 10px 14px;
  border-radius: var(--r-input);
  margin: 0 0 var(--sp-3);
}

/* ---------- Primary next action ---------- */
.primary-task {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--stage-soft);
  border: none;
  border-radius: 20px;
  padding: var(--sp-6);
  margin: var(--sp-2) 0 4px;
  cursor: pointer;
}

.primary-task .you-here {
  display: block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  /* Stage 7: was var(--stage-color) on the stage-soft card (~3.4:1). */
  color: var(--plum-dark);
  margin-bottom: 8px;
}

.primary-task h2 {
  font-size: 20px;
  font-weight: 600;
  margin: 0 0 6px;
}

.primary-task p {
  font-size: 14.5px;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-4);
  line-height: 1.55;
}

.primary-task-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}

.primary-task .time-chip {
  background: var(--white);
  /* Stage 7: was var(--stage-color) on white (~4:1). */
  color: var(--plum-dark);
}

.primary-task .cta {
  /* Stage 7: white CTA text on the raw stage hue measured ~4:1. Same
     darkening overlay as .done-btn keeps the stage colour, clears AA. */
  background: linear-gradient(0deg, rgba(28, 12, 20, 0.26), rgba(28, 12, 20, 0.26)),
    var(--stage-color);
}

.arrival-note {
  font-size: 12.5px;
  font-style: italic;
  color: var(--text-muted);
  margin: 0 0 var(--sp-3);
}

.do-later-link {
  display: block;
  width: 100%;
  text-align: center;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 14px;
  padding: var(--sp-2) 0 var(--sp-8);
  cursor: pointer;
  text-decoration: underline;
}

/* ---------- Journey path ---------- */
.path-heading {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 var(--sp-3);
}

.journey-path {
  display: flex;
  flex-direction: column;
  margin-bottom: var(--sp-6);
}

.journey-path.compact {
  margin: var(--sp-2) 0 var(--sp-4);
}

.path-node {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: none;
  border: none;
  text-align: left;
  width: 100%;
  padding: 9px 0;
  cursor: pointer;
  position: relative;
}

.path-node:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 8px;
  top: 26px;
  bottom: -5px;
  width: 1.5px;
  background: var(--divider);
}

.node-dot {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  flex-shrink: 0;
  margin-top: 2px;
  transition: all 0.2s ease;
}

.path-node.completed .node-dot {
  background: var(--stage-color);
  border-color: var(--stage-color);
}

.path-node.current .node-dot {
  width: 21px;
  height: 21px;
  border-color: var(--stage-color);
  background: var(--stage-soft);
  box-shadow: 0 0 0 3px var(--stage-soft);
  margin-top: 0;
}

.path-node.doLater .node-dot {
  border-style: dashed;
  border-color: var(--text-muted);
}

.node-label {
  flex: 1;
  min-width: 0;
  padding-top: 1px;
}

.node-title {
  display: block;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-primary);
}

.path-node.completed .node-title {
  color: var(--text-muted);
  text-decoration: line-through;
  font-weight: 400;
}

.path-node.current .node-title {
  font-size: 15.5px;
  font-weight: 600;
}

.path-node.doLater .node-title {
  color: var(--text-muted);
}

.node-tag {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-top: 2px;
}

.path-node.current .node-tag {
  /* Stage 7: was var(--stage-color) (~3.4:1 on white). */
  color: var(--plum-dark);
}

.path-node.doLater .node-tag {
  color: var(--text-muted);
}

/* ---------- Other stages ---------- */
.other-stages {
  margin: var(--sp-6) 0;
}

.stage-row-block {
  margin-bottom: 2px;
}

.stage-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  background: none;
  border: none;
  border-top: 1px solid var(--divider);
  padding: 14px 0;
  cursor: pointer;
  text-align: left;
}

.stage-row-num {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--surface-warm);
  /* Stage 7: was var(--stage-color) on the warm surface (~3.3:1). */
  color: var(--plum-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  flex-shrink: 0;
}

.stage-row-txt {
  flex: 1;
  min-width: 0;
}

.stage-row-name {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}

.stage-row-meta {
  display: block;
  font-size: 12.5px;
  color: var(--text-muted);
  margin-top: 2px;
}

.stage-row-chev {
  display: flex;
  color: var(--text-muted);
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.stage-row.expanded .stage-row-chev {
  transform: rotate(90deg);
}

.browse-footer {
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--divider);
}

.all-caught-up-hero {
  text-align: center;
  padding: var(--sp-12) 0 var(--sp-8);
}

.all-caught-up-hero h1 {
  font-size: 26px;
  font-weight: 600;
  margin: var(--sp-4) 0 var(--sp-2);
}

.all-caught-up-hero p {
  font-size: 15px;
  color: var(--text-secondary);
  margin: 0;
}

/* ---------- Guide page: meta + tri-state rows ---------- */
.item-meta-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--text-muted);
  font-weight: 500;
  margin: 4px 0 var(--sp-4);
}

.dot-sep {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--text-muted);
}

.item-row-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  background: none;
  border: none;
  border-bottom: 1px solid var(--divider);
  padding: 14px 0;
  cursor: pointer;
  text-align: left;
}

.item-row-btn:last-child {
  border-bottom: none;
}

.status-dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  flex-shrink: 0;
}

.status-dot.completed {
  background: var(--plum);
  border-color: var(--plum);
}

.status-dot.doLater {
  border-style: dashed;
  border-color: var(--text-muted);
}

/* Reference guides aren't tracked — a plain label, not a progress dot. */
.ref-badge {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  background: var(--surface-warm);
  border-radius: var(--r-pill);
  padding: 5px 10px;
}

.item-row-btn .txt {
  flex: 1;
  min-width: 0;
}

.item-row-btn .txt h2 {
  font-size: 15.5px;
  font-weight: 600;
  margin: 0;
}

.item-row-btn.completed .txt h2 {
  color: var(--text-muted);
  text-decoration: line-through;
  font-weight: 500;
}

.item-row-btn .txt p {
  font-size: 13.5px;
  color: var(--text-secondary);
  margin: 3px 0 0;
  line-height: 1.45;
}

.item-row-btn .chev {
  color: var(--text-muted);
  flex-shrink: 0;
}

.already-done-note {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-warm);
  border-radius: var(--r-input);
  padding: 12px 14px;
  font-size: 14px;
  color: var(--text-secondary);
  margin-bottom: var(--sp-3);
}

.already-done-note svg {
  color: var(--plum);
  flex-shrink: 0;
}

.already-done-note #undo-complete-btn {
  margin-left: auto;
  font-size: 13px;
  flex-shrink: 0;
}

.cta-full.done-btn {
  /* Stage hue kept, but darkened with an overlay so white button text clears
     WCAG AA (4.5:1) for every stage colour — the raw stage-1 orange measured
     ~4:1 (Stage 7 QA). */
  background: linear-gradient(0deg, rgba(28, 12, 20, 0.26), rgba(28, 12, 20, 0.26)),
    var(--stage-color, var(--plum));
}

.do-later-btn {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: var(--sp-2);
}

/* ---------- Completion moments ---------- */
.task-complete-view,
.stage-complete-view {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.task-complete-view .back-btn,
.stage-complete-view .back-btn {
  align-self: flex-start;
  margin-bottom: var(--sp-6);
}

.task-complete-check {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--stage-color, var(--plum));
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: var(--sp-6) 0 var(--sp-6);
}

.stage-complete-illus {
  margin: var(--sp-4) 0 var(--sp-4);
}

.stage-complete-view .onboard-heading {
  max-width: 300px;
}

.next-stage-name {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 var(--sp-4);
}

/* ==================================================
   Home (light front door) — search entry + mini trail
   ================================================== */

.home-search {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: var(--surface-warm);
  border: none;
  border-radius: var(--r-input);
  padding: 13px 16px;
  color: var(--text-muted);
  font-size: 14.5px;
  cursor: pointer;
  margin-bottom: var(--sp-6);
}

.home-search svg {
  flex-shrink: 0;
}

.mini-trail {
  display: block;
  margin: 0 0 4px;
  overflow: visible;
}

.trail-node {
  cursor: pointer;
}

.trail-label {
  font-family: "Inter", sans-serif;
  font-size: 10.5px;
  font-weight: 500;
}

.trail-label.current {
  fill: var(--text-primary);
  font-weight: 600;
}

.trail-label.completed {
  fill: var(--text-secondary);
}

.trail-label.upcoming {
  fill: var(--text-muted);
}

.trail-progress-label {
  text-align: center;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-6);
}

.view-journey-link {
  display: block;
  width: 100%;
  text-align: center;
  margin: 4px 0 var(--sp-8);
}

.quick-help {
  padding-top: var(--sp-4);
  border-top: 1px solid var(--divider);
}

.all-done-mini {
  text-align: center;
  padding: var(--sp-8) 0 var(--sp-4);
  color: var(--text-secondary);
}

.all-done-mini svg {
  color: var(--plum);
  margin-bottom: var(--sp-3);
}

.all-done-mini p {
  font-size: 15px;
  margin: 0 0 var(--sp-4);
}

/* ---------- Global Home control (top of every non-Home screen) ---------- */
.home-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  background: var(--surface-warm);
  border: none;
  border-radius: var(--r-pill);
  padding: 0 14px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-primary);
  cursor: pointer;
  flex-shrink: 0;
}

.home-btn svg {
  color: var(--plum);
  flex-shrink: 0;
}

.journey-topbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--sp-4);
}

/* =====================================================================
   PHASE 3 — WARM EDITORIAL JOURNEY
   Scoped entirely under ".app.onboarding" (set by render() in app.js
   whenever nav.view is one of TOP_LEVEL_VIEWS: welcome, question,
   generating, payoff, unlock, auth, checkout). This is a pre-existing hook
   already in the codebase — it covers exactly the onboarding-shell family
   of screens and NONE of Home / Journey / Search / Profile / Category /
   Guide, which live outside it. Every rule below is scoped this way
   deliberately, so this redesign cannot bleed into screens this phase was
   not approved to touch, even though several classes here (.cta-full,
   .text-btn, .onboard-heading, .payoff-row, .unlock-card, .ask-input,
   .auth-error) are also used by those other screens elsewhere in the file.
   See AFTERLANDING_UPGRADE.md / DESIGN_SYSTEM.md Phase 3 for the approved
   direction and scope. Only Welcome, Questionnaire, Payoff, Paywall, and
   Auth (email + OTP) were redesigned; "generating" and "checkout" inherit
   this base shell/typography/button refinement as a disclosed side effect
   of sharing the same shell classes, not as a separate redesign pass.
   ===================================================================== */

.app.onboarding {
  background: var(--bg-page);
}

.app.onboarding #view-root {
  animation: onboardFadeIn var(--motion-base) var(--ease-out-warm);
}

@keyframes onboardFadeIn {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ---------- Shell rhythm ---------- */
.app.onboarding .onboard-shell {
  padding-top: var(--sp-8);
  padding-bottom: var(--sp-6);
  justify-content: center;
}

/* Welcome specifically gets the tallest, most deliberate composition — its
   own modifier so Payoff/Paywall/Auth (also ".onboard-shell") aren't
   affected by this specific rule. */
.app.onboarding .onboard-shell.welcome-shell {
  justify-content: center;
  min-height: calc(100vh - var(--sp-8));
}

/* ---------- Brand lockup (Welcome) ---------- */
/* Composition-only treatment of the EXISTING logo asset — no new logo file
   is introduced here (see DESIGN_SYSTEM.md Section J: logo evolution is
   separate, future, approved work). This gives the existing mark more
   deliberate presence via spacing/rhythm rather than a new asset. */
.app.onboarding .welcome-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: var(--sp-8);
}

.app.onboarding .welcome-logo {
  width: min(58%, 220px);
  margin-bottom: 0;
}

.app.onboarding .welcome-illustration-wrap {
  margin: var(--sp-6) 0 var(--sp-8);
  opacity: 0.9;
}

/* ---------- Typography ---------- */
.app.onboarding .onboard-heading {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: 650;
  line-height: var(--lh-tight);
  letter-spacing: -0.015em;
  max-width: 340px;
  margin: 0 0 var(--sp-4);
}

.app.onboarding .onboard-heading.display {
  font-size: var(--fs-display);
  max-width: 320px;
}

.app.onboarding .onboard-sub {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-relaxed);
  color: var(--ink-secondary, var(--text-secondary));
  max-width: 300px;
  margin: 0 0 var(--sp-8);
}

.app.onboarding .eyebrow-label {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--ink-muted, var(--text-muted));
  margin: 0 0 var(--sp-2);
}

/* Small, quiet commercial line under the Welcome CTA — states the actual
   price/terms plainly (trust through specificity, DESIGN_SYSTEM.md
   Principle 5), not a marketing flourish. */
.app.onboarding .welcome-price-note {
  /* text-secondary, not text-muted: at this font size text-muted falls
     below 4.5:1 contrast on --bg-page (measured ~3.1:1) — see
     AFTERLANDING_UPGRADE.md accessibility checks. */
  font-size: var(--fs-caption);
  color: var(--text-secondary);
  margin: 0 0 var(--sp-6);
  letter-spacing: 0.01em;
}

/* ---------- Buttons ---------- */
.app.onboarding .cta-full {
  border-radius: var(--r-btn);
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: 0.005em;
  padding: 16px;
  transition: background var(--motion-fast) ease, opacity var(--motion-fast) ease,
    transform var(--motion-fast) ease;
}

.app.onboarding .cta-full:hover:not(:disabled) {
  background: var(--interactive-hover);
}

.app.onboarding .cta-full:active:not(:disabled) {
  background: var(--interactive-active);
  transform: scale(0.99);
}

.app.onboarding .text-btn {
  font-size: var(--fs-body-sm);
  font-weight: 600;
  color: var(--brand-deep);
  background: none;
  border: none;
  cursor: pointer;
  padding: var(--sp-2) 0;
}

/* ---------- Questionnaire ---------- */
.app.onboarding .q-header {
  margin-bottom: var(--sp-6);
}

.app.onboarding .q-count {
  /* text-secondary, not the base rule's text-muted — same contrast fix as
     the other captions in this block. */
  color: var(--text-secondary);
}

.app.onboarding .q-prompt {
  font-size: var(--fs-h2);
  font-weight: 650;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
}

.app.onboarding .q-sub {
  font-size: var(--fs-body);
  color: var(--text-secondary);
  line-height: var(--lh-normal);
}

.app.onboarding .option-row {
  border-radius: var(--r-btn);
  padding: 17px 18px;
  font-size: var(--fs-body);
  transition: border-color var(--motion-fast) ease, background var(--motion-fast) ease,
    color var(--motion-fast) ease;
}

.app.onboarding .option-row:hover:not(.selected) {
  border-color: var(--line-strong);
  background: var(--bg-alt);
}

.app.onboarding .option-row.selected {
  border-color: var(--brand-primary);
  background: var(--brand-soft);
  color: var(--brand-deep);
}

/* ---------- Payoff facts row ---------- */
/* Surfaces only what onboarding actually collected (city, stage) as a
   quiet proof-of-personalisation moment — no invented recommendation
   intelligence, per the approved Payoff spec. */
.app.onboarding .payoff-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  justify-content: center;
  margin: 0 0 var(--sp-6);
}

.app.onboarding .payoff-fact-chip {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--brand-deep);
  background: var(--brand-muted);
  border-radius: var(--r-pill);
  padding: 7px 14px;
}

/* The journey/progress motif on Payoff — a quiet visual bridge between "here's
   what we learned about you" (the facts chips above) and "here's your plan"
   (the priority list below). See DESIGN_SYSTEM.md's motif-usage audit for
   why this is one of only two places this motif appears. */
.app.onboarding .payoff-motif {
  margin: 0 0 var(--sp-6);
  opacity: 0.92;
}

.app.onboarding .payoff-label {
  /* text-secondary, not the base rule's text-muted: measured ~3.1:1 on
     bg-page, below 4.5:1 AA at this size. */
  font-size: var(--fs-label);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
}

.app.onboarding .payoff-row {
  font-size: var(--fs-body);
}

/* ---------- Paywall ---------- */
.app.onboarding .unlock-card {
  background: var(--bg-surface);
  border: 1px solid var(--line-default);
  box-shadow: none;
  border-radius: var(--r-tile);
  padding: var(--sp-6) var(--sp-6) var(--sp-4);
}

.app.onboarding .unlock-card-price {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}

.app.onboarding .unlock-card-sub {
  font-size: var(--fs-body-sm);
  color: var(--text-secondary);
}

/* New, factual trust line — only claims actually true today: Stripe is
   the real checkout processor, and the refund policy links to the real
   policy in legal.html. No invented guarantees (DESIGN_SYSTEM.md
   Principle 5 / the explicit instruction not to fabricate trust copy). */
.app.onboarding .unlock-trust-line {
  /* text-secondary, not text-muted: text-muted measures ~3.3:1 on white at
     this size, below the 4.5:1 AA floor — see AFTERLANDING_UPGRADE.md
     accessibility checks. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-caption);
  color: var(--text-secondary);
  margin: 0 0 var(--sp-2);
}

.app.onboarding .unlock-trust-line a {
  color: var(--text-secondary);
  text-decoration: underline;
}

/* ---------- Auth (email + OTP) ---------- */
.app.onboarding .ask-input.auth-input {
  background: var(--bg-surface);
  border: 1px solid var(--line-default);
  border-radius: var(--r-input);
  padding: 14px var(--sp-4);
  transition: border-color var(--motion-fast) ease;
}

.app.onboarding .ask-input.auth-input:focus-within {
  border-color: var(--brand-primary);
}

.app.onboarding .ask-input.auth-input input {
  font-size: var(--fs-body-lg);
}

/* OTP field reads more like a code entry surface, generously
   letter-spaced, rather than a plain text input. */
.app.onboarding #auth-otp-field {
  letter-spacing: 0.3em;
  font-weight: 600;
  font-size: 20px;
  text-align: center;
}

.app.onboarding .auth-error {
  color: var(--status-danger);
  background: var(--status-danger-soft);
  border-radius: var(--r-input);
  padding: var(--sp-2) var(--sp-3);
  max-width: 320px;
}

.app.onboarding .auth-hint {
  /* text-secondary, not the base rule's text-muted: same contrast fix as
     .payoff-label/.welcome-price-note/.unlock-trust-line above. */
  font-size: var(--fs-caption);
  color: var(--text-secondary);
}

/* ---------- Wider viewports (tablet/desktop) ---------- */
/* Scoped to the onboarding shell only (Phase 3.7 §10) — Home/Journey/Search/
   Profile/Category/Guide are untouched and still just centre-column at any
   width. This is deliberately light-touch: a soft radial wash behind the
   centred column so wide viewports read as "composed" rather than "a phone
   screen stranded in a big empty page" — not a desktop redesign. */
@media (min-width: 768px) {
  .app.onboarding {
    background: radial-gradient(ellipse 900px 700px at 50% 38%, rgba(201, 98, 43, 0.05), transparent 60%),
      radial-gradient(ellipse 700px 900px at 50% 65%, rgba(62, 37, 65, 0.05), transparent 65%),
      var(--bg-page);
    min-height: 100vh;
  }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  /* Stage 7: the earlier block only covered the onboarding shell. This
     global rule also neutralises the Phase 4 product-screen animations
     and transitions (view fades, mini-trail, hover states, etc.). */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .app.onboarding #view-root {
    animation: none;
  }
}

/* =====================================================================
   PHASE 4 — PRODUCT SCREENS (Home, Journey, Search, Profile, Category,
   Guide, locked-guide, bottom nav)
   Unlike the Phase 3 block above, these rules are NOT scoped under
   ".app.onboarding" — the classes touched here (.greeting, .page-header h1,
   .primary-task, .stage-name, .item-title, .item-row-btn, .profile-summary,
   .nav-btn, etc.) are exclusively used by these product screens and never
   appear inside the onboarding-shell family, so there is no shared-class
   bleed risk to guard against the way Phase 3 had to. Reuses the same
   :root tokens (colour/spacing/radius/motion) introduced in Phase 3 — no
   new arbitrary values were introduced (Phase 4 §N).
   ===================================================================== */

/* ---------- Typography: Familjen reserved for genuine brand/title
   moments only (screen titles, Home's greeting and next-step headline,
   Journey's stage name, a guide's own title, Profile's big percentage).
   Deliberately NOT applied to .item-row-btn h3 or .step-body h3 — those
   are repeated, functional list/step text, not brand moments (Phase 4 §P
   audit — see DESIGN_SYSTEM.md Section U for the full list of what was
   deliberately left in Inter and why). ---------- */
.page-header h1,
.page-heading,
.greeting,
.primary-task h2,
.stage-name,
.item-title,
.profile-summary .big-pct,
.onboard-heading {
  font-family: var(--font-display);
  letter-spacing: -0.01em;
}

/* ---------- Bottom navigation ---------- */
.nav-btn {
  /* text-secondary, not text-muted: measured ~3.3:1 on white, below the
     4.5:1 AA floor at this size — same fix as the Phase 3 captions. */
  color: var(--text-secondary);
  transition: color var(--motion-fast) ease;
  min-height: 44px;
}

.nav-btn.active {
  color: var(--brand-primary);
}

.nav-btn .label {
  font-weight: 600;
}

/* ---------- Home: next-step card ---------- */
.primary-task {
  border-radius: var(--r-tile);
  transition: transform var(--motion-fast) ease;
}

.primary-task:active {
  transform: scale(0.99);
}

.primary-task .you-here {
  font-family: "Inter", sans-serif;
  letter-spacing: var(--tracking-wide);
}

.home-search {
  transition: border-color var(--motion-fast) ease, background var(--motion-fast) ease;
}

.home-search:hover {
  background: var(--bg-alt);
}

/* ---------- List rows (Category / Journey stage lists / Search results):
   already divider-separated rather than individually boxed — refined here,
   not restructured (Phase 4 card-soup audit, DESIGN_SYSTEM.md Section U). ---------- */
.item-row-btn {
  transition: background var(--motion-fast) ease;
  border-radius: var(--r-btn);
  padding-left: var(--sp-2);
  padding-right: var(--sp-2);
  margin: 0 calc(var(--sp-2) * -1);
}

.item-row-btn:hover {
  background: var(--bg-alt);
}

.item-row-btn:last-child {
  border-bottom: none;
}

/* ---------- Chips (Home quick-help) ---------- */
.chip {
  transition: background var(--motion-fast) ease, border-color var(--motion-fast) ease;
}

.chip:hover {
  background: var(--bg-alt);
  border-color: var(--line-strong);
}

/* ---------- Profile: real onboarding facts, row-based (not another
   boxed card) per the Phase 4 "no card-soup" discipline. ---------- */
.profile-facts {
  margin-bottom: var(--sp-6);
}

.profile-fact-row {
  display: flex;
  justify-content: space-between;
  font-size: 14.5px;
  padding: 10px 0;
  border-bottom: 1px solid var(--divider);
}

.profile-fact-row span:first-child {
  color: var(--text-secondary);
}

.profile-fact-row .v {
  font-weight: 600;
  color: var(--text-primary);
}

/* ---------- Wider viewports for the product screens (Home/Journey/Search/
   Profile/Category/Guide) — same restrained treatment as the onboarding
   shell (Phase 3.7 §10), extended here per Phase 4 §S: "desktop must begin
   feeling deliberately designed... do not merely scale a narrow mobile
   shell." Still not a desktop redesign — no new layout, just the same soft
   wash so the centred column doesn't sit in a flat empty page. ---------- */
@media (min-width: 768px) {
  .app:not(.onboarding) {
    background: radial-gradient(ellipse 900px 700px at 50% 30%, rgba(201, 98, 43, 0.04), transparent 60%),
      radial-gradient(ellipse 700px 900px at 50% 70%, rgba(62, 37, 65, 0.04), transparent 65%),
      var(--bg-page);
    min-height: 100vh;
  }
}

/* ---------- Journey: the strongest expression of the journey/progress
   motif in the product, per Phase 4 §B — the stage colour system already
   in .path-heading/.stage-name/mini-trail IS that expression; no new
   Concept-C illustration was added here (see the motif-usage audit —
   duplicating the step icon next to a screen that already visualises
   stages as a trail would be decoration, not function). ---------- */
.stage-tagline {
  max-width: 100%;
}

/* =====================================================================
   SECTION W — EDITORIAL FIELD GUIDE
   Approved design direction (see DESIGN_SYSTEM.md Section V + W and
   prototypes/sophistication-direction.html). An EVOLUTION of the Phase 3/4
   system: same mark, same Familjen + Inter, same plum/cream, same
   Home/Journey/Search/Profile nav. What changes is composition —
   hairline rules, tonal bands, hanging numerals, a horizontal progress
   datum, a controlled reading measure, and a real desktop layout —
   in place of a stack of tinted rounded cards. Containers are kept only
   where they carry real product meaning (a tappable object, the paywall
   action, locked content, a grouped selection).
   This block is last in the file, so equal-specificity rules win.
   ===================================================================== */

:root {
  /* de-pinked cream + warm stone rules (prototype-established) */
  --surface-warm: #f8f5ef;
  --surface-warm-2: #f1ece2;
  --band: #efe9dd;
  --rule: #e5ddcd;
  --rule-strong: #c9bfa8;
  --ink-ed: #211f24;
  /* orange is now a MARKER only — one darker value, used for the current
     datum position and small emphasis, never a fill or a button */
  --marker: #b4531d;
  --reading: 40rem;      /* ~64 char measure for guide/marketing body */
  --fg-pad: 20px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* the product commits to a warm light identity; keep it light even
       under a dark OS, but lift the ground very slightly */
  }
}

/* ---------- shell + masthead ---------- */
.app { background: var(--surface-warm); }
#view-root { padding: 0 0 var(--sp-8); }
.fg-page { padding: 0 var(--fg-pad); }

.fg-masthead {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 15px var(--fg-pad) 12px;
  border-bottom: 1px solid var(--ink-ed);
  margin-bottom: 22px;
}
.fg-masthead .fg-brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  letter-spacing: -0.01em; color: var(--text-primary);
  background: none; border: none; padding: 0; cursor: pointer;
}
.fg-masthead .fg-brand img { width: 17px; height: 19px; display: block; }
.fg-masthead .fg-running {
  font-size: 12.5px; color: var(--text-muted); letter-spacing: .01em;
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: none; cursor: pointer; font-family: inherit;
}
.fg-masthead .fg-running.link { color: var(--plum); font-weight: 600; }

/* ---------- rules + eyebrows ---------- */
.fg-rule { height: 1px; background: var(--rule); border: 0; margin: 22px 0; }
.fg-rule.ink { background: var(--ink-ed); }
.fg-eyebrow {
  display: flex; align-items: center; gap: 10px;
  font-size: 12.5px; font-weight: 600; color: var(--plum);
  letter-spacing: .01em; margin: 0 0 10px;
}
.fg-eyebrow::before { content: ""; width: 22px; height: 1px; background: var(--plum); flex-shrink: 0; }
.fg-eyebrow.plain::before { display: none; }
/* Quieter than an eyebrow: groups a short list under a "Do now" / "Prepare
   now" style label without competing with section eyebrows. */
.fg-subhead {
  font-family: var(--font-display); font-weight: 600; font-size: 13px;
  color: var(--text-primary); margin: 0 0 4px; letter-spacing: -0.005em;
}

/* ---------- editorial openers ---------- */
.fg-opener {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -0.022em;
  font-size: clamp(29px, 8.4vw, 34px); line-height: 1.06; margin: 24px 0 0;
  max-width: 13ch; text-wrap: balance; color: var(--text-primary);
}
.fg-standfirst {
  font-size: 16px; color: var(--text-secondary); line-height: 1.5;
  margin: 16px 0 0; max-width: 34ch;
}
.fg-greet {
  font-family: var(--font-display); font-weight: 600; font-size: 30px;
  letter-spacing: -0.02em; margin: 22px 0 4px; color: var(--text-primary);
}
.fg-progress-line { font-size: 14.5px; color: var(--text-secondary); margin: 0; }
.fg-progress-line b {
  font-family: var(--font-display); font-weight: 600; color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* ---------- tonal band — "the one thing" ---------- */
.fg-band {
  display: block; width: calc(100% + 2 * var(--fg-pad));
  margin: 22px calc(-1 * var(--fg-pad)); padding: 20px var(--fg-pad) 22px;
  background: var(--band);
  border-top: 1px solid var(--rule-strong); border-bottom: 1px solid var(--rule-strong);
  text-align: left; color: inherit; border-left: 0; border-right: 0;
  cursor: pointer;
}
button.fg-band { -webkit-appearance: none; appearance: none; font: inherit; }
.fg-band .fg-band-lbl {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-display); font-weight: 600; font-size: 13px;
  color: var(--text-secondary); margin: 0 0 10px;
}
.fg-band .fg-band-lbl::before { content: ""; width: 16px; height: 1px; background: var(--text-secondary); }
.fg-band h2, .fg-band .fg-band-title {
  font-family: var(--font-display); font-weight: 600; font-size: 21px;
  line-height: 1.2; letter-spacing: -0.01em; margin: 0 0 6px; color: var(--text-primary);
}
.fg-band p { font-size: 14.5px; color: var(--text-secondary); margin: 0 0 16px; }
.fg-band .fg-band-foot {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}
.fg-band .fg-mins {
  font-family: var(--font-display); font-weight: 600; font-size: 14px;
  font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.fg-band .fg-band-go {
  color: var(--plum); font-weight: 600; font-size: 14px;
  display: inline-flex; align-items: center; gap: 6px;
}

/* ---------- horizontal datum ---------- */
.fg-datum { margin: 6px 0 2px; }
.fg-datum .fg-track {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--ink-ed);
}
.fg-datum .fg-stage {
  appearance: none; background: none; border: 0; cursor: pointer; text-align: left;
  padding: 13px 6px 0 0; font-family: var(--font-display); font-weight: 500;
  font-size: 12px; color: var(--text-muted); position: relative;
}
.fg-datum .fg-stage::before {
  content: ""; position: absolute; top: -4px; left: 0; width: 7px; height: 7px;
  border-radius: 50%; border: 1.5px solid var(--rule-strong); background: var(--surface-warm);
}
.fg-datum .fg-stage.done { color: var(--text-secondary); }
.fg-datum .fg-stage.done::before { background: var(--text-muted); border-color: var(--text-muted); }
.fg-datum .fg-stage.here { color: var(--text-primary); font-weight: 600; }
.fg-datum .fg-stage.here::before {
  width: 9px; height: 9px; border-radius: 2px; top: -5px;
  background: var(--marker); border-color: var(--marker);
}
.fg-datum .fg-stage:focus-visible { outline-offset: -2px; }
.fg-datum .fg-datum-cnt {
  margin: 12px 0 0; font-size: 12.5px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.fg-datum .fg-datum-cnt b { font-family: var(--font-display); font-weight: 600; color: var(--text-primary); }
.fg-datum .fg-datum-cnt a { color: inherit; }

/* ---------- chapter heading (Journey) ---------- */
.fg-chapter { display: grid; grid-template-columns: 2.1rem 1fr; gap: 0 14px; margin: 22px 0 0; }
.fg-chapter .fg-chapter-n {
  font-family: var(--font-display); font-weight: 600; font-size: 1rem;
  color: var(--marker); font-variant-numeric: tabular-nums;
}
.fg-chapter h1 {
  grid-column: 2; font-family: var(--font-display); font-weight: 600;
  font-size: 27px; line-height: 1.08; letter-spacing: -0.02em; margin: 0;
  color: var(--text-primary);
}
.fg-chapter .fg-chapter-tag { grid-column: 2; font-size: 14.5px; color: var(--text-secondary); margin: 8px 0 0; }

/* ---------- editorial list rows (path / other stages / category / search / actions) ---------- */
.fg-list { margin: 6px 0 0; }
.fg-row {
  display: grid; grid-template-columns: 1.7rem 1fr auto; gap: 0 12px; align-items: baseline;
  width: 100%; text-align: left; background: none; border: 0;
  border-top: 1px solid var(--rule); padding: 13px 0; cursor: pointer; font: inherit;
  color: var(--text-primary);
}
.fg-list > .fg-row:first-child { border-top: 1px solid var(--ink-ed); }
.fg-row .fg-mk {
  font-size: 13px; color: var(--text-muted); font-variant-numeric: tabular-nums;
  font-family: var(--font-display); font-weight: 600;
}
.fg-row .fg-ttl { font-size: 15px; line-height: 1.35; }
.fg-row .fg-hint { display: block; font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
.fg-row .fg-aside { font-size: 12.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.fg-row.done .fg-ttl { color: var(--text-muted); text-decoration: line-through; text-decoration-thickness: 1px; }
.fg-row.done .fg-mk { color: var(--text-muted); }
.fg-row.here .fg-mk { color: var(--marker); }
.fg-row.here .fg-mk::after { content: " ▪"; }
.fg-row.locked .fg-ttl { color: var(--text-secondary); }
/* A task that stays in the Journey but doesn't apply to this user's status. */
.fg-row.na .fg-ttl { color: var(--text-secondary); }
.fg-row.na .fg-mk { color: var(--text-muted); }
.fg-row .fg-lock { font-size: 12px; color: var(--text-muted); }

/* ---------- guide ---------- */
.fg-byline {
  font-size: 13px; color: var(--text-muted); padding: 0 0 14px;
  border-bottom: 1px solid var(--ink-ed); margin: 0 0 18px;
}
.fg-byline b { font-family: var(--font-display); font-weight: 600; color: var(--text-secondary); }
.fg-byline a { color: var(--plum); }
.fg-lede {
  font-size: 17px; line-height: 1.5; color: var(--text-primary);
  border-left: 2px solid var(--rule-strong); padding-left: 16px; margin: 0 0 22px;
  max-width: var(--reading);
}
.fg-checklist { list-style: none; margin: 0 0 22px; padding: 0; max-width: var(--reading); }
.fg-checklist li {
  display: grid; grid-template-columns: 1.3rem 1fr; gap: 0 4px;
  padding: 9px 0; border-top: 1px solid var(--rule); font-size: 14.5px; line-height: 1.45;
}
.fg-checklist li:first-child { border-top: 1px solid var(--rule-strong); }
.fg-checklist li .fg-ck { color: var(--plum); font-weight: 700; }
.fg-steps { counter-reset: fgstep; margin: 4px 0 10px; max-width: var(--reading); }
.fg-step {
  display: grid; grid-template-columns: 2rem 1fr; gap: 0 14px;
  padding: 16px 0; border-top: 1px solid var(--rule);
}
.fg-step:first-child { border-top: 1px solid var(--ink-ed); }
.fg-step::before {
  counter-increment: fgstep; content: counter(fgstep);
  font-family: var(--font-display); font-weight: 600; font-size: 1rem;
  color: var(--ink-ed); font-variant-numeric: tabular-nums;
}
.fg-step h2, .fg-step h3 {
  grid-column: 2; font-family: var(--font-display); font-weight: 600;
  font-size: 15.5px; margin: 1px 0 5px; color: var(--text-primary);
}
.fg-step p { grid-column: 2; font-size: 14px; color: var(--text-secondary); margin: 0; line-height: 1.5; }
.fg-step ul { grid-column: 2; margin: 8px 0 0; padding-left: 18px; font-size: 13.5px; color: var(--text-secondary); }
.fg-deflist { margin: 20px 0; max-width: var(--reading); }
.fg-def {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 10px 0; border-top: 1px solid var(--rule); font-size: 14px; line-height: 1.45;
}
.fg-def:first-child { border-top: 1px solid var(--rule-strong); }
.fg-def .fg-term { color: var(--text-muted); flex-shrink: 0; }
.fg-def .fg-val { text-align: right; font-variant-numeric: tabular-nums; }
.fg-where { font-size: 15px; line-height: 1.55; margin: 0 0 14px; max-width: var(--reading); }
.fg-trouble { max-width: var(--reading); }
.fg-trouble .fg-q {
  font-family: var(--font-display); font-weight: 600; font-size: 14.5px;
  margin: 14px 0 4px; padding-top: 14px; border-top: 1px solid var(--rule);
}
.fg-trouble .fg-q:first-child { border-top: 1px solid var(--rule-strong); }
.fg-trouble .fg-a { font-size: 14px; color: var(--text-secondary); margin: 0; line-height: 1.5; }
.fg-next-note {
  font-size: 14px; color: var(--text-secondary); margin: 18px 0 0;
  padding-top: 14px; border-top: 1px solid var(--rule); max-width: var(--reading);
}
.fg-next-note b { font-family: var(--font-display); font-weight: 600; color: var(--text-primary); display: block; margin-bottom: 2px; }
.fg-source {
  margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--ink-ed);
  font-size: 12.5px; color: var(--text-muted); max-width: var(--reading);
}
.fg-source a { color: var(--plum); }

/* ---------- links list (other useful actions / lookups) ---------- */
.fg-links { list-style: none; margin: 6px 0 0; padding: 0; }
.fg-links li { padding: 9px 0; border-top: 1px solid var(--rule); font-size: 14.5px; }
.fg-links li:first-child { border-top: 1px solid var(--rule-strong); }
.fg-links li a {
  color: var(--plum); text-decoration: underline; text-underline-offset: 2px;
  display: inline-flex; align-items: baseline; gap: 6px;
}
.fg-search-field {
  display: flex; align-items: center; gap: 10px;
  border: 0; border-bottom: 1.5px solid var(--ink-ed);
  background: none; padding: 10px 0; width: 100%;
  font-size: 15px; color: var(--text-primary); font-family: inherit;
}
.fg-search-field::placeholder { color: var(--text-muted); }

/* ---------- buttons ---------- */
.fg-btn {
  display: inline-flex; align-items: center; gap: 8px; justify-content: center;
  background: var(--plum); color: #fff; border: none;
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  padding: 13px 22px; border-radius: 4px; cursor: pointer; text-decoration: none;
}
.fg-btn:hover { background: var(--plum-dark); }
.fg-btn.block { display: flex; width: 100%; }
.fg-btn.ghost { background: none; color: var(--plum); border: 1px solid var(--rule-strong); }
.fg-tlink {
  background: none; border: 0; color: var(--plum); font-weight: 600; font-size: 14px;
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer; padding: 8px 0;
}
.fg-quiet { font-size: 13px; color: var(--text-muted); }
.fg-quiet a { color: var(--plum); }

/* ---------- paywall ---------- */
.fg-price-hero { display: flex; align-items: baseline; gap: 10px; margin: 18px 0 2px; }
.fg-price-hero .fg-price-big {
  font-family: var(--font-display); font-weight: 600; font-size: clamp(46px, 14vw, 54px);
  letter-spacing: -0.03em; line-height: 1; font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.fg-price-hero .fg-price-unit {
  font-family: var(--font-display); font-weight: 600; font-size: 18px; color: var(--text-secondary);
}
.fg-price-sub { font-size: 13.5px; color: var(--text-muted); margin: 6px 0 0; }

/* ---------- OTP / auth (task screens — quieter) ---------- */
.fg-task-shell { padding: 0 var(--fg-pad) var(--sp-8); max-width: 420px; }
.fg-task-shell .fg-opener { font-size: 26px; max-width: none; }
.fg-otp-input, .fg-email-input {
  width: 100%; border: 0; border-bottom: 2px solid var(--ink-ed); background: none;
  font-family: var(--font-display); font-size: 22px; padding: 12px 2px; letter-spacing: .12em;
  color: var(--text-primary); font-variant-numeric: tabular-nums;
}
.fg-email-input { font-family: "Inter", sans-serif; font-size: 17px; letter-spacing: 0; }
.fg-otp-input:focus, .fg-email-input:focus { outline: none; border-bottom-color: var(--plum); }

/* ---------- questionnaire ---------- */
.fg-q-head { padding: 15px var(--fg-pad) 0; }
.fg-q-progress { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.fg-q-count {
  font-family: var(--font-display); font-weight: 600; font-size: 13px;
  color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.fg-q-track { flex: 1; height: 2px; background: var(--rule); position: relative; }
.fg-q-track > i { position: absolute; inset: 0 auto 0 0; background: var(--marker); }
.fg-q-prompt {
  font-family: var(--font-display); font-weight: 600; font-size: 25px;
  line-height: 1.12; letter-spacing: -0.02em; margin: 26px 0 6px; text-wrap: balance;
  max-width: 18ch; color: var(--text-primary);
}
.fg-q-sub { font-size: 14.5px; color: var(--text-secondary); margin: 0 0 4px; }
.fg-options { margin: 18px 0 0; }
.fg-option {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; background: none; cursor: pointer; font: inherit;
  border: 0; border-top: 1px solid var(--rule);
  padding: 15px 4px 15px 0; font-size: 16px; color: var(--text-primary);
}
.fg-options .fg-option:first-child { border-top: 1px solid var(--ink-ed); }
.fg-options .fg-option:last-of-type { border-bottom: 1px solid var(--rule); }
.fg-option .fg-opt-mark {
  width: 20px; height: 20px; border: 1.5px solid var(--rule-strong); border-radius: 50%;
  flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: #fff;
}
.fg-option.selected { color: var(--text-primary); font-weight: 600; }
.fg-option.selected .fg-opt-mark { background: var(--plum); border-color: var(--plum); }
.fg-option-more {
  display: flex; align-items: center; gap: 8px; width: 100%; background: none; border: 0;
  border-top: 1px solid var(--rule); padding: 14px 0; cursor: pointer;
  font: inherit; font-size: 14px; color: var(--plum); font-weight: 600;
}
.fg-q-cta { position: fixed; left: 0; right: 0; bottom: 0; padding: 14px var(--fg-pad); }
.fg-q-cta .fg-btn { max-width: 480px; margin: 0 auto; }

/* ---------- payoff ---------- */
.fg-payoff-facts { display: flex; gap: 8px; flex-wrap: wrap; margin: 16px 0 0; }
.fg-fact-chip {
  font-family: var(--font-display); font-weight: 500; font-size: 12.5px;
  color: var(--text-secondary); border: 1px solid var(--rule-strong); padding: 4px 10px; border-radius: 3px;
}
.fg-payoff-sec { margin: 22px 0 0; }
.fg-payoff-sec .fg-payoff-lbl {
  font-family: var(--font-display); font-weight: 600; font-size: 13px; color: var(--text-secondary);
  margin: 0 0 6px; display: flex; align-items: center; gap: 10px;
}
.fg-payoff-sec .fg-payoff-lbl::before { content: ""; width: 16px; height: 1px; background: var(--text-secondary); }
.fg-payoff-item {
  display: grid; grid-template-columns: 1.2rem 1fr; gap: 8px; padding: 8px 0;
  border-top: 1px solid var(--rule); font-size: 15px;
}
.fg-payoff-item:first-of-type { border-top: 1px solid var(--rule-strong); }
.fg-payoff-item.done .fg-pmark { color: var(--text-muted); }
.fg-payoff-item.done span:last-child { color: var(--text-secondary); }
.fg-payoff-item .fg-pmark { color: var(--text-muted); font-family: var(--font-display); font-weight: 600; }

/* ---------- completion ---------- */
.fg-complete {
  padding: 0 var(--fg-pad) var(--sp-8);
}
.fg-complete .fg-complete-mark {
  width: 40px; height: 40px; border-radius: 3px; background: var(--plum); color: #fff;
  display: flex; align-items: center; justify-content: center; margin: 20px 0 18px;
}
.fg-complete h1 {
  font-family: var(--font-display); font-weight: 600; font-size: 28px;
  letter-spacing: -0.02em; margin: 0 0 8px; color: var(--text-primary);
}
.fg-complete .fg-complete-sub { font-size: 15px; color: var(--text-secondary); margin: 0 0 20px; max-width: 36ch; }

/* ---------- locked guide ---------- */
.fg-locked-preview { margin: 0 0 4px; }
.fg-locked-card {
  border: 1px solid var(--rule-strong); border-radius: 6px; padding: 18px 18px 8px;
  margin: 16px 0;
}
.fg-locked-card .fg-locked-lbl {
  font-family: var(--font-display); font-weight: 600; font-size: 13px;
  color: var(--text-secondary); margin: 0 0 6px;
}
.fg-locked-card ul { list-style: none; margin: 0; padding: 0; }
.fg-locked-card li {
  display: grid; grid-template-columns: 1.2rem 1fr; padding: 7px 0;
  border-top: 1px solid var(--rule); font-size: 14px;
}
.fg-locked-card li:first-child { border-top: none; }
.fg-locked-card li .fg-ck { color: var(--plum); font-weight: 700; }
/* the paywall action IS a real product object — it keeps a container */
.fg-buy {
  border: 1px solid var(--plum); border-radius: 8px; padding: 20px; margin: 16px 0;
}
.fg-buy .fg-price-hero { margin-top: 0; }
.fg-buy .fg-btn { margin-top: 14px; }

/* ---------- trust rows ---------- */
.fg-trust {
  display: flex; align-items: baseline; gap: 8px; font-size: 12.5px;
  color: var(--status-success); margin: 12px 0;
}
.fg-trust.info { color: var(--text-secondary); }
.fg-trust a { color: var(--plum); }

/* ---------- bottom nav — bordered top bar, active = plum top rule ---------- */
.bottom-nav.fg-nav {
  background: var(--surface-warm); border-top: 1px solid var(--ink-ed);
  height: calc(var(--nav-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.bottom-nav.fg-nav .nav-btn {
  flex-direction: column; gap: 4px; background: none; border: 0;
  border-top: 2px solid transparent; margin-top: -1px;
  font-family: var(--font-display); font-weight: 500; font-size: 11.5px;
  color: var(--text-muted); min-height: 44px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.bottom-nav.fg-nav .nav-btn svg,
.bottom-nav.fg-nav .nav-btn img { width: 19px; height: 19px; opacity: .85; }
.bottom-nav.fg-nav .nav-btn.active { color: var(--text-primary); border-top-color: var(--plum); }
.bottom-nav.fg-nav .nav-btn.active svg,
.bottom-nav.fg-nav .nav-btn.active img { opacity: 1; }
.bottom-nav.fg-nav .nav-btn .label { font-family: inherit; }

/* ---------- reading measure for guide/marketing body text ---------- */
.fg-page .fg-body { max-width: var(--reading); }
.fg-page > p, .fg-page .who-block p { max-width: var(--reading); }

/* ---------- eligibility / who block ---------- */
.fg-who {
  font-size: 14px; color: var(--text-secondary); line-height: 1.55;
  padding: 12px 0 12px 14px; border-left: 2px solid var(--rule-strong);
  margin: 0 0 20px; max-width: var(--reading);
}
.fg-who p { margin: 0 0 8px; }
.fg-who p:last-child { margin: 0; }

/* ---------- preview line (Home) ---------- */
.fg-preview-line {
  display: flex; align-items: baseline; gap: 8px; font-size: 13px;
  color: var(--text-secondary); margin: 10px 0 0;
  background: none; border: 0; padding: 0; cursor: pointer; font-family: inherit;
}
.fg-preview-line .fg-preview-badge {
  font-family: var(--font-display); font-weight: 600; font-size: 11px;
  letter-spacing: .04em; text-transform: uppercase; color: var(--plum);
}
.fg-preview-line .fg-preview-price { color: var(--plum); font-weight: 600; margin-left: auto; }

/* =====================================================================
   DESKTOP — real composition (≥ 960px)
   Guide + Home + Journey get a reading column + context rail.
   Everything else stays a comfortably-wide single column.
   ===================================================================== */
@media (min-width: 960px) {
  .app { max-width: 1120px; }
  #view-root { padding-bottom: var(--sp-12); }
  .fg-masthead { padding-left: 40px; padding-right: 40px; }
  .fg-page { padding: 0 40px; }
  .bottom-nav.fg-nav { max-width: 1120px; }

  /* two-column spread: rail + reading column */
  .fg-spread { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 0; }
  .fg-spread .fg-rail {
    border-right: 1px solid var(--rule-strong); padding: 8px 32px 32px 0;
    position: sticky; top: 20px; align-self: start;
  }
  .fg-spread .fg-main { padding: 8px 0 0 40px; max-width: 680px; }
  .fg-spread .fg-rail .fg-band {
    width: auto; margin: 16px 0; padding: 16px 16px 18px; border-radius: 4px;
    border-left: 1px solid var(--rule-strong); border-right: 1px solid var(--rule-strong);
  }
  .fg-spread .fg-rail .fg-opener,
  .fg-spread .fg-rail .fg-greet { font-size: 24px; max-width: none; }

  /* guide: reading column + margin notes */
  .fg-guide-spread { display: grid; grid-template-columns: minmax(0, 640px) 240px; gap: 0 40px; }
  .fg-guide-spread .fg-notes {
    border-left: 1px solid var(--rule-strong); padding-left: 24px; font-size: 13px;
    position: sticky; top: 20px; align-self: start;
  }
  .fg-guide-spread .fg-notes .fg-notes-h {
    font-family: var(--font-display); font-weight: 600; color: var(--text-primary);
    font-size: 13px; margin: 2px 0 10px;
  }
  .fg-guide-spread .fg-notes .fg-def { padding: 8px 0; }
  .fg-guide-spread .fg-main-narrow { max-width: 640px; }

  .fg-opener { font-size: 40px; max-width: 16ch; }
  .fg-greet { font-size: 34px; }
  .fg-chapter h1 { font-size: 34px; }
  .fg-band { width: auto; margin-left: 0; margin-right: 0; border-radius: 4px;
    border-left: 1px solid var(--rule-strong); border-right: 1px solid var(--rule-strong); }
}

/* small-height phones — tighten the editorial rhythm so nothing needs a long scroll */
@media (max-height: 700px) {
  .fg-opener { font-size: 27px; margin-top: 16px; }
  .fg-greet { font-size: 26px; margin-top: 16px; }
  .fg-band { margin-top: 16px; margin-bottom: 16px; padding-top: 16px; padding-bottom: 18px; }
  .fg-rule { margin: 16px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .fg-datum .fg-stage::before, .fg-row, .fg-band { transition: none !important; }
}

/* inline link-buttons (internal navigation styled as links) */
.fg-inline-link, .fg-link-btn {
  background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  color: var(--plum); text-decoration: underline; text-underline-offset: 2px;
}
.fg-inline-link { font-size: inherit; color: inherit; }
.fg-links li .fg-link-btn { font-size: 14.5px; }
.fg-complete-mini { display: flex; align-items: baseline; gap: 10px; color: var(--status-success); }
.fg-complete-mini svg { flex-shrink: 0; }

/* arrival hint — editorial aside grammar (small, hairline-marked, not a pill) */
.fg-main-narrow .arrival-note,
.fg-guide-spread .arrival-note,
.arrival-note {
  font-size: 13px;
  font-style: normal;
  color: var(--text-secondary);
  margin: 0 0 var(--sp-4);
  padding-left: 12px;
  border-left: 2px solid var(--rule-strong);
  line-height: 1.5;
}

/* fg-spread: on narrow screens the rail + main simply stack — give the main
   column air so its first eyebrow doesn't collide with the rail's last link.
   On desktop the rule border does the separating and the columns align at top. */
.fg-spread .fg-main { margin-top: 22px; }
.fg-guide-spread { justify-content: center; }
@media (min-width: 960px) {
  .fg-spread .fg-main { margin-top: 0; }
  .fg-spread .fg-main > :first-child { margin-top: 0; }
  .fg-spread .fg-rail > .fg-greet:first-child,
  .fg-spread .fg-rail > .fg-chapter:first-child { margin-top: 0; }
}

/* content that only earns its place in the desktop two-column composition */
.fg-deskonly { display: none; }
@media (min-width: 960px) { .fg-deskonly { display: block; } }
.fg-mobonly { display: block; }
@media (min-width: 960px) { .fg-mobonly { display: none; } }

/* The bottom nav element stays in the DOM on onboarding / paywall / checkout
   screens (render() empties its innerHTML rather than removing it). Left
   visible it paints an empty white bar over the bottom of those screens — on
   Welcome it clipped the "Explore first / Sign in" row. Hide it when empty. */
.bottom-nav:empty { display: none; }

/* Art-direction gate fixes (2026-09-09) */

/* 1. A disabled primary CTA was rendering as full plum with a pointer cursor —
      indistinguishable from an enabled one. The questionnaire's Continue is
      disabled until an answer is chosen, so this was actively misleading. */
.fg-btn:disabled,
.fg-btn[disabled] {
  background: var(--surface-warm-2);
  color: var(--text-muted);
  border-color: var(--rule-strong);
  cursor: not-allowed;
}
.fg-btn:disabled:hover,
.fg-btn[disabled]:hover { background: var(--surface-warm-2); }

/* 2. Questionnaire: with only 3–5 short options the block sat at the top and
      left a ~330–430px void above the anchored CTA. Auto margins centre the
      question in the space between the progress head and the CTA, and collapse
      to 0 when a long option list needs the room, so nothing ever clips. */
.fg-q-head + .fg-page {
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 200px);
  min-height: calc(100dvh - 200px);
}
.fg-q-head + .fg-page > .fg-q-prompt { margin-top: auto; }
.fg-q-head + .fg-page > .fg-options { margin-bottom: auto; }

/* 3. body is the ground behind .app — keep it the page colour so a short page,
      an overscroll bounce or a safe-area gap never flashes white. */
body { background: var(--surface-warm); }

/* 4. Payoff: the two onboarding facts rendered as bordered pills — the last
      generic-SaaS chip left in the product. Set them as an editorial metadata
      line instead. */
.fg-payoff-facts {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px;
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--rule);
}
.fg-fact-chip {
  border: 0; background: none; border-radius: 0; padding: 0;
  font-size: 13.5px; color: var(--text-secondary); letter-spacing: 0;
}
.fg-fact-chip + .fg-fact-chip::before { content: "·"; margin-right: 8px; color: var(--text-muted); }

/* 5. Guide header + lede. .fg-g-title had no rule of its own and inherited the
      page-opener h1 size, so at 390px a long guide title ran to three ~34px
      lines. The byline's source link was full plum and wrapped to two lines,
      shouting louder than the title. And .fg-lede — which is the guide's ANSWER,
      not an aside — was enclosed in a rule + indent, so a long quick answer read
      as a 14-line pull-quote wall before any structure appeared. Size and
      leading now carry the lede's role instead of enclosure. */
.fg-g-title {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(25px, 6.6vw, 29px); line-height: 1.1; letter-spacing: -0.02em;
  margin: 8px 0 10px; max-width: 20ch; text-wrap: balance; color: var(--text-primary);
}
.fg-byline a {
  color: var(--text-secondary);
  text-decoration: underline;
  text-decoration-color: var(--rule-strong);
  text-underline-offset: 2px;
}
.fg-byline a:hover, .fg-byline a:focus-visible { color: var(--plum); text-decoration-color: currentColor; }
.fg-lede {
  font-size: 16.5px; line-height: 1.55; color: var(--text-primary);
  border-left: 0; padding-left: 0; margin: 0 0 24px;
  max-width: var(--reading);
}
@media (min-width: 960px) {
  .fg-g-title { font-size: 34px; }
  .fg-lede { font-size: 17px; }
}

/* 6. "Other useful actions" kept the pre-editorial .action-row pill styling
      (1px border + radius, shrink-wrapped to the label) — card-soup remnants
      sitting in the highest-value screen, with ragged right edges. Set them as
      full-width editorial rows like every other list in the product. */
.fg-links li .action-row,
.fg-links .action-row {
  display: flex; width: 100%; align-items: baseline; justify-content: space-between;
  gap: 12px; border: 0; border-radius: 0;
  margin: 0; padding: 13px 0; font-size: 14.5px; font-weight: 400;
  color: var(--text-primary); text-decoration: none;
}
.fg-links .action-row:hover, .fg-links .action-row:focus-visible { color: var(--plum); }
.fg-links .action-row svg { color: var(--text-muted); flex-shrink: 0; }

/* 7. Definition rows right-aligned their value. Fine for "10 min" or a price;
      for a six-line Cost note it produced a ragged-left paragraph. Keep the
      value block flush right, but set its text left so long values read. */
.fg-def .fg-val { text-align: left; }
.fg-def .fg-val.num { text-align: right; }

/* 8. "At a glance" is a DESKTOP margin note. On mobile it stacked underneath
      the completion CTA and repeated stage / read time / cost / source that the
      guide had already stated inline — ~150px of duplicate content after the
      call to action. */
.fg-guide-spread .fg-notes { display: none; }
@media (min-width: 960px) { .fg-guide-spread .fg-notes { display: block; } }

/* 9. Match the closing source citation to the byline: a source is metadata,
      not a call to action. Still a real, clickable, visible link. */
.fg-source a {
  color: var(--text-secondary);
  text-decoration: underline;
  text-decoration-color: var(--rule-strong);
  text-underline-offset: 2px;
}
.fg-source a:hover, .fg-source a:focus-visible { color: var(--plum); text-decoration-color: currentColor; }

/* 10. Locked guide preview stacked two bordered, rounded containers — the
       "Inside this guide" teaser directly above the purchase object. Two
       enclosed boxes in a row is the one place this design still read as card
       soup, and it split the eye's attention away from the thing being bought.
       The teaser becomes a tonal band (an existing primitive); the purchase
       object stays the only enclosed thing on the screen. */
.fg-locked-card {
  border: 0; border-top: 1px solid var(--rule-strong); border-bottom: 1px solid var(--rule-strong);
  border-radius: 0; background: var(--band);
  padding: 16px var(--fg-pad) 6px;
  width: calc(100% + 2 * var(--fg-pad));
  margin: 18px calc(-1 * var(--fg-pad));
}
@media (min-width: 960px) {
  .fg-locked-card { width: auto; margin-left: 0; margin-right: 0; border-radius: 4px;
    border-left: 1px solid var(--rule-strong); border-right: 1px solid var(--rule-strong); }
}

/* 11. Desktop rail was 300px. At 960–1040 — right where the two-column
       composition first activates — that left the "next step" band a 267px
       measure (description wrapping to five choppy lines) and squeezed the
       datum's four stage labels to 67px each, so "Find your feet" and
       "Work & build" wrapped onto two lines. The datum is a core proprietary
       element; it must never break. Wider rail + a rail-specific datum size. */
@media (min-width: 960px) {
  .fg-spread { grid-template-columns: 340px minmax(0, 1fr); }
  .fg-spread .fg-rail .fg-band { padding: 15px 14px 17px; }
  .fg-spread .fg-rail .fg-datum .fg-stage {
    font-size: 11px; letter-spacing: -0.005em; hyphens: none; padding-right: 4px;
  }
  .fg-spread .fg-rail .fg-datum-cnt { font-size: 14px; }
}

/* 12. Journey's chapter heading kept the full-width 34px h1 after it moved into
       the 340px rail, so the stage name filled the rail edge-to-edge and the
       11px datum directly beneath it read as a caption rather than its own
       element. Match the rail's own display scale (as .fg-greet already does)
       and give the datum room to be a separate beat. */
@media (min-width: 960px) {
  .fg-spread .fg-rail .fg-chapter h1 { font-size: 24px; }
  .fg-spread .fg-rail .fg-chapter { margin-top: 0; }
  .fg-spread .fg-rail .fg-datum { margin-top: 20px; }
}

/* 13. The completion mark was a filled orange square. Orange in this system
       means one thing — "your current position" — and the datum sits directly
       below it saying exactly that about a different stage. Two meanings for
       one colour on one screen. The mark is plum (brand confirmation); the
       check glyph carries "done". Orange is now unambiguous everywhere. */

/* Master-audit fix (P3): on Home in the entitled state, "Do this later" sat
   directly against the datum below it and read as a label for the track rather
   than an action on the band above. Give the datum its own beat when it follows
   that link. */
.fg-tlink + .fg-datum { margin-top: 22px; }

/* Personalised "For you" line inside a guide's who/eligibility panel. Sits
   inside .fg-who, marked by the plum rule so it reads as this reader's own
   situation rather than more general text. */
.fg-who .fg-foryou { border-left: 2px solid var(--plum); padding-left: 12px; margin-top: 12px; }
.fg-who .fg-foryou b { display: block; font-family: var(--font-display); font-weight: 600;
  color: var(--plum); font-size: 12.5px; letter-spacing: .01em; margin-bottom: 3px; }

/* Trader identity / support line. Deliberately quiet — it is there to be
   found at the point of sale and in Profile, not to compete with content. */
.fg-trader { font-size: 12.5px; line-height: 1.55; color: var(--text-muted);
  margin: 18px 0 0; padding-top: 12px; border-top: 1px solid var(--rule); }
.fg-trader a { color: var(--text-secondary); text-decoration: underline;
  text-decoration-color: var(--rule-strong); text-underline-offset: 2px; }
.fg-trader a:hover, .fg-trader a:focus-visible { color: var(--plum); }

/* =====================================================================
   Section W2 — Journey screen polish (2026-09-10)
   Presentation only: one clearly dominant focal task, quieter completed
   tasks, and fewer structural rules. Existing Editorial Field Guide
   tokens only — no new colour, type family or component.
   ===================================================================== */

/* -- Focal task: the loudest element on the screen. The 3px orange edge is
      the system's "your current position" marker, used at the one place it
      most literally means that. -- */
.fg-band { border-left: 3px solid var(--marker); }
.fg-band .fg-band-lbl {
  color: var(--marker); text-transform: uppercase;
  letter-spacing: .07em; font-size: 11px; margin-bottom: 12px;
}
.fg-band .fg-band-lbl::before { background: var(--marker); width: 14px; }
.fg-band .fg-band-title { font-size: 22px; line-height: 1.2; margin-bottom: 8px; }
.fg-band p { font-size: 15px; line-height: 1.55; margin-bottom: 18px; }
.fg-band .fg-band-foot { gap: 0; }
.fg-band .fg-mins {
  font-size: 13px; color: var(--text-secondary);
  padding-right: 14px; margin-right: 14px;
  border-right: 1px solid var(--rule-strong);
}
.fg-band .fg-band-go {
  text-decoration: underline; text-decoration-color: var(--rule-strong);
  text-decoration-thickness: 1.5px; text-underline-offset: 3px;
}
.fg-band:hover .fg-band-go,
.fg-band:focus-visible .fg-band-go { text-decoration-color: var(--plum); }

/* -- Completed tasks recede: no strikethrough, just a quiet colour. -- */
.fg-row.done .fg-ttl { text-decoration: none; }

/* -- Stage path list: grouped by spacing, not a rule between every task. -- */
.fg-list--plain { margin-top: 2px; }
.fg-list--plain > .fg-row,
.fg-list--plain > .fg-row:first-child { border-top: 0; padding: 7px 0; }
.fg-list--plain > .fg-row .fg-ttl { font-size: 14.5px; }
.fg-list--plain > .fg-row.here .fg-ttl { font-weight: 600; color: var(--text-primary); }
.fg-list--plain > .fg-row.here .fg-hint { color: var(--marker); }

/* -- The move from "your journey" to "the whole library" is the one place
      on this screen a rule still earns its keep. -- */
.fg-eyebrow.section-shift {
  margin-top: 34px; padding-top: 26px; border-top: 1px solid var(--rule);
}
.fg-journey .fg-datum-cnt {
  margin: 12px 0 0; font-size: 12.5px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.fg-journey .fg-datum-cnt b {
  font-family: var(--font-display); font-weight: 600; color: var(--text-secondary);
}

/* -- Desktop: the rail should read as an intentional panel, not a sidebar. -- */
@media (min-width: 960px) {
  .fg-journey .fg-spread .fg-rail .fg-band {
    margin: 20px 0 6px; padding: 18px 16px 20px;
    border-left: 3px solid var(--marker);
    border-right: 1px solid var(--rule-strong);
    border-radius: 0 3px 3px 0;
  }
  .fg-journey .fg-spread .fg-rail .fg-band .fg-band-title { font-size: 20px; }
  .fg-journey .fg-spread .fg-rail .fg-band p { font-size: 13.5px; line-height: 1.5; }
  .fg-journey .fg-spread .fg-main { padding-left: 48px; }
}

/* =====================================================================
   Section W3 — Search zero-result state (Step 4, 2026-09-11)
   Category chips for the honest empty state. No new tokens.
   ===================================================================== */
.fg-cat-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fg-cat-chips .fg-chip {
  font: inherit; font-size: 13px; font-weight: 500;
  color: var(--text-primary); background: var(--surface-warm-2);
  border: 1px solid var(--rule-strong); border-radius: 999px;
  padding: 6px 13px; cursor: pointer; line-height: 1.3;
}
.fg-cat-chips .fg-chip:hover,
.fg-cat-chips .fg-chip:focus-visible { border-color: var(--plum); color: var(--plum); }

/* =====================================================================
   Section W4 — Analytics consent notice (2026-09-15)
   A slim strip, not a modal: normal document flow at the very top of
   .app (see index.html — #analytics-consent sits before #view-root), so
   it simply pushes the masthead down a little while shown and takes no
   space at all once answered. Deliberately NOT position:fixed — the app
   already has two different fixed-to-viewport-bottom bars (.bottom-nav,
   .fg-q-cta) depending on the screen, and stacking a third one at the
   bottom would either overlap them or need per-screen height math. A
   top-of-flow strip has no such collision, on any screen, at any width.
   ===================================================================== */
.consent-notice {
  background: var(--surface-warm-2);
  border-bottom: 1px solid var(--divider);
  padding: 14px var(--page-pad);
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
}
.consent-notice-text {
  margin: 0 0 12px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-secondary);
  max-width: 62ch;
}
.consent-notice-actions {
  display: flex;
  gap: 10px;
}
.consent-notice-actions .fg-btn {
  flex: 1;
  padding: 10px 16px;
  font-size: 14px;
  border-radius: var(--r-btn);
}

@media (min-width: 960px) {
  .consent-notice {
    padding-left: 40px;
    padding-right: 40px;
  }
  .consent-notice-actions {
    justify-content: flex-end;
  }
  .consent-notice-actions .fg-btn {
    flex: none;
    min-width: 160px;
  }
}
