/* style.css — Tif.Pink Birthday Slice game UI (HUD, touch controls, overlays).
   Built on tokens from ../assets/css/base.css */

#game {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  overflow: hidden;
  background: var(--sky);
  touch-action: none; /* prevent scroll/zoom while playing */
  user-select: none; -webkit-user-select: none;

  /* Responsive layout vars — driven by data-device-class CSS rules.
     DESIGN_REQUIRED: defaults below are functional placeholders. */
  --control-scale: 1;
  --overlay-max-w: 720px;
  --obj-min: 160px;

  /* Approved Phase 3 semantic tokens (Secondary Button + Icon Control + Quest Card +
     Reward Chip) — VALUES RESOLVED from the authoritative Figma variable export
     (v1.1.13). Figma is the source of truth (v1.1); these are NO LONGER placeholders.
     NAMES mirror Figma variables; only the hex VALUES were filled in. */
  --action-secondary: #E7F6FF;        /* Color/Action/Secondary (Secondary Button Default) — Figma authoritative */
  --secondary-pressed: #B8E4FF;       /* Color/Action/Secondary Pressed — Figma authoritative */
  --action-disabled: #F4E8E1;         /* Color/Action/Disabled (shared disabled/locked neutral surface) — Figma authoritative */
  --icon-primary: #2A2230;            /* Color/Icon/Primary — Figma authoritative */
  --icon-on-brand: #FFFFFF;           /* Color/Icon/On Brand — Figma authoritative */
  --icon-on-disabled: #766D7D;        /* Color/Icon/On Disabled — Figma authoritative */
  --quest-active-surface: #FFFCF8;     /* Color/Quest/Active Surface — Figma authoritative */
  --quest-active-border: #B8E4FF;      /* Color/Quest/Active Border — Figma authoritative */
  --quest-progress-track: #FBE8D0;     /* Color/Quest/Progress Track — Figma authoritative */
  --quest-progress-fill: #65C0F4;      /* Color/Quest/Progress Fill — Figma authoritative */
  --quest-complete-surface: #E8F6E6;   /* Color/Quest/Complete Surface — Figma authoritative */
  --quest-complete-accent: #75BD70;    /* Color/Quest/Complete Accent — Figma authoritative */
  --quest-complete-border: #75BD70;    /* Color/Quest/Complete Border — Figma authoritative */
  --quest-locked-surface: #F4E8E1;     /* Color/Quest/Locked Surface — Figma authoritative */
  --quest-locked-text: #766D7D;        /* Color/Quest/Locked Text — Figma authoritative */
  --quest-locked-border: #9B6A52;      /* Color/Quest/Locked Border — Figma authoritative */
  --quest-reward: #F6C94C;             /* Color/Quest/Reward — Figma authoritative */

  /* Approved Phase 3 semantic tokens (Reward Chip) — VALUES RESOLVED (v1.1.13). */
  --reward-available-surface: #FFF5C8; /* Color/Reward/Available Surface — Figma authoritative */
  --reward-available-border: #FFE280;  /* Color/Reward/Available Border — Figma authoritative */
  --reward-earned-surface: #E8F6E6;    /* Color/Reward/Earned Surface — Figma authoritative */
  --reward-earned-border: #BFE6B9;     /* Color/Reward/Earned Border — Figma authoritative */
  --reward-locked-surface: #F4E8E1;    /* Color/Reward/Locked Surface — Figma authoritative */
  --reward-locked-border: #9B6A52;     /* Color/Reward/Locked Border — Figma authoritative */
  --reward-glyph: #F6C94C;             /* Color/Reward/Glyph — Figma authoritative */
  --reward-text: #2A2230;              /* Color/Reward/Text — Figma authoritative */
  --reward-locked-text: #766D7D;      /* Color/Reward/Locked Text — Figma authoritative */
  --hud-surface: #FFFCF8;             /* Color/HUD/Surface */
  --hud-border: #B8E4FF;              /* Color/HUD/Border */
  --hud-text: #2A2230;                /* Color/HUD/Text */
  --hud-subtext: #766D7D;             /* Color/HUD/Subtext */
  --hud-progress-track: #FBE8D0;      /* Color/HUD/Progress Track */
  --hud-progress-fill: #65C0F4;       /* Color/HUD/Progress Fill */
  --hud-star: #F6C94C;               /* Color/HUD/Star */
  --hud-star-surface: #FFF5C8;        /* Color/HUD/Star Surface */
  --dialog-surface: #FFFCF8;          /* Color/Dialog/Surface */
  --dialog-border: #FBE8D0;           /* Color/Dialog/Border */
  --dialog-title: #2A2230;            /* Color/Dialog/Title */
  --dialog-body: #766D7D;             /* Color/Dialog/Body */
  --celebration-accent: #F45C92;      /* Color/Dialog/Celebration Accent */
  --parent-gate-accent: #9B6A52;      /* Color/Dialog/Parent Gate Accent */
  --soft-accent: #FFE5EF;             /* Color/Dialog/Soft Accent */
  --birthday-surface: #FFE5EF;        /* Color/Birthday/Surface */
  --birthday-border: #FFA8C6;         /* Color/Birthday/Border */
  --birthday-title: #2A2230;         /* Color/Birthday/Title */
  --birthday-body: #51475B;           /* Color/Birthday/Body (corrected for a11y contrast) */
  --birthday-glyph: #F6C94C;          /* Color/Birthday/Glyph (Sparkle/Gift/Crown/Star) */
  --birthday-finale-accent: #F45C92;  /* Color/Birthday/Finale Accent */
  --replay-surface: #E7F6FF;          /* Color/Birthday/Replay Surface */
  --replay-border: #B8E4FF;           /* Color/Birthday/Replay Border */
  --radius-lg: 28px;                   /* large radius (HUD/Dialog/Birthday CTA surfaces) */
  --radius-pill: 999px;               /* pill radius (inner chips/bars) */
}

/* Keep viewport-derived values in the stylesheet so runtime layout changes do
   not create inline style attributes under a strict CSP. */
#game[data-device-class="compact-phone"] { --control-scale: .9; --overlay-max-w: 320px; --obj-min: 92px; }
#game[data-device-class="large-phone"] { --control-scale: 1; --overlay-max-w: 420px; --obj-min: 110px; }
#game[data-device-class="tablet"] { --control-scale: 1.1; --overlay-max-w: 560px; --obj-min: 140px; }
#game[data-device-class="ipad"] { --control-scale: 1.25; --overlay-max-w: 680px; --obj-min: 160px; }
#game[data-device-class="desktop"] { --control-scale: 1; --overlay-max-w: 720px; --obj-min: 160px; }

/* ---------- responsive device-class reflow (layout logic only) ----------
   Final visual treatment is DESIGN_REQUIRED from the Figma master.
   These rules only adapt spacing/sizing per device class. */
#game[data-device-class="compact-phone"] .hud,
#game[data-device-class="large-phone"] .hud { gap: 8px; padding: max(8px, env(safe-area-inset-top)) 10px 8px; }
#game[data-device-class="compact-phone"] .hud-brand,
#game[data-device-class="large-phone"] .hud-brand { font-size: clamp(12px, 3.4vw, 16px); padding: 5px 10px; }
#game[data-device-class="compact-phone"] .obj,
#game[data-device-class="large-phone"] .obj { min-width: var(--obj-min); padding: 5px 8px; }
#game[data-device-class="compact-phone"] .obj-label { font-size: 11px; }
#game[data-device-class="compact-phone"] .pip { width: 12px; height: 12px; }
#game[data-device-class="compact-phone"] .card { padding: 18px; }
#game[data-device-class="compact-phone"] .card h1 { font-size: 22px; }
#game[data-device-class="compact-phone"] .card h2 { font-size: 18px; }
#game[data-device-class="compact-phone"] .tada { font-size: clamp(24px, 8vw, 34px); }
/* Tablet/iPad: a touch more breathing room for controls + cards */
#game[data-device-class="tablet"] .joystick,
#game[data-device-class="ipad"] .joystick { width: clamp(130px, 20vw, 200px); height: clamp(130px, 20vw, 200px); }
#game[data-device-class="tablet"] .action-btn,
#game[data-device-class="ipad"] .action-btn { width: clamp(80px, 12vw, 120px); height: clamp(80px, 12vw, 120px); }
/* Desktop 16:9: keep the play field centered with a comfortable max width so the
   world isn't stretched absurdly wide on ultra-wide monitors. */
