/* Flauna — field-notebook / specimen-label visual style.
   A nature game, not a wellness app or a dark arcade UI: two flat
   background layers (page-bg behind everything, paper for the card
   surfaces) create depth instead of a shadow, a serif is reserved for
   headline moments, hairline rules replace shadows everywhere else, and
   content is left-aligned throughout. CSS variables throughout so the
   palette — and its contrast rules — live in one place.

   Color usage rules (checked against WCAG AA — see the creative-direction
   brief for the full contrast table):
   - --clay is for FILLS/borders/decorative accents only, never text.
     Use --clay-text wherever clay-family text is wanted (5.27:1 on paper;
     plain --clay on paper is 2.63:1 and fails at any text size).
   - Never put --ink text on a solid --moss fill (2.40:1, fails) — moss
     fills get light/paper text on top. Moss AS TEXT on paper (5.39:1) or
     on a light moss-tinted background is fine.
   - --stone is for decorative dividers only (e.g. the specimen tag's
     hairline). --stone-strong is for borders that convey real state
     (selection/focus), and per the brief it should never carry that
     meaning alone — pair it with a fill/background change too.
   - Anything under 14px is a contrast risk regardless of color; small
     captions/meta text below uses --slate or --ink, not a fainter tone. */

:root {
  /* Raw palette (see creative-direction brief) */
  --page-bg: #DEDCC8;    /* behind everything outside the main card */
  --paper: #F2F0E6;      /* question/results card, any raised surface */
  --ink: #26291F;
  --moss: #3F6B4A;
  --clay: #C0895E;       /* fills/decoration only — never text, see above */
  --clay-text: #8A5732;  /* use for any clay-family TEXT instead of --clay */
  --slate: #4A6069;
  --stone: #DAD6C7;         /* decorative dividers only */
  --stone-strong: #90855F;  /* functional borders — selection/focus */
  --brick: #A9553A;         /* dedicated "wrong answer" fill — light text on top, like moss */

  --px-unit: 4px; /* one pixel of the torn-paper border art — see .paper-box */

  /* Precomputed tints (palette color mixed with --paper) — hand-computed
     rather than color-mix() so this renders identically on older engines.
     Recompute if the raw palette above ever changes. */
  --moss-tint: #DDE0D3;   /* moss @ ~12% over paper */
  --clay-tint: #ECE4D6;   /* clay @ ~12% over paper */

  /* Semantic aliases — the rest of this file reads through these, not the
     raw palette, so a future theme only has to change this block. */
  --color-bg: var(--page-bg);
  --color-surface: var(--paper);
  --color-border: var(--stone);
  --color-border-strong: var(--stone-strong);
  --color-text: var(--ink);
  --color-text-muted: var(--slate);
  --color-text-faint: var(--slate); /* small text is a contrast risk — no fainter than slate */
  --color-accent: var(--clay);          /* fills/borders only */
  --color-accent-text: var(--clay-text); /* clay-family TEXT, always safe */
  --color-accent-ink: var(--ink); /* text color placed on top of --color-accent fills */

  --color-correct-bg: var(--moss-tint);
  --color-correct-border: var(--moss);
  --color-correct-text: var(--moss);

  --color-wrong-bg: var(--paper);
  --color-wrong-border: var(--stone);
  --color-wrong-text: var(--slate);

  /* For text/hairline uses on a light (paper) background — timer urgency,
     review-answer "wrong" text. NOT for the option's own wrong-answer
     fill, which is a solid --brick fill with light text — see
     .option-btn.is-selected-wrong, which sets those explicitly instead of
     through this alias (light-on-brick and dark-on-paper are different
     enough treatments that sharing one alias between them was a bug). */
  --color-selected-wrong-bg: var(--clay-tint);
  --color-selected-wrong-border: var(--clay);
  --color-selected-wrong-text: var(--clay-text);

  --radius-card: 4px;
  --radius-md: 8px;
  --radius-sm: 4px;

  --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans: 'Work Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-pixel: 'Silkscreen', monospace; /* game-chrome only: tags, buttons, counters — never body copy */
}

* {
  box-sizing: border-box;
}

