/* The A Little Sauna scene styles WITHOUT the prototype page's own rules (body, h1, buttons, the frame), so the scene
   can sit inside a normal website page (the survey, /rituals/next). Everything below the marker line is als.css from its
   "~48s day clock" comment onward, unchanged; apps/web/src/lib/survey/scene.test.ts fails if the two drift apart.
   To refresh: copy als.css from that comment to the end below the marker. */
.als-scene svg{display:block;width:100%;height:100%}
@media (prefers-reduced-motion: reduce){ .als-scene *{animation:none !important} }
/* ---- als.css from here ---- */
  /* ~48s day clock */
  /* skyDawn is the always-opaque BASE so the cross-fades never let the dark background show through (that caused the
     dark/greenish dip just after dawn). Each layer fades IN over the one below BEFORE that one fades out → full coverage all day.
     Timeline: dawn (base) · day 22–48% · dusk 52–70% · night 71–92%, matched to the sun + moon below. */
  .skyDawn{}.skyDay{opacity:0;animation:skyDay 48s ease-in-out infinite}
  .skyDusk{opacity:0;animation:skyDusk 48s ease-in-out infinite}.skyNight{opacity:0;animation:skyNight 48s ease-in-out infinite}
  @keyframes skyDay{0%,12%{opacity:0}22%{opacity:1}48%{opacity:1}55%{opacity:0}100%{opacity:0}}
  @keyframes skyDusk{0%,44%{opacity:0}52%{opacity:1}70%{opacity:1}77%{opacity:0}100%{opacity:0}}
  @keyframes skyNight{0%,61%{opacity:0}71%{opacity:1}92%{opacity:1}98%{opacity:0}100%{opacity:0}}
  /* sun: rises cresting the horizon (~7%), peaks (25%), SETS below the horizon (~51%) and stays hidden on the way back, no bounce */
  .sun{animation:sun 48s linear infinite}
  @keyframes sun{0%{transform:translate(40px,492px);opacity:0}6%{transform:translate(58px,456px);opacity:0}11%{transform:translate(78px,418px);opacity:.92}25%{transform:translate(180px,108px);opacity:1}42%{transform:translate(284px,418px);opacity:.92}47%{transform:translate(308px,456px);opacity:.45}51%{transform:translate(332px,492px);opacity:0}100%{transform:translate(40px,492px);opacity:0}}
  /* the moon has its OWN gentle drift across the night sky (not the sun's arc; height + path vary per scene; it passes behind the clouds). Fades in/out with the night, no bounce. */
  .moon{opacity:0;animation:moonFade 48s ease-in-out infinite, moonDrift 48s linear infinite}
  @keyframes moonFade{0%,60%{opacity:0}70%{opacity:.95}90%{opacity:.92}98%{opacity:0}100%{opacity:0}}
  @keyframes moonDrift{from{transform:translate(var(--mx0,110px),var(--my,170px))}to{transform:translate(var(--mx1,250px),var(--my,170px))}}
  .moonShadow{transform-box:fill-box;transform-origin:center;animation:moonPhase 200s linear infinite}
  @keyframes moonPhase{0%{transform:translateX(-3px)}50%{transform:translateX(23px)}100%{transform:translateX(-3px)}}
  .stars{opacity:0;animation:stars 48s ease-in-out infinite}@keyframes stars{0%,61%{opacity:0}71%{opacity:.95}91%{opacity:.9}98%{opacity:0}100%{opacity:0}}
  .night{opacity:0;animation:night 48s ease-in-out infinite}
  @keyframes night{0%{opacity:.06}14%{opacity:0}46%{opacity:0}56%{opacity:.16}72%{opacity:.5}90%{opacity:.5}98%{opacity:.12}100%{opacity:.06}}
  /* clouds catch the light. BODY tint through the day: soft rosy dawn → white midday → dusky mauve dusk → cool grey night */
  .cloud{fill:#ecd9cf;animation:cloudTint 48s ease-in-out infinite}
  @keyframes cloudTint{0%,11%{fill:#ecd9cf}25%,40%{fill:#f7f3ec}51%,58%{fill:#caa1aa}72%,90%{fill:#8f97a8}100%{fill:#ecd9cf}}
  /* warm UNDERSIDE, only lit at dawn/dusk (the low sun underlights the cloud), gone by midday/night */
  .cloudLit{fill:#f8cda2;opacity:0;animation:cloudLit 48s ease-in-out infinite}
  @keyframes cloudLit{0%{opacity:0}6%{opacity:.48;fill:#f8cda2}13%{opacity:.4;fill:#f6c8a0}26%,40%{opacity:.1;fill:#fbf2e6}50%{opacity:.62;fill:#f3a866}57%{opacity:.6;fill:#ef9a5c}66%,100%{opacity:0;fill:#ef9a5c}}
  /* grey rain / overcast clouds, muted, a touch lighter by day, darker at night */
  .cloudGrey{fill:#9aa1ad;animation:cloudGrey 48s ease-in-out infinite}
  @keyframes cloudGrey{0%,11%{fill:#9aa1ad}25%,40%{fill:#aab1bb}51%,58%{fill:#8b8794}72%,90%{fill:#565d6e}100%{fill:#9aa1ad}}
  @keyframes cloudDrift{from{transform:translateX(-90px)}to{transform:translateX(450px)}}
  @keyframes rainfall{from{transform:translateY(-16px)}to{transform:translateY(670px)}}
  .win{animation:winPulse 6s ease-in-out infinite}@keyframes winPulse{0%,100%{opacity:.92}50%{opacity:1}}
  .winGlow{animation:winGlow 6s ease-in-out infinite}@keyframes winGlow{0%,100%{opacity:.3}50%{opacity:.5}}
  .winNight{opacity:0;animation:winNight 48s ease-in-out infinite}
  @keyframes winNight{0%{opacity:.18}24%{opacity:0}48%{opacity:0}58%{opacity:.32}72%{opacity:.95}90%{opacity:.9}100%{opacity:.18}}
  /* the INTERIOR window shows the sky outside, matched to the day clock (dawn mauve → day blue → dusk → night navy) */
  .skywin{animation:skywin 48s ease-in-out infinite}
  @keyframes skywin{0%,11%{fill:#cbb6c8}25%,40%{fill:#aacfe2}51%,58%{fill:#8e6f93}72%,90%{fill:#1a2440}100%{fill:#cbb6c8}}
  .puff{opacity:0;animation:puff 5s ease-out infinite}.puff:nth-child(2){animation-delay:1.6s}.puff:nth-child(3){animation-delay:3.2s}
  @keyframes puff{0%{opacity:0;transform:translate(0,0) scale(.5)}20%{opacity:.5}100%{opacity:0;transform:translate(-16px,-78px) scale(1.7)}}
  .fairy{animation:fairy 48s ease-in-out infinite}@keyframes fairy{0%{opacity:.5}25%{opacity:.35}72%{opacity:1}100%{opacity:.5}}
  /* the festoon cross-fades on the day clock: BUNTING shows by day, FAIRY LIGHTS take over at night */
  /* the bunting stays up day and night; it does not vanish at dusk, it gets LIT (the glow lives in #nightlights) */
  .festoonDay{animation:festoonDay 48s ease-in-out infinite}
  @keyframes festoonDay{0%{opacity:.85}12%{opacity:1}48%{opacity:1}72%{opacity:.8}90%{opacity:.82}100%{opacity:.85}}
  .festoonNight{opacity:0;animation:festoonNight 48s ease-in-out infinite}
  @keyframes festoonNight{0%{opacity:.12}24%{opacity:0}48%{opacity:0}60%{opacity:.45}72%{opacity:1}90%{opacity:.95}100%{opacity:.12}}
  /* fairy bulbs read as LIT: a soft blooming halo + a gentle twinkle (staggered per bulb) */
  .fglow{transform-box:fill-box;transform-origin:center;animation:fglow 3.4s ease-in-out infinite}
  @keyframes fglow{0%,100%{opacity:.22;transform:scale(.84)}50%{opacity:.46;transform:scale(1.12)}}
  .ftw{animation:ftw 3.4s ease-in-out infinite}@keyframes ftw{0%,100%{opacity:.82}50%{opacity:1}}
  /* NIGHT GLOW: warm firelight pools that actually brighten the bottom once the place is lit. They sit above the night
     overlay and screen-blend (so they lift the scene, not just tint it), fade in with the evening, flicker like flame. */
  #nightlights{opacity:0;mix-blend-mode:screen;animation:nightGlow 48s ease-in-out infinite}
  /* on at DUSK (rises from 46%, with the night overlay), full through the night, fully off by DAWN (faded out by 10%, before the sun rises at 11%) */
  @keyframes nightGlow{0%{opacity:.28}10%{opacity:0}46%{opacity:0}58%{opacity:.5}72%{opacity:1}90%{opacity:.94}100%{opacity:.28}}
  .ngPool{transform-box:fill-box;transform-origin:center;animation:ngFlick 2.9s ease-in-out infinite}
  @keyframes ngFlick{0%,100%{opacity:.82;transform:scale(.99)}28%{opacity:1;transform:scale(1.035)}52%{opacity:.74;transform:scale(.97)}76%{opacity:.94;transform:scale(1.02)}}
  .ngSlow{animation-duration:6.5s}    /* the broad ground wash breathes slowly, a steady warm base */
  .ngFire{animation-duration:1.5s}    /* the firepit is the liveliest flame */
  @media (prefers-reduced-motion:reduce){.ngPool{animation:none}}

  /* glass door, glows; opens as a bather arrives/leaves (driven by the behaviour engine) */
  #doorPanel{transform-box:fill-box;transform-origin:left center;transition:transform .45s ease}
  .doorGlow{opacity:.32;transition:opacity .45s ease}

  /* lifelike walkers */
  .walker{animation:bob .46s ease-in-out infinite}@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-1.1px)}}
  .legA,.legB,.armL,.armR{transform-box:fill-box;transform-origin:top center}
  .legA{animation:stepA .46s ease-in-out infinite}.legB{animation:stepB .46s ease-in-out infinite}
  .armL{animation:armA .46s ease-in-out infinite}.armR{animation:armB .46s ease-in-out infinite}
  @keyframes stepA{0%,100%{transform:rotate(17deg)}50%{transform:rotate(-17deg)}}@keyframes stepB{0%,100%{transform:rotate(-17deg)}50%{transform:rotate(17deg)}}
  @keyframes armA{0%,100%{transform:rotate(13deg)}50%{transform:rotate(-13deg)}}@keyframes armB{0%,100%{transform:rotate(-13deg)}50%{transform:rotate(13deg)}}
  /* chopping wood, the axe swings down on the .chop group, pivoting roughly at the shoulder */
  .chop{transform-box:fill-box;transform-origin:78% 72%;animation:chop 1.15s ease-in-out infinite}
  @keyframes chop{0%,38%{transform:rotate(-48deg)}57%{transform:rotate(20deg)}65%{transform:rotate(14deg)}100%{transform:rotate(-48deg)}}
  /* the dog trotting, gentle body bob + little alternating legs */
  .dogBob{transform-box:fill-box;transform-origin:center;animation:dogBob .4s ease-in-out infinite}
  @keyframes dogBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-0.7px)}}
  .dogLegA,.dogLegB{transform-box:fill-box;transform-origin:top center}
  .dogLegA{animation:dogStepA .4s ease-in-out infinite}.dogLegB{animation:dogStepB .4s ease-in-out infinite}
  @keyframes dogStepA{0%,100%{transform:rotate(19deg)}50%{transform:rotate(-19deg)}}
  @keyframes dogStepB{0%,100%{transform:rotate(-19deg)}50%{transform:rotate(19deg)}}
  /* seated: still arms + slow breathing with the occasional sigh */
  .rest{transform-box:fill-box;transform-origin:bottom center;animation:rest 7s ease-in-out infinite}
  @keyframes rest{0%,100%{transform:translateY(0)}14%{transform:translateY(-0.4px)}28%{transform:translateY(0)}42%{transform:translateY(-0.4px)}52%{transform:translateY(0)}62%{transform:translateY(-1.9px) scaleX(1.03)}74%{transform:translateY(0.3px)}84%{transform:translateY(0)}}
  /* a brief room-filling steam burst when water hits the rocks */
  .steamBurst{transform-box:fill-box;transform-origin:center bottom;animation:steamBurst 3.8s ease-out}
  @keyframes steamBurst{0%{opacity:0;transform:translateY(36px) scale(.4)}16%{opacity:.55}55%{opacity:.5;transform:translateY(-18px) scale(1.7)}100%{opacity:0;transform:translateY(-78px) scale(2.3)}}
  /* the OPEN sign swings as it's hung out (pivots on the bracket at the top) */
  .signSwing{transform-box:fill-box;transform-origin:50% 0%}
  @keyframes signFlip{0%{transform:rotate(-24deg)}55%{transform:rotate(10deg)}80%{transform:rotate(-4deg)}100%{transform:rotate(0)}}
  /* the little OPEN placard swings gently in the breeze, pivoting where it hangs from the board */
  .openSway{transform-box:fill-box;transform-origin:50% 0%;animation:openSway 3.6s ease-in-out infinite}
  @keyframes openSway{0%,100%{transform:rotate(-4deg)}50%{transform:rotate(4deg)}}

  /* particles */
  .snow,.petal{opacity:0;animation:fall linear infinite}.leaf{opacity:0;animation:leaf linear infinite}
  @keyframes fall{0%{opacity:0;transform:translate(0,-12px)}10%{opacity:.7}90%{opacity:.65}100%{opacity:0;transform:translate(-14px,560px)}}
  @keyframes leaf{0%{opacity:0;transform:translate(0,-12px) rotate(0)}10%{opacity:.85}90%{opacity:.7}100%{opacity:0;transform:translate(-26px,540px) rotate(220deg)}}
  .firefly{opacity:0;animation:firefly ease-in-out infinite}
  @keyframes firefly{0%,100%{opacity:0;transform:translate(0,0)}40%{opacity:.9;transform:translate(6px,-7px)}70%{opacity:.5;transform:translate(-4px,3px)}}

  /* fire pit */
  .flame{transform-box:fill-box;transform-origin:bottom center;animation:flame .5s ease-in-out infinite alternate}
  @keyframes flame{from{transform:scaleY(.88) scaleX(1.02)}to{transform:scaleY(1.14) scaleX(.9)}}
  .fireGlow{animation:fireGlow .9s ease-in-out infinite alternate}@keyframes fireGlow{from{opacity:.4}to{opacity:.72}}
  /* bathing-in-water bob, get-in/out fade, wade-into-the-sea */
  .bob2{animation:bob2 2.6s ease-in-out infinite}@keyframes bob2{0%,100%{transform:translateY(0)}50%{transform:translateY(1.6px)}}
  .inout{animation:inout 13s ease-in-out infinite}@keyframes inout{0%,5%{opacity:0}13%{opacity:1}46%{opacity:1}54%{opacity:0}100%{opacity:0}}
  .seaWalk{animation:seaWalk 12s ease-in-out infinite}
  @keyframes seaWalk{0%{transform:translate(0,0);opacity:0}8%{opacity:1}42%{transform:translate(-12px,-28px)}60%{transform:translate(-12px,-28px)}90%{transform:translate(0,0);opacity:1}100%{opacity:0}}
  /* interior */
  .sitter{transform-box:fill-box;transform-origin:center bottom;animation:sit 3.2s ease-in-out infinite}
  @keyframes sit{0%,100%{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-0.7px) rotate(1.3deg)}}
  .chatter{opacity:0;animation:chatter 4.5s ease-in-out infinite}
  @keyframes chatter{0%,68%{opacity:0}74%{opacity:.85}88%{opacity:.85}95%{opacity:0}100%{opacity:0}}
  /* gentle outdoor natter, a speech bubble drifts in & out SLOWLY (calm, but clearly readable now), staggered per person */
  .chat{opacity:0;animation:chat 6.4s ease-in-out infinite}
  @keyframes chat{0%,46%{opacity:0}59%{opacity:1}84%{opacity:1}93%{opacity:0}100%{opacity:0}}
  /* the dog's light bark, a quick little pop above its head */
  .bark{transform-box:fill-box;transform-origin:center;animation:bark .7s ease-out}
  @keyframes bark{0%{opacity:0;transform:scale(.2)}25%{opacity:1;transform:scale(1.25)}55%{opacity:1;transform:scale(.95)}100%{opacity:0;transform:scale(.95)}}
  /* a new amenity arriving: a gentle settle-in, never a hard pop (and the scene never darkens to announce it) */
  .popIn{animation:popIn 1s ease both}
  @keyframes popIn{0%{opacity:0}100%{opacity:1}}
  /* a sparkle burst that draws the eye to a thing as it arrives: a warm flash + spinning gold stars */
  .sparkGlow{transform-box:fill-box;transform-origin:center;animation:sparkGlow .85s ease-out both}
  @keyframes sparkGlow{0%{opacity:0;transform:scale(.3)}22%{opacity:.6}100%{opacity:0;transform:scale(1.7)}}
  .sparkle{transform-box:fill-box;transform-origin:center;animation:sparklePop 1.1s ease-out both}
  @keyframes sparklePop{0%{opacity:0;transform:scale(.2) rotate(0deg)}26%{opacity:1;transform:scale(1.35) rotate(45deg)}100%{opacity:0;transform:scale(.55) rotate(100deg)}}
  .loyly{opacity:0;animation:loyly 9s ease-out infinite}
  @keyframes loyly{0%{opacity:0;transform:translate(0,0) scale(.4)}6%{opacity:.6}38%{opacity:.18}54%{opacity:0;transform:translate(-12px,-150px) scale(2.6)}100%{opacity:0;transform:translate(-12px,-150px) scale(2.6)}}
  /* light-the-fire scene: the fire catches and grows, the taper touches then withdraws */
  .lightfire{transform-box:fill-box;transform-origin:bottom center;animation:lightfire 6s ease-in-out infinite}
  @keyframes lightfire{0%{transform:scale(.1);opacity:.45}22%{transform:scaleX(.5) scaleY(.32);opacity:.85}70%{transform:scale(1);opacity:1}100%{transform:scaleX(1.04) scaleY(1.08);opacity:1}}
  /* the stove lighting: one flame catches, then more spread across the logs, all cut out together before the loop */
  .fireSeq{animation:fireSeq 7s ease-in-out infinite}
  @keyframes fireSeq{0%{opacity:0}8%{opacity:1}82%{opacity:1}94%{opacity:0}100%{opacity:0}}
  .cat0,.cat1,.cat2{transform-box:fill-box;transform-origin:bottom center}
  .cat0{animation:cat0 7s ease-out infinite}.cat1{animation:cat1 7s ease-out infinite}.cat2{animation:cat2 7s ease-out infinite}
  @keyframes cat0{0%{transform:scale(.05)}9%{transform:scaleX(.6) scaleY(.4)}28%{transform:scale(1)}100%{transform:scale(1)}}
  @keyframes cat1{0%,11%{transform:scale(.05)}22%{transform:scaleX(.6) scaleY(.42)}42%{transform:scale(1)}100%{transform:scale(1)}}
  @keyframes cat2{0%,24%{transform:scale(.05)}38%{transform:scaleX(.55) scaleY(.4)}56%{transform:scale(1)}100%{transform:scale(1)}}
  .fireGlow2{opacity:.14;animation:fireGlow2 6s ease-in-out infinite}
  @keyframes fireGlow2{0%{opacity:.12}22%{opacity:.3}70%{opacity:.54}100%{opacity:.6}}
  /* logs catch and start to glow as the fire takes hold */
  .logGlow{opacity:0;animation:logGlow 6s ease-in-out infinite}
  @keyframes logGlow{0%,28%{opacity:0}66%{opacity:.9}100%{opacity:1}}
  /* little puffs of smoke rising as it lights */
  .fsmoke{opacity:0;animation:fsmoke 2.6s ease-out infinite}
  @keyframes fsmoke{0%{opacity:0;transform:translate(0,0) scale(.5)}18%{opacity:.45}100%{opacity:0;transform:translate(-12px,-78px) scale(1.9)}}
  /* robin: perch on the roof -> fly to the tree -> back */
  /* the bird is JS-driven (position + facing). The wings only flap while FLYING (the bird group gets .flying); at rest they're still. */
  .robinWing{transform-box:fill-box;transform-origin:right center}
  .flying .robinWing{animation:robinWing .3s ease-in-out infinite}
  @keyframes robinWing{0%,100%{transform:rotate(-10deg) scaleY(1)}50%{transform:rotate(12deg) scaleY(.6)}}
  /* stars twinkle + the odd shooting star (night only, inside #stars) */
  @keyframes twinkle{0%,100%{opacity:1}50%{opacity:.25}}
  .shootingStar{opacity:0;animation:shoot 11s linear infinite}  /* a fast, bright streak that fades as it dies */
  @keyframes shoot{0%,85%{opacity:0;transform:translate(56px,38px)}86%{opacity:1;transform:translate(64px,42px)}92%{opacity:1;transform:translate(300px,178px)}95%{opacity:0;transform:translate(332px,196px)}100%{opacity:0;transform:translate(56px,38px)}}
  /* butterflies (spring) / dragonflies (summer) */
  .bWing{transform-box:fill-box;transform-origin:center;animation:bWing .4s ease-in-out infinite alternate}
  @keyframes bWing{from{transform:scaleX(1)}to{transform:scaleX(.45)}}
  .fly1{animation:fly1 19s ease-in-out infinite}@keyframes fly1{0%{transform:translate(60px,470px)}25%{transform:translate(126px,432px)}50%{transform:translate(196px,462px)}75%{transform:translate(132px,502px)}100%{transform:translate(60px,470px)}}
  .fly2{animation:fly2 23s ease-in-out infinite}@keyframes fly2{0%{transform:translate(312px,496px)}30%{transform:translate(258px,452px)}60%{transform:translate(326px,470px)}100%{transform:translate(312px,496px)}}
  /* condensation drips on the interior window */
  .drip{opacity:0;animation:drip 5s ease-in infinite}@keyframes drip{0%{opacity:0;transform:translateY(0)}10%{opacity:.7}100%{opacity:0;transform:translateY(72px)}}
  /* firelight flicker on the interior walls */
  .firelight{animation:firelight 2.4s ease-in-out infinite}@keyframes firelight{0%,100%{opacity:.10}30%{opacity:.2}55%{opacity:.07}80%{opacity:.17}}
  /* steam rising off a bather who's just come out into the cold (the 'phew') */
  .bsteam{opacity:0;animation:bsteam 2.3s ease-out infinite}@keyframes bsteam{0%{opacity:0;transform:translate(0,0) scale(.5)}22%{opacity:.5}100%{opacity:0;transform:translate(-4px,-30px) scale(1.5)}}
  /* a splash ripple when someone gets into the plunge / sea */
  .ripple{transform-box:fill-box;transform-origin:center;opacity:0;animation:ripple 1.1s ease-out}@keyframes ripple{0%{opacity:.7;transform:scale(.3)}100%{opacity:0;transform:scale(1.7)}}
  .matchflame{transform-box:fill-box;transform-origin:bottom center;animation:flame .4s ease-in-out infinite alternate}
  .taper{animation:taper 6s ease-in-out infinite}
  @keyframes taper{0%{opacity:0;transform:translate(20px,10px)}8%{opacity:1;transform:translate(0,0)}24%{transform:translate(0,0)}45%{opacity:1;transform:translate(48px,22px)}70%{opacity:0;transform:translate(80px,38px)}100%{opacity:0;transform:translate(80px,38px)}}
