:root {
  --navy: #1E40AF;
  --navy-deep: #142B63;
  --navy-dark: #0F172A;
  --blue-light: #3B82F6;
  --blue-accent-light: #E9EEFB;
  --orange: #F97316;
  /* #F97316 is 2.62:1 on cream — fine as a large fill, fails as text and as
     a meaningful icon. Use this deeper tone anywhere orange has to be READ. */
  --orange-text: #C2410C;
  --orange-light: #FBEADD;
  /* Darkened from #B08D57, which measured 2.89:1 on cream — it carries the
     step counter and the only label distinguishing the two review drafts,
     for readers who are mostly 50+. This clears AA at 4.6:1, same hue. */
  --bronze: #8A6B3D;
  --bronze-light: #F1E9DA;
  --white: #FFFFFF;
  --surface: #FFFFFF;
  --bg: #FAF7F2;
  --bg-muted: #F5EFE6;
  --text: #1C1917;
  --text-secondary: #6B6155;
  --border: #E6DFD2;
  --success: #16A34A;
  --danger: #DC2626;
  --radius-lg: 24px;
  --radius-md: 16px;
  --radius-sm: 10px;
  --shadow-sm: 0 1px 3px rgba(28, 25, 23, 0.06);
  --shadow-md: 0 12px 28px rgba(30, 64, 175, 0.10);
  --shadow-lg: 0 26px 52px rgba(15, 23, 42, 0.15);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --font: 'Inter', -apple-system, sans-serif;
  --font-display: 'Fraunces', 'Inter', serif;
}

/* Warm, editorial, and deliberately light by default — cream surfaces carry the
   "luxury" work while navy/orange stay the recognizable iVentures brand anchors. */

[hidden] { display: none !important; }
* { box-sizing: border-box; }

/* Visible to screen readers, invisible on screen. Used for the <label>s on
   inputs that show a placeholder visually — a placeholder alone disappears
   as soon as you type and isn't a reliable accessible name. */
.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;
}

/* Keyboard focus ring. :focus-visible only fires for keyboard/AT navigation,
   so mouse users never see it — but tabbing through the form stays legible
   and on-brand instead of relying on the browser's default outline. */
:focus-visible {
  outline: 3px solid var(--navy);
  outline-offset: 3px;
  border-radius: 4px;
}
.choice:focus-visible, .btn:focus-visible { outline-offset: 2px; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

.app { min-height: 100dvh; display: flex; flex-direction: column; position: relative; }

/* Ambient background texture — warm paper-like wash, no stock gradients */
.app::before {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(680px circle at 6% -8%, rgba(249, 115, 22, 0.06), transparent 55%),
    radial-gradient(760px circle at 108% 6%, rgba(30, 64, 175, 0.06), transparent 55%),
    radial-gradient(560px circle at 50% 105%, rgba(176, 141, 87, 0.08), transparent 60%);
}

/* Top bar */
.topbar { position: sticky; top: 0; z-index: 10; background: rgba(250, 247, 242, 0.82); backdrop-filter: blur(14px) saturate(1.4); border-bottom: 1px solid var(--border); }
.topbar-inner { max-width: 640px; margin: 0 auto; padding: 14px 20px; display: flex; align-items: center; gap: 14px; }
.brand { display: flex; align-items: center; gap: 9px; font-weight: 700; color: var(--navy-dark); font-size: 0.98rem; white-space: nowrap; }
.brand-mark { width: 24px; height: 24px; object-fit: contain; flex-shrink: 0; }
.brand em { font-style: normal; color: var(--orange-text); }
.progress-track { flex: 1; height: 6px; background: var(--bg-muted); border-radius: 99px; overflow: hidden; position: relative; }
.progress-fill { height: 100%; width: 0%; background: linear-gradient(90deg, var(--navy), var(--orange)); border-radius: 99px; transition: width 0.5s var(--ease-expo); position: relative; }
.progress-fill::after {
  content: ''; position: absolute; inset: 0; border-radius: 99px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5), transparent);
  animation: shimmer 1.6s ease-in-out infinite;
}
@keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
.progress-label { font-size: 0.75rem; font-weight: 700; color: var(--text-secondary); white-space: nowrap; font-variant-numeric: tabular-nums; transition: color 0.4s ease; }
.progress-label-final { color: var(--orange-text); }

/* Stage */
.stage { flex: 1; max-width: 640px; width: 100%; margin: 0 auto; padding: 0 20px; display: flex; }
.screen { display: none; width: 100%; align-items: center; }
.screen.active { display: flex; animation: screenIn 0.42s var(--ease-expo); }
@keyframes screenIn { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: translateX(0); } }
.screen-inner { width: 100%; padding: 32px 0 48px; }