/* ---------- Paper box: torn-edge card/button treatment ---------- */
/* Ported from a Claude Design mockup (paper/, kept locally as reference —
   see paper/Paper Boxes.dc.html for the full specimen sheet and recipe
   comments). One 96x96 SVG tile per fill color, drawn on a 4px pixel
   grid, applied via border-image so it stretches to any box size with no
   corner distortion. background-clip: padding-box keeps the fill out of
   the torn edge; the drop-shadow is a hard 0-blur offset (pixel-art
   "cut-paper" shadow, not a soft one) that follows the torn silhouette
   rather than the rectangular box, which box-shadow can't do.
   This supersedes the earlier "hairline only, no shadow anywhere" rule
   for the elements it's applied to (header, cards, buttons, options) —
   an intentional revision, not an inconsistency. */

.paper-box,
.card,
.learn-more-section,
.btn-secondary,
.option-btn,
.score-block {
  position: relative;
  border: calc(4 * var(--px-unit)) solid transparent;
  border-image: url("borders/torn-paper.svg") 16 repeat;
  background:
    repeating-conic-gradient(rgba(38, 41, 31, 0.032) 0 25%, transparent 0 50%) 0 0 / calc(2 * var(--px-unit)) calc(2 * var(--px-unit)),
    linear-gradient(158deg, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0) 45%, rgba(38, 41, 31, 0.035)),
    var(--paper);
  background-clip: padding-box;
  filter: drop-shadow(var(--px-unit) var(--px-unit) 0 rgba(38, 41, 31, 0.3));
}

.paper-box--moss,
.option-btn.is-correct,
.score-block.is-correct {
  border-image: url("borders/torn-mossfill.svg") 16 repeat;
  background:
    repeating-conic-gradient(rgba(255, 255, 255, 0.05) 0 25%, transparent 0 50%) 0 0 / calc(2 * var(--px-unit)) calc(2 * var(--px-unit)),
    linear-gradient(158deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, 0.1)),
    var(--moss);
  filter: drop-shadow(var(--px-unit) var(--px-unit) 0 rgba(38, 41, 31, 0.35));
  color: var(--paper);
}

.paper-box--brick,
.option-btn.is-selected-wrong {
  border-image: url("borders/torn-brick.svg") 16 repeat;
  background:
    repeating-conic-gradient(rgba(255, 255, 255, 0.05) 0 25%, transparent 0 50%) 0 0 / calc(2 * var(--px-unit)) calc(2 * var(--px-unit)),
    linear-gradient(158deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, 0.1)),
    var(--brick);
  filter: drop-shadow(var(--px-unit) var(--px-unit) 0 rgba(38, 41, 31, 0.35));
  color: var(--paper);
}

.paper-box--clay,
.btn-primary {
  border-image: url("borders/torn-clay.svg") 16 repeat;
  background: var(--clay);
  filter: drop-shadow(var(--px-unit) var(--px-unit) 0 rgba(38, 41, 31, 0.35));
  color: var(--ink);
}

/* Tactile press: flush against the "page", shadow gone, on tap/click.
   Skipped automatically once disabled, since disabled elements don't
   receive :active in browsers. Cards/header aren't interactive, so they
   don't get this — only real buttons and options. */
.paper-box:not(:disabled):active,
.btn:not(:disabled):active,
.option-btn:not(:disabled):active {
  transform: translate(var(--px-unit), var(--px-unit));
  filter: none;
}

@media (hover: hover) {
  .paper-box:not(:disabled):hover,
  .btn:not(:disabled):hover,
  .option-btn:not(:disabled):hover {
    transform: translate(-1px, -1px);
  }
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--color-bg);
  color: var(--color-text);
}

