/*
 * §9a design + interaction pass — v3.
 *
 * v1 applied the brand book literally (uppercase, solid-fill selection) and
 * read flat and harsh. v2 fixed the HCI problems but kept a stark white page
 * and the brand display font running through every line of UI. This pass —
 * after two reference sites the client liked (noho.ink's warm block-colour
 * backgrounds and playful photo grid; kucibiome's quiz — segmented progress
 * bar, a real photo in frame on its own colour, restrained system type) —
 * goes further: a warm cream page instead of white, real Yo-Chi product
 * photography instead of the brand-PDF swirl, and the brand's own display
 * fonts (Simpliciter Sans, Doughy) pulled back to just the one place each
 * reference uses a display font — a header, a callout — with everything
 * else set in the system font stack so it reads like a native app, not a
 * brand pamphlet.
 */

@font-face {
  font-family: "Simpliciter Sans";
  src: url("/fonts/SimpliciterSans-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Simpliciter Sans";
  src: url("/fonts/SimpliciterSans-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Doughy";
  src: url("/fonts/Doughy-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --ink: #000000;
  --white: #ffffff;
  /* Vanilla Bean (brand p57) — the page's base colour now, not stark white.
     Both reference sites run a warm neutral behind everything; this is the
     brand's own version of that neutral, not an invented one. */
  --paper: #fbf3e6;
  --muted: rgba(0, 0, 0, 0.56);
  --line: rgba(0, 0, 0, 0.14);
  --line-soft: rgba(0, 0, 0, 0.08);

  /* Interactive surfaces (chips, option rows, fields, the appbar) sit on
     --paper as white cards, so they read as lifted content rather than
     disappearing into it the way they would if both were the same cream. */
  --card: #ffffff;

  /* Berry Blush (p56) — the one interactive accent, used as a tint+border,
     never as a big solid block (a full block reads harsh and, with white
     text on it, measures under WCAG AA at this weight/size — checked). */
  --accent: #ec5a6f;
  --accent-tint: rgba(236, 90, 111, 0.14);
  --accent-tint-strong: rgba(236, 90, 111, 0.22);

  --wash-vanilla: #fff6e9;
  --wash-frosty: #d8e9f2;
  --wash-coconut: #f2f1f3;
  /* Mats for the intro's little scattered photo stickers — distinct from
     --paper so they read as their own colour block, noho-style, not a
     photo floating loose on the page. */
  --mat-blue: #d8e9f2;
  --mat-pink: #f8dfe3;

  --radius-pill: 999px;
  --radius-card: 20px;
  --radius-field: 14px;

  /* The one place this pass draws a hard line: everything that isn't a
     header or the sign-off sticker sets in the system stack, not a brand
     display font — "web safe and slick", per the client's own direction,
     closer to how Apple/Culture Amp-style flows actually typeset. */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: light;
}

* { box-sizing: border-box; }
::selection { background: var(--accent-tint-strong); }

html, body { height: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 16px/1.5 var(--font-ui);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

/* position:relative + overflow-x:hidden are load-bearing for the JS-driven
   screen transition in main.js (animateSwap) — the outgoing/incoming screens
   sit absolutely positioned inside this box while they cross over. */
#app { max-width: 34rem; margin: 0 auto; min-height: 100%; position: relative; overflow-x: hidden; }

/* ---------------------------------------------------------------- chrome */

.page { display: flex; flex-direction: column; min-height: 100vh; }

/* Segmented bar + "N / total" numeral, replacing the old 3-dot indicator —
   kucibiome's quiz makes exactly this trade and it reads much more like
   "here is where you are in a known-length thing" than dots do. */
.appbar {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1.1rem 1.25rem 0.6rem;
}
.appbar-top { display: flex; align-items: center; justify-content: space-between; }
.appbar .wordmark { height: 15px; width: auto; display: block; }
.appbar .back {
  border: 0; background: none; padding: 0.25rem; margin: -0.25rem;
  font-size: 1.1rem; line-height: 1; color: var(--ink);
}
.progress-count {
  font-size: 0.78rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.progress-track { display: flex; gap: 5px; }
.progress-seg {
  flex: 1;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--line-soft);
  transition: background-color 0.25s var(--ease);
}
.progress-seg.on { background: var(--ink); }

.screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  padding: 0.75rem 1.25rem calc(2.5rem + env(safe-area-inset-bottom));
}

h1 {
  font-family: "Simpliciter Sans", sans-serif;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-size: 1.5rem;
  line-height: 1.25;
  margin: 0;
}

.header { margin: 0; color: var(--muted); font-size: 0.95rem; }
.hint { margin: 0; color: var(--muted); font-size: 0.9rem; }
.body { margin: 0; }

/* Flavour line — Q1/Q3 personality text filling the dead space below the
   scale/slider (28 Oct design review). Originally pinned to the bottom of
   the .screen flex column via margin-top: auto; moved 29 Oct 2026 to sit
   directly under the scale (Q1) / anchors (Q3) in normal flow instead —
   pinning it to the bottom left too big a gap above it. `.screen`'s own
   `gap` rule already gives it the same breathing room as every other
   element on the screen, so no extra margin is needed here. */
.flavor {
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
  font-style: italic;
  line-height: 1.45;
}

/* Loading — centred, branded "one moment" state while the initial GET is
   in flight. Pulses the same wordmark the appbar uses; the global
   prefers-reduced-motion rule below already freezes the animation. */
.loading-screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  padding: 2rem 1.25rem;
}
.loading-mark {
  height: 28px;
  width: auto;
  animation: loadingPulse 1.6s ease-in-out infinite;
}
@keyframes loadingPulse {
  0%, 100% { opacity: 0.35; transform: scale(0.92); }
  50% { opacity: 1; transform: scale(1); }
}
.loading-text { margin: 0; color: var(--muted); font-size: 0.9rem; }

/* ---------------------------------------------------------------- intro
 *
 * Restructured after noho.ink (block colour, a scattered photo grid) and
 * kucibiome's quiz (a real photo framed — in its own colour, not bled to
 * the edges — sitting above the pitch on a calm page). The old version
 * bled the photo to the screen edges and overlaid the headline on a
 * gradient scrim; this one frames it as a card with the page's cream
 * showing around it, the way both references actually do it, and adds a
 * two-photo "scattered stickers" moment stealing the grid's energy without
 * needing a whole tile wall for a single-screen intro. */

.intro { display: flex; flex-direction: column; min-height: 100vh; }
.intro-topbar { padding: 1.1rem 1.25rem 0; }
.intro-topbar .wordmark { height: 16px; width: auto; display: block; }

.intro-hero {
  position: relative;
  margin: 0.9rem 1rem 0;
  aspect-ratio: 5 / 4;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--mat-blue);
}
.intro-photo { width: 100%; height: 100%; object-fit: cover; display: block; }

.intro-collage {
  display: flex;
  gap: 0.85rem;
  padding: 0 1.5rem;
  margin: -1.05rem 0 0.5rem;
  position: relative;
  z-index: 1;
}
.collage-item {
  width: 60px;
  height: 60px;
  padding: 5px;
  border-radius: 14px;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.16);
  flex-shrink: 0;
}
.collage-item img { width: 100%; height: 100%; object-fit: cover; border-radius: 9px; display: block; }
.collage-item.c1 { background: var(--mat-pink); transform: rotate(-7deg); }
.collage-item.c2 { background: var(--wash-vanilla); transform: rotate(6deg); margin-top: 10px; }

