/* ==========================================================
   Rooms: every part of the nursery gets its own wall colour,
   toy-block headings, a nightlight glow behind Pip, shelves
   for the projects and a night-o-meter that fills as you read
   ========================================================== */

:root,
[data-theme="day"] {
  --wall-hero: #fde4eb;
  --stripe-hero: rgba(217, 120, 151, 0.16);
  --wall-about: #efe5fa;
  --stripe-about: rgba(178, 150, 222, 0.32);
  --wall-made: #fff0d4;
  --stripe-made: rgba(232, 160, 60, 0.15);
  --wall-wish: #e6f4e8;
  --stripe-wish: rgba(130, 190, 135, 0.24);
  --wall-foot: #f9dfe7;
  --dot-tint: rgba(163, 64, 99, 0.13);
  --heading-drop: #f4b3c6;
  --rail: #fffaf3;
  --rail-line: #e7c7d1;
  --shelf: #d5a77f;
  --shelf-edge: #9c6c4c;
  --panel-shadow: 0 22px 44px -26px rgba(122, 52, 86, 0.45);
  --glow: rgba(255, 196, 102, 0.55);
}

[data-theme="night"] {
  --wall-hero: #2a1a3e;
  --stripe-hero: rgba(242, 166, 191, 0.07);
  --wall-about: #221a3d;
  --stripe-about: rgba(201, 182, 228, 0.08);
  --wall-made: #2a1c35;
  --stripe-made: rgba(255, 207, 107, 0.06);
  --wall-wish: #1b2138;
  --stripe-wish: rgba(191, 227, 192, 0.06);
  --wall-foot: #160f27;
  --dot-tint: rgba(255, 207, 107, 0.14);
  --heading-drop: #563a73;
  --rail: #33264f;
  --rail-line: #4a3a6a;
  --shelf: #6e4c3c;
  --shelf-edge: #3e2a22;
  --panel-shadow: 0 22px 44px -24px rgba(0, 0, 0, 0.7);
  --glow: rgba(255, 196, 102, 0.42);
}

/* ---------- the rooms ---------- */
.hero { background-color: var(--wall-hero); --wall-stripe: var(--stripe-hero); --wall-dot: var(--dot-tint); }
.about { background-color: var(--wall-about); --wall-stripe: var(--stripe-about); --wall-dot: var(--dot-tint); }
.made { background-color: var(--wall-made); --wall-stripe: var(--stripe-made); --wall-dot: var(--dot-tint); }
.wishes { background-color: var(--wall-wish); --wall-stripe: var(--stripe-wish); --wall-dot: var(--dot-tint); }
.foot { background-color: var(--wall-foot); border-top: 0; }

/* a painted dado rail where one room meets the next */
.about,
.made,
.wishes,
.foot { box-shadow: inset 0 10px 0 var(--rail), inset 0 12px 0 var(--rail-line); }