body {
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

.app {
  position: relative;
  z-index: 1; /* explicit stack level above .scene-strip's 0 — see there */
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 0 16px 32px;
}

/* On a narrow viewport there are no side gutters to see the fixed scene
   through (unlike desktop, where it's visible either side of the centered
   column) — so once it's showing, add real scroll room below the content.
   Scrolling past the UI reveals more of the scene underneath it, since
   the scene itself is fixed and doesn't move with the page. */
body.has-scene .app {
  padding-bottom: 70vh;
}

/* ---------- Intro splash (see playIntroSplash in app.js) ---------- */
/* Header + main content start invisible so the very first thing on
   screen is the big centered logo over the scene, then crossfade in once
   the splash finishes/is skipped.

   The transition is scoped to only the REVEAL (splashing -> normal), not
   the initial hide — CSS applies whichever transition is in effect on the
   state being transitioned TO, so putting it only on the plain (non-
   splashing) rule means entering intro-splashing is an instant, silent
   snap to hidden, and leaving it is the smooth 0.6s crossfade. Without
   this split, the same 0.6s transition also applied when FIRST hiding
   the UI, which meant the real intro screen was briefly visible fading
   out before the splash had faded in over it — a flicker right at the
   start, worst on faster (desktop) paints. */
body:not(.intro-splashing) .app-header,
body:not(.intro-splashing) .main {
  transition: opacity 0.6s ease;
}

body.intro-splashing .app-header,
body.intro-splashing .main {
  opacity: 0;
}

.intro-splash {
  position: fixed;
  inset: 0;
  z-index: 2; /* above .app's 1 and .scene-strip's 0 */
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  /* No background of its own — the whole point is the scene stays
     visible behind the logo, not covered by a splash-screen color. */
}

.intro-splash-logo {
  /* A plain width in a real length unit, not a unitless scale() transform
     — width: clamp() with vw is completely ordinary CSS, unlike mixing a
     bare number with vw inside clamp() for scale() (see the .wordmark
     comment above for why that broke). Responsibly sized per device: a
     floor so it's never too small on a narrow phone, 55vw so it scales
     with the viewport in between, and a ceiling so it doesn't become
     enormous on a wide desktop window. */
  width: clamp(200px, 55vw, 480px);
  height: auto;
  transform: translateY(16px);
  opacity: 0;
  transition: opacity 2s ease, transform 2s ease;
}

.intro-splash.is-visible .intro-splash-logo {
  opacity: 1;
  transform: translateY(0);
}

.intro-splash.is-leaving {
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}

.app-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  /* Flat surface, not a torn-paper box: a top nav wants a clean, flush
     edge, not a jagged one, and the torn texture's transparent "holes"
     right at the very top of the viewport read as a gap rather than a
     tear. Own opaque background (the nature scene sits fixed behind the
     whole page) with a plain hairline instead. Same width as the UI
     below it (no negative margin) and a bit of breathing room underneath
     before the main card starts. */
  background: var(--paper);
  border-bottom: 1px solid var(--color-border);
  margin: 0 0 20px;
  padding: 10px 16px;
}

/* Wordmark: a real SVG now (public/logo/), not the CSS box-shadow
   pixel-art trick this used to be — same drawn-not-typed 5x7 logotype
   (see the "Flauna Logo" design sheet) exported as actual vector rects.
   The box-shadow version worked fine at its own fixed size, but scaling
   it up for the intro splash (see .intro-splash-logo) needed a transform,
   and mixing a unitless scale() with a vw-based clamp() turned out to be
   invalid CSS — an <img> just takes a width in any valid length unit,
   no transform gymnastics required. Four colour variants are stored in
   public/logo/ (clay/cream/ink/moss, matching the design sheet's
   colourways) — only clay is wired up anywhere right now. */
.wordmark {
  display: block;
  height: 22px;
  width: auto;
}

.app-header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.day-label {
  font-family: var(--font-pixel);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ---------- Audio controls (see AUDIO_LAYERS in app.js) ---------- */

.audio-control {
  position: relative;
}

.audio-toggle-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

.audio-toggle-btn:hover {
  background: var(--stone);
}

.audio-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 190px;
  background: var(--paper);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  box-shadow: 0 4px 14px rgba(38, 41, 31, 0.18);
  z-index: 5;
}

.audio-layer-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
}

.audio-layer-row + .audio-layer-row {
  border-top: 1px solid var(--stone);
  margin-top: 4px;
}

.audio-layer-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  color: var(--color-text);
  flex: none;
  white-space: nowrap;
}

.audio-layer-label input[type="checkbox"] {
  accent-color: var(--moss);
  width: 16px;
  height: 16px;
}

.audio-layer-volume {
  flex: 1;
  min-width: 0;
  accent-color: var(--clay);
}

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.loading {
  text-align: left;
  color: var(--color-text-muted);
  padding: 60px 0;
  font-size: 0.95rem;
}