/* Stagger question content in for an "assembled" feel */
.screen-inner > * { animation: itemIn 0.5s var(--ease-expo) backwards; }
.screen-inner > *:nth-child(1) { animation-delay: 0.02s; }
.screen-inner > *:nth-child(2) { animation-delay: 0.07s; }
.screen-inner > *:nth-child(3) { animation-delay: 0.12s; }
.screen-inner > *:nth-child(4) { animation-delay: 0.17s; }
.screen-inner > *:nth-child(5) { animation-delay: 0.22s; }
.screen-inner > *:nth-child(n+6) { animation-delay: 0.26s; }
@keyframes itemIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* Hero banner — real brand lockup on navy, exactly like iventures.in */
.hero-banner {
  width: 100%; max-width: 480px; border-radius: var(--radius-lg); overflow: hidden; position: relative;
  background: radial-gradient(120% 140% at 20% 0%, #1E3A8A 0%, #0F172A 60%, #0B1120 100%);
  padding: 30px 20px; margin-bottom: 28px; box-shadow: var(--shadow-lg);
  border: 1px solid rgba(176, 141, 87, 0.35);
}
.hero-banner-glow {
  position: absolute; inset: 0;
  background:
    radial-gradient(220px circle at 85% 20%, rgba(249, 115, 22, 0.35), transparent 60%),
    radial-gradient(280px circle at 10% 90%, rgba(59, 130, 246, 0.28), transparent 60%);
}
.hero-logo { position: relative; width: 100%; max-width: 280px; height: auto; display: block; margin: 0 auto; }

/* Welcome / thank you
   This is the one screen every client sees whether they scroll or not, and
   most won't — so it has to hold everything (logo, promise, credibility,
   the button) inside one viewport with nothing cut off and no scrollbar.
   Every gap/margin below is a clamp() tied to dvh: on a tall screen it sits
   at its normal size, on a short one (SE, older Androids, a squat browser
   chrome bar) it compresses instead of pushing the button off-screen. */
.welcome-inner { text-align: center; display: flex; flex-direction: column; align-items: center; padding-top: clamp(4px, 2dvh, 28px); }
[data-screen="welcome"] .screen-inner { padding: clamp(8px, 2dvh, 32px) 0 clamp(8px, 1.5dvh, 20px); }
.hero-banner { padding: clamp(14px, 3dvh, 30px) 20px; margin-bottom: clamp(10px, 2.4dvh, 28px); }
.hero-logo { max-width: min(280px, 34dvh); }
.welcome-badge { margin-bottom: clamp(8px, 1.6dvh, 18px); }
h1 { font-family: var(--font-display); font-size: clamp(1.55rem, 5.2dvh, 2.35rem); line-height: 1.14; margin: 0 0 clamp(6px, 1.2dvh, 14px); font-weight: 600; letter-spacing: -0.01em; }
h1 .accent { color: var(--orange-text); font-style: italic; }
.subtitle { color: var(--text-secondary); font-size: clamp(0.92rem, 2.1dvh, 1.05rem); line-height: 1.5; max-width: 420px; margin: 0 0 clamp(10px, 2dvh, 28px); }
.stats-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; width: 100%; max-width: 460px; margin-bottom: 14px; }
.stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px 6px; box-shadow: var(--shadow-sm); transition: transform 0.2s var(--ease-expo); }
.stat strong { display: block; font-family: var(--font-display); font-size: 1.05rem; color: var(--navy); font-weight: 600; }
.stat span { display: block; font-size: 0.68rem; color: var(--text-secondary); margin-top: 2px; text-transform: uppercase; letter-spacing: 0.04em; }
/* Regulatory credibility, not a decoration — a HNI prospect checks this before
   anything else, so it gets its own pill rather than hiding as a fourth stat
   tile (that read as "Registered", no number, easy to skim past). Bronze/gold
   rather than navy: navy is already the button and the hero banner, so a navy
   badge here just blended into that block. Gold reads as "certified seal"
   rather than "another blue thing" and stays inside the existing palette. */
.trust-badge {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bronze-light); color: var(--bronze);
  border: 1.5px solid rgba(138, 107, 61, 0.35);
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.01em;
  padding: 8.5px 16px; border-radius: 99px; margin-bottom: clamp(12px, 2.6dvh, 28px);
  box-shadow: var(--shadow-sm);
}
.trust-badge svg { flex-shrink: 0; }
.hint { color: var(--text-secondary); font-size: 0.85rem; margin-top: clamp(6px, 1.2dvh, 18px); }
.check-badge.pending {
  background: var(--blue-accent-light);
  color: var(--navy);
  box-shadow: 0 0 0 8px rgba(30, 64, 175, 0.06);
}
.check-badge { width: 76px; height: 76px; border-radius: 50%; background: rgba(22,163,74,0.1); color: var(--success); display: flex; align-items: center; justify-content: center; margin-bottom: 22px; box-shadow: 0 0 0 8px rgba(22,163,74,0.06); animation: popIn 0.5s var(--ease-spring); }

/* Buttons */
.btn { font-family: var(--font); font-weight: 700; border: none; border-radius: 99px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 8px; transition: transform 0.16s var(--ease-spring), box-shadow 0.2s ease, background 0.2s ease; }
.btn:active { transform: scale(0.96); }
.btn-primary { background: linear-gradient(135deg, var(--navy) 0%, var(--navy-deep) 100%); color: var(--white); padding: 14px 24px; font-size: 1rem; box-shadow: var(--shadow-md); }
.btn-primary:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.btn-secondary { background: var(--surface); color: var(--navy); border: 1.5px solid var(--border); padding: 14px 24px; font-size: 1rem; }
.btn-secondary:hover { border-color: var(--bronze); color: var(--bronze); }
.btn-ghost { background: transparent; color: var(--text-secondary); padding: 14px 18px; font-size: 0.95rem; }
.btn-ghost:hover { color: var(--text); }
.btn-large { width: 100%; max-width: 320px; padding: 16px 24px; font-size: 1.05rem; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; box-shadow: none; }

