/* Funnel renderer — mobile-first. Shares the design-system tokens defined in
   heracles/components.css; the values below are the same, restated so this
   sheet still resolves if it is ever loaded on its own. */
:root {
  --bg:#F0E8DF; --surface:#fffffa; --accent-foreground:#fffffa; --input:var(--surface); --border:#e9ddcd;
  --primary:#a22c29; --primary-dark:#861f1c;
  --ink:#1f1d1a; --text:#3d3833; --muted:#6b635b; --faint:#97897a;
  --ok:#1e7846; --warn:#9a6a10;
  --radius:16px; --radius-lg:16px;
  --display:'Helvetica Neue', Helvetica, Arial, sans-serif;
  --sans:'Helvetica Neue', Helvetica, Arial, sans-serif;
  --heading-weight:600;
  --shadow:0 1px 2px rgba(31,29,26,.04), 0 8px 24px rgba(31,29,26,.06);
  --sp-prog-head:16px; --sp-ovl-head:5px; --sp-head-sub:9px;
  --sp-head-body:11px; --sp-head-cards:20px; --sp-card:9px;
  --sp-head-solo:32px;
}
* { box-sizing:border-box; }
html, body { margin:0; }
/* Inverted surface system — funnel only.
   The marketing site is a white page with beige sections; the funnel opens
   straight off it, so the page is white here too and the beige becomes the
   tint that cards and option rows are made of. The dash keeps the beige page
   (it is a workspace, entered from email, not from that handoff).
   Scoped to body.funnel because components.css is shared with the dash and
   loads after this file — a class selector out-specifies its :root. */
body.funnel {
  --bg:#ffffff;
  --surface:#f7f3ee;      /* cards, option rows — the tint that sits on white */
  --surface-2:#f0e8df;    /* the deeper tint: stat tiles, dose chips */
  --input:#ffffff;        /* fields invert too, so they read as cut into the card */

  background:var(--bg); color:var(--text); font-family:var(--sans);
  -webkit-font-smoothing:antialiased; line-height:1.5;
}
.funnel-shell {
  max-width:28rem; margin:0 auto; padding:1rem 1.25rem 4rem;  /* demo: max-w-md (448px) + px-5 */
  min-height:100dvh; display:flex; flex-direction:column;
}
/* Step content sits directly on the ambient background (no outer card). */
.step { padding-top:0; }
.step .q-title { font-size:1.42rem; line-height:1.16; }  /* questionnaire only */
.funnel-top { display:flex; align-items:center; gap:.5rem; padding:.25rem 0 1rem; }
.funnel-brand { font-family:var(--display); font-weight:var(--heading-weight); color:var(--ink); font-size:1.05rem; letter-spacing:.14em; }
/* Restart is a secondary action, so it takes the outlined-burgundy pill. As a
   white card with a hairline it was indistinguishable from the answer rows
   below it — it looked like something to pick, not a way out. */
.funnel-restart {
  margin-left:auto; font-size:.72rem; font-weight:600; color:var(--primary); text-decoration:none;
  border:1.5px solid var(--primary); padding:.32rem .8rem; border-radius:999px; background:transparent;
}
.funnel-restart:hover { background:var(--primary); color:#fff; }

/* progress */
.progress { height:3px; border-radius:999px; background:var(--border); overflow:hidden; margin-bottom:.5rem; }
.progress > span { display:block; height:100%; background:var(--primary); border-radius:999px; transition:width .35s ease; }
/* Tight, not 2rem — the gap under the progress bar was the single biggest
   source of dead space at the top of every step. */
.progress-label { font-size:.68rem; color:var(--muted); margin:0 0 var(--sp-prog-head); letter-spacing:.03em; }

/* card */
.card {
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg);
  padding:1.5rem 1.25rem; box-shadow:var(--shadow);
}
.eyebrow { font-size:.66rem; font-weight:700; text-transform:uppercase; letter-spacing:.12em; color:var(--primary); margin:0 0 var(--sp-ovl-head); }
.q-title { font-family:var(--display); font-weight:var(--heading-weight); color:var(--ink); font-size:1.42rem; line-height:1.16; letter-spacing:0; }
.q-sub, .q-help { font-size:.86rem; color:var(--muted); line-height:1.45; }
.q-body { font-size:.92rem; color:var(--text); line-height:1.5; }
/* Heading-block rhythm — see components.css for the reasoning. */
.q-title, .q-sub, .q-help, .q-body { margin:0 0 var(--sp-head-cards); }
.q-title:has(+ .q-sub), .q-title:has(+ .q-help) { margin-bottom:var(--sp-head-sub); }
.q-title:has(+ .q-body), .q-sub:has(+ .q-body), .q-help:has(+ .q-body) { margin-bottom:var(--sp-head-body); }
/* A heading with no sub-line under it sits directly on the choices. The
   base 20px is the gap below a sub-line, not below a heading, so on its
   own it crowds the first option — and makes those screens read tighter
   than the ones that do have a sub-line. 32px is about 1.4x the heading
   size: enough to separate, less than the ~49px a sub-line occupies,
   which would look like a line had been deleted. */