/* ---------- Cards / generic ---------- */

.card {
  /* Torn-paper box treatment (border/background/shadow) comes from the
     shared .paper-box ruleset below — this just sets the card's own
     padding, since the border-image eats into the box differently than
     a hairline border did. */
  padding: 22px 18px;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ---------- Specimen tag (question card header) ---------- */

.specimen-tag {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-family: var(--font-pixel);
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-faint);
  padding-bottom: 10px;
  margin-bottom: 18px;
  border-bottom: 2px dotted var(--color-border);
}

.specimen-tag-right {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

/* The running score — bolder and in the accent color so the total
   climbing across the round is easy to notice at a glance, not just
   revealed all at once on the results screen. */
.specimen-tag-score {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--color-accent-text);
}

.specimen-tag-emoji {
  font-size: 0.95rem;
  letter-spacing: 0;
  text-transform: none;
}

/* ---------- Intro screen ---------- */

.intro-screen {
  text-align: left;
  padding-top: 24px;
}

.intro-kicker {
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-bottom: 8px;
}

.intro-title {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  font-weight: 600;
  margin: 0 0 12px;
}

.intro-body {
  color: var(--color-text-muted);
  font-size: 0.95rem;
  line-height: 1.5;
  margin: 0 0 28px;
}

.already-played-note {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  margin-top: 14px;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 10px 18px;
  font-family: var(--font-pixel);
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  cursor: pointer;
}

.btn-primary {
  /* --clay fill from .paper-box--clay below; --ink text is safe there
     (~4.9:1) — see the creative-direction contrast notes at the top. */
  width: 100%;
}

.btn-secondary {
  color: var(--color-text-muted);
  font-size: 0.75rem;
  min-height: 40px;
  padding: 8px 16px;
}

.btn:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Functional state (keyboard focus) — --stone-strong, not plain --stone,
   since this border is the thing telling someone an element is focused. */
.btn:focus-visible,
.option-btn:focus-visible {
  outline: 2px solid var(--color-border-strong);
  outline-offset: 2px;
}

/* ---------- Question screen ---------- */

.question-progress {
  display: flex;
  justify-content: flex-start;
  gap: 6px;
  margin-bottom: 18px;
}

.progress-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-border);
}

.progress-dot.is-done {
  background: var(--color-accent);
}

.progress-dot.is-current {
  background: var(--color-text-muted);
}

.question-type-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-faint);
  text-align: left;
  margin-bottom: 6px;
}

.points-earned-badge {
  margin-top: 14px;
  text-align: left;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--color-text-muted);
}

.points-earned-badge.is-correct {
  color: var(--color-correct-text);
}

.species-name-reveal {
  /* At 1.1rem (~17.6px) this is under the ~20px threshold where plain
     --clay might pass as large text, and --clay on paper (2.63:1) fails
     regardless of size — use --clay-text (5.27:1) for the headline color. */
  font-family: var(--font-serif);
  text-align: left;
  font-size: 1.1rem;
  color: var(--color-accent-text);
  font-weight: 600;
  margin-bottom: 10px;
}

/* ---------- "What" question image (Wikipedia thumbnail, best-effort) ---------- */

.what-image-wrap {
  margin-bottom: 16px;
}

.what-image-wrap.is-empty {
  display: none;
  margin: 0;
}

.what-image {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--color-surface); /* sits inside the paper card, not the outer page */
}

.what-image-skeleton {
  width: 100%;
  height: 180px;
  border-radius: var(--radius-md);
  background: var(--color-border);
  opacity: 0.6;
}

.question-text {
  font-size: 1.15rem;
  font-weight: 600;
  text-align: left;
  margin: 0 0 22px;
  line-height: 1.4;
}

.options-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.option-btn {
  display: block;
  width: 100%;
  min-height: 48px;
  text-align: left;
  padding: 12px 16px;
  color: var(--color-text);
  font-size: 0.98rem;
  font-family: inherit;
  cursor: pointer;
}

.option-btn:disabled {
  cursor: default;
}

/* The answer "stamp": a quick, slightly imperfect settle — not a smooth
   fade — the one deliberate feedback motion in the whole app besides the
   scene pieces. Plays once, on the render where the class is first set. */