/* dusk: the lavender wall fades into the night sky of the first scene */
.story__intro {
  padding-bottom: clamp(160px, 30vh, 280px);
  background: linear-gradient(var(--wall-about) 0%, var(--wall-about) 56%, #cfb0d2 68%, #5a4479 86%, #1b2050 100%);
}
[data-theme="night"] .story__intro { background: linear-gradient(var(--wall-about), #1b2050); }

/* ---------- toy-block headings ---------- */
.about__title,
.story__intro h2,
.made__head h2,
.wishes__head h2 {
  font-weight: 700;
  letter-spacing: 0.005em;
  text-shadow: 0 3px 0 var(--heading-drop), 0 6px 0 var(--heading-drop);
}
.made__head h2,
.wishes__head h2,
.about__title { font-size: clamp(2.3rem, 7vw, 3.6rem); }
.exhibit__text h3 { text-shadow: 0 2px 0 var(--heading-drop); }

/* ---------- hero: a warm nightlight glow behind Pip ---------- */
.hero::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: 50%; top: 32%;
  width: min(760px, 120vw);
  aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(circle, var(--glow) 0%, rgba(255, 196, 102, 0.18) 38%, transparent 66%);
  pointer-events: none;
}
@media (min-width: 900px) {
  .hero::before { left: 72%; top: 52%; }
}
.hero__window,
.hero__pip,
.hero__copy { position: relative; z-index: 1; }
.hero__pip { z-index: 2; }

/* the P-i-p blocks stack like real blocks, with a little depth */
.blocks-title .lb { box-shadow: inset -0.06em -0.08em 0 rgba(90, 52, 72, 0.12), 0.05em 0.07em 0 rgba(90, 52, 72, 0.28), 0 0.2em 0.28em -0.12em rgba(90, 52, 72, 0.45); }

/* ---------- projects sit on shelves ---------- */
.exhibit {
  position: relative;
  padding: clamp(20px, 4vw, 40px);
  background: var(--card);
  border-radius: 28px;
  box-shadow: var(--panel-shadow);
}
.exhibit::after {
  /* the wooden shelf the toy stands on */
  content: "";
  position: absolute;
  left: 18px; right: 18px; bottom: -14px;
  height: 16px;
  border-radius: 6px;
  background: linear-gradient(var(--shelf) 0 62%, var(--shelf-edge) 62%);
  box-shadow: 0 10px 18px -10px rgba(60, 30, 20, 0.5);
}
.exhibit + .exhibit { margin-top: 18px; }

/* 3D tilt on the toy side of each exhibit (motion.js sets --rx/--ry); fine pointers only */
.exhibit > :not(.exhibit__text) {
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transform-style: preserve-3d;
}

/* ---------- the wish jar and the 3D Pip get paper cards too ---------- */
.spin {
  border-style: solid;
  border-color: transparent;
  background: radial-gradient(circle at 50% 42%, rgba(255, 207, 107, 0.28), transparent 62%), var(--card);
  box-shadow: var(--panel-shadow);
}
.spin.is-grabbed .spin__canvas { cursor: grabbing; }

/* ---------- night-o-meter: how far through the night you've scrolled ---------- */
.nightmeter {
  position: fixed;
  z-index: 49;
  left: 0; right: 0;
  top: calc(var(--bar) + 9px);
  height: 5px;
  pointer-events: none;
}
.nightmeter__fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--blk-c), var(--blk-d), var(--blk-e), var(--blk-g), var(--blk-a));
  transform-origin: 0 50%;
  transform: scaleX(0);
  border-radius: 0 4px 4px 0;
}
.nightmeter__moon {
  position: absolute;
  top: 50%; left: 0;
  width: 18px; height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50%;
  background: radial-gradient(circle at 65% 35%, transparent 5px, #ffe08a 5.5px);
  filter: drop-shadow(0 0 4px rgba(255, 207, 107, 0.8));
  transform: translateX(0);
}

/* ---------- springier buttons ---------- */
@media (hover: hover) and (pointer: fine) {
  .toy-btn:hover { transform: translateY(-3px) rotate(-1deg); }
  .toy-btn--soft:hover { transform: translateY(-3px) rotate(1deg); }
}
.toy-btn:active { transform: translateY(4px) scale(0.97); }

/* ---------- reduced motion: no tilt ---------- */
@media (prefers-reduced-motion: reduce) {
  .exhibit > :not(.exhibit__text) { transform: none; }
}

/* the hero's first-visit drop-in starts from here (index.html adds .intro, motion.js removes it) */
.intro .blocks-title .lb,
.intro .hero__hi,
.intro .hero__job,
.intro .hero__tagline,
.intro .hero__intro,
.intro .hero__actions { opacity: 0; }

/* story cards tip up into place like pages as they scroll in (native scroll timeline, no script) */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .step { view-timeline: --page block; perspective: 1000px; }
    .step .card {
      transform-origin: 50% 100%;
      animation: page-in linear both;
      animation-timeline: --page;
      animation-range: entry 5% entry 65%;
    }
    @keyframes page-in {
      from { rotate: x 32deg; translate: 0 48px; }
      to { rotate: x 0deg; translate: 0 0; }
    }
  }
}

/* the 3D Pip gets more room on wide screens */
@media (min-width: 900px) {
  .spin { max-width: 380px; }
  .spin__canvas { max-width: 340px; }
}