.q-title:has(+ .opts), .q-title:has(+ form) { margin-bottom:var(--sp-head-solo); }

/* options */
.opts, .cards { display:flex; flex-direction:column; gap:var(--sp-card); margin:0; }
/* Borderless: on a white page a filled row defines its own edge, and a line
   around every option turned a list of choices into a stack of boxes. The
   fill does the work the border used to (same 1.21:1 against the page), and
   the accent is spent on the selected ring instead of outlining everything. */
.opt {
  display:flex; align-items:center; gap:.75rem; width:100%; text-align:left;
  background:var(--surface-2); border:none; border-radius:var(--radius);
  padding:.85rem .95rem; font:inherit; color:var(--text); cursor:pointer;
  transition:background .15s, box-shadow .15s, transform .05s;
}
.opt:hover { background:var(--border); }
.opt:active { transform:scale(.995); }
.opt input { accent-color:var(--primary); width:1.15rem; height:1.15rem; flex:none; }
.opt-label { font-weight:500; font-size:.95rem; color:var(--ink); }
.opt-help { display:block; font-size:.78rem; color:var(--muted); margin-top:.1rem; }
/* Selected = a burgundy ring. An inset shadow rather than a border, so it
   appears without shifting the row's size and unselected rows carry no line
   at all. Still no colour wash — the fill is unchanged. */
.opt.selected { box-shadow:inset 0 0 0 1.5px var(--primary); background:var(--surface-2); }
.opt-divider { height:1px; background:var(--border); margin:.55rem .25rem; }

/* ── consent declarations ────────────────────────────────────────────────── */
/* Read-only list — a single "I agree" accepts the set, so these are statements
   to read rather than controls to operate. Ticks in the accent make it clear
   each line is part of what's being agreed, without implying eight tap targets. */
.decl-list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.7rem; }
.decl-item {
  position:relative; padding-left:1.65rem; font-size:.9rem; line-height:1.45; color:var(--text);
}
.decl-item::before {
  content:"✓"; position:absolute; left:0; top:0; width:1.2rem; height:1.2rem;
  display:grid; place-items:center; font-size:.7rem; font-weight:700;
  color:var(--primary); background:rgba(162,44,41,.1); border-radius:999px;
}