.intro-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.2rem 1.5rem calc(2.5rem + env(safe-area-inset-bottom));
}
.intro-eyebrow { margin: 0; color: var(--muted); font-size: 0.95rem; }
.intro-headline {
  font-family: "Doughy", "Simpliciter Sans", sans-serif;
  font-weight: 400;
  font-size: 2.5rem;
  line-height: 1.05;
  margin: 0.1rem 0 0;
}
.intro-reassure { margin: 0.3rem 0 1rem; color: var(--muted); font-size: 0.95rem; max-width: 26rem; }
.intro-cta { width: 100%; }

/* ---------------------------------------------------------------- buttons */

button {
  font: inherit;
  cursor: pointer;
  color: inherit;
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 0.85rem 1.1rem;
  text-align: left;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease),
    color 0.15s var(--ease), transform 0.12s var(--ease);
}
button:active { transform: scale(0.97); }
button:disabled { opacity: 0.4; cursor: default; transform: none; }
button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.primary {
  text-align: center;
  font-weight: 700;
  background: var(--ink);
  border-color: var(--ink);
  color: var(--white);
  padding: 1rem 1.1rem;
}
.primary:active { transform: scale(0.98); }

.secondary {
  text-align: center;
  color: var(--muted);
  background: transparent;
  border-color: transparent;
  padding: 0.6rem 1.1rem;
}

/* ------------------------------------------------------ selection language
 * Shared by CSAT rows and chips: a tint + a coloured border + an explicit
 * checkmark, rather than a solid colour fill — so "selected" never depends
 * on colour alone, and reads as considered rather than loud. */