/* ==========================================================
   The story camera (native scroll timelines, no script):
   - inside a scene, the picture drifts and zooms slowly while you read
   - between scenes, the old picture holds still while the camera pushes in,
     and the next one opens from a cartoon iris in the middle
   ========================================================== */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .scene { view-timeline: --scene block; overflow-x: clip; } /* zoomed pictures never widen the page */

    /* a slow drift while the scene is pinned, so it never sits still like a slide */
    .scene .stage > .art,
    .scene .stage > .pan,
    #stage-6 > :first-child {
      animation: scene-drift linear both;
      animation-timeline: --scene;
      animation-range: contain 0% contain 100%;
    }
    @keyframes scene-drift {
      from { scale: 1; translate: 0 0; }
      to { scale: 1.07; translate: 0 -1.5%; }
    }

    /* leaving: hold the picture in place (it would otherwise be shoved up) and push in */
    .scene:has(+ .scene) .stage {
      animation: scene-out linear both;
      animation-timeline: --scene;
      animation-range: exit 0% exit 100%;
    }
    @keyframes scene-out {
      from { translate: 0 0; scale: 1; }
      to { translate: 0 100%; scale: 1.22; }
    }

    /* arriving: also held in place, opening from a small circle with a gentle zoom-out */
    .scene + .scene .stage {
      animation: scene-in linear both;
      animation-timeline: --scene;
      animation-range: entry 0% entry 100%;
    }
    @keyframes scene-in {
      from { translate: 0 -100%; scale: 1.25; clip-path: circle(0% at 50% 46%); }
      25% { clip-path: circle(6% at 50% 46%); }
      to { translate: 0 0; scale: 1; clip-path: circle(80% at 50% 46%); }
    }

    /* touch screens scroll on their own thread, and the hold-in-place + iris above can only run
       on the main thread, so it lagged a frame behind the finger and the picture shook. Here
       scenes ride the scroll naturally: the old one sinks back, the new one settles in. Scale
       and opacity only, so it stays in step with the finger. */
    @media (pointer: coarse), (max-width: 760px) {
      .scene:has(+ .scene) .stage { animation-name: scene-out-touch; }
      .scene + .scene .stage { animation-name: scene-in-touch; }
    }
    @keyframes scene-out-touch {
      from { scale: 1; opacity: 1; }
      to { scale: 0.92; opacity: 0.5; }
    }
    @keyframes scene-in-touch {
      from { scale: 1.06; opacity: 0.5; }
      to { scale: 1; opacity: 1; }
    }
  }
}

/* ==========================================================
   Wall decorations (motion.js adds .deco to each room)
   ========================================================== */
:root, [data-theme="day"] { --deco-heart: #f4a3bc; --pool-a: rgba(255, 255, 255, 0.7); --pool-b: rgba(255, 196, 120, 0.28); }
[data-theme="night"] { --deco-heart: #b8607f; --pool-a: rgba(201, 182, 228, 0.12); --pool-b: rgba(255, 196, 102, 0.12); }

.hero, .about, .made, .wishes { position: relative; isolation: isolate; overflow-x: clip; }
.deco { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.deco__pool { position: absolute; width: 46vmax; aspect-ratio: 1; border-radius: 50%; }
.deco__pool--a { left: -14vmax; top: -10vmax; background: radial-gradient(circle, var(--pool-a), transparent 65%); }
.deco__pool--b { right: -16vmax; bottom: -14vmax; background: radial-gradient(circle, var(--pool-b), transparent 65%); }
.deco__i { position: absolute; left: var(--x); top: var(--y); width: var(--s); opacity: calc(0.35 + var(--d) * 0.5); }
.deco__i svg { width: 100%; height: auto; overflow: visible; }
.deco__i--star { --twinkle: #f2b53a; }
[data-theme="night"] .deco__i--cloud { opacity: calc(0.12 + var(--d) * 0.25); }
@media (max-width: 700px) { .deco__i { width: calc(var(--s) * 0.7); } .deco__i--cloud:nth-child(odd) { display: none; } }

.deco__layer { position: absolute; inset: 0; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* one plain transform animation per depth layer (no var() in keyframes), so it can run on
       the compositor instead of recalculating every shape on every frame */
    .hero, .about, .made, .wishes { view-timeline: --room block; }
    .deco__layer { animation: linear both; animation-timeline: --room; animation-range: cover; }
    .deco__layer--1 { animation-name: deco-far; }
    .deco__layer--2 { animation-name: deco-mid; }
    .deco__layer--3 { animation-name: deco-near; }
    @keyframes deco-far { from { transform: translateY(50px); } to { transform: translateY(-50px); } }
    @keyframes deco-mid { from { transform: translateY(85px); } to { transform: translateY(-85px); } }
    @keyframes deco-near { from { transform: translateY(120px); } to { transform: translateY(-120px); } }
  }
}