/* Question screens */
.q-icon { width: 46px; height: 46px; border-radius: 14px; background: linear-gradient(135deg, var(--blue-accent-light), var(--bronze-light)); color: var(--navy); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; box-shadow: var(--shadow-sm); }
.q-icon:empty { display: none; }
.q-eyebrow { color: var(--bronze); font-weight: 700; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px; }
.q-title { font-family: var(--font-display); font-size: 1.7rem; font-weight: 600; margin: 0 0 6px; letter-spacing: -0.005em; line-height: 1.22; }
.q-title .title-accent { color: var(--orange-text); }
/* The word "optional" has to be seen, not read — clients were treating the
   notes box as one more required field and stalling at the finish line. */
.q-sub .optional-strong { display: block; color: var(--bronze); font-weight: 700; font-size: 1.08rem; margin-bottom: 4px; }
.q-sub { color: var(--text-secondary); margin: 0 0 24px; font-size: 0.95rem; }

.choice-grid { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; }
.choice {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-md);
  padding: 16px 18px; cursor: pointer; text-align: left; font-family: var(--font);
  font-size: 1rem; font-weight: 600; color: var(--text);
  transition: border-color 0.18s ease, background 0.18s ease, transform 0.16s var(--ease-spring), box-shadow 0.18s ease;
  box-shadow: var(--shadow-sm);
}
.choice:hover { border-color: var(--blue-light); background: var(--blue-accent-light); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.choice:active { transform: scale(0.97); }
.choice.selected { border-color: var(--navy); background: var(--blue-accent-light); color: var(--navy); }
.choice .choice-main { display: flex; align-items: center; gap: 12px; }
.choice .check { width: 22px; height: 22px; border-radius: 50%; border: 2px solid #C9BFA8; flex-shrink: 0; display: flex; align-items: center; justify-content: center; transition: border-color 0.18s ease, background 0.18s ease; }
.choice.selected .check { background: var(--navy); border-color: var(--navy); color: var(--white); animation: popIn 0.32s var(--ease-spring); }
.choice .choice-sub { display: block; font-size: 0.8rem; font-weight: 500; color: var(--text-secondary); margin-top: 2px; }
@keyframes popIn { 0% { transform: scale(0); } 60% { transform: scale(1.18); } 100% { transform: scale(1); } }

/* Star rating */
.stars-grid { align-items: center; }
.star-row { display: flex; gap: 10px; justify-content: center; margin: 8px 0 4px; position: relative; }
/* Spark burst, 5-star tap only — see celebrateFiveStars() in app.js. Absolute
   over the row rather than the whole screen: it has to read as the stars
   celebrating, not an unrelated effect happening near them. */
.star-burst { position: absolute; inset: 0; pointer-events: none; }
.star-burst span {
  position: absolute; top: 50%; left: 50%; width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange); transform: translate(-50%, -50%) scale(1);
  animation: sparkOut 0.55s var(--ease-expo) forwards;
}
.star-burst span.bronze { background: var(--bronze); }
@keyframes sparkOut {
  0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(0.3); opacity: 0; }
}
.star {
  /* Empty stars were var(--border) — 1.24:1 on cream, five faint smudges.
     This is the control the whole flow branches on, so it has to be visible
     to someone in reading glasses outdoors. */
  width: 52px; height: 52px; padding: 6px; border: none; background: none;
  cursor: pointer; color: #C9BFA8;
  transition: transform 0.18s var(--ease-spring), color 0.18s ease;
}
.star svg { fill: currentColor; display: block; }
.star.on { color: var(--orange); }
.star.on svg { animation: popIn 0.32s var(--ease-spring); }
.star:hover { transform: scale(1.12); }
.star:active { transform: scale(0.94); }
.star-caption {
  text-align: center; margin: 4px 0 24px; font-weight: 700;
  color: var(--text-secondary); font-size: 0.95rem; min-height: 1.2em;
}
@media (min-width: 420px) { .star {
  /* Empty stars were var(--border) — 1.24:1 on cream, five faint smudges.
     This is the control the whole flow branches on, so it has to be visible
     to someone in reading glasses outdoors. */ width: 60px; height: 60px; } }

/* Slider rating (app-experience question) */
.slider-grid { align-items: stretch; }
.slider-wrap { padding: 8px 4px 4px; }
.slider-value {
  text-align: center; font-family: var(--font-display); font-size: 2.2rem; font-weight: 700;
  color: var(--navy); margin: 0 0 20px;
}
.slider-input {
  -webkit-appearance: none; appearance: none; width: 100%; height: 8px; border-radius: 99px;
  background: linear-gradient(to right, var(--orange) 0%, var(--orange) calc((var(--pct, 50) * 1%)), var(--border) calc((var(--pct, 50) * 1%)), var(--border) 100%);
  outline: none; cursor: pointer; margin: 0 0 14px;
}
.slider-input.slider-untouched { background: var(--border); }
.slider-input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--orange); border: 3px solid var(--white); box-shadow: var(--shadow-md);
  cursor: pointer; transition: transform 0.16s var(--ease-spring);
}
.slider-input::-webkit-slider-thumb:active { transform: scale(1.15); }
.slider-input.slider-untouched::-webkit-slider-thumb { background: var(--text-secondary); }
.slider-input::-moz-range-thumb {
  width: 30px; height: 30px; border-radius: 50%; background: var(--orange);
  border: 3px solid var(--white); box-shadow: var(--shadow-md); cursor: pointer;
}
.slider-input.slider-untouched::-moz-range-thumb { background: var(--text-secondary); }
.slider-input::-moz-range-track { height: 8px; border-radius: 99px; background: var(--border); }
.slider-input::-moz-range-progress { height: 8px; border-radius: 99px; background: var(--orange); }
.slider-labels {
  display: flex; justify-content: space-between; font-size: 0.85rem; font-weight: 600;
  color: var(--text-secondary); margin: 0 2px;
}
.slider-followup { margin-top: 28px; animation: itemIn 0.3s var(--ease-expo); }
.slider-followup-label { display: block; font-size: 0.88rem; font-weight: 600; color: var(--text-secondary); margin: 0 0 10px; }
.slider-followup-input { min-height: 90px; margin-bottom: 0; }