@keyframes option-stamp {
  0%   { transform: scale(1.06) rotate(-1deg); opacity: 0.7; }
  55%  { transform: scale(0.97) rotate(0.6deg); }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

.option-btn.is-correct,
.option-btn.is-selected-wrong {
  animation: option-stamp 0.22s ease-out;
}

.option-btn.is-correct {
  /* Solid --moss fill + light text via .paper-box--moss below. */
  font-weight: 600;
}

.option-btn.is-selected-wrong {
  /* Solid --brick fill + light text via .paper-box--brick below — its own
     dedicated "wrong answer" color, not a clay workaround. */
}

.option-btn.is-muted {
  opacity: 0.55;
}

.option-btn.is-removed {
  display: none;
}

.question-footer {
  margin-top: 18px;
  display: flex;
  justify-content: flex-start;
}

.learn-more-card {
  margin-top: 18px;
  padding: 4px 0 4px 14px;
  border-left: 3px solid var(--color-accent);
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--color-text-muted);
}

.learn-more-card strong {
  color: var(--color-text);
}

.next-btn-wrap {
  margin-top: 18px;
}

/* ---------- Results screen ---------- */

.results-screen {
  padding-top: 8px;
}

.results-score {
  text-align: left;
  margin-bottom: 4px;
}

.results-score-value {
  /* Large text only needs 3:1, but plain --clay is 2.63:1 on paper and
     fails even that — --clay-text (5.27:1) is the safe warm option here. */
  font-family: var(--font-serif);
  font-size: 3rem;
  font-weight: 600;
  color: var(--color-accent-text);
  line-height: 1;
}

.results-score-label {
  font-size: 0.85rem;
  color: var(--color-text-muted);
  margin-top: 6px;
}

.score-block-row {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 22px 0 12px;
}

/* Torn-paper boxes (see the .paper-box system) instead of flat
   input-like squares, with the question number inside each one — reads
   as "5 specimen tags, one per question" rather than looking like a
   row of checkboxes. Thinner border than the standard .paper-box scale
   (--px-unit-based 16px would swallow a box this small) but the same
   torn-edge art, just compressed into a narrower frame. */
.score-block {
  width: 46px;
  height: 46px;
  border-width: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-pixel);
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.score-block.is-correct {
  color: var(--paper);
}

.flavour-stats {
  text-align: left;
  font-size: 0.85rem;
  color: var(--color-text-muted);
  margin-bottom: 22px;
}

.share-btn {
  width: 100%;
}

/* ---------- Review answers (toggle under Share) ---------- */

.review-answers-wrap {
  margin-top: 10px;
}

.review-toggle-btn {
  width: 100%;
}