.scale { display: flex; flex-direction: column; gap: 0.6rem; }
.scale-option {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  min-height: 3.4rem;
  border-radius: var(--radius-card);
}
.scale-value {
  font-family: "Simpliciter Sans", sans-serif;
  font-weight: 700;
  width: 1.1rem;
  color: var(--muted);
}
.scale-check {
  margin-left: auto;
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  flex-shrink: 0;
}
.scale-option[aria-pressed="true"] {
  background: var(--accent-tint);
  border-color: var(--accent);
}
.scale-option[aria-pressed="true"] .scale-value { color: var(--ink); }
.scale-option[aria-pressed="true"] .scale-check {
  background: var(--accent);
  border-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 10.5l3 3 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}

.chips { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.6rem 1rem 0.6rem 0.7rem;
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: 0.95rem;
}
.chip-check {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  flex-shrink: 0;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.chip.on {
  background: var(--accent-tint);
  border-color: var(--accent);
}
.chip.on .chip-check {
  background: var(--accent);
  border-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 10.5l3 3 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 12px;
}

.field { display: flex; flex-direction: column; gap: 0.4rem; }
.field > span { font-size: 0.9rem; color: var(--muted); }
textarea, input[type="text"] {
  font: inherit;
  padding: 0.75rem;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-field);
  background: var(--card);
  color: inherit;
  resize: vertical;
  width: 100%;
}
textarea:focus, input[type="text"]:focus {
  outline: none;
  border-color: var(--ink);
}

/* ------------------------------------------------------------- consent quote
 * Added 29 Oct 2026 (design review) alongside the consent-screen rewrite —
 * same card treatment as .voucher-card (white card, 1.5px line, radius-field)
 * so it reads as "lifted content" the same way the rest of the UI does,
 * rather than inventing a new visual language for one screen.
 */
.quote-card {
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-field);
  padding: 0.9rem 1.05rem;
}
.quote-label {
  margin: 0 0 0.3rem;
  font-size: 0.78rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-weight: 700;
}
.quote-text {
  margin: 0;
  font-size: 0.98rem;
  font-style: italic;
  color: var(--ink);
}

/* ---------------------------------------------------------------- NPS slider */

.nps-value {
  font-family: "Simpliciter Sans", sans-serif;
  font-weight: 700;
  font-size: 3.4rem;
  line-height: 1;
  text-align: center;
  margin: 0.25rem 0;
  font-variant-numeric: tabular-nums;
}

.nps-track-wrap { padding: 0.6rem 0.2rem; }

.nps-slider {
  --fill: 50%;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 40px;
  background: transparent;
  margin: 0;
  padding: 0;
  border: none;
  cursor: pointer;
}
.nps-slider::-webkit-slider-runnable-track {
  height: 12px;
  border-radius: var(--radius-pill);
  background: linear-gradient(to right, var(--accent) var(--fill), var(--wash-coconut) var(--fill));
}
.nps-slider::-moz-range-track {
  height: 12px;
  border-radius: var(--radius-pill);
  background: var(--wash-coconut);
}
.nps-slider::-moz-range-progress {
  height: 12px;
  border-radius: var(--radius-pill);
  background: var(--accent);
}
.nps-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 30px; height: 30px;
  margin-top: -9px;
  border-radius: 50%;
  background: var(--card);
  border: 2.5px solid var(--ink);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
  transition: transform 0.12s var(--ease);
}
.nps-slider:active::-webkit-slider-thumb { transform: scale(1.15); }
.nps-slider::-moz-range-thumb {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--card);
  border: 2.5px solid var(--ink);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
}
.nps-slider:not(.touched)::-webkit-slider-thumb { background: var(--wash-coconut); }
.nps-slider:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--ink); outline-offset: 2px; }

.anchors { display: flex; justify-content: space-between; color: var(--muted); font-size: 0.85rem; }

.choices { display: flex; flex-direction: column; gap: 0.6rem; }

/* ------------------------------------------------------ confirmation screen
 *
 * Rewritten 29 October 2026 (design review): the screen read flat and
 * transactional with no imagery — see copy.js's comment above
 * `doneHeadline`. The old brand-tagline sticker (`.sign-off`, a stuck-on
 * washi-taped pill) is gone; the closing line is now just another
 * `.flavor` line, same treatment as DONE_SUBHEAD above it and the Q1/Q3
 * flavour lines elsewhere on the survey.
 */
.done-hero {
  position: relative;
  aspect-ratio: 2 / 1;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--mat-blue);
}
/* .intro-photo (width/height/object-fit/display) is reused on this img —
   same "framed card" treatment as the intro screen's hero shot. */

/* `.already` (29 Oct 2026): the already-submitted screen reuses this same
   hero photo, dialled back a touch so it doesn't read as a fresh "just
   happened" moment on a repeat visit — see copy.js's alreadySubmitted*
   comment and main.js's alreadySubmittedView(). */