#game[data-device-class="desktop"] #stage { width: min(100%, 177.78vh); margin: 0 auto; left: 50%; transform: translateX(-50%); }
#stage { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* ---------- HUD ---------- */
.hud {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: 12px;
  padding: max(10px, env(safe-area-inset-top)) 14px 10px;
  pointer-events: none;
  flex-wrap: wrap;
}
.hud-brand {
  font-weight: 800; letter-spacing: .5px;
  background: rgba(255,255,255,.82); color: var(--brown-deep);
  padding: 6px 12px; border-radius: 999px; box-shadow: var(--shadow);
  font-size: clamp(14px, 2.2vw, 18px);
}
.objectives { display: flex; gap: 10px; flex: 1; flex-wrap: wrap; }
.obj {
  background: rgba(255,255,255,.82); border-radius: 14px; padding: 6px 10px;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 4px; min-width: 120px;
}
.obj-label { font-size: 12px; color: var(--ink-soft); font-weight: 700; }
.pips { display: flex; gap: 4px; }
.pip { width: 14px; height: 14px; border-radius: 50%; background: #e7d8c9; box-shadow: inset 0 0 0 2px #fff; }
.pip.done { background: var(--green-deep); }
.badges { display: flex; gap: 8px; }
.badge {
  background: var(--gold); color: #6b4e00; font-weight: 800; font-size: 12px;
  padding: 6px 10px; border-radius: 999px; box-shadow: var(--shadow);
  display: inline-flex; align-items: center; gap: 6px;
}
.badge-glyph { width: 20px; height: 20px; display: block; flex: 0 0 auto; } /* genuine Figma Crown vector (no emoji) */

/* ---------- prompt ---------- */
.prompt {
  position: absolute; left: 50%; bottom: 14%;
  transform: translateX(-50%);
  background: rgba(255,255,255,.92); color: var(--ink);
  padding: 12px 18px; border-radius: 999px; font-weight: 700;
  box-shadow: var(--shadow); font-size: clamp(14px, 2.4vw, 18px);
  animation: bob 1.4s ease-in-out infinite;
}
@keyframes bob { 0%,100%{ transform: translateX(-50%) translateY(0);} 50%{ transform: translateX(-50%) translateY(-6px);} }

/* ---------- touch controls ---------- */
.touch { position: absolute; inset: 0; pointer-events: none; }
.joystick {
  position: absolute; left: 4%; bottom: 6%;
  width: calc(clamp(110px, 22vw, 160px) * var(--control-scale, 1));
  height: calc(clamp(110px, 22vw, 160px) * var(--control-scale, 1));
  border-radius: 50%; background: rgba(255,255,255,.35); border: 3px solid rgba(255,255,255,.6);
  pointer-events: auto; touch-action: none;
}
.stick {
  position: absolute; left: 50%; top: 50%; width: 46%; height: 46%;
  transform: translate(-50%, -50%); border-radius: 50%;
  background: rgba(255,255,255,.92); box-shadow: var(--shadow);
}
.action-btn {
  position: absolute; right: 5%; bottom: 8%;
  width: calc(clamp(72px, 14vw, 104px) * var(--control-scale, 1));
  height: calc(clamp(72px, 14vw, 104px) * var(--control-scale, 1));
  border-radius: 50%; border: none; pointer-events: auto;
  background: var(--gold); color: #6b4e00; font-size: 32px; font-weight: 900;
  box-shadow: var(--shadow);
}
.action-btn:active { transform: scale(.94); }

/* ---------- overlays / modals ---------- */
.overlay {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(40, 25, 20, .45); padding: 18px; z-index: 20;
}
.card {
  background: var(--cream); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 22px; max-width: min(var(--overlay-max-w, 720px), 92vw); width: 100%; text-align: center;
  max-height: 90vh; overflow: auto;
}
.card h1 { margin: 0 0 6px; color: var(--brown-deep); }
.card h2 { margin: 0 0 10px; color: var(--brown-deep); }
.card p { color: var(--ink-soft); line-height: 1.5; }
/* Primary Button — Figma Phase 3 (Primary Button PASS) seam.
   Scoped to primary actions only; do NOT generalize to other components.
   Figma values RESOLVED from the authoritative component (Figma node 14:14) — the source of
   truth, NOT placeholders:
     Play    Default #F45C92  Pressed #D94079  Disabled #FFE5EF
     Parent  Default #B92C63  Pressed #8F214D  Disabled #F4E8E1
   Approved: Play/Parent modes, Default/Pressed/Disabled states, 64px preferred / 56px min
   touch target, Nunito Bold 20/28, pressed scale 0.96, Fast 140ms, disabled quiet. */
.btn {
  --btn-fill-play: #F45C92;        /* token: Color/Action/Primary (Play Default) — Figma authoritative */
  --btn-fill-parent: #B92C63;      /* token: Color/Action/Primary (Parent Default) — Figma authoritative */
  --btn-pressed-play: #D94079;     /* token: Color/Action/Primary Pressed (Play) — Figma authoritative */
  --btn-pressed-parent: #8F214D;  /* token: Color/Action/Primary Pressed (Parent) — Figma authoritative */
  --btn-disabled-play: #FFE5EF;    /* token: Color/Action/Primary Disabled (Play) — Figma authoritative */
  --btn-disabled-parent: #F4E8E1;  /* token: Color/Action/Primary Disabled (Parent) — Figma authoritative */
  --btn-disabled-text: #766D7D;    /* token: Color/Text/On Disabled (Disabled Text) — Figma authoritative */
  --btn-fill: var(--btn-fill-play);
  --btn-pressed: var(--btn-pressed-play);
  --btn-disabled-surface: var(--btn-disabled-play);
  display: inline-flex; align-items: center; justify-content: center;
  margin: 8px 6px 0; padding: 0 22px;
  min-height: 64px; min-width: 64px;      /* approved child touch target (64 preferred / 56 floor) */
  border: none; border-radius: var(--radius, 18px);
  background: var(--btn-fill); color: #fff;
  font-family: var(--font-body, "Nunito", system-ui, sans-serif);
  font-weight: 700; font-size: 20px; line-height: 28px;   /* approved label type */
  box-shadow: var(--shadow);
  transition: transform 140ms ease-out, background-color 140ms ease-out, opacity 140ms ease-out; /* Fast */
}
/* Secondary Button — Figma Phase 3 (Secondary Button PASS) seam.
   Scoped to secondary/reversible actions (Back/Later/Maybe/Not Now) ONLY.
   Pill geometry, NO elevation, subordinate to Primary. Do NOT generalize to other components.
   VALUES RESOLVED from the authoritative Figma variable export (v1.1.13) — no placeholders remain.
   Approved: Play/Parent modes, Default/Pressed/Disabled states, 64/56px touch, Nunito Bold
   20/28, pressed scale 0.96, Fast 140ms, pill, icon pending INSTANCE_SWAP. */
.btn.secondary {
  --btn2-fill-play: var(--action-secondary);  /* token: Color/Action/Secondary (Play) — Figma authoritative #E7F6FF */
  --btn2-fill-parent: var(--action-secondary);/* token: Color/Action/Secondary (Parent) — same resolved token (parent variant not separately specified) */
  --btn2-fill: var(--btn2-fill-play);
  --btn2-text: var(--ink);                    /* calm dark ink on light fill (accessible, approved base token) */
  --btn2-pressed: var(--secondary-pressed);   /* token: Color/Action/Secondary Pressed — Figma authoritative #B8E4FF */
  --btn2-disabled-fill: var(--action-disabled);/* token: Color/Action/Disabled — Figma authoritative #F4E8E1 */
  --btn2-disabled-text: #766D7D;              /* token: Color/Text/On Disabled — Figma authoritative #766D7D */
  background: var(--btn2-fill); color: var(--btn2-text);
  box-shadow: none;                           /* Secondary: no default elevation */
  border-radius: 999px;                       /* pill geometry */
}
[data-mode="parent"] .btn.secondary { --btn2-fill: var(--btn2-fill-parent); } /* Parent mode-aware fill (seam) */
.btn.secondary:active { transform: scale(0.96); background: var(--btn2-pressed); } /* press scale + stronger sky */
.btn.secondary[disabled], .btn.secondary.is-disabled {
  background: var(--btn2-disabled-fill); color: var(--btn2-disabled-text);
  opacity: 1; cursor: default; box-shadow: none; /* approved disabled tokens; not a duplicate */
}
[data-mode="parent"] .btn { --btn-fill: var(--btn-fill-parent); --btn-pressed: var(--btn-pressed-parent); --btn-disabled-surface: var(--btn-disabled-parent); } /* Parent mode-aware fill/press/disabled (seam) */
.btn:active { transform: scale(0.96); background: var(--btn-pressed); } /* approved press scale + Figma pressed fill */
.btn[disabled], .btn.is-disabled { background: var(--btn-disabled-surface); color: var(--btn-disabled-text); opacity: 1; cursor: default; } /* disabled = Figma light surface + quiet disabled text (#766D7D, visible but quiet) */

/* Icon Control — Figma Phase 3 (Icon Control PASS) seam.
   Scoped to .icon-btn ONLY. 64×64 control / 32×32 glyph. Do NOT generalize to other controls.
   Fill VALUES RESOLVED from the authoritative Figma variable export (v1.1.13); glyphs come from
   Figma INSTANCE_SWAP (vector asset transfer pending). 
   Approved: Play/Parent modes, Default/Pressed/Disabled states, 6 variants, INSTANCE_SWAP "Glyph",
   pressed scale 0.96, Fast 140ms, disabled glyph opacity 0.52 (recognizable, NOT an error state). */
.icon-btn {
  --ic-fill: var(--action-secondary);            /* token: Color/Action/Secondary (Default) */
  --ic-pressed: var(--secondary-pressed);        /* token: Color/Action/Secondary Pressed */
  --ic-disabled-fill: var(--action-disabled);    /* token: Color/Action/Disabled (approved, reused) */
  --ic-glyph: var(--icon-primary);               /* token: Color/Icon/Primary */
  --ic-disabled-glyph: var(--icon-on-disabled);  /* token: Color/Icon/On Disabled */
  width: 64px; height: 64px; padding: 0; border: none;
  border-radius: var(--radius, 18px);            /* large rounded (placeholder radius) */
  background: var(--ic-fill); color: var(--ic-glyph);
  box-shadow: var(--shadow);                     /* floating HUD elevation */
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; pointer-events: auto;
  transition: transform 140ms ease-out, background-color 140ms ease-out, box-shadow 140ms ease-out; /* Fast */
}
.icon-btn .glyph { width: 32px; height: 32px; display: block; } /* vector glyph slot — INSTANCE_SWAP from Figma; no emoji/unicode/raster stand-in */
.icon-btn:active { transform: scale(0.96); background: var(--ic-pressed); box-shadow: none; } /* pressed: 0.96, no shadow */
.icon-btn[disabled], .icon-btn.is-disabled {
  background: var(--ic-disabled-fill); color: var(--ic-disabled-glyph);
  cursor: default; box-shadow: none;
}
.icon-btn[disabled] .glyph, .icon-btn.is-disabled .glyph { opacity: 0.52; } /* token: opacity/disabled — recognizable, not an error */

/* Quest Card — Figma Phase 3 (Quest Card PASS) seam.
   Scoped to .quest-card ONLY. 360×226 card. Do NOT generalize.
   Fill VALUES RESOLVED from the authoritative Figma variable export (v1.1.13) — no placeholders remain.
   Approved: states Active/Complete/Locked; Title/Progress/Reward/State properties;
   never red / never FAIL / never punishment (Locked). */
.quest-card {
  --qc-surface: var(--quest-active-surface);
  --qc-border: var(--quest-active-border);
  --qc-progress: var(--quest-progress-fill);   /* sky active progress fill */
  --qc-label: var(--ink-soft);
  --qc-reward: var(--quest-reward);
  --qc-track: var(--quest-progress-track);
  width: 360px; max-width: 92vw; min-height: 226px;
  box-sizing: border-box; padding: 20px 22px; gap: 12px;
  border-radius: 28px;                          /* large rounded (placeholder radius) */
  background: var(--qc-surface); border: 3px solid var(--qc-border);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; text-align: left;
}
.quest-card .qc-title { font-family: var(--font); font-weight: 700; font-size: 20px; color: var(--brown-deep); }
.quest-card .qc-progress { font-weight: 800; font-size: 18px; color: var(--qc-label); }
.quest-card .qc-bar { appearance: none; display: block; width: 100%; height: 12px; border: 0; border-radius: 999px; background: var(--qc-track); overflow: hidden; }
.quest-card .qc-bar::-webkit-progress-bar { background: var(--qc-track); border-radius: 999px; }
.quest-card .qc-bar::-webkit-progress-value { background: var(--qc-progress); border-radius: 999px; }
.quest-card .qc-bar::-moz-progress-bar { background: var(--qc-progress); border-radius: 999px; }
.quest-card .qc-reward { font-weight: 800; color: var(--qc-reward); }
.quest-card.is-complete {
  --qc-surface: var(--quest-complete-surface);
  --qc-border: var(--quest-complete-border);
  --qc-progress: var(--quest-complete-accent);   /* leaf accent */
  --qc-label: var(--quest-complete-accent);      /* Figma authoritative complete accent #75BD70 (replaces base --green-deep) */
}
.quest-card.is-locked {
  --qc-surface: var(--quest-locked-surface);
  --qc-border: var(--quest-locked-border);
  --qc-label: var(--quest-locked-text);
  --qc-track: transparent;                        /* empty progress */
}
.quest-card.is-locked .qc-bar { visibility: hidden; }

/* Reward Chip — Figma Phase 3 (Reward Chip PASS) seam.
   Scoped to .reward-chip ONLY. ~51px pill, 24px vector glyph, Nunito SemiBold 18px.
   Do NOT generalize. Fill VALUES RESOLVED from the authoritative Figma variable export (v1.1.13);
   glyphs come from Figma INSTANCE_SWAP (vector asset transfer pending).
   Approved: non-interactive display-only badge (Available/Earned/Locked); 24px vector glyph;
   pill; sunshine (available) / leaf (earned) / cocoa (locked, never red); glyph via INSTANCE_SWAP. */
.reward-chip {
  --rc-surface: var(--reward-available-surface);
  --rc-border: var(--reward-available-border);
  --rc-text: var(--reward-text);
  --rc-glyph: var(--reward-glyph);
  display: inline-flex; align-items: center; gap: 8px; /* glyph-to-label spacing */
  height: 51px; padding: 12px 16px; border-radius: 999px; /* pill geometry */
  box-sizing: border-box;
  background: var(--rc-surface); border: 2px solid var(--rc-border);
  color: var(--rc-text);
  font-family: var(--font-body, "Nunito", system-ui, sans-serif);
  font-weight: 600; font-size: 18px; line-height: 1; /* SemiBold 18px */
  pointer-events: none; user-select: none; /* display-only (no 56/64px touch target) */
}
.reward-chip .glyph { width: 24px; height: 24px; display: block; flex: 0 0 auto; } /* vector glyph slot — INSTANCE_SWAP; no emoji/unicode/raster stand-in */
.reward-chip.is-earned {
  --rc-surface: var(--reward-earned-surface);
  --rc-border: var(--reward-earned-border);
  /* positive completed feeling; no aggressive celebration inside the static chip */
}
.reward-chip.is-locked {
  --rc-surface: var(--reward-locked-surface);
  --rc-border: var(--reward-locked-border);
  --rc-text: var(--reward-locked-text);
  /* never red / never failure / never punishment; softer text */
}
.reward-chip.is-locked .glyph { opacity: 0.52; } /* recognizable at reduced visual intensity (matches disabled convention) */

/* ===== Quest & Rewards surface (Figma Phase 10 APPROVED, page 16_Quest & Rewards) =====
   Full-screen DOM scene (mirrors the Treehouse hub). Reuses the approved Quest Card
   (32:24) + Reward Chip (40:26) components — those tokens/fills are resolved above.
   Structural layout only. Motion: surface reveal ~220ms; state change ~220ms; the
   Reward Chip "earned" glow <=600ms. Reduced motion drops translation/scaling -> ~220ms
   opacity/state only. Phone = TRUE responsive reflow (NOT a scaled desktop). Primary
   action 64px; child-interaction floor 56px. */
.quest {
  position: absolute; inset: 0; z-index: 15;
  display: flex; flex-direction: column; box-sizing: border-box;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  background: radial-gradient(120% 70% at 50% 0%, var(--pink-soft), var(--cream) 62%), var(--cream);
  overflow: auto;
  animation: q-reveal 220ms ease-out;
}
.quest.hidden { display: none; }
.q-header { text-align: center; margin: 8px 0 14px; }
.q-title { margin: 0; color: var(--brown-deep); font-family: var(--font); font-weight: 800; font-size: clamp(24px, 5vw, 40px); }
.q-sub { margin: 4px 0 0; color: var(--ink-soft); font-weight: 700; font-size: clamp(14px, 3.2vw, 20px); }

.q-body { flex: 1 1 auto; display: grid; gap: 16px; align-content: center; justify-items: center; }
.quest[data-comp="desktop"] .q-body,
.quest[data-comp="tablet"] .q-body { grid-template-columns: minmax(220px, 1fr) 2fr; align-items: center; }
.quest[data-comp="phone"] .q-body { grid-template-columns: 1fr; }

.q-cappy {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: rgba(255,255,255,.6); border: 3px solid var(--pink); border-radius: var(--radius-lg);
  padding: 16px; box-shadow: var(--shadow);
}
.q-cappy-img { width: clamp(120px, 22vw, 200px); height: auto; }

.q-journey { display: flex; flex-direction: column; align-items: center; gap: 16px; width: 100%; max-width: 420px; }
.q-journey .quest-card { width: 100%; max-width: 360px; }
.q-journey .reward-chip { align-self: center; } /* display-only (keeps approved 51px + pointer-events:none) */
/* V5-E: ACTIVE centers on the quest (no large standalone Cappy portrait); COMPLETE keeps
   Cappy as part of the celebration. Pure layout — no logic/progression change. */
.quest .q-cappy.hidden { display: none; }
.quest .q-body.is-active { grid-template-columns: 1fr; }
.quest .q-body.is-active .q-journey { max-width: 480px; }

/* Next Quest Gate — calm, child-controlled. Never a countdown / timer / teleport. */
.next-quest-gate {
  width: 100%; max-width: 360px; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 14px 16px; border-radius: var(--radius-lg);
  background: rgba(255,255,255,.7); border: 2px dashed var(--hud-border);
  text-align: center;
}
.next-quest-gate .nqg-label { margin: 0; color: var(--ink-soft); font-weight: 700; font-size: clamp(14px, 3.2vw, 18px); }
.next-quest-gate.is-ready { border-style: solid; border-color: var(--quest-complete-border); background: rgba(232,246,230,.8); }
.next-quest-gate.is-ready .nqg-label { color: var(--quest-complete-accent); }

.q-footer { display: flex; gap: 12px; justify-content: center; padding: 12px 0 4px; flex-wrap: wrap; }
.q-footer .btn { min-height: 64px; padding: 0 28px; font-size: 18px; } /* primary action 64px (>= 56px floor) */

/* HUD "Quests" button — persistent, available in the meadow. */
.hud-quest-btn {
  margin-left: 8px; align-self: center;
  font-family: var(--font); font-weight: 800; font-size: 16px;
  color: var(--brown-deep); background: var(--action-secondary);
  border: 2px solid var(--hud-border); border-radius: 999px;
  padding: 8px 16px; cursor: pointer; min-height: 48px; pointer-events: auto;
}
.hud-quest-btn:active { background: var(--secondary-pressed); }

/* Phone TRUE responsive reflow (NOT a scaled desktop). Controls >= 56px. */
.quest[data-comp="phone"] .q-body { grid-template-columns: 1fr; }
.quest[data-comp="phone"] .q-footer { flex-direction: column; }
.quest[data-comp="phone"] .q-footer .btn { width: 100%; min-height: 64px; }

/* V5.1 CLOSEOUT: guarantee the Quest COMPLETE "Back to Treehouse" CTA stays visible at
   390x844 WITHOUT scrolling. ACTIVE + tablet/desktop layouts are intentionally untouched. */
.quest[data-comp="phone"] { padding-top: 10px; padding-bottom: 10px; }
.quest[data-comp="phone"] .q-footer { padding: 8px 0 4px; }
.quest[data-comp="phone"] .q-body.is-complete { gap: 10px; }
.quest[data-comp="phone"] .q-body.is-complete .q-cappy-img { width: clamp(72px, 22vw, 92px); }
.quest[data-comp="phone"] .q-body.is-complete .q-journey { gap: 8px; }

/* Calm surface reveal (~220ms) + Reward Chip "earned" glow (<=600ms). */
@keyframes q-reveal { from { opacity: 0; } to { opacity: 1; } }
.reward-chip.is-earned { animation: q-chip-glow 600ms ease-out; }
@keyframes q-chip-glow { from { box-shadow: 0 0 0 0 rgba(117,189,112,.5); } to { box-shadow: 0 0 0 6px rgba(117,189,112,0); } }

/* Reduced motion: replace reveal/scale with ~220ms opacity/state only. Preserve all
   states/actions/states. */
#game.reduced-motion .quest { animation: none; opacity: 1; }
#game.reduced-motion .reward-chip.is-earned { animation: none; }
#game.reduced-motion .btn,
#game.reduced-motion .hud-quest-btn { transition: background-color 220ms ease-out, border-color 220ms ease-out, color 220ms ease-out; }
@media (prefers-reduced-motion: reduce) {
  .quest { animation: none; opacity: 1; }
  .reward-chip.is-earned { animation: none; }
  .btn, .hud-quest-btn { transition: background-color 220ms ease-out, border-color 220ms ease-out, color 220ms ease-out; }
}

/* candle puzzle */
.candles { display: flex; gap: 12px; justify-content: center; margin: 16px 0; flex-wrap: wrap; }
.candle {
  width: 54px; height: 90px; border-radius: 10px; background: #fff3e0; position: relative;
  box-shadow: var(--shadow); border: 3px solid #f0d9bf; cursor: pointer;
  display: flex; align-items: flex-start; justify-content: center;
}
.candle .flame {
  width: 16px; height: 22px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: radial-gradient(circle at 50% 70%, #fff3b0, #ffb703 60%, #fb8500);
  margin-top: -14px; opacity: 0; transition: opacity .2s, transform .2s; transform: scale(.6);
}
.candle.lit .flame { opacity: 1; transform: scale(1); }
.candle.preview { box-shadow: 0 0 0 4px var(--gold), var(--shadow); transform: translateY(-6px); }
.candle:disabled { cursor: default; }

/* birthday book */
.book-text {
  white-space: pre-wrap; text-align: left; background: #fff; border-radius: 12px;
  padding: 16px; font-size: 18px; line-height: 1.6; color: var(--ink);
  border: 2px dashed #e7d8c9; margin: 12px 0;
}
.book-edit { width: 100%; min-height: 180px; font-family: inherit; font-size: 16px; border-radius: 12px; border: 2px solid #e7d8c9; padding: 12px; resize: vertical; }

/* finale */
.tada { font-size: clamp(26px, 6vw, 44px); color: var(--brown-deep); font-weight: 900; }
.subtitle { color: var(--ink-soft); }

/* desktop hint */
.deskhint {
  position: absolute; right: 14px; bottom: 12px; color: var(--ink-soft);
  background: rgba(255,255,255,.7); padding: 6px 12px; border-radius: 999px; font-size: 12px;
}

@media (prefers-reduced-motion: reduce) {
  .prompt { animation: none; }
  .candle { transition: none; }
}

/* ===== Phase 3 APPROVED components — HUD Control (47:26), Dialog (49:27), Birthday CTA (53:29) =====
   Scoped to their own classes ONLY. Do NOT generalize to other controls. VALUES RESOLVED
   (v1.1.14), Figma authoritative. Glyphs are Figma vector INSTANCE_SWAP slots (empty — never
   emoji / unicode / raster stand-ins). */

/* ---------- HUD Control (child-facing: next objective + progress + stars only) ---------- */
.hud-control {
  --hc-surface: var(--hud-surface);
  --hc-border: var(--hud-border);
  --hc-text: var(--hud-text);
  --hc-subtext: var(--hud-subtext);
  --hc-track: var(--hud-progress-track);
  --hc-fill: var(--hud-progress-fill);
  --hc-star: var(--hud-star);
  --hc-star-surface: var(--hud-star-surface);
  display: flex; align-items: center; gap: 14px; box-sizing: border-box;
  width: 420px; max-width: calc(100vw - 24px);
  min-height: 100px; padding: 14px 18px;
  background: var(--hc-surface); border: 3px solid var(--hc-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
  color: var(--hc-text); font-family: var(--font-body, "Nunito", system-ui, sans-serif);
  pointer-events: none; /* child-facing display-only HUD — not an activation control */
}
.hud-control--expanded { width: 620px; }
.hud-control .hc-quest { font-weight: 800; font-size: 16px; line-height: 1.25; min-width: 0; }
.hud-control .hc-progress { display: flex; flex-direction: column; gap: 5px; flex: 1 1 auto; min-width: 0; }
.hud-control .hc-count { font-weight: 800; font-size: 14px; color: var(--hc-subtext); }
.hud-control .hc-bar { appearance: none; display: block; width: 100%; height: 10px; border: 0; border-radius: var(--radius-pill); background: var(--hc-track); overflow: hidden; }
.hud-control .hc-bar::-webkit-progress-bar { background: var(--hc-track); border-radius: var(--radius-pill); }
.hud-control .hc-bar::-webkit-progress-value { background: var(--hc-fill); border-radius: var(--radius-pill); transition: width 140ms ease-out; }
.hud-control .hc-bar::-moz-progress-bar { background: var(--hc-fill); border-radius: var(--radius-pill); }

/* Parent-gate controls injected by the Birthday Book flow. */
.parent-gate-input { font-size: 18px; padding: 10px; border-radius: 10px; border: 2px solid #e7d8c9; width: 100%; text-transform: uppercase; box-sizing: border-box; }
.parent-gate-error { color: #c0392b; min-height: 18px; }
.hud-control .hc-stars { display: inline-flex; align-items: center; gap: 8px; font-weight: 800; font-size: 14px; color: var(--hc-subtext); white-space: nowrap; }
.hud-control .hc-star-slot { width: 26px; height: 26px; border-radius: var(--radius-pill); background: var(--hc-star-surface); display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.hud-control .hc-star-slot .glyph { width: 16px; height: 16px; display: block; } /* vector glyph INSTANCE_SWAP slot */
/* compact / large phones: full width, allow wrap */
#game[data-device-class="compact-phone"] .hud-control,
#game[data-device-class="large-phone"] .hud-control { width: auto; flex: 1 1 100%; }

/* ---------- Dialog (modal frame: Info / Celebration / ParentGate) ---------- */
.dialog {
  --dlg-surface: var(--dialog-surface);
  --dlg-border: var(--dialog-border);
  --dlg-title: var(--dialog-title);
  --dlg-body: var(--dialog-body);
  --dlg-accent: var(--celebration-accent);
  background: var(--dlg-surface) !important;
  border: 2px solid var(--dlg-border) !important;
  border-radius: var(--radius-lg) !important;
  color: var(--dlg-body) !important;
  animation: dlg-in 180ms ease-out; /* entrance bounce/scale — removed under reduced-motion */
}
.dialog h1, .dialog h2 { color: var(--dlg-title) !important; }
.dialog p { color: var(--dlg-body) !important; }
.dialog--celebration { --dlg-accent: var(--celebration-accent); border-color: var(--celebration-accent) !important; }
.dialog--parentGate { --dlg-accent: var(--parent-gate-accent); border-color: var(--parent-gate-accent) !important; }
@keyframes dlg-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }

/* ---------- Birthday CTA (GiftEntry / Finale / Replay) ---------- */
.birthday-cta {
  --bcta-surface: var(--birthday-surface);
  --bcta-border: var(--birthday-border);
  --bcta-title: var(--birthday-title);
  --bcta-body: var(--birthday-body);
  --bcta-glyph: var(--birthday-glyph);
  --bcta-finale-accent: var(--birthday-finale-accent);
  --bcta-replay-surface: var(--replay-surface);
  --bcta-replay-border: var(--replay-border);
}
.birthday-cta--giftEntry, .birthday-cta--finale {
  background: var(--bcta-surface) !important;
  border: 2px solid var(--bcta-border) !important;
}
.birthday-cta--giftEntry h1, .birthday-cta--giftEntry h2,
.birthday-cta--finale h1, .birthday-cta--finale h2 { color: var(--bcta-title) !important; }
.birthday-cta--giftEntry p, .birthday-cta--finale p { color: var(--bcta-body) !important; }
/* Replay CTA — a small birthday surface wrapping the replay action (uses approved Primary Button) */
.birthday-cta--replay {
  display: inline-block; padding: 10px 14px; border-radius: var(--radius-lg);
  background: var(--bcta-replay-surface); border: 2px solid var(--bcta-replay-border);
  box-shadow: var(--shadow);
}

/* ===== Birthday Opening (Figma Phase 6 — APPROVED) =====
   Structural layout only. Final visual treatment of the Birthday Opening composition is
   Figma-owned (DESIGN_REQUIRED); these rules adapt spacing/composition per device class and
   honor the phone touch-target rule (full-size 64px Primary Button, never scaled down).
   The Dialog + Birthday CTA components themselves carry the approved tokens. */
.birthday-cta { padding-bottom: max(22px, env(safe-area-inset-bottom)); } /* keep CTA clear of home indicator/browser chrome */
.birthday-cta .bo-grid { display: block; text-align: center; }
.birthday-cta .bo-greeting { margin: 4px 0 10px; }
.birthday-cta .bo-line {
  margin: 8px 0; font-weight: 700; font-size: clamp(15px, 4vw, 18px);
  color: var(--bcta-body); transition: color 140ms ease-out;
}
.birthday-cta .bo-line.bo-latest { color: var(--bcta-title); }
.birthday-cta .bo-gift { display: flex; justify-content: center; }
/* Desktop = true two-column (left greeting+Cappy-facing text, right gift entry). Do NOT
   stretch the phone/tablet single-column layout into desktop — keep each composition intact. */
.birthday-cta[data-bo-comp="desktop"] .bo-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: center; text-align: left;
}
.birthday-cta[data-bo-comp="desktop"] .bo-gift { justify-content: center; }
/* Phone: full-size Primary Button (64px min) — do NOT scale the CTA down to fit the phone.
   A full-width 64px control preserves the approved child touch target (>= 56px floor, 64px for primary). */
#game[data-device-class="compact-phone"] .birthday-cta .btn,
#game[data-device-class="large-phone"] .birthday-cta .btn { width: 100%; min-height: 64px; }
/* Reduced motion: drop the Dialog entrance transition. The opening still unfolds in the same
   logical order with the same state confirmations — only the transition style changes. */
#game.reduced-motion .dialog { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  .birthday-cta .bo-line { transition: none; }
}

/* ===== Tifany Treehouse — Personal Home Hub (Figma Phase 8 APPROVED) =====
   Structural layout only. Final visual treatment of the Main Room composition + the
   Candle/Star/Book/Door vectors is Figma-owned (DESIGN_REQUIRED). Cappy uses the GENUINE
   transferred Figma SVG; candle/star/book/door use FUNCTIONAL placeholder pips/slots (the
   same pre-v1.1.28 Cappy placeholder precedent) so the experience is testable now and the
   real vectors drop in later with no code change. Tokens ALIAS base.css primitives — NO
   second palette invented. Motion: calm Cappy idle, candle glow ~600ms, star appear ~360ms,
   book pop ~600ms, door ready ~600ms. Reduced motion drops decorative loops; state +
   confirmation preserved (~220ms state transitions). */
.treehouse {
  position: absolute; inset: 0; z-index: 15;
  display: flex; flex-direction: column; box-sizing: border-box;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  background:
    radial-gradient(120% 70% at 50% 0%, var(--pink-soft), var(--cream) 62%), var(--cream);
  overflow: auto;
}
.treehouse.hidden { display: none; }
.th-header { text-align: center; margin: 8px 0 14px; }
.th-title { margin: 0; color: var(--brown-deep); font-family: var(--font); font-weight: 800; font-size: clamp(24px, 5vw, 40px); }
.th-subtitle { margin: 4px 0 2px; color: var(--ink-soft); font-weight: 700; font-size: clamp(14px, 3.2vw, 20px); }
.th-tap { margin: 0; color: var(--ink-soft); font-size: clamp(12px, 2.6vw, 16px); }

.th-body { flex: 1 1 auto; display: grid; gap: 16px; align-content: center; }
/* Desktop/tablet: room = Cappy + destinations grid. Phone = TRUE responsive single column
   (NOT a scaled desktop) with full-width child-sized rows (>= 56px hit zones). */
.treehouse[data-comp="desktop"] .th-body,
.treehouse[data-comp="tablet"] .th-body { grid-template-columns: minmax(220px, 1fr) 2fr; align-items: center; }

.th-cappy {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: rgba(255,255,255,.6); border: 3px solid var(--pink); border-radius: var(--radius-lg);
  padding: 16px; box-shadow: var(--shadow);
}
.th-cappy-img { width: clamp(120px, 22vw, 200px); height: auto; }
.th-cappy-caption { color: var(--brown-deep); font-weight: 800; font-size: clamp(14px, 3vw, 18px); }

.th-destinations { display: grid; gap: 12px; }
.treehouse[data-comp="desktop"] .th-destinations,
.treehouse[data-comp="tablet"] .th-destinations { grid-template-columns: 1fr 1fr; }
.treehouse[data-comp="phone"] .th-destinations { grid-template-columns: 1fr; }

.th-dest {
  display: flex; align-items: center; gap: 14px; text-align: left;
  background: rgba(255,255,255,.82); border: 3px solid var(--pink-soft); border-radius: var(--radius-lg);
  padding: 14px; box-shadow: var(--shadow); cursor: pointer;
  min-height: 64px; /* approved child touch-target floor (56px) for primary-ish regions */
  font-family: var(--font-body, "Nunito", system-ui, sans-serif); color: var(--ink);
  transition: transform 140ms ease-out, border-color 140ms ease-out, background-color 140ms ease-out;
}
.th-dest:active { transform: scale(.97); border-color: var(--pink); }
.th-dest-art { flex: 0 0 auto; display: inline-flex; gap: 5px; align-items: center; }
.th-dest-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.th-dest-label { font-weight: 800; font-size: clamp(15px, 3.4vw, 20px); color: var(--brown-deep); }
.th-dest-hint { font-weight: 600; font-size: clamp(11px, 2.6vw, 14px); color: var(--ink-soft); }

/* Functional placeholder pips/slots (DESIGN_REQUIRED: final Figma vectors). These are UI
   status affordances (holders/sockets/slots), NOT character art. Friends slots stay EMPTY
   until approved Figma characters exist — never emoji/Unicode/stock/AI/programmer art. */
.th-pip { width: 16px; height: 22px; border-radius: 5px; background: #fff; box-shadow: inset 0 0 0 2px var(--pink-soft); }
.th-pip.lit { background: var(--gold); box-shadow: inset 0 0 0 2px var(--gold); animation: th-glow 600ms ease-out; }
.th-star { width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: inset 0 0 0 2px var(--pink-soft); }
.th-star.filled { background: var(--gold); box-shadow: inset 0 0 0 2px var(--gold); animation: th-glow 360ms ease-out; }
.th-slot { width: 22px; height: 22px; border-radius: 50%; border: 2px dashed var(--pink-soft); background: transparent; }
.th-book { width: 26px; height: 20px; border-radius: 4px; background: var(--pink-soft); border: 2px solid var(--pink); }
.th-book.unlocked { background: var(--pink); }
.th-lock { font-size: 11px; font-weight: 800; color: var(--ink-soft); margin-left: 4px; }
.th-door { width: 22px; height: 30px; border-radius: 4px 4px 2px 2px; background: var(--green-deep); border: 2px solid var(--brown); }
.th-door.ready { box-shadow: 0 0 0 3px var(--gold); animation: th-door 600ms ease-out; }
.th-dest--door { border-color: var(--green-deep); } /* the adventure entry — distinct, calm */

@keyframes th-glow { from { transform: scale(.7); opacity: .4; } to { transform: scale(1); opacity: 1; } }
@keyframes th-door { from { box-shadow: 0 0 0 0 var(--gold); } to { box-shadow: 0 0 0 3px var(--gold); } }

.th-footer { display: flex; justify-content: center; margin-top: 14px; }

/* Reduced motion: drop decorative loops (glow/door pulse). Preserve state + confirmation;
   keep ~220ms state transitions only. */
#game.reduced-motion .th-pip.lit,
#game.reduced-motion .th-star.filled,
#game.reduced-motion .th-door.ready { animation: none; }
#game.reduced-motion .th-dest { transition: background-color 220ms ease-out, border-color 220ms ease-out; }
@media (prefers-reduced-motion: reduce) {
  .th-pip.lit, .th-star.filled, .th-door.ready { animation: none; }
  .th-dest { transition: background-color 220ms ease-out, border-color 220ms ease-out; }
}

/* ============================================================
   Birthday Book — Persistent Story & Memory Library
   (Figma Phase 9 APPROVED, page 15_Birthday Book, node 6:18)
   Reader set 102:304: desktop 102:100 (1440x900, two-page spread),
   tablet 102:185 (834x1194, single), phone 102:249 (390x844, TRUE reflow).
   Nav controls: 64px preferred, 56px absolute min (including phone compact).
   Tokens ALIAS base.css / existing treehouse primitives — no second palette.
   ============================================================ */
.birthdaybook {
  position: absolute; inset: 0; z-index: 16;
  display: flex; flex-direction: column; box-sizing: border-box;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  background:
    radial-gradient(120% 70% at 50% 0%, var(--pink-soft), var(--cream) 62%), var(--cream);
  overflow: auto;
}
.birthdaybook.hidden { display: none; }

.bb-header { text-align: center; margin: 6px 0 12px; }
.bb-title { margin: 0; color: var(--brown-deep); font-family: var(--font); font-weight: 800; font-size: clamp(24px, 5vw, 40px); }
.bb-subtitle { margin: 4px 0 6px; color: var(--ink-soft); font-weight: 700; font-size: clamp(14px, 3.2vw, 20px); }

/* Chapter tabs (Birthday Meadow active; Keep Exploring = locked future preview) */
.bb-tabs { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin: 6px 0 10px; }
.bb-tab {
  font-family: var(--font-body, "Nunito", system-ui, sans-serif); font-weight: 800;
  font-size: clamp(14px, 2.8vw, 18px); padding: 10px 18px; border-radius: 999px;
  border: 2px solid var(--pink); background: var(--pink-soft); color: var(--brown-deep);
  cursor: default; min-height: 44px; display: inline-flex; align-items: center;
}
.bb-tab.active { background: var(--pink); color: #fff; border-color: var(--pink); }
.bb-tab.locked { background: transparent; border-color: var(--brown); color: var(--ink-soft); cursor: pointer; }
.bb-tab.locked:active { transform: scale(.97); }

.bb-body { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; padding: 8px 0; min-height: 0; }

/* Desktop: two-page spread (pages 2-3). Cream book frame with brown spine. */
.bb-spread {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 14px; align-items: stretch;
  width: 100%; max-width: 1100px;
  background: var(--cream); border: 3px solid var(--brown); border-radius: 18px;
  padding: 22px; box-shadow: var(--shadow);
}
.bb-spread .bb-spine { width: 6px; background: var(--brown); border-radius: 4px; }

/* Single page wrapper (cover on desktop, all pages on tablet/phone). */
.bb-page--single, .bb-page--solo {
  background: #fff; border-radius: 14px; border: 2px solid var(--pink-soft);
  padding: 22px; display: flex; flex-direction: column; gap: 14px;
  width: 100%;
}
.bb-page--solo { max-width: 720px; }
.bb-page--single { max-width: 720px; }

.bb-page {
  background: #fff; border-radius: 14px; border: 2px solid var(--pink-soft);
  padding: 22px; display: flex; flex-direction: column; gap: 14px;
  min-height: 520px;
}
.bb-chapter { color: var(--ink-soft); font-weight: 800; font-size: clamp(12px, 2.4vw, 14px); letter-spacing: 1px; text-transform: uppercase; margin: 0; }
.bb-page-title { color: var(--brown-deep); font-family: var(--font); font-weight: 800; font-size: clamp(22px, 4vw, 32px); margin: 0; }

/* Illustrations: story (light blue), memory (light green), cover (pink-soft).
   Cappy uses the genuine transferred SVG (rendered as <img> by game.js).
   Supporting elements are functional placeholders built from approved tokens. */
.bb-illustration {
  border-radius: 14px; padding: 18px; flex: 1 1 auto; display: flex;
  align-items: center; justify-content: center; position: relative; min-height: 260px;
}
.bb-illustration--story { background: #d8eef9; border: 2px solid #bfe0f0; }
.bb-illustration--memory { background: #e3f3df; border: 2px solid #c9e6c3; }
.bb-illustration--cover { background: var(--pink-soft); border: 2px solid var(--pink); min-height: 220px; }

/* Story scene: positions Cappy, stars, pond, candle on the light-blue panel. */
.bb-scene { position: relative; width: 100%; height: 100%; min-height: 240px; }
.bb-scene-cappy { position: absolute; left: 6%; bottom: 12%; width: 36%; max-width: 170px; }
.bb-scene-pond { position: absolute; left: 50%; bottom: 14%; width: 30%; height: 28%;
  background: radial-gradient(ellipse at 40% 40%, #bfe1f5 0%, #88c3e3 70%, #5fa9cf 100%);
  border-radius: 50%; box-shadow: inset 0 -4px 6px rgba(255,255,255,.5); }
.bb-scene-candle { position: absolute; right: 8%; bottom: 28%; display: flex; flex-direction: column; align-items: center; }
.bb-scene-candle .body { width: 20px; height: 38px; background: #fff3e0; border: 2px solid var(--brown); border-radius: 4px 4px 2px 2px; }
.bb-scene-candle .flame { width: 14px; height: 20px; background: var(--gold); border-radius: 50% 50% 40% 40%; box-shadow: 0 0 10px var(--gold); }
.bb-scene-candle .holder { width: 32px; height: 5px; background: var(--gold); border-radius: 50%; margin-top: -2px; }
.bb-scene-star { position: absolute; width: 22px; height: 22px; }
.bb-scene-star::before { content: ""; position: absolute; inset: 0; background: var(--gold);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
.bb-scene-star.s { width: 14px; height: 14px; }
.bb-scene-star.pos-a { left: 38%; top: 24%; }
.bb-scene-star.pos-b { left: 48%; top: 14%; }
.bb-scene-star.pos-c { left: 30%; top: 38%; }

/* Memory scene: candle (if found) + N stars (0..3) — truthful to save state. */
.bb-mem { display: flex; align-items: center; justify-content: center; gap: 20px; flex-wrap: wrap; }
.bb-mem-candle { display: flex; flex-direction: column; align-items: center; }
.bb-mem-candle .body { width: 24px; height: 46px; background: #fff3e0; border: 2px solid var(--brown); border-radius: 4px 4px 2px 2px; }
.bb-mem-candle .flame { width: 18px; height: 24px; background: var(--gold); border-radius: 50% 50% 40% 40%; box-shadow: 0 0 12px var(--gold); }
.bb-mem-candle .holder { width: 38px; height: 6px; background: var(--gold); border-radius: 50%; margin-top: -2px; }
.bb-mem-candle.empty { opacity: .4; filter: grayscale(.4); }
.bb-mem-candle.empty .flame, .bb-mem-candle.empty .holder { display: none; }
.bb-mem-candle.empty .body { background: #f5efe6; }
.bb-mem-stars { display: inline-flex; gap: 12px; }
.bb-mem-star { width: 28px; height: 28px; position: relative; }
.bb-mem-star::before { content: ""; position: absolute; inset: 0; background: var(--gold);
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
.bb-mem-star.empty::before { background: #fff; box-shadow: inset 0 0 0 2px var(--pink-soft); }

/* Cover illustration: simple warm meadow */
.bb-cover-art { text-align: center; color: var(--brown-deep); font-weight: 800; font-size: clamp(20px, 3.6vw, 28px); }

.bb-caption { color: var(--ink); font-family: var(--font-body, "Nunito", system-ui, sans-serif);
  font-weight: 600; font-size: clamp(16px, 3vw, 20px); line-height: 1.5; margin: 0; }

/* Footer navigation — Back Home / Previous / Next. 64px preferred height. */
.bb-footer {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 14px; flex-wrap: wrap;
}
.bb-footer .btn { min-height: 64px; padding: 0 22px; font-size: clamp(16px, 3.2vw, 20px); }
.bb-footer .btn.secondary { min-height: 64px; }
.bb-pages { color: var(--ink-soft); font-weight: 700; font-size: clamp(14px, 2.8vw, 18px); }

/* Composition selectors — show the right container per device class. */
.birthdaybook[data-comp="desktop"] .bb-spread { display: grid; }
.birthdaybook[data-comp="desktop"] .bb-page--solo { display: flex; }
.birthdaybook[data-comp="desktop"] .bb-page--single { display: none; }

.birthdaybook[data-comp="tablet"] .bb-spread,
.birthdaybook[data-comp="phone"] .bb-spread { display: none; }
.birthdaybook[data-comp="tablet"] .bb-page--solo,
.birthdaybook[data-comp="phone"] .bb-page--solo { display: none; }
.birthdaybook[data-comp="tablet"] .bb-page--single,
.birthdaybook[data-comp="phone"] .bb-page--single { display: flex; }

/* Phone TRUE responsive reflow (NOT a scaled desktop). Controls >= 56px.
   The reader nav is a single compact bar (Back Home / Previous / Next with the page
   indicator above) — NOT the large full-width vertically stacked controls the human
   review rejected. All controls stay >= 56px (64px preferred). */
.birthdaybook[data-comp="phone"] .bb-page { padding: 16px; min-height: 440px; }
.birthdaybook[data-comp="phone"] .bb-illustration { min-height: 200px; padding: 12px; }
.birthdaybook[data-comp="phone"] .bb-caption { font-size: clamp(15px, 4vw, 18px); }
.birthdaybook[data-comp="phone"] .bb-footer { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px; }
.birthdaybook[data-comp="phone"] .bb-footer .btn { min-height: 64px; width: auto; flex: 1 1 auto; min-width: 0; padding: 0 14px; }
.birthdaybook[data-comp="phone"] .bb-pages { order: -1; flex-basis: 100%; text-align: center; }

/* Tablet: single page, row nav. */
.birthdaybook[data-comp="tablet"] .bb-page--single { max-width: 760px; }

/* Page reveal: gentle opacity + short translation (up to ~360ms). */
.bb-page--reveal { animation: bb-reveal 360ms ease-out; }
@keyframes bb-reveal { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
/* Memory confirmation (~360ms). */
.bb-mem-star:not(.empty)::before,
.bb-mem-candle:not(.empty) .flame { animation: bb-glow 360ms ease-out; transform-origin: center; }
@keyframes bb-glow { from { transform: scale(.6); opacity: .4; } to { transform: scale(1); opacity: 1; } }
/* Book unlock reveal (up to ~600ms) — used when the (future) unlock fires. */
.bb-unlock-reveal { animation: bb-unlock 600ms ease-out; }
@keyframes bb-unlock { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: scale(1); } }

/* Reduced motion: replace translation/page-flip with ~220ms opacity/state only.
   Preserve every page, story, memory, locked/unlocked state, navigation. */
#game.reduced-motion .bb-page--reveal,
#game.reduced-motion .bb-unlock-reveal { animation: none; opacity: 1; transform: none; }
#game.reduced-motion .bb-mem-star:not(.empty)::before,
#game.reduced-motion .bb-mem-candle:not(.empty) .flame { animation: none; }
#game.reduced-motion .bb-tab,
#game.reduced-motion .btn { transition: background-color 220ms ease-out, border-color 220ms ease-out, color 220ms ease-out; }
@media (prefers-reduced-motion: reduce) {
  .bb-page--reveal, .bb-unlock-reveal { animation: none; opacity: 1; transform: none; }
  .bb-mem-star:not(.empty)::before,
  .bb-mem-candle:not(.empty) .flame { animation: none; }
  .bb-tab, .btn { transition: background-color 220ms ease-out, border-color 220ms ease-out, color 220ms ease-out; }
}

/* ============================================================
   V4 TARGETED VISUAL FIDELITY — composition alignment
   (Figma Phase 6 / 8 / 10 storyboard frames). Structural layout
   + the approved tokens only; no new palettes invented.
   ============================================================ */

/* ---- V5-A: Birthday Opening full-page composition (Figma Phase 6, node 76:120) ----
   The page ITSELF is the birthday composition: a full-screen pink scene over the calm
   field (drawOpeningSky), NOT a centered modal card over a muted scrim. Responsive:
   phone/tablet = stacked single column; desktop = two columns (left: heading + Cappy
   hero, right: gift panel + CTA). The INTRO→READY progressive reveal (greeting →
   birthday → crown → gift → CTA) is driven by renderOpeningState; these rules only
   PLACE the elements. Reduced motion: no entrance animation (only short color/opacity
   state transitions are allowed). */
.overlay.opening-fullpage {
  background: transparent; padding: 0; align-items: stretch; justify-content: flex-start;
  overflow: auto;
}
.bo-page {
  flex: 1 1 auto; display: flex; flex-direction: column; box-sizing: border-box;
  width: 100%; min-height: 100%;
  padding: max(20px, env(safe-area-inset-top)) 20px max(20px, env(safe-area-inset-bottom));
  background: linear-gradient(180deg, #ffd6ec 0%, #fff2f8 100%);
  color: var(--birthday-body);
}
.bo-left { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.bo-head { text-align: center; margin: 6px 0 2px; }
.bo-greet { margin: 2px 0; font-family: var(--font); font-weight: 800; font-size: clamp(18px, 5vw, 26px); color: var(--birthday-title); }
.bo-big { margin: 2px 0; font-family: var(--font); font-weight: 800; font-size: clamp(28px, 8vw, 56px); line-height: 1.05; color: var(--birthday-title); text-shadow: 0 2px 0 rgba(255,255,255,.6); }
.bo-sub { margin: 2px 0; font-weight: 700; font-size: clamp(14px, 3.6vw, 20px); color: var(--birthday-body); }

/* Hero: large Cappy + genuine Birthday Crown on an approved soft-blue oval "spotlight". */
.bo-hero { position: relative; display: flex; align-items: center; justify-content: center; margin: 8px auto; width: min(92vw, 460px); }
.bo-oval {
  position: absolute; left: 50%; top: 52%; transform: translate(-50%, -50%);
  width: 90%; height: 88%; border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, #d4ecff 0%, #bfe3ff 46%, #e9f6ff 72%, rgba(233,246,255,0) 100%);
  z-index: 0;
}
.bo-cappy-wrap { position: relative; z-index: 1; width: clamp(170px, 52vw, 300px); }
.bo-cappy-img { width: 100%; height: auto; display: block; }
.bo-crown-img {
  position: absolute; top: -10%; left: 50%; transform: translateX(-50%);
  width: 52%; height: auto; pointer-events: none; z-index: 2;
}

/* Right column: gift card + CTA. */
.bo-right { display: flex; flex-direction: column; align-items: center; gap: 14px; margin-top: 8px; }
.bo-giftcard {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  background: rgba(255,255,255,.78); border: 3px solid #fff; border-radius: var(--radius-lg);
  padding: 18px; box-shadow: var(--shadow); width: min(86vw, 360px);
}
.bo-gift {
  position: relative; width: clamp(84px, 26vw, 120px); height: clamp(84px, 26vw, 120px);
  border-radius: 18px; background: linear-gradient(160deg, #ffd1e8, #ff9ec4);
  border: 4px solid #fff; box-shadow: var(--shadow);
}
.bo-gift::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 14%; background: #fff; transform: translateX(-50%); }
.bo-gift::after { content: ""; position: absolute; left: 0; right: 0; top: 38%; height: 14%; background: #fff; }
.bo-world { margin: 0; font-weight: 700; font-size: clamp(15px, 4vw, 19px); color: var(--birthday-body); text-align: center; }

.bo-cta { width: min(86vw, 360px); display: flex; justify-content: center; }
.bo-cta .btn { width: 100%; min-height: 64px; font-size: clamp(18px, 5vw, 22px); }
.bo-cta-hidden { display: none !important; }

.bo-foot { margin-top: auto; padding-top: 14px; text-align: center; }
.bo-footer-text { margin: 0; font-weight: 600; font-size: clamp(11px, 2.8vw, 14px); color: var(--ink-soft); opacity: .85; }

/* Progressive reveal: hidden lines start collapsed; renderOpeningState toggles .hidden. */
.bo-line.hidden { display: none; }
.bo-line.bo-latest { color: var(--birthday-title); }

/* Desktop = true two-column (left: heading + hero, right: gift panel + CTA). Keep each
   composition intact — do NOT stretch the phone column into desktop. */
.bo-page[data-bo-comp="desktop"] {
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: center;
  grid-template-areas: "left right" "foot foot";
  max-width: 1100px; margin: 0 auto;
}
.bo-page[data-bo-comp="desktop"] .bo-left { grid-area: left; }
.bo-page[data-bo-comp="desktop"] .bo-right { grid-area: right; }
.bo-page[data-bo-comp="desktop"] .bo-foot { grid-area: foot; }

/* Phone/tablet: full-size Primary Button (>= 64px) — never scale the CTA down to fit. */
#game[data-device-class="compact-phone"] .bo-page .btn,
#game[data-device-class="large-phone"] .bo-page .btn { width: 100%; min-height: 64px; }

/* Reduced motion: drop decorative transitions during the opening reveal. State order +
   confirmations are identical (test-locked in birthdayOpening.js). */
#game.reduced-motion .bo-page .bo-line { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .bo-page .bo-line { transition: none; }
  .bo-cappy-img, .bo-crown-img, .bo-oval, .bo-gift { animation: none !important; }
}

/* ---- V5-C: Treehouse ACTUAL ROOM composition (Figma Phase 8, node 97:1159) ----
   The hub is ONE cozy room, not a dashboard/settings list. The wall (upper band) holds
   the window, the Meadow Memory Wall, the Candle Shelf, and the Adventure Door; the floor
   (lower band) holds Cappy's home nook, Friends & Pets, and the Birthday Book. Existing
   state logic (candle/star/book/door view-models + tap handlers) is UNCHANGED — only
   placement + visual treatment change. No Tifany avatar; Cappy uses the GENUINE Figma SVG. */
.treehouse .th-room {
  flex: 1 1 auto; display: grid; gap: 12px; position: relative; overflow: hidden;
  grid-template-columns: 1.15fr 1fr;
  grid-template-areas:
    "win      wall"
    "shelf    wall"
    "door     cappy"
    "friends  book";
  align-content: center; padding: 20px; border-radius: 24px;
  background: linear-gradient(180deg, #fde7f1 0%, #fdeef4 58%, #ffe9d6 58%, #f3d6b6 100%);
  box-shadow: var(--shadow);
}
/* Wall/floor seam — reads as the room's baseboard. */
.treehouse .th-room::before {
  content: ""; position: absolute; left: 0; right: 0; top: 58%; height: 5px;
  background: rgba(255,255,255,.55); z-index: 0; transform: translateY(-50%);
}
.treehouse .th-room > * { position: relative; z-index: 1; }

/* Window — a real window on the wall (sky + frame + crossbar). */
.treehouse .th-window {
  grid-area: win; position: relative; justify-self: start; align-self: start;
  width: clamp(64px, 16vw, 110px); height: clamp(48px, 11vw, 78px);
  background: linear-gradient(180deg, #bfe9ff, #e9f7ff);
  border: 5px solid #fff; border-radius: 14px; box-shadow: var(--shadow);
}
.treehouse .th-window::after {
  content: ""; position: absolute; inset: 0; border-radius: 10px;
  background:
    linear-gradient(#fff, #fff) center / 100% 3px no-repeat,
    linear-gradient(#fff, #fff) center / 3px 100% no-repeat;
}

/* Cappy — a small character placed naturally in the room near the Adventure Door.
   NOT a card at all (V5.1 closeout: removed the standalone "Cappy is home" card treatment).
   Transparent, just the genuine Figma SVG + a tiny caption, so it reads as a figure in the room. */
.treehouse .th-cappy {
  grid-area: cappy; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  align-self: center;
  background: transparent; border: none; box-shadow: none; padding: 4px; min-height: 0;
}
.treehouse .th-cappy-img { width: clamp(48px, 11vw, 72px); height: auto; }
.treehouse .th-cappy-caption { color: var(--brown-deep); font-weight: 800; font-size: clamp(10px, 2.2vw, 13px); margin: 0; }
.treehouse .th-room .th-dest {
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start; text-align: left;
  background: rgba(255,255,255,.88); min-height: 64px;
}
/* Candle Shelf + Memory Wall read as ledges/shelves mounted on the wall. */
.treehouse .th-room-shelf {
  grid-area: shelf;
  background: linear-gradient(180deg, rgba(255,255,255,.96), rgba(255,255,255,.82));
  border-bottom: 7px solid #e7b98f; /* shelf board */
}
.treehouse .th-room-wall {
  grid-area: wall;
  background: linear-gradient(180deg, rgba(255,255,255,.96), rgba(255,255,255,.82));
  border-bottom: 7px solid #e7b98f;
}
.treehouse .th-room-friends { grid-area: friends; }
.treehouse .th-room-book { grid-area: book; }
/* Adventure Door — a large door on the wall, the primary destination (V5.1: large, not a small row). */
.treehouse .th-room-door {
  grid-area: door; align-self: stretch; justify-content: center;
  background: linear-gradient(180deg, #f3e2cf, #e7c9a6);
  border: 3px solid #c79a6b; border-radius: 14px 14px 6px 6px;
  position: relative; min-height: 118px;
}
.treehouse .th-room-door::after {
  content: ""; position: absolute; right: 14px; top: 50%; width: 10px; height: 10px;
  background: #c79a6b; border-radius: 50%; transform: translateY(-50%); /* knob */
}
.treehouse .th-room .th-dest--door { background: linear-gradient(180deg, #f3e2cf, #e7c9a6); }
.treehouse[data-comp="phone"] .th-room {
  grid-template-columns: 1fr;
  grid-template-areas: "win" "shelf" "wall" "friends" "book" "door" "cappy";
}
.treehouse[data-comp="phone"] .th-room-door { min-height: 104px; }

/* ---- Quest & Rewards active/complete presentation (Figma Phase 10, 108:231 / 108:254) ---- */
.quest .qc-status { align-self: flex-start; }
.quest .qc-status--active {
  display: inline-block; font-weight: 800; font-size: 14px; letter-spacing: 1px;
  color: #fff; background: var(--quest-complete-accent); padding: 4px 14px;
  border-radius: 999px; text-transform: uppercase;
}
.quest .qc-celebrate { display: flex; flex-direction: column; gap: 8px; align-items: center; text-align: center; }
.quest .qc-found { margin: 0; color: var(--brown-deep); font-family: var(--font); font-weight: 800; font-size: clamp(22px, 4vw, 30px); }
.quest .qc-memory { margin: 0; color: var(--ink); font-weight: 600; font-size: clamp(14px, 3vw, 18px); max-width: 34ch; }
.quest .qc-found-badge {
  display: inline-block; font-weight: 800; letter-spacing: 1px; color: #fff;
  background: var(--quest-complete-accent); padding: 8px 16px; border-radius: 999px; font-size: 15px;
}
.quest .qc-safe { margin: 0; color: var(--ink-soft); font-weight: 700; font-size: clamp(13px, 2.6vw, 16px); }
.quest .qc-guidance { margin: 2px 0 0; color: var(--brown-deep); font-weight: 800; font-size: clamp(15px, 3.2vw, 20px); }
.quest .qc-reassure { margin: 0; color: var(--ink-soft); font-weight: 600; font-size: clamp(13px, 2.8vw, 16px); }

/* ============================================================
   V4-B — Birthday Meadow composition hierarchy (Figma refs 86:69 / 86:214 / 86:359 / 82:2)
   Composition-ONLY (logic untouched). Canonical hierarchy:
     PRIMARY  = NEXT objective card (already the strong anchor via .hud-control)
     SECONDARY = stars-collected context (inside the objective card)
     TERTIARY = Crown badge, Quests button, brand wordmark
   Goal: the NEXT objective must read as the visual anchor and must NOT be
   overpowered by the Crown badge, the Quests button, or the brand pill.
   Touch controls are tuned per viewport so the Star-action (collect) and the
   joystick stay ergonomic and never overlap the centered cake prompt / top HUD.
   ============================================================ */

/* Brand wordmark — a QUIET tertiary mark, not a competing white pill. */
.hud-brand {
  font-weight: 700; letter-spacing: .4px;
  background: rgba(255,255,255,.5); color: var(--ink-soft);
  padding: 4px 10px; border-radius: 999px; box-shadow: none;
  font-size: clamp(12px, 2vw, 15px);
}

/* Crown (and other unlock) badges — achievement context kept clearly SECONDARY
   to the objective: smaller, lighter, softer shadow. Gold retained for warmth. */
.badge {
  background: var(--gold); color: #6b4e00; font-weight: 700; font-size: 11px;
  padding: 4px 9px; border-radius: 999px; box-shadow: 0 1px 2px rgba(40,25,20,.18);
  gap: 5px;
}
.badge-glyph { width: 16px; height: 16px; }

/* Quests button — secondary navigation; a step quieter than the objective. */
.hud-quest-btn { font-weight: 700; font-size: 15px; min-height: 44px; padding: 7px 14px; }

/* Touch controls — ergonomic, non-overlapping placement per viewport.
   Joystick bottom-left, Star-action (collect) bottom-right; neither overlaps the
   centered cake prompt (bottom 14%) or the top HUD. Explicit stacking so they
   sit above the canvas but below modals. */
.touch { z-index: 5; }
.joystick { z-index: 6; }
.action-btn { z-index: 6; }

/* Compact / large phone: keep controls comfortably inside safe areas and off the
   centered prompt. A touch smaller so they never crowd the objective HUD. */
#game[data-device-class="compact-phone"] .joystick,
#game[data-device-class="large-phone"] .joystick {
  left: max(4%, env(safe-area-inset-left)); bottom: max(8%, env(safe-area-inset-bottom));
  width: clamp(96px, 26vw, 140px); height: clamp(96px, 26vw, 140px);
}
#game[data-device-class="compact-phone"] .action-btn,
#game[data-device-class="large-phone"] .action-btn {
  right: max(5%, env(safe-area-inset-right)); bottom: max(10%, env(safe-area-inset-bottom));
  width: clamp(64px, 17vw, 92px); height: clamp(64px, 17vw, 92px); font-size: 28px;
}

/* ============================================================
   Cappy's Lantern Lagoon — Pattern/Sequence station (Phase 1.1, Lawrence APPROVED)
   Full-screen DOM WORLD scene (mirrors .treehouse / .quest). Driven by pure logic (L.lantern*).
   Figma design APPROVED; lagoon environment + 5 dual-coded physical lanterns are engine/CSS to the
   approved composition (no DESIGN_REQUIRED watermark). Cappy = GENUINE Figma SVG. Dual-coded lanterns
   (color + shape glyph), >=60px targets. Phone = TRUE responsive reflow. Reduced-motion preserves
   MEANING (static numbered demo / instant thick border / orange-dashed wrong / green check / rainbow
   success / instant golden glow) — not just transition-disable.
   ============================================================ */
.lantern { position: absolute; inset: 0; z-index: 15; display: flex; flex-direction: column;
  gap: clamp(10px, 2vh, 20px); padding: clamp(14px, 3.5vw, 34px); box-sizing: border-box;
  background: linear-gradient(180deg, #ffe3f1 0%, #fff6ef 100%); color: var(--brown-deep);
  font-family: var(--font-body, "Nunito", system-ui, sans-serif); overflow-y: auto; }
.lantern.hidden { display: none; }

/* Lightweight gameplay HUD (V1.2 Blocker 2): LEFT safe-return / CENTER pattern-progress dots /
   RIGHT objective star. The HUD is the navigation contract (approved hierarchy); the title/caption
   below are intentionally secondary. Child-safe targets (>=44px). */
.lh-hud { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: clamp(8px, 2vw, 18px); width: 100%; padding: clamp(6px, 1.4vw, 12px) clamp(10px, 2.2vw, 18px);
  background: rgba(255,255,255,.55); border: 2px solid rgba(58,47,42,.12); border-radius: 16px;
  box-shadow: 0 2px 8px rgba(0,0,0,.06); }
.lh-hud-left, .lh-hud-center, .lh-hud-right { display: flex; align-items: center; gap: 8px; }
.lh-hud-center { flex: 1 1 auto; justify-content: center; }
.lh-hud-back { display: inline-flex; align-items: center; gap: 4px; min-height: 48px; padding: 0 14px;
  border: 2px solid rgba(58,47,42,.18); border-radius: 999px; background: #fff; color: var(--brown-deep);
  font-weight: 800; font-size: 15px; cursor: pointer; box-shadow: 0 2px 0 rgba(0,0,0,.08); }
.lh-hud-back:hover { transform: translateY(-1px); }
.lh-hud-back:active { transform: translateY(0); }
.lh-hud-back-arrow { font-size: 22px; line-height: 1; }
.lh-hud-back-label { font-size: 14px; }
.lh-hud-star { font-size: 20px; color: #f3a623; text-shadow: 0 1px 0 #fff; }
.lh-hud-obj { font-weight: 800; font-size: 14px; color: #7a3b5a; }
/* Pattern-progress dots: dual-coded by fill (done = gold) + ring (current = pink outline) */
.lh-dot { width: 14px; height: 14px; border-radius: 50%; background: rgba(58,47,42,.18);
  border: 2px solid rgba(58,47,42,.22); }
.lh-dot.done { background: #f3a623; border-color: #d98e15; box-shadow: 0 0 8px rgba(243,166,35,.6); }
.lh-dot.current { background: #fff; border: 3px solid #f45c92; box-shadow: 0 0 0 3px rgba(244,92,146,.25); }

.lh-header { text-align: center; flex: 0 0 auto; margin-top: 2px; }
.lh-title { margin: 0; font-family: var(--font, "Fredoka", system-ui, sans-serif); font-weight: 700;
  font-size: clamp(16px, 3.6vw, 24px); color: var(--brown-deep); text-shadow: 0 1px 0 #fff; }
.lh-caption { margin: 3px 0 0; font-weight: 700; font-size: clamp(13px, 2.2vw, 17px); color: #6b5f74; min-height: 1.2em; }

/* Stage = the lagoon WORLD. Background environment layers are absolute (behind, z-index 0):
   sky / sun / clouds / distant trees / shore / water / ripples / central island (grass + hill +
   trees) / secondary islet. Cappy + lanterns + path + reward are foreground (z-index 2), grounded
   over the island. This delivers the approved world depth (Blocker 1) — multiple land masses,
   lagoon water as real space, vegetation — without changing any mechanic. */
.lh-stage.lh-lagoon { position: relative; flex: 1 1 auto; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: clamp(8px, 1.6vh, 16px);
  padding: clamp(10px, 2vh, 18px) clamp(10px, 2vw, 22px) clamp(16px, 7%, 44px);
  border-radius: 20px; overflow: hidden; isolation: isolate;
  background: linear-gradient(180deg, #bfe9ff 0%, #e9f6ff 38%, #cdeeff 46%, #8fd0ef 46%, #4f9fd6 100%); }
.lh-sky, .lh-sun, .lh-clouds, .lh-shore, .lh-water, .lh-ripple, .lh-far-trees,
.lh-island, .lh-islet { position: absolute; z-index: 0; pointer-events: none; }
.lh-sky { inset: 0 0 54% 0; background: linear-gradient(180deg, #bfe9ff, #e9f6ff); }
.lh-sun { top: 6%; right: 8%; width: clamp(54px, 12vw, 110px); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, #fff7d6 0%, #ffe9a8 55%, rgba(255,233,168,0) 72%);
  box-shadow: 0 0 40px 12px rgba(255,233,168,.55); }
.lh-clouds { inset: 9% 0 auto 0; height: 18%; }
.lh-clouds span { position: absolute; background: rgba(255,255,255,.85); border-radius: 999px; }
.lh-clouds span:nth-child(1) { left: 13%; top: 26%; width: 22%; height: 16px; box-shadow: 0 14px 0 -4px rgba(255,255,255,.85); }
.lh-clouds span:nth-child(2) { right: 15%; top: 10%; width: 16%; height: 12px; box-shadow: 0 10px 0 -5px rgba(255,255,255,.8); }
.lh-far-trees { left: 0; right: 0; bottom: 46%; height: 12%; display: flex; align-items: flex-end;
  justify-content: space-around; opacity: .82; }
.lh-far-trees span { width: 12%; height: 100%; background: #8fce9f; border-radius: 50% 50% 0 0; }
.lh-far-trees span:nth-child(2) { height: 74%; }
.lh-far-trees span:nth-child(3) { height: 122%; }
.lh-water { left: 0; right: 0; bottom: 0; height: 46%; background: linear-gradient(180deg, #7cc6ea, #3f9fd6 70%, #2f86c2); }
.lh-ripple { left: 0; right: 0; bottom: 0; height: 46%; opacity: .7; mix-blend-mode: screen;
  background: repeating-linear-gradient(180deg, rgba(255,255,255,0) 0 10px, rgba(255,255,255,.12) 10px 12px); }
.lh-shore { left: 0; right: 0; bottom: 44%; height: 4%; background: linear-gradient(180deg, #ffe9b0, #f3d28a); }
/* Central island = the play land mass (grass cap + hill + two trees) */
.lh-island { left: 50%; bottom: 28%; transform: translateX(-50%); width: min(92%, 720px); height: 34%;
  background: radial-gradient(130% 120% at 50% 0%, #ffe7a8 0%, #f3cf86 60%, #e3ad57 100%);
  border-radius: 50% 50% 44% 44% / 80% 80% 24% 24%; box-shadow: 0 8px 16px rgba(0,0,0,.10); }
.lh-grass { position: absolute; left: 8%; right: 8%; top: 6%; height: 26%; background: #bfe39a; border-radius: 999px; }
.lh-hill { position: absolute; left: 16%; top: -8%; width: 40%; height: 46%; background: #a9d685; border-radius: 50% 50% 0 0; }
.lh-trees { position: absolute; left: 0; right: 0; top: -16%; display: flex; justify-content: space-around; }
.lh-tree { position: relative; width: 11%; height: 60%; background: #6fae6a; border-radius: 50% 50% 0 0; }
.lh-tree::after { content: ""; position: absolute; left: 50%; bottom: -20%; transform: translateX(-50%);
  width: 40%; height: 28%; background: #8a5a3b; border-radius: 4px; }
.lh-tree-b { height: 46%; }
/* Secondary land mass — multiple land masses in the lagoon */
.lh-islet { left: 5%; bottom: 13%; width: min(20%, 180px); height: 13%;
  background: radial-gradient(130% 120% at 50% 0%, #ffe7a8, #e3ad57);
  border-radius: 50% 50% 44% 44% / 80% 80% 24% 24%; box-shadow: 0 6px 12px rgba(0,0,0,.10); }

.lh-cappy, .lh-lanterns, .lh-path, .lh-keepsake { position: relative; z-index: 2; }
.lh-cappy { display: flex; justify-content: center; }
.lh-cappy-img { width: clamp(84px, 22vw, 150px); height: auto; filter: drop-shadow(0 6px 6px rgba(0,0,0,.20)); }

/* 5 physical dual-coded lantern posts (color + shape glyph). >=60px targets. */
.lh-lanterns { display: flex; gap: clamp(10px, 2.4vw, 22px); justify-content: center; align-items: flex-end;
  flex-wrap: wrap; width: min(100%, 880px); margin: 0 auto; }
.lantern-post { position: relative; min-width: 60px; min-height: 60px; width: clamp(60px, 15vw, 96px);
  aspect-ratio: 1 / 1.18; border: 3px solid rgba(58,47,42,.20); background: var(--lc, #ffd56b);
  border-radius: 50% 50% 46% 46% / 62% 62% 40% 40%;
  display: flex; align-items: center; justify-content: center; cursor: default;
  color: #3a2f2a; box-shadow: 0 6px 0 rgba(0,0,0,.10), inset 0 0 0 2px rgba(255,255,255,.35);
  transition: transform 140ms ease-out, box-shadow 140ms ease-out, border-color 120ms; }
.lantern-post::before { content: ""; position: absolute; left: 50%; top: -10%; width: 26%; height: 14%;
  transform: translateX(-50%); background: #fff3d0; border-radius: 999px; border: 2px solid rgba(58,47,42,.20); }
.lantern-post .lc-body { display: flex; align-items: center; justify-content: center; }
.lantern-post .lc-glyph { width: clamp(30px, 7vw, 46px); height: clamp(30px, 7vw, 46px); display: block; }
.lantern-post .lc-glyph svg { width: 100%; height: 100%; fill: #3a2f2a; display: block; }
.lantern-post .lc-order { position: absolute; left: 6px; top: 4px; font-size: 0.72em; font-weight: 900;
  background: rgba(255,255,255,.92); border-radius: 999px; padding: 1px 7px; color: #3a2f2a; }

/* State cues (color is NEVER the only differentiator) */
.lantern-post.in-pattern { outline: 3px solid #F45C92; outline-offset: 2px; }
.lantern-post.next { outline: 4px solid #2A2230; outline-offset: 3px; }   /* activation (yourTurn) */
.lantern-post.wrong { border: 4px dashed #ff7a1a; box-shadow: 0 0 0 4px rgba(255,122,26,.22), 0 6px 0 rgba(0,0,0,.10); } /* D */
.lantern-post.lit { box-shadow: 0 0 0 4px #fff, 0 0 20px 6px rgba(246,201,76,.9), 0 6px 0 rgba(0,0,0,.10); }
.lantern-post.lit::after { content: "✓"; position: absolute; right: 2px; bottom: 0; color: #1f9d4d;
  font-weight: 900; font-size: clamp(16px, 4vw, 22px); text-shadow: 0 1px 0 #fff; }  /* correct = green check */
.lantern-post.tappable { cursor: pointer; }
.lantern-post.tappable:enabled:hover { transform: translateY(-3px) scale(1.04); }
.lantern-post.tappable:enabled:active { transform: translateY(0) scale(.97); }
.lantern-post:disabled { cursor: default; }
.lantern-post.tappable:focus-visible { outline: 4px solid #2A2230; outline-offset: 3px; }

/* Pattern-path affordance: demonstrated order as numbered shape steps */
.lh-path { display: flex; gap: 8px; list-style: none; margin: 0; padding: 0; justify-content: center; flex-wrap: wrap; }
.lc-step { position: relative; width: clamp(40px, 9vw, 56px); height: clamp(40px, 9vw, 56px); border-radius: 50%;
  background: var(--lc, #ffd56b); display: flex; align-items: center; justify-content: center;
  border: 3px solid rgba(58,47,42,.18); color: #3a2f2a; }
.lc-step .lc-glyph { width: 60%; height: 60%; }
.lc-step .lc-glyph svg { width: 100%; height: 100%; fill: #3a2f2a; display: block; }
.lc-step .lc-step-n { position: absolute; right: -4px; top: -4px; min-width: 20px; height: 20px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center; font-weight: 900; font-size: 12px; color: #3a2f2a;
  background: #fff; border: 2px solid #3a2f2a; border-radius: 999px; }
.lc-step.done { box-shadow: 0 0 0 3px #fff, 0 0 14px 3px rgba(246,201,76,.85); }
.lc-step.current { outline: 4px solid #2A2230; outline-offset: 2px; }

/* Reward keepsake (H): earned paper lantern — pink/gold + star + glow + tassel */
.lh-keepsake.earned { display: flex; flex-direction: column; align-items: center; gap: 6px; margin: 4px auto 0;
  padding: 14px 22px; border-radius: 18px; background: linear-gradient(180deg, #ffd9ec 0%, #ffe9c2 100%);
  border: 3px solid #f3a6cf; box-shadow: 0 0 24px 6px rgba(246,201,76,.7); }
.lh-keepsake .lk-body { width: clamp(54px, 12vw, 84px); aspect-ratio: 1 / 1.18; position: relative;
  border-radius: 50% 50% 46% 46% / 62% 62% 40% 40%;
  background: radial-gradient(120% 90% at 50% 30%, #ff8fc4 0%, #f3a6cf 60%, #e07fb0 100%); }
.lh-keepsake .lk-body::before { content: ""; position: absolute; left: 50%; top: -14%; width: 22%; height: 18%;
  transform: translateX(-50%); background: #ffd56b; border-radius: 999px; }  /* tassel top */
.lh-keepsake .lk-body::after { content: "★"; position: absolute; left: 50%; top: 44%; transform: translate(-50%,-50%);
  color: #fff6cf; font-size: clamp(20px, 5vw, 32px); }
.lh-keepsake .lk-cap { margin: 0; font-weight: 800; color: #7a3b5a; }

/* Footer controls */
.lh-footer { display: flex; flex-direction: column; align-items: center; gap: 10px;
  position: sticky; bottom: 0; background: linear-gradient(180deg, rgba(255,246,239,0), #fff6ef 40%); padding-top: 8px; }
.lh-footer .btn { min-height: 64px; min-width: 200px; }

/* ---- Responsive composition (TRUE reflow, not a scaled desktop) ---- */
.lantern[data-comp="phone"] .lh-lanterns { width: 100%; gap: clamp(8px, 3vw, 14px); }
.lantern[data-comp="phone"] .lantern-post { width: clamp(56px, 17vw, 76px); }
.lantern[data-comp="phone"] .lh-footer .btn { width: 100%; min-height: 64px; }
/* Tablet = vertical depth (column keeps the world layered sky -> trees/island -> water) */
.lantern[data-comp="tablet"] .lh-lanterns { width: min(82%, 720px); }
/* Desktop = horizontal world (NOT a centered board): Cappy + lanterns side by side across a wide lagoon */
.lantern[data-comp="desktop"] .lh-stage.lh-lagoon { flex-direction: row; align-items: flex-end;
  justify-content: center; flex-wrap: wrap; gap: clamp(18px, 3vw, 44px); }
.lantern[data-comp="desktop"] .lh-cappy { flex: 0 0 auto; align-self: center; }
.lantern[data-comp="desktop"] .lh-lanterns { width: auto; max-width: 72%; }
.lantern[data-comp="desktop"] .lh-path { width: 100%; }

/* ---- Reduced motion: preserve MEANING (static cues), remove decorative motion/scale ---- */
#game.reduced-motion .lantern-post,
#game.reduced-motion .lantern-post.tappable:enabled:hover,
#game.reduced-motion .lantern-post.tappable:enabled:active { transform: none; transition: none; }
#game.reduced-motion .lantern-post.next { outline: 5px solid #2A2230; outline-offset: 3px; }      /* instant thick border */
#game.reduced-motion .lantern-post.wrong { border: 5px dashed #ff7a1a; box-shadow: 0 0 0 4px rgba(255,122,26,.25); } /* static orange dashed */
#game.reduced-motion .lantern-post.lit { box-shadow: 0 0 0 4px #fff, 0 0 0 5px rgba(31,157,77,.7); } /* green ring, no glow */
#game.reduced-motion .lantern-post.lit::after { content: "✓"; color: #1f9d4d; }                    /* green check, static */
#game.reduced-motion .lantern[data-state="success"] .lantern-post.lit {                           /* static rainbow ring */
  box-shadow: 0 0 0 3px #ff5d8f, 0 0 0 6px #ffd166, 0 0 0 9px #8fd49b, 0 0 0 12px #7cc4ff; }
#game.reduced-motion .lh-keepsake.earned { box-shadow: 0 0 0 4px rgba(246,201,76,.7); }            /* instant golden glow */

/* ---- Treehouse Lantern Lagoon keepsake (V1.2 Blocker 3): approved small paper-lantern display
   (~56x72) on the Treehouse shelf. Visual is the primary signal; the text label is secondary.
   LOCKED = grey silhouette + lock. EARNED = pink/gold body + star + glow + tassel. ---- */
.th-keepsake { display: inline-flex; align-items: center; gap: 12px; margin: 6px auto 0; padding: 8px 16px;
  border-radius: 18px; background: linear-gradient(180deg, #ffe3f1, #ffe9c2); border: 2px solid #f3a6cf;
  color: #7a3b5a; font-weight: 800; font-size: 15px; box-shadow: 0 0 14px 2px rgba(246,201,76,.5); }
.th-keepsake.locked { background: #efeae6; border-color: #c9c2bc; color: #6b635c; box-shadow: none; }
.th-keepsake-art { position: relative; width: 56px; height: 72px; flex: 0 0 auto;
  border-radius: 50% 50% 46% 46% / 62% 62% 40% 40%; display: block; }
.th-keepsake-art.earned { background: radial-gradient(120% 90% at 50% 28%, #ff8fc4 0%, #f3a6cf 58%, #e07fb0 100%);
  box-shadow: 0 0 16px 3px rgba(246,201,76,.7); }
.th-keepsake-art.locked { background: radial-gradient(120% 90% at 50% 28%, #cfc8c2 0%, #b7afa8 60%, #9c938c 100%); }
.thk-cap { position: absolute; left: 50%; top: -7%; transform: translateX(-50%); width: 30%; height: 16%;
  background: #ffd56b; border-radius: 999px; border: 2px solid rgba(58,47,42,.18); }
.thk-star { position: absolute; left: 50%; top: 44%; transform: translate(-50%,-50%); color: #fff6cf;
  font-size: 22px; text-shadow: 0 1px 0 rgba(122,59,90,.4); }
.thk-tassel { position: absolute; left: 50%; bottom: -12%; transform: translateX(-50%); width: 3px; height: 16%;
  background: #f3a623; border-radius: 2px; }
.thk-lock { position: absolute; left: 50%; top: 46%; transform: translate(-50%,-50%); color: #6b635c; font-size: 18px; }
.th-keepsake-label { font-size: 13px; font-weight: 700; }
/* Reduced motion: static golden ring (meaning preserved), no glow animation */
#game.reduced-motion .th-keepsake-art.earned { box-shadow: 0 0 0 4px rgba(246,201,76,.7); }