.review-answers {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.review-answers[hidden] {
  display: none;
}

.review-item {
  padding: 12px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.review-item-type {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-faint);
  margin-bottom: 4px;
}

.review-item-question {
  font-size: 0.92rem;
  font-weight: 600;
  margin-bottom: 8px;
}

.review-item-answer {
  font-size: 0.88rem;
  padding: 2px 0;
}

.review-item-answer.is-correct {
  color: var(--color-correct-text);
}

.review-item-answer.is-wrong {
  color: var(--color-selected-wrong-text);
}

.review-item-meta {
  margin-top: 6px;
  font-size: 0.78rem;
  color: var(--color-text-faint);
}

.streak-line {
  text-align: left;
  font-size: 0.95rem;
  color: var(--color-text-muted);
  margin-top: 16px;
}

/* Its own paper surface, not bare on page-bg — page-bg is "the table the
   notebook sits on" and shouldn't carry body copy of its own, and this
   section holds a full paragraph. */
.learn-more-section {
  /* Torn-paper box treatment from .paper-box below. */
  margin-top: 20px;
  padding: 18px;
}

/* Wikipedia thumbnail (best-effort, see renderLearnMoreImage) — same
   treatment as .what-image, just its own class since the two are
   populated independently and never need to share state. */
.learn-more-image-wrap {
  margin-bottom: 14px;
}

.learn-more-image-wrap.is-empty {
  display: none;
  margin: 0;
}

.learn-more-image {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.learn-more-image-skeleton {
  width: 100%;
  height: 160px;
  border-radius: var(--radius-md);
  background: var(--color-border);
  opacity: 0.6;
}

.learn-more-section-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.learn-more-section-emoji {
  font-size: 2rem;
  line-height: 1;
}

.learn-more-section-name {
  font-family: var(--font-serif);
  font-size: 1.3rem;
  font-weight: 600;
}

.learn-more-section-body {
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* ---------- Nature scene ---------- */
/* A fixed, full-viewport woodland illustration sitting behind everything
   (negative z-index) — ported from a Claude Design mockup, kept as one
   fixed scene rather than randomized art. Lives outside #main so it
   survives every screen re-render. Five layers fade in as questions are
   answered; every UI surface in front of it (header, cards) carries its
   own opaque background so content stays readable on top of it. */

.scene-strip {
  /* z-index: 0 here + z-index: 1 on .app (below), rather than a negative
     value here — negative z-index behind a sibling that has its own
     background is a classic real-browser footgun (the ancestor's own
     background can end up painting over it in practice, unlike the naive
     spec reading). Explicit non-negative stack levels in the same
     stacking context are unambiguous. */
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #0b1215; /* the illustration's own base, showing before/between layers */
  pointer-events: none;
}

.scene-layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.7s steps(5), transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.scene-layer.is-revealed {
  opacity: 1;
  transform: translateY(0);
}

.scene-layer svg {
  display: block;
  width: 100%;
  height: 100%;
}

.scene-layer-background { z-index: 1; }
.scene-layer-tree       { z-index: 2; }
.scene-layer-shrub      { z-index: 3; }
.scene-layer-groundcover { z-index: 4; }
.scene-layer-creature   { z-index: 5; }

/* The foreground layers now fit their full width in view rather than
   cropping to cover (see the "meet" fit in app.js's sceneSvgWrap) — the
   whole composition is visible on any viewport without needing scroll
   room to reveal cropped-off parts, so mobile needs less of it than the
   70vh above. */
@media (max-width: 640px) {
  body.has-scene .app {
    padding-bottom: 40vh;
  }
}

.scene-grain {
  position: absolute;
  inset: 0;
  z-index: 6;
  opacity: 0.22;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* Ported animation set — kept exactly as designed. */
@keyframes sway1 { 0%, 100% { transform: rotate(-1.4deg); } 50% { transform: rotate(1.4deg); } }
@keyframes sway2 { 0%, 100% { transform: rotate(1.1deg); } 50% { transform: rotate(-1.6deg); } }
@keyframes sway3 { 0%, 100% { transform: rotate(-0.8deg); } 50% { transform: rotate(1.9deg); } }
@keyframes drift { from { transform: translateX(-24px); } to { transform: translateX(176px); } }
@keyframes bee { 0% { transform: translate(0,0); } 25% { transform: translate(7px,-4px); } 50% { transform: translate(14px,1px); } 75% { transform: translate(6px,4px); } 100% { transform: translate(0,0); } }
@keyframes hover { 0%, 100% { transform: translate(0,0); } 33% { transform: translate(-5px,-3px); } 66% { transform: translate(4px,2px); } }
@keyframes glide { 0% { transform: translate(0,0); } 50% { transform: translate(26px,-5px); } 100% { transform: translate(0,0); } }
@keyframes flutter { 0%, 100% { transform: translate(0,0) scaleX(1); } 50% { transform: translate(-3px,-2px) scaleX(0.7); } }
@keyframes wink { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

@media (prefers-reduced-motion: reduce) {
  .scene-strip * {
    animation: none !important;
  }
}

/* ---------- Testing tools (dev aid, not a shipped feature) ---------- */

.dev-tools {
  margin-top: 18px;
  background: var(--color-surface);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  padding: 4px 14px;
  color: var(--color-text-faint);
}

.dev-tools summary {
  cursor: pointer;
  padding: 10px 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text-muted);
}

.dev-tools-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 14px;
}

.dev-tools .btn-secondary {
  width: 100%;
}

@media (max-width: 360px) {
  .results-score-value {
    font-size: 2.5rem;
  }
  .score-block {
    width: 36px;
    height: 36px;
  }
}