/* ── height / weight, metric or imperial ─────────────────────────────────── */
.measure-units { display:flex; gap:.4rem; margin-bottom:.75rem; }
.measure-unit-btn {
  flex:1; padding:.5rem .75rem; border-radius:999px; cursor:pointer;
  background:transparent; border:1.5px solid var(--border);
  font:inherit; font-size:.82rem; font-weight:600; color:var(--muted);
  transition:border-color .12s, color .12s, background .12s;
}
.measure-unit-btn:hover { border-color:var(--border-strong,#d6c7b2); }
/* Selected unit uses the same language as every other selected thing in the
   funnel: white surface, burgundy border and label. Never a colour wash. */
.measure-unit-btn.is-on { border-color:var(--primary); color:var(--primary); background:var(--surface); }

.measure-fields { display:flex; gap:.6rem; }
.measure-field { position:relative; flex:1; display:block; }
.measure-field .field { padding-right:3rem; }
.measure-suffix {
  position:absolute; right:1rem; top:50%; transform:translateY(-50%);
  font-size:.85rem; color:var(--muted); pointer-events:none;
}
/* Strip the spinners — they invite click-to-increment on a value people type. */
.measure-field input::-webkit-outer-spin-button,
.measure-field input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
.measure-field input[type=number] { -moz-appearance:textfield; appearance:textfield; }
.measure-error { color:var(--primary); }

/* free-text inputs */
.field {
  width:100%; border:1.5px solid var(--border); border-radius:var(--radius);
  background:#fff; padding:.8rem .9rem; font:inherit; color:var(--ink);
}
.field:focus { outline:none; border-color:var(--primary); box-shadow:0 0 0 3px rgba(162,44,41,.12); }
.field-hint { font-size:.75rem; color:var(--faint); margin:.4rem 0 0; }

/* buttons — primary is a flat filled pill, secondary an outlined burgundy pill */
.btn { display:block; width:100%; border:none; border-radius:999px; padding:.9rem 1rem; font:inherit; font-weight:600; cursor:pointer; text-align:center; }
.btn-primary { background:var(--primary); color:var(--accent-foreground); box-shadow:none; }
.btn-primary:hover { background:var(--primary-dark); }
.btn-primary:disabled { background:#d9a9a7; color:#fff; box-shadow:none; cursor:not-allowed; }
.btn-secondary { background:transparent; border:1.5px solid var(--primary); color:var(--primary); }
.btn-secondary:hover { background:var(--primary); color:#fff; }
.btn-ghost { background:transparent; border:1.5px solid var(--border); color:var(--text); }
.actions { margin-top:var(--sp-head-cards); display:flex; flex-direction:column; gap:.55rem; }
.hint { font-size:.75rem; color:var(--faint); text-align:center; margin:.55rem 0 0; }
.skip { display:block; width:100%; text-align:center; background:none; border:none; color:var(--primary); font:inherit; font-size:.82rem; font-weight:600; padding:.55rem; cursor:pointer; text-decoration:none; }

/* back */
.funnel-back { margin-top:.75rem; }
.funnel-back button { background:none; border:none; color:var(--primary); font:inherit; font-size:.85rem; cursor:pointer; padding:.3rem 0; }

/* terminal — same chip shape and palette as the plan/price labels */
.verdict-tag { display:inline-block; font-size:.62rem; text-transform:uppercase; letter-spacing:.09em; padding:.2rem .5rem; border-radius:6px; margin-bottom:.85rem; font-weight:700; }
.verdict-eligible { background:#c0d9af; color:#3c493f; }
.verdict-review { background:rgba(180,120,20,.14); color:var(--warn); }
.verdict-rejected { background:var(--primary); color:#fff; }
.terminal-reason { font-size:.78rem; color:var(--faint); margin:.6rem 0 0; }

/* content: value-prop ticks */
.ticks { list-style:none; margin:.25rem 0 0; padding:0; display:flex; flex-direction:column; gap:.55rem; }
.ticks li { position:relative; padding-left:1.65rem; font-size:.92rem; color:var(--text); }
.ticks li::before {
  content:"✓"; position:absolute; left:0; top:-.05rem; width:1.2rem; height:1.2rem;
  display:grid; place-items:center; font-size:.72rem; font-weight:700;
  color:var(--primary); background:rgba(162,44,41,.1); border-radius:999px;
}

/* content: info card (image + supportive text) */
/* Lead image on a content screen. A fixed 3:2 frame with a cover crop, so a
   set of photos with mixed native ratios (and whatever gets shot later) all
   render at the same height — otherwise a portrait shot swallows the screen
   and the step-to-step rhythm breaks. */
.info-media {
  margin:0 0 var(--sp-head-cards); border-radius:var(--radius); overflow:hidden;
  background:var(--surface-2,#f7f3ee); aspect-ratio:3/2;
}
.info-media img { display:block; width:100%; height:100%; object-fit:cover; }

/* content: stat card (optional lifestyle image below the figure) */
.stat-media { border-radius:var(--radius-lg); overflow:hidden; margin:1.25rem 0 0; aspect-ratio:1/1; background:var(--surface-2,#f7f3ee); }
.stat-media img { width:100%; height:100%; object-fit:cover; object-position:center 28%; display:block; }
.stat { text-align:center; padding:.5rem 0; }
.stat-figure { font-family:var(--display); font-weight:var(--heading-weight); color:var(--primary); font-size:2.1rem; line-height:1.1; margin:0 0 .5rem; letter-spacing:0; }
.stat .q-body { text-align:center; }

/* content: mandatory notice */
.notice { border-left:3px solid var(--primary); background:rgba(162,44,41,.04); border-radius:8px; padding:.85rem 1rem; }
.notice-label { font-size:.66rem; text-transform:uppercase; letter-spacing:.12em; color:var(--primary); font-weight:600; margin:0 0 .35rem; }
.notice .q-title { font-size:1.15rem; }
.notice .q-body { margin-bottom:0; }

/* recommendation card */
.rec-card { border:1px solid var(--border); border-radius:var(--radius); background:var(--bg); padding:.5rem .95rem; margin:1rem 0 .35rem; }
.rec-row { display:flex; justify-content:space-between; align-items:baseline; gap:1rem; padding:.55rem 0; border-bottom:1px solid var(--border); font-size:.9rem; }
.rec-row:last-child { border-bottom:none; }
.rec-row span { color:var(--muted); }
.rec-row b { color:var(--ink); text-align:right; }

/* ending: GP block + signposts */
.gp-block { border:1px solid var(--border); background:var(--bg); border-radius:var(--radius); padding:.9rem 1rem; margin-top:1.1rem; font-size:.88rem; color:var(--text); }
.gp-title { font-weight:600; color:var(--ink); margin:0 0 .3rem; }
.gp-block p:last-child { margin:0; }
.signposts { display:flex; flex-direction:column; gap:.55rem; margin-top:1.1rem; }
.signpost { display:flex; flex-direction:column; text-decoration:none; border:1px solid var(--border); background:var(--surface); border-radius:var(--radius); padding:.75rem .9rem; }
.signpost b { color:var(--ink); font-size:.92rem; }
.signpost span { color:var(--muted); font-size:.8rem; }

/* staff preview banner */
.preview-banner { background:var(--warn); color:#fff; text-align:center; font-size:.72rem; font-weight:600; letter-spacing:.04em; padding:.35rem; border-radius:8px; margin-bottom:.75rem; }

/* Whose account this checkout belongs to. An authenticated session silently
   overrides anything typed into the account form, so the funnel says so. */
.signed-in { display:flex; align-items:center; gap:.75rem; flex-wrap:wrap;
  background:var(--surface-2); border:1px solid var(--border); border-radius:10px;
  padding:.5rem .75rem; margin-bottom:.75rem; font-size:.8rem; color:var(--muted); }
.signed-in-main { flex:1 1 auto; min-width:0; }
.signed-in-main b { color:var(--ink); font-weight:600; }
.signed-in-action { flex:none; color:var(--accent); font-weight:600; text-decoration:none; white-space:nowrap; }
.signed-in-action:hover { text-decoration:underline; }
.signed-in-note { flex:1 1 100%; margin:.35rem 0 0; font-size:.76rem; line-height:1.45; }
.signed-in--warn { background:rgba(162,44,41,.06); border-color:rgba(162,44,41,.3); }
.signed-in--warn .signed-in-main b { color:var(--accent); }

/* validation error */
.form-error { background:rgba(162,44,41,.08); color:var(--primary); border:1px solid rgba(162,44,41,.25); border-radius:10px; padding:.6rem .8rem; font-size:.82rem; margin:0 0 1rem; }

/* building-your-plan interstitial (auto-advancing) */
.bp { text-align:center; padding:1.5rem 0 1rem; }
.bp-title { text-align:center; }
.bp-author { display:inline-flex; align-items:center; gap:.65rem; margin:.4rem 0 2rem; }
.bp-avatar { width:44px; height:44px; border-radius:999px; object-fit:cover; flex:none; }
.bp-author-txt { text-align:left; }
.bp-author-name { font-weight:600; color:var(--ink); font-size:.9rem; line-height:1.2; }
.bp-author-role { font-size:.8rem; color:var(--muted); line-height:1.2; }
.bp-steps { list-style:none; margin:0 auto; padding:0; display:flex; flex-direction:column; gap:1.1rem; max-width:20rem; text-align:left; }
.bp-step { display:flex; align-items:center; gap:.75rem; font-size:1rem; color:var(--ink); opacity:0; animation:bp-fade .5s ease forwards; }
.bp-step:nth-child(1) { animation-delay:.2s; }
.bp-step:nth-child(2) { animation-delay:1.5s; }
.bp-step:nth-child(3) { animation-delay:2.8s; }
/* Outlined terracotta progress ring per step (sweeps round), then a check draws in. */
.bp-check { flex:none; width:1.7rem; height:1.7rem; }
.bp-check svg { width:100%; height:100%; display:block; }
.bp-track { fill:none; stroke:var(--border); stroke-width:2.5; }
.bp-prog { fill:none; stroke:var(--primary); stroke-width:2.5; stroke-linecap:round; stroke-dasharray:94.25; stroke-dashoffset:94.25; transform:rotate(-90deg); transform-origin:18px 18px; }
.bp-tick { fill:none; stroke:var(--primary); stroke-width:2.5; stroke-linecap:round; stroke-linejoin:round; stroke-dasharray:18; stroke-dashoffset:18; opacity:0; }
.bp-step:nth-child(1) .bp-prog { animation:bp-sweep 1.2s ease forwards .2s; }
.bp-step:nth-child(2) .bp-prog { animation:bp-sweep 1.2s ease forwards 1.5s; }
.bp-step:nth-child(3) .bp-prog { animation:bp-sweep 1.2s ease forwards 2.8s; }
.bp-step:nth-child(1) .bp-tick { animation:bp-draw .3s ease forwards 1.4s; }
.bp-step:nth-child(2) .bp-tick { animation:bp-draw .3s ease forwards 2.7s; }
.bp-step:nth-child(3) .bp-tick { animation:bp-draw .3s ease forwards 4.0s; }
@keyframes bp-fade { from { opacity:0; transform:translateY(5px); } to { opacity:1; transform:none; } }
@keyframes bp-sweep { to { stroke-dashoffset:0; } }
@keyframes bp-draw { to { stroke-dashoffset:0; opacity:1; } }
.bp-form { display:none; }

/* recommendation price line */
/* Prices stay in the sans, bold. Money is data, not a heading; setting it in
   the heading face made it read as decorative rather than as the number to compare. */
.rec-price-line { margin:1.1rem 0 0; color:var(--muted); font-variant-numeric:tabular-nums; }
.rec-price-line b { font-family:var(--sans); font-size:1.5rem; color:var(--ink); font-weight:700; }

/* htmx */
.htmx-swapping #funnel-card, #funnel-card.htmx-swapping { opacity:.35; transition:opacity .12s; }
[x-cloak] { display:none !important; }

@media (min-width:640px) {
  .funnel-shell { padding:2rem 1rem 4rem; }
  .card { padding:2rem 1.75rem; }
  .q-title, .step .q-title { font-size:1.6rem; }
}

/* ── Weight-loss projection chart (WL / GLP-1 expected-loss card) ─────────── */
.wl-proj { margin:1.25rem 0 .25rem; }
.wl-proj-svg { display:block; width:100%; height:auto; overflow:visible; }
.wl-area { fill:var(--primary); opacity:.10; }
.wl-line { fill:none; stroke:var(--primary); stroke-width:2.5; stroke-linejoin:round; stroke-linecap:round; }
.wl-axis { stroke:var(--border); stroke-width:1; }
.wl-dot { fill:var(--primary); stroke:var(--accent-foreground); stroke-width:2; }
.wl-dot-end { fill:var(--primary-dark); }
.wl-tick { fill:var(--faint); font:500 11px var(--sans); text-anchor:middle; }
.wl-axis-label { fill:var(--faint); font:500 10px var(--sans); letter-spacing:.02em; }
.wl-label { fill:var(--muted); font:600 11px var(--sans); }
.wl-label-end { fill:var(--ink); font:700 12px var(--sans); }
.wl-proj-cap { margin-top:.5rem; font-size:.72rem; line-height:1.4; color:var(--faint); }

/* ── Campaign forms ───────────────────────────────────────────────────────
   Campaign landing pages borrow this stylesheet wholesale (see
   campaigns/templates/campaigns/base.html). The only thing they need that
   the questionnaire does not is vertical rhythm between stacked fields —
   the questionnaire asks one thing per screen, so it never had to space
   two of them. */
.campaign-field { margin-bottom: 1.35rem; }
.campaign-field > label { display: block; font-weight: 600; margin-bottom: .35rem; }
.campaign-field .field-hint { margin: 0 0 .5rem; }
.campaign-field .opts { margin-top: .5rem; }
.campaign-field .opt { cursor: pointer; }