/* Chip-style grid for multi-select questions with many short options */
.choice-grid.chips { flex-direction: row; flex-wrap: wrap; gap: 10px; }
.choice-grid.chips .choice {
  flex: 0 0 auto; padding: 11px 16px; border-radius: 99px; font-size: 0.92rem;
  width: auto;
}
.choice-grid.chips .choice .check { width: 18px; height: 18px; }

/* Sticky so Continue is always in reach. The services screen is 13 chips tall
   on a phone — with the actions in normal flow the button sits below the fold
   and every client has to scroll to find it. Bleeds past .stage's 20px side
   padding so the fade reaches both screen edges. */
.q-actions {
  display: flex; align-items: center; justify-content: space-between;
  position: sticky; bottom: 0; z-index: 5;
  margin: 8px -20px 0;
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(to top, var(--bg) 58%, rgba(250, 247, 242, 0));
}

/* Text input (name, other) */
.text-input, .notes-textarea {
  width: 100%; border: 1.5px solid var(--border); border-radius: var(--radius-md);
  padding: 16px; font-family: var(--font); font-size: 1.05rem; color: var(--text); background: var(--surface);
  margin-bottom: 24px; box-shadow: var(--shadow-sm); transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.text-input:focus, .notes-textarea:focus { outline: none; border-color: var(--navy); box-shadow: 0 0 0 4px var(--blue-accent-light); }
.notes-textarea { min-height: 130px; resize: vertical; }
.other-input-wrap { margin-top: -8px; margin-bottom: 20px; animation: itemIn 0.3s var(--ease-expo); }
.other-input-wrap .text-input { margin-bottom: 0; }

/* Second field on the phone+email screen — sits directly under the primary
   text input, same visual weight as the pill row label above a choice grid. */
.secondary-input-wrap { margin-top: -10px; }
.secondary-input-label { display: block; font-size: 0.82rem; font-weight: 600; color: var(--text-secondary); margin: 0 0 8px; }
.contact-hint {
  margin: -14px 0 20px; font-size: 0.84rem; line-height: 1.45; color: var(--orange-text);
  animation: itemIn 0.3s var(--ease-expo);
}

/* Multi-part question: one row per thing being rated, a compact 1-5 scale on
   each. Sized so all five buttons fit within the content width of a 375px
   phone without wrapping or shrinking below a 44px tap target. */
.grid-rows { display: flex; flex-direction: column; gap: 14px; }
.grid-row {
  background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-md);
  padding: 14px 16px 16px; box-shadow: var(--shadow-sm);
}
.grid-row-head { display: flex; flex-direction: column; margin-bottom: 12px; }
.grid-row-label { font-size: 0.98rem; font-weight: 700; color: var(--text); line-height: 1.3; }
.grid-row-sub { font-size: 0.8rem; color: var(--text-secondary); margin-top: 3px; line-height: 1.35; }
.grid-scale { display: flex; gap: 8px; }
.grid-dot {
  flex: 1; min-width: 0; min-height: 44px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--text-secondary); font-family: var(--font);
  font-size: 0.98rem; font-weight: 700; cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease, transform 0.12s ease;
}
.grid-dot:hover { border-color: var(--navy); }
.grid-dot:active { transform: scale(0.94); }
.grid-dot.selected { background: var(--navy); border-color: var(--navy); color: #fff; }
.grid-anchors {
  display: flex; justify-content: space-between; margin-top: 8px;
  font-size: 0.74rem; font-weight: 600; color: var(--text-muted, var(--text-secondary)); opacity: 0.8;
}
.grid-counter {
  text-align: center; font-size: 0.84rem; font-weight: 600; color: var(--text-secondary);
  margin: 16px 0 0;
}
.grid-counter-done { color: var(--orange-text); }

/* Optional comment box under a star, slider or grid question — same idea as
   the "Other" free-text field, but for a rating rather than a choice. */
.rating-followup { margin-top: 22px; animation: itemIn 0.3s var(--ease-expo); }
.rating-followup-label { display: block; font-size: 0.86rem; font-weight: 600; color: var(--text-secondary); margin: 0 0 10px; }
.rating-followup-input { min-height: 90px; margin-bottom: 0; }

/* Secondary pill row (city, tenure) — deliberately lighter than .choice so it
   reads as the optional follow-up it is, not a second question competing for
   attention with the one above it. */
.pill-row-wrap { margin: -8px 0 24px; animation: itemIn 0.3s var(--ease-expo); }
.pill-row-label { font-size: 0.82rem; font-weight: 600; letter-spacing: 0.02em; color: var(--text-secondary); margin: 0 0 10px; }
.pill-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pill {
  flex: 0 0 auto; padding: 9px 15px; border-radius: 99px; cursor: pointer;
  border: 1.5px solid var(--border); background: var(--surface);
  font-family: var(--font); font-size: 0.86rem; font-weight: 500; color: var(--text-secondary);
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.pill:hover { border-color: var(--blue-light); background: var(--blue-accent-light); }
.pill:active { transform: scale(0.96); }
.pill.selected { border-color: var(--navy); background: var(--navy); color: var(--white); font-weight: 600; }
.pill-other-wrap { margin-top: 12px; animation: itemIn 0.3s var(--ease-expo); }
.pill-other-wrap .text-input { margin-bottom: 0; font-size: 0.95rem; padding: 12px 14px; }

/* Loading */
.loading-inner { flex-direction: column; align-items: center; text-align: center; padding-top: 96px; }
.loader-ring { width: 56px; height: 56px; border: 4px solid var(--blue-accent-light); border-top-color: var(--navy); border-right-color: var(--orange); border-radius: 50%; animation: spin 0.9s linear infinite; margin-bottom: 24px; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading-text { color: var(--text-secondary); font-size: 1rem; font-weight: 500; }

/* Results */
.results-inner { padding-top: 24px; }
.review-cards { display: flex; flex-direction: column; gap: 16px; margin-bottom: 24px; }
.review-card { background: var(--surface); border: 1.5px solid var(--border); border-radius: var(--radius-lg); padding: 20px; box-shadow: var(--shadow-sm); }
.review-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.review-card-label { font-size: 0.75rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; color: var(--bronze); }
.stars { color: var(--bronze); letter-spacing: 2px; font-size: 0.95rem; }
.review-text { font-family: var(--font-display); font-size: 1rem; line-height: 1.62; color: var(--text); margin: 0 0 16px; white-space: pre-wrap; }
.review-edit-textarea {
  width: 100%; border: 1.5px solid var(--navy); border-radius: var(--radius-md);
  padding: 12px 14px; font-family: var(--font-display); font-size: 1rem; line-height: 1.62;
  color: var(--text); background: var(--surface); margin: 0 0 16px; resize: none; overflow: hidden;
  box-shadow: 0 0 0 4px var(--blue-accent-light);
}
.review-edit-textarea:focus { outline: none; }
.review-actions { display: flex; gap: 10px; }
/* No font-size override: this is the primary action of the whole product
   and was rendering at 14.4px while every other primary button was 16px. */
.review-actions .btn { flex: 1; padding: 12px 14px; }

.guide-card { background: var(--bg-muted); border-radius: var(--radius-md); padding: 20px; margin-bottom: 20px; border: 1px solid var(--border); }
.guide-card h3 { margin: 0 0 10px; font-size: 1rem; font-family: var(--font-display); }
.guide-card ol { margin: 0 0 12px; padding-left: 20px; color: var(--text-secondary); font-size: 0.9rem; line-height: 1.7; }
.guide-card ol strong { color: var(--text); }
.privacy-note { margin: 0; font-size: 0.8rem; color: var(--text-secondary); font-style: italic; }

/* ---------------------------------------------------------------------------
   "How to post" — shown as a loop of the actual gesture rather than prose.
   The paste step is the only part of this flow we cannot do for the client, so
   it's the one thing worth spending real design on. A four-line numbered list
   got skipped; a short animation of the thing they're about to do does not.

   One 9s timeline drives every element — each rule below animates the same
   duration and just holds still until its slice arrives. Keeping a single
   duration is what keeps the steps in sync without any JS.
   --------------------------------------------------------------------------- */
.post-demo { display: flex; justify-content: center; margin: 4px 0 18px; }
.demo-screen {
  width: 100%; max-width: 240px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 14px; padding: 14px;
  box-shadow: var(--shadow-sm);
}
.demo-label { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-secondary); margin-bottom: 8px; }

/* Stars fill left to right, one after another, during their slice. */
.demo-stars { display: flex; gap: 4px; margin-bottom: 10px; }
.demo-stars span {
  width: 17px; height: 17px; background: var(--border);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  animation: demoStar 9s var(--ease-expo) infinite;
}
.demo-stars span:nth-child(1) { animation-delay: 0s; }
.demo-stars span:nth-child(2) { animation-delay: 0.12s; }
.demo-stars span:nth-child(3) { animation-delay: 0.24s; }
.demo-stars span:nth-child(4) { animation-delay: 0.36s; }
.demo-stars span:nth-child(5) { animation-delay: 0.48s; }
@keyframes demoStar {
  0%, 52% { background: var(--border); transform: scale(1); }
  57% { background: var(--orange); transform: scale(1.25); }
  62%, 100% { background: var(--orange); transform: scale(1); }
}

/* The review box: a tap ripple, then a Paste bubble, then text appearing. */
.demo-box {
  position: relative; min-height: 54px; border: 1.5px solid var(--border);
  border-radius: 9px; padding: 9px; margin-bottom: 10px; background: var(--bg);
  animation: demoBoxFocus 9s var(--ease-expo) infinite;
}
@keyframes demoBoxFocus {
  0%, 14% { border-color: var(--border); }
  18%, 50% { border-color: var(--navy); }
  55%, 100% { border-color: var(--border); }
}

/* The long-press: a finger-sized ring that lands and holds. */
.demo-tap {
  position: absolute; left: 24px; top: 18px; width: 22px; height: 22px;
  border-radius: 50%; background: rgba(30, 64, 175, 0.28); opacity: 0;
  animation: demoTap 9s var(--ease-expo) infinite;
}
@keyframes demoTap {
  0%, 4% { opacity: 0; transform: scale(0.4); }
  9% { opacity: 1; transform: scale(1); }
  16% { opacity: 1; transform: scale(1.5); }
  20%, 100% { opacity: 0; transform: scale(1.8); }
}

/* The Paste bubble — this is the single instruction that matters. */
.demo-paste {
  position: absolute; left: 14px; top: -12px; z-index: 2;
  background: var(--navy-dark); color: var(--white);
  font-size: 0.65rem; font-weight: 700; padding: 4px 11px; border-radius: 6px;
  opacity: 0; transform: translateY(4px);
  animation: demoPaste 9s var(--ease-spring) infinite;
}
@keyframes demoPaste {
  0%, 17% { opacity: 0; transform: translateY(4px) scale(0.9); }
  21%, 30% { opacity: 1; transform: translateY(0) scale(1); }
  34%, 100% { opacity: 0; transform: translateY(-3px) scale(0.95); }
}

/* Pasted text, arriving line by line. */
.demo-line {
  display: block; height: 6px; border-radius: 3px; background: var(--text-secondary);
  opacity: 0.55; width: 0; margin-bottom: 6px;
  animation: demoLine 9s var(--ease-expo) infinite;
}
.demo-line.l2 { animation-delay: 0.35s; }
.demo-line.l3 { animation-delay: 0.7s; }
@keyframes demoLine {
  0%, 32% { width: 0; }
  40%, 100% { width: 100%; }
}
.demo-line.l3 { max-width: 62%; }

/* Post: goes live and pulses once the rest is done. */
.demo-post {
  text-align: center; font-size: 0.75rem; font-weight: 700; padding: 9px;
  border-radius: 99px; background: var(--border); color: var(--text-secondary);
  animation: demoPost 9s var(--ease-spring) infinite;
}
@keyframes demoPost {
  0%, 66% { background: var(--border); color: var(--text-secondary); transform: scale(1); box-shadow: none; }
  72% { background: var(--navy); color: var(--white); transform: scale(1.06); box-shadow: var(--shadow-md); }
  78%, 100% { background: var(--navy); color: var(--white); transform: scale(1); box-shadow: var(--shadow-md); }
}

/* The written steps, kept to three and under five words each. They brighten in
   time with the animation so the words and the picture teach the same beat. */
.post-steps { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.post-steps li {
  display: flex; align-items: center; gap: 10px;
  font-size: 0.9rem; color: var(--text-secondary);
  animation: demoStepOn 9s var(--ease-expo) infinite;
}
.post-steps li strong { color: var(--text); }
.step-dot {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  background: var(--border); color: var(--text-secondary);
  font-size: 0.72rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.3s ease, color 0.3s ease;
}
/* Scoped to the demo's own steps: the step-1 dot above the demo is always
   lit, and an unscoped animation here overrode that back to grey. */
.post-steps .step-dot { animation: demoDotOn 9s var(--ease-expo) infinite; }
/* Two steps now — step 1 happens on this page, not on Google, so it sits
   above the demo. These two track the demo's paste phase and its stars/post
   phase respectively. */
.post-steps li:nth-child(1), .post-steps li:nth-child(1) .step-dot { animation-delay: 0s; }
.post-steps li:nth-child(2), .post-steps li:nth-child(2) .step-dot { animation-delay: 4.5s; }

/* Step 1 — the tap that happens right here. Always lit, because it's the
   action the client takes next; the demo below covers what follows on Google. */
.guide-here {
  display: flex; align-items: center; gap: 10px;
  font-size: 0.9rem; color: var(--text); line-height: 1.5;
  padding-bottom: 14px; margin-bottom: 2px; border-bottom: 1px solid var(--border);
}
.guide-here strong { color: var(--navy); }
.step-dot.on { background: var(--navy); color: var(--white); }
.guide-then {
  margin: 12px 0 2px; font-size: 0.8rem; font-weight: 600;
  letter-spacing: 0.03em; color: var(--text-secondary);
}

/* Hand-off between the instructions and the reviews themselves. The arrow
   nudges downward so the connection between "below" and the cards is made
   without anyone having to read the sentence. */
.reviews-lead { text-align: center; margin: 4px 0 18px; }
.reviews-lead h3 { margin: 0 0 4px; font-family: var(--font-display); font-size: 1.1rem; }
.reviews-lead p { margin: 0 0 6px; font-size: 0.86rem; color: var(--text-secondary); }
.reviews-arrow { color: var(--orange-text); animation: nudgeDown 1.9s var(--ease-expo) infinite; }
@keyframes nudgeDown {
  0%, 55%, 100% { transform: translateY(0); opacity: 0.75; }
  70% { transform: translateY(5px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .reviews-arrow { animation: none; }
}
@keyframes demoStepOn {
  0%, 2% { color: var(--text-secondary); }
  6%, 28% { color: var(--text); }
  33%, 100% { color: var(--text-secondary); }
}
@keyframes demoDotOn {
  0%, 2% { background: var(--border); color: var(--text-secondary); }
  6%, 28% { background: var(--navy); color: var(--white); }
  33%, 100% { background: var(--border); color: var(--text-secondary); }
}

/* Motion is the whole point here, so when it's switched off the demo has to
   settle on the FINISHED state — a frozen empty box would teach nothing. */
@media (prefers-reduced-motion: reduce) {
  .demo-stars span, .demo-box, .demo-tap, .demo-paste, .demo-line,
  .demo-post, .post-steps li, .step-dot { animation: none !important; }
  .demo-stars span { background: var(--orange); }
  .demo-line { width: 100%; }
  .demo-tap, .demo-paste { opacity: 0; }
  .demo-post { background: var(--navy); color: var(--white); }
  .step-dot { background: var(--navy); color: var(--white); }
  .post-steps li { color: var(--text); }
}

/* ---------------------------------------------------------------------------
   "Copied!" overlay — the paste instruction at the ONLY moment it can't be
   missed. Full-screen so there is nothing else to look at; the three steps
   are the entire message. Google opens from the button here, not before.
   --------------------------------------------------------------------------- */
.copy-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(15, 23, 42, 0.62);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.copy-overlay[hidden] { display: none; }
.copy-overlay-card {
  background: var(--surface); border-radius: var(--radius-lg);
  max-width: 420px; width: 100%; max-height: calc(100dvh - 40px); overflow-y: auto;
  padding: 28px 24px calc(24px + env(safe-area-inset-bottom, 0px));
  text-align: center; box-shadow: var(--shadow-lg);
  animation: popIn 0.4s var(--ease-spring);
}
.copy-overlay-badge {
  width: 68px; height: 68px; border-radius: 50%; margin: 0 auto 12px;
  background: rgba(22, 163, 74, 0.12); color: var(--success);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 8px rgba(22, 163, 74, 0.06);
  animation: popIn 0.5s var(--ease-spring);
}
.copy-overlay-card h2 {
  font-family: var(--font-display); font-size: 2rem; margin: 0 0 6px; color: var(--text);
}
.copy-overlay-sub { color: var(--text-secondary); font-size: 1rem; line-height: 1.5; margin: 0 0 18px; }
.copy-overlay-sub strong { color: var(--text); }
.copy-overlay-steps {
  list-style: none; margin: 0 0 22px; padding: 16px;
  background: var(--bg-muted); border-radius: var(--radius-md); border: 1px solid var(--border);
  text-align: left;
}
.copy-overlay-steps li {
  display: flex; align-items: center; gap: 12px;
  font-size: 1.02rem; line-height: 1.45; color: var(--text);
  padding: 8px 0;
}
.copy-overlay-steps li + li { border-top: 1px dashed var(--border); }
/* The two or three words that ARE the instruction — bigger than everything
   around them on purpose. */
.copy-overlay-steps .big-key { color: var(--orange-text); font-size: 1.15em; }
.copy-overlay-card .btn-large { max-width: none; width: 100%; margin-bottom: 6px; }

/* Toast */
.toast {
  position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 20px);
  background: var(--navy-dark); color: var(--white); padding: 12px 20px; border-radius: 99px;
  font-size: 0.9rem; font-weight: 600; box-shadow: var(--shadow-lg); opacity: 0; pointer-events: none;
  transition: all 0.3s var(--ease-spring); z-index: 50; white-space: nowrap;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* Footer */
.app-footer { text-align: center; padding: 18px; color: var(--text-secondary); font-size: 0.78rem; display: flex; align-items: center; justify-content: center; gap: 8px; }
.footer-mark { width: 16px; height: 16px; object-fit: contain; opacity: 0.7; }

/* Responsive */
@media (min-width: 480px) {
  h1 { font-size: 2.75rem; }
  .stats-row { gap: 12px; }
}

/* ---------------------------------------------------------------------------
   Mobile. Effectively every client opens this on a phone, from a link an
   advisor sent them — so these aren't defensive tweaks, they're the primary
   case. Each rule below fixes something that only goes wrong on a handset.
   --------------------------------------------------------------------------- */

/* iOS Safari zooms the whole page in when you focus an input whose font is
   under 16px, and it does not zoom back out afterwards — the client is left
   on a form that no longer fits the screen. Every field must stay at 16px+. */
.text-input, .notes-textarea, .pill-other-wrap .text-input, input, textarea {
  font-size: max(16px, 1rem);
}

/* Kills the grey flash Android draws over a tapped element, and the ~300ms
   delay browsers add while they wait to see if a tap is a double-tap. Without
   touch-action the form feels laggy even though nothing is actually slow. */
.btn, .choice, .pill, .star, .post-btn {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  user-select: none;
}

/* 44px is the smallest target most people can hit reliably one-handed
   (Apple's HIG figure, and WCAG 2.5.8 asks for 24px as a hard floor). The
   pills were ~36px, which is a miss-tap on the move. */
.pill { min-height: 44px; display: inline-flex; align-items: center; }
.choice { min-height: 48px; }
.btn { min-height: 46px; }

/* The sticky action bar covers the bottom of the scroll area, so the last
   option needs room to clear it — otherwise the final chip on a long list can
   never be scrolled out from under the Continue button. */
.screen-inner { padding-bottom: 12px; }

/* Notched and gesture-bar phones: keep the footer above the home indicator. */
.app-footer { padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }

/* Very short viewports (browser chrome + address bar eating into a small
   phone, or a keyboard-adjacent split view) — the dvh clamps above still
   leave the welcome screen taller than the box on these. Cut the two
   elements that cost the most height and carry the least meaning at a
   glance: the decorative glow banner shrinks further, and the footer's
   compliance line (already repeated in the trust badge above the fold)
   drops out rather than forcing a scrollbar on the very first thing anyone
   sees. */
@media (max-height: 620px) {
  .hero-banner { padding: 10px 20px; margin-bottom: 10px; }
  .hero-logo { max-width: 150px; }
  .welcome-badge { margin-bottom: 6px; }
  h1 { font-size: 1.4rem; margin-bottom: 4px; }
  .subtitle { font-size: 0.86rem; margin-bottom: 8px; }
  .stats-row { margin-bottom: 8px; }
  .trust-badge { margin-bottom: 10px; padding: 7px 14px; font-size: 0.72rem; }
  /* Footer is a sibling of <main>, not of any one screen, so it can't be
     targeted per-screen in CSS — dropped everywhere at this height instead.
     Its one job (the SEBI line) is already covered by the welcome screen's
     own trust badge, so nothing is lost on the screen that matters. */
  .app-footer { display: none; }
  .hint { display: none; }
}

/* Stops the rubber-band scroll of the page behind the form on iOS, which
   makes a short screen feel loose and unfinished. */
body { overscroll-behavior-y: contain; }

@media (max-width: 380px) {
  /* Small handsets (SE, older Androids). The chip grid is the first thing to
     overflow, so it loses padding before anything else does. */
  /* Padding only, deliberately NOT font-size. This block is active on the
     iPhone SE / 8 / 12 mini — the handsets this audience is most likely to be
     holding — so shrinking the type here would hurt exactly the readers who
     can least afford it. */
  .choice-grid.chips .choice { padding: 10px 12px; }
  .pill { padding: 9px 12px; }
  .stage { padding: 0 16px; }
  .q-actions { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; }
}

/* --- Referrals ----------------------------------------------------------- */
/* Two ways to add someone: the browser's own contact picker where it exists,
   and typing, which always works. The picker button is deliberately not the
   only affordance — it is Chrome-on-Android only. */
.referral-pick {
  width: 100%; justify-content: center; gap: 10px; margin-bottom: 10px;
}
.referral-privacy {
  margin: 0 0 4px; font-size: 0.78rem; line-height: 1.5;
  color: var(--text-secondary); text-align: center;
}
/* A labelled rule, so "or type their details" reads as an alternative rather
   than an instruction to do both. */
.referral-or {
  display: flex; align-items: center; gap: 12px;
  margin: 14px 0 16px; color: var(--text-secondary);
  font-size: 0.8rem; font-weight: 600;
}
.referral-or::before, .referral-or::after {
  content: ''; flex: 1; height: 1px; background: var(--border);
}
.referral-form { display: grid; grid-template-columns: 1fr 1fr auto; gap: 10px; align-items: start; }
.referral-form .referral-input { margin-bottom: 0; }
.referral-add { white-space: nowrap; padding-left: 20px; padding-right: 20px; }
.referral-add:disabled { opacity: 0.45; cursor: not-allowed; }
/* Stacked on a phone: three controls side by side leaves each too narrow to
   read the placeholder, let alone type a name into. */
@media (max-width: 560px) {
  .referral-form { grid-template-columns: 1fr; }
  .referral-add { width: 100%; }
}
.referral-list { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.referral-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--radius-md); padding: 14px 16px; box-shadow: var(--shadow-sm);
  animation: itemIn 0.3s var(--ease-expo);
}
.referral-item-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.referral-item-text strong { font-size: 0.98rem; color: var(--text); overflow-wrap: anywhere; }
.referral-item-text span { font-size: 0.85rem; color: var(--text-secondary); }
.referral-remove {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  border: 1.5px solid var(--border); background: var(--bg);
  color: var(--text-secondary); display: grid; place-items: center; cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.referral-remove:hover { color: var(--orange-text); border-color: var(--orange-text); }

/* Word under the slider number — the scale's own vocabulary, so a 6 reads
   the same to everyone who picks it. */
.slider-caption {
  margin: 2px 0 14px; text-align: center;
  font-size: 0.92rem; font-weight: 600; color: var(--text-secondary);
}
/* Issue chips, revealed under a low app score. */
.app-issues { margin-top: 26px; animation: itemIn 0.3s var(--ease-expo); }
.issue-row { display: flex; flex-wrap: wrap; gap: 8px; }
/* The referral block shares the recommend screen, so it needs a rule above it
   to read as a second, separate ask rather than more of the same question. */
.referral-wrap { margin-top: 30px; padding-top: 26px; border-top: 1px solid var(--border); }
.referral-heading {
  font-family: var(--font-display); font-size: 1.12rem; line-height: 1.35;
  font-weight: 600; color: var(--text); margin: 0 0 8px;
}
.referral-privacy { text-align: left; }
.referral-relation { appearance: none; cursor: pointer; background-image: none; }

/* "And then what happens?" — confirmation under a choice question, once
   something has actually been picked. */
.picked-note {
  display: flex; align-items: flex-start; gap: 9px;
  margin: 18px 0 0; padding: 13px 15px;
  background: var(--blue-accent-light); border-radius: var(--radius-sm);
  font-size: 0.86rem; line-height: 1.5; color: var(--navy-deep);
  animation: itemIn 0.3s var(--ease-expo);
}
.picked-note svg { flex: 0 0 auto; margin-top: 2px; color: var(--navy); }