.done-hero.already .intro-photo { filter: saturate(0.82); }

.voucher-card {
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-field);
  padding: 0.9rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.voucher-headline {
  font-family: "Simpliciter Sans", sans-serif;
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--accent);
}
.voucher-detail { font-size: 0.8rem; color: var(--muted); }

.done-bear {
  display: block;
  width: 140px;
  height: auto;
  margin: 0.2rem auto 0;
}

/* The merch link reuses `.secondary`'s muted, unbold, borderless look
   (29 Oct 2026: "even lighter and not bold") — `.secondary` itself is a
   `button` rule, so this repeats just enough of it for an `<a>`. */
a.secondary {
  display: block;
  text-align: center;
  color: var(--muted);
  text-decoration: none;
  padding: 0.6rem 1.1rem;
}

/* -------------------------------------------------------- not-found screen
 *
 * "Sorry, we're closed." (29 Oct 2026 design review, mockup "D — with
 * bear"). Unlike every other screen in the flow this one is centred rather
 * than left-aligned — deliberate: it's the one genuine dead end (no
 * question to answer, nowhere to go but back to a real link), so it's meant
 * to read more like a system/404 page than a step in the survey. It still
 * shares the page's warm chrome (the wordmark appbar via page(null, ...))
 * so it never feels like it's left the site.
 */
.screen.not-found {
  align-items: center;
  justify-content: center;
  text-align: center;
}

/* Same artwork and width as `.done-bear`, with one difference: that image's
   own bounding box includes its speech bubble hanging off to the right, so
   simply centring the <img> centres the bubble+bear pair, not the bear
   itself — the bear's body ends up visibly off-centre. `margin-left` here
   re-centres the bear's body specifically (Christian: "the base of the bear
   should be the centred part"); the offset is `.done-bear`'s 140px width
   scaled against the bear's own pixel bounding box measured out of the
   source PNG (see claude/design-review-findings.md for the measurement). */
.not-found-bear {
  display: block;
  width: 140px;
  height: auto;
  margin: 0 0 0.2rem 36px;
}

/* §9a: "spend the one real flourish on the voucher arriving." A confetti
   burst in the secondary palette (p56) — not a loop, not a distraction,
   just a beat of "nice one" before the page settles. Enlarged 29 Oct 2026
   (12 pieces, longer fall) after design review flagged the original as too
   subtle to register as the screen's one flourish. */
.confetti {
  position: relative;
  height: 0;
  pointer-events: none;
}
.confetti-piece {
  position: absolute;
  top: 0;
  width: 9px; height: 9px;
  border-radius: 2px;
  opacity: 0;
  animation: confettiFall 1100ms var(--ease) forwards;
}
@keyframes confettiFall {
  0% { opacity: 0; transform: translate(0, -12px) rotate(0deg); }
  14% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx, 20px), 150px) rotate(220deg); }
}
.confetti-piece.c0 { left: 4%;  background: #ec5a6f; animation-delay: 0ms;   --dx: 10px; }
.confetti-piece.c1 { left: 16%; background: #8bcb90; animation-delay: 40ms; --dx: -14px; }
.confetti-piece.c2 { left: 28%; background: #baadd1; animation-delay: 80ms; --dx: 18px; }
.confetti-piece.c3 { left: 40%; background: #fabc94; animation-delay: 20ms; --dx: -8px; }
.confetti-piece.c4 { left: 52%; background: #ec5a6f; animation-delay: 100ms; --dx: 12px; }
.confetti-piece.c5 { left: 64%; background: #8bcb90; animation-delay: 60ms; --dx: -20px; }
.confetti-piece.c6 { left: 76%; background: #baadd1; animation-delay: 10ms; --dx: 6px; }
.confetti-piece.c7 { left: 88%; background: #fabc94; animation-delay: 70ms; --dx: -10px; }
.confetti-piece.c8 { left: 22%; background: #e7b0be; animation-delay: 120ms; --dx: 16px; }
.confetti-piece.c9 { left: 70%; background: #e7b0be; animation-delay: 30ms; --dx: -16px; }
.confetti-piece.c10 { left: 10%; background: #baadd1; animation-delay: 135ms; --dx: -20px; top: 20px; }
.confetti-piece.c11 { left: 48%; background: #ec5a6f; animation-delay: 75ms;  --dx: 10px; top: 10px; }

@media (max-width: 24rem) {
  .intro-headline { font-size: 2.2rem; }
  .nps-value { font-size: 2.8rem; }
}

/* §9a: non-negotiable. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
