/* ============ Home page: step inside her stories ============
   One long page made of her worlds. Each scene is alive — rain, snow, embers,
   fog, flickering windows, a rally that never ends — and the moving things are
   what you touch: a window, a pair of eyes, the ball. Touching one opens a
   story card (js/home.js). Nothing is drawn as a button. */

/* ---------- hello ---------- */
.hello {
  position: relative; min-height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding: max(7rem, 13vh) 1.5rem 4rem; text-align: center; overflow: hidden; isolation: isolate;
}
.hello-sky {
  position: absolute; inset: 0; z-index: -1;
  background: #05070d url(../assets/new/hero-book.jpg) center bottom / cover no-repeat;
  animation: skyDrift 40s ease-in-out infinite alternate; transform-origin: 55% 80%;
}
.hello-sky::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(5,7,13,0.55), rgba(5,7,13,0.1) 45%, transparent 75%, var(--ink));
}
@keyframes skyDrift { to { transform: scale(1.06); } }
.hello .fx { z-index: 0; }
.hello-inner { position: relative; z-index: 2; }
/* a pool of shadow behind the words so they read over the glowing book */
.hello-inner::before { content: ""; position: absolute; inset: -18% -22%; z-index: -1; background: radial-gradient(closest-side, rgba(5,7,13,0.72), rgba(5,7,13,0.35) 60%, transparent); }
/* loose pages lift out of the open book and drift away */
.loose-pages { position: absolute; left: 50%; bottom: 22%; width: 0; height: 0; z-index: 1; pointer-events: none; }
.loose-pages i {
  position: absolute; left: 0; top: 0; width: 46px; height: 60px; border-radius: 2px;
  background: linear-gradient(135deg, #fff3d6, #e8cf9a); box-shadow: 0 0 18px rgba(255,200,110,0.55);
  opacity: 0; animation: pageLift 11s ease-in infinite;
}
.loose-pages i:nth-child(2) { animation-delay: 3.7s; animation-duration: 13s; }
.loose-pages i:nth-child(3) { animation-delay: 7.4s; animation-duration: 12s; }
@keyframes pageLift {
  0%   { opacity: 0; transform: translate(0, 0) rotate(0) rotateY(0) scale(0.6); }
  10%  { opacity: 0.95; }
  50%  { transform: translate(-90px, -38vh) rotate(-35deg) rotateY(160deg) scale(0.8); }
  80%  { opacity: 0.6; }
  100% { opacity: 0; transform: translate(140px, -75vh) rotate(25deg) rotateY(340deg) scale(0.5); }
}
.loose-pages i:nth-child(2) { animation-name: pageLift2; }
@keyframes pageLift2 {
  0%   { opacity: 0; transform: translate(40px, 0) rotate(0) rotateY(0) scale(0.55); }
  12%  { opacity: 0.9; }
  55%  { transform: translate(160px, -40vh) rotate(30deg) rotateY(-170deg) scale(0.75); }
  100% { opacity: 0; transform: translate(-60px, -78vh) rotate(-20deg) rotateY(-330deg) scale(0.45); }
}
.anchor { display: block; position: relative; top: -70px; }
.hello-mark { height: 64px; width: auto; margin: 0 auto 1.2rem; animation: emblemGlint 5s ease-in-out infinite; }
.hello h1 { font-size: clamp(3.2rem, 10vw, 7.5rem); line-height: 0.98; margin-top: 0.6rem; text-shadow: 0 6px 44px rgba(0,0,0,0.8); }
.hello-sub {
  max-width: 36rem; margin: 1.5rem auto 0;
  font-family: var(--font-display); font-style: italic;
  font-size: clamp(1.1rem, 2.1vw, 1.45rem); line-height: 1.5; color: var(--cream-dim);
}
.hello-hint {
  margin-top: 2rem; display: inline-flex; align-items: center; gap: 0.7rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--cream-faint);
}
.glow-dot { width: 8px; height: 8px; border-radius: 50%; background: #f7c86b; animation: glowPulse 2.2s ease-out infinite; }
@keyframes glowPulse { 0% { box-shadow: 0 0 0 0 rgba(247,200,107,0.6); } 100% { box-shadow: 0 0 0 14px rgba(247,200,107,0); } }

.hello-worlds { display: flex; gap: clamp(0.8rem, 2.5vw, 2rem); justify-content: center; flex-wrap: wrap; margin-top: 3.5rem; }
.hello-worlds a { width: clamp(78px, 9vw, 112px); text-decoration: none; color: var(--cream-dim); transition: transform 0.4s var(--ease-out), color 0.3s; animation: floaty 6s ease-in-out infinite; }
.hello-worlds a:nth-child(2) { animation-delay: -1.5s; }
.hello-worlds a:nth-child(3) { animation-delay: -3s; }
.hello-worlds a:nth-child(4) { animation-delay: -4.5s; }
@keyframes floaty { 50% { translate: 0 -8px; } }
.hello-worlds img { width: 100%; aspect-ratio: 2/3; object-fit: cover; border: 1px solid rgba(244,237,223,0.2); box-shadow: 0 16px 34px rgba(0,0,0,0.6); }
.hello-worlds span { display: block; margin-top: 0.6rem; font-size: 0.62rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; line-height: 1.4; }
.hello-worlds a:hover, .hello-worlds a:focus-visible { transform: translateY(-6px) scale(1.05); color: var(--cream); }

.hero-rise { animation: heroRise 1.3s cubic-bezier(0.22, 0.8, 0.28, 1) 0.15s both; }
@keyframes heroRise { from { opacity: 0; transform: translate3d(0, 28px, 0); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }

/* ---------- a world ---------- */
.world { position: relative; }
.world-head { max-width: 44rem; margin: 0 auto; padding: clamp(5rem, 12vh, 8rem) 1.5rem 2.5rem; text-align: center; }
.world-head h2 { font-size: clamp(2.2rem, 5.5vw, 4rem); line-height: 1.05; margin-top: 0.7rem; }
.world-head p { margin: 1.2rem auto 0; max-width: 36rem; color: var(--cream-dim); }
.chapter-label { text-align: center; padding: 4.5rem 1.5rem 1.6rem; font-family: var(--font-display); font-size: clamp(1.4rem, 3vw, 2rem); color: var(--cream); }
.chapter-label span { display: block; margin-bottom: 0.4rem; font-family: var(--font-body); font-size: 0.68rem; font-weight: 600; letter-spacing: 0.24em; text-transform: uppercase; color: var(--accent); }

/* ---------- the stage ---------- */
.stage { --sh: clamp(480px, 56.25vw, 92vh); position: relative; height: var(--sh); overflow: hidden; isolation: isolate; }
/* the picture keeps its 16:9 shape so animated pieces stay pinned to what they
   sit on; it pushes in slowly as you scroll (--zoom, set in js/home.js) */
.stage-frame {
  position: absolute; top: 50%; left: 50%;
  width: max(100%, calc(var(--sh) * 16 / 9)); aspect-ratio: 16 / 9;
  transform: translate(-50%, -50%);
}
@media (max-width: 900px) { .stage-frame { transform: translate(calc(var(--fx, 50%) * -1), -50%); } }
.stage-bg { width: 100%; height: 100%; object-fit: cover; display: block; }
.stage::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(180deg, var(--ink) 0%, transparent 14%, transparent 80%, var(--ink) 100%);
}
.fx { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }

/* everything placed on the picture uses its centre point */
.win, .lamp, .moon, .twinkle, .burn, .fire, .spot { position: absolute; left: var(--x); top: var(--y); transform: translate(-50%, -50%); }

/* lit windows breathe, each on its own clock */
.win {
  width: var(--w); height: var(--h); pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(closest-side, rgba(255,214,140,0.75), rgba(255,190,100,0.25) 60%, transparent);
  animation: winBreathe var(--d, 4s) ease-in-out infinite;
}
@keyframes winBreathe { 0%, 100% { opacity: 0.35; } 40% { opacity: 0.9; } 47% { opacity: 0.55; } 52% { opacity: 0.85; } }
.lamp {
  width: 5%; aspect-ratio: 1; pointer-events: none; mix-blend-mode: screen; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,210,130,0.85), rgba(255,170,80,0.25) 45%, transparent);
  animation: lampFlicker var(--d, 4s) ease-in-out infinite;
}
.lamp.warm { width: 8%; }
@keyframes lampFlicker { 0%, 100% { opacity: 0.7; scale: 1; } 30% { opacity: 1; scale: 1.08; } 33% { opacity: 0.5; } 36% { opacity: 0.95; } 70% { opacity: 0.8; scale: 0.96; } }

/* fog rolls through in two or three layers at different speeds */
.fog { position: absolute; left: -20%; right: -20%; pointer-events: none; }
.fog i { position: absolute; inset: 0; border-radius: 50%; filter: blur(30px); }
.fog-street { top: 58%; height: 30%; }
.fog-street i { background: radial-gradient(50% 50% at 50% 50%, rgba(160,170,190,0.28), transparent 70%); animation: fogRoll 26s linear infinite alternate; }
.fog-street i:nth-child(2) { top: 30%; animation-duration: 38s; animation-direction: alternate-reverse; opacity: 0.8; }
.fog-green { top: 50%; height: 50%; }
.fog-green i { background: radial-gradient(50% 50% at 50% 50%, rgba(110,190,120,0.32), transparent 70%); animation: fogRoll 30s linear infinite alternate; }
.fog-green i:nth-child(2) { top: 25%; animation-duration: 44s; animation-direction: alternate-reverse; }
.fog-green i:nth-child(3) { top: -20%; animation-duration: 22s; opacity: 0.6; }
@keyframes fogRoll { from { transform: translate3d(-18%, 0, 0); } to { transform: translate3d(18%, 0, 0); } }

/* ---------- things you can touch ----------
   Invisible until you reach them. On hover the spot warms with light, and
   each one has its own little performance. */
.spot {
  width: var(--w); height: var(--h); z-index: 3;
  border: 0; padding: 0; background: transparent; cursor: pointer; border-radius: 8px;
  transition: box-shadow 0.4s, background 0.4s;
}
.spot:hover, .spot:focus-visible {
  background: radial-gradient(closest-side, rgba(255,226,160,0.35), transparent);
  box-shadow: 0 0 40px 10px rgba(255, 214, 140, 0.25); outline: none;
}
.spot-soft:hover, .spot-soft:focus-visible { background: radial-gradient(closest-side, rgba(255,226,160,0.12), transparent); box-shadow: none; }

/* Invidia passes the attic window */
.shade {
  position: absolute; left: 30%; bottom: 0; width: 60%; height: 95%;
  background: url(../assets/new/invidia-silhouette.png) center bottom / contain no-repeat; opacity: 0;
  filter: brightness(0.15); animation: pass 9s ease-in-out infinite;
}
@keyframes pass {
  0%, 55% { opacity: 0; transform: translateX(-160%); }
  60% { opacity: 0.9; }
  78% { opacity: 0.9; transform: translateX(60%); }
  84%, 100% { opacity: 0; transform: translateX(120%); }
}
/* a candle carried past the dormitory window */
.candle {
  position: absolute; left: 50%; top: 55%; width: 30%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,240,190,1), rgba(255,190,90,0.5) 50%, transparent);
  mix-blend-mode: screen; opacity: 0;
  animation: candle 12s ease-in-out infinite 2s;
}
@keyframes candle {
  0%, 60% { opacity: 0; transform: translate(-200%, 0); }
  66% { opacity: 1; }
  86% { opacity: 1; transform: translate(80%, -6%); }
  92%, 100% { opacity: 0; transform: translate(140%, -6%); }
}
/* the front door opens a crack and light spills down the steps */
.door-spill {
  position: absolute; left: 50%; top: 20%; width: 55%; height: 140%; transform-origin: top center;
  background: linear-gradient(180deg, rgba(255,220,150,0.85), rgba(255,200,120,0.25) 60%, transparent);
  clip-path: polygon(40% 0, 60% 0, 100% 100%, 0 100%);
  mix-blend-mode: screen; translate: -50% 0; opacity: 0;
  animation: spill 11s ease-in-out infinite 4s;
}
@keyframes spill {
  0%, 62% { opacity: 0; scale: 0.2 1; }
  70%, 84% { opacity: 1; scale: 1 1; }
  92%, 100% { opacity: 0; scale: 0.2 1; }
}
.spot-door:hover .door-spill { animation: none; opacity: 1; scale: 1 1; transition: opacity 0.4s; }

/* lantern flames */
.flame {
  position: absolute; left: 50%; top: 45%; width: 70%; aspect-ratio: 1; border-radius: 50%; translate: -50% -50%;
  background: radial-gradient(closest-side, rgba(255,236,170,0.95), rgba(255,170,60,0.45) 45%, transparent);
  mix-blend-mode: screen; animation: lampFlicker 2.3s ease-in-out infinite;
}
.flame.big { width: 120%; }

/* wakers' eyes: open, blink, gone */
.spot-eyes { border-radius: 50%; }
.eyes { position: absolute; inset: 0; opacity: 0; animation: eyes var(--d, 8s) ease-in-out infinite; animation-delay: var(--o, 0s); }
.eyes::before, .eyes::after {
  content: ""; position: absolute; top: 40%; width: 16%; aspect-ratio: 1.6; border-radius: 50%;
  background: #d8ff9a; box-shadow: 0 0 10px 3px rgba(190,255,120,0.9);
}
.eyes::before { left: 26%; } .eyes::after { right: 26%; }
.eyes.small::before, .eyes.small::after { width: 12%; }
@keyframes eyes {
  0%, 58% { opacity: 0; transform: scaleY(1); }
  62% { opacity: 1; }
  70% { opacity: 1; transform: scaleY(1); }
  71% { transform: scaleY(0.1); }
  73% { transform: scaleY(1); }
  82% { opacity: 1; }
  86%, 100% { opacity: 0; }
}
.spot-eyes:hover .eyes { animation: none; opacity: 1; }

/* moon glow and twinkling village windows */
.moon {
  width: var(--s); aspect-ratio: 1; border-radius: 50%; pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(closest-side, rgba(200,230,255,0.45), rgba(160,200,255,0.12) 60%, transparent);
  animation: moon 7s ease-in-out infinite;
}
@keyframes moon { 50% { scale: 1.15; opacity: 0.7; } }
.twinkle {
  width: 2.2%; aspect-ratio: 1; border-radius: 50%; pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(closest-side, rgba(255,210,120,0.95), transparent);
  animation: winBreathe var(--d, 4s) ease-in-out infinite;
}

/* the burning city glows and gutters; the Pall creeps */
.burn {
  width: 34%; height: 18%; pointer-events: none; mix-blend-mode: screen; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,120,40,0.55), rgba(255,80,20,0.15) 60%, transparent);
  animation: lampFlicker 3.1s ease-in-out infinite;
}
.pall-mist { position: absolute; inset: -10% -15% -10% 38%; pointer-events: none; }
.pall-mist i {
  position: absolute; inset: 0; mix-blend-mode: multiply;
  background:
    radial-gradient(40% 35% at 30% 40%, rgba(8,4,4,0.8), transparent 70%),
    radial-gradient(35% 30% at 60% 70%, rgba(8,4,4,0.75), transparent 70%),
    radial-gradient(30% 40% at 15% 78%, rgba(8,4,4,0.65), transparent 70%);
  animation: pall 16s ease-in-out infinite alternate;
}
.pall-mist i:nth-child(2) { animation-duration: 23s; animation-direction: alternate-reverse; opacity: 0.8; }
@keyframes pall { from { transform: translate3d(3%, 0, 0) scale(1); } to { transform: translate3d(-12%, -3%, 0) scale(1.12); } }

/* the writing room fire and the cauldron's steam */
.fire {
  width: 16%; height: 20%; pointer-events: none; mix-blend-mode: screen; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255,190,90,0.8), rgba(255,130,40,0.25) 55%, transparent);
  animation: lampFlicker 1.9s ease-in-out infinite;
}
.steam { position: absolute; left: 50%; top: 10%; width: 60%; height: 100%; translate: -50% 0; pointer-events: none; }
.steam i {
  position: absolute; left: 30%; bottom: 40%; width: 40%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(230,225,215,0.45), transparent); filter: blur(6px);
  opacity: 0; animation: steam 6s ease-out infinite;
}
.steam i:nth-child(2) { animation-delay: 1.5s; left: 40%; }
.steam i:nth-child(3) { animation-delay: 3s; left: 22%; }
.steam i:nth-child(4) { animation-delay: 4.5s; left: 35%; }
@keyframes steam {
  0% { opacity: 0; transform: translate(0, 0) scale(0.6); }
  20% { opacity: 0.9; }
  100% { opacity: 0; transform: translate(18%, -260%) scale(1.8); }
}

/* ---------- props: objects in front of the scene ----------
   Each one flies in and lands when its world arrives, then drifts with scroll
   (translate, from js/home.js) and lifts when touched. */
.props { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.props > * { pointer-events: auto; position: absolute; }
button.prop, .polaroid, .scoreboard, .medals, .notebook, .letter { border: 0; background: none; padding: 0; cursor: pointer; font: inherit; color: inherit; }
.prop, .prop-book, .polaroid, .scoreboard, .medals, .notebook, .letter { rotate: var(--rot, 0deg); transition: transform 0.45s var(--ease-out), rotate 0.45s var(--ease-out), filter 0.4s, box-shadow 0.4s; }
[data-depth] { translate: 0 var(--py, 0px); }

.props > *, .court-table > * { opacity: 0; }
.in .props > *, .court-table.in > * { opacity: 1; animation: land 1.1s cubic-bezier(0.2, 0.9, 0.3, 1.25) backwards; }
.in .props > :nth-child(2), .court-table.in > :nth-child(2) { animation-delay: 0.15s; }
.in .props > :nth-child(3), .court-table.in > :nth-child(3) { animation-delay: 0.3s; }
.in .props > :nth-child(4), .court-table.in > :nth-child(4) { animation-delay: 0.45s; }
.court-table.in > :nth-child(5) { animation-delay: 0.6s; }
.court-table.in > :nth-child(6) { animation-delay: 0.75s; }
@keyframes land {
  0% { opacity: 0; transform: translateY(-140px) rotate(-18deg) scale(1.15); }
  60% { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
.prop:hover, .prop:focus-visible, .prop-book:hover, .prop-book:focus-visible,
.polaroid:hover, .polaroid:focus-visible, .scoreboard:hover, .scoreboard:focus-visible,
.medals:hover, .medals:focus-visible, .notebook:hover, .notebook:focus-visible,
.letter:hover, .letter:focus-visible { rotate: 0deg; transform: translateY(-10px) scale(1.04); outline: none; }

.prop-book { right: 4%; bottom: 7%; width: clamp(104px, 11vw, 168px); text-decoration: none; }
.prop-book img { width: 100%; aspect-ratio: 2/3; object-fit: cover; box-shadow: 0 24px 50px rgba(0,0,0,0.75), 0 0 0 1px rgba(244,237,223,0.2); }

/* Stanton: a torn newspaper clipping that lifts at the corner in the wind */
.prop-clipping { left: 4%; bottom: 9%; width: clamp(170px, 17vw, 250px); }
.clip-paper {
  display: block; padding: 1rem 1.1rem 1.2rem; text-align: left;
  background: #ece2cb; color: #2a2116; box-shadow: 0 20px 40px rgba(0,0,0,0.65);
  clip-path: polygon(0 3%, 8% 0, 22% 2%, 40% 0, 61% 3%, 80% 0, 100% 2%, 98% 30%, 100% 62%, 97% 100%, 70% 97%, 45% 100%, 20% 97%, 0 100%, 2% 60%);
  transform-origin: 20% 100%; animation: flutter 5s ease-in-out infinite;
}
@keyframes flutter { 0%, 100% { transform: skewY(0) rotate(0); } 45% { transform: skewY(-1.5deg) rotate(-1deg); } 55% { transform: skewY(1deg) rotate(0.6deg); } }
.clip-mast { display: block; font-family: var(--font-display); font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; border-bottom: 1px solid #2a2116; padding-bottom: 0.35rem; }
.clip-head { display: block; margin-top: 0.55rem; font-family: var(--font-display); font-style: italic; font-size: clamp(0.85rem, 1.1vw, 1.02rem); line-height: 1.25; }
.clip-cols { display: block; height: 2.6rem; margin-top: 0.6rem; background: repeating-linear-gradient(180deg, rgba(42,33,22,0.35) 0 1px, transparent 1px 6px); }

/* First Born: the vial that holds the cure, bubbling */
.prop-vial { right: 17%; bottom: 8%; width: clamp(56px, 5.5vw, 84px); filter: drop-shadow(0 0 18px rgba(111,195,212,0.55)); }
.prop-vial svg { width: 100%; display: block; overflow: visible; }
.serum { animation: serumGlow 3.2s ease-in-out infinite; }
@keyframes serumGlow { 50% { fill: #a7e4ef; } }
.bubble { animation: bubble 2.6s ease-in infinite; }
.bubble.b2 { animation-delay: 1.2s; animation-duration: 3.1s; }
@keyframes bubble { 0% { transform: translateY(0); opacity: 0; } 20% { opacity: 1; } 100% { transform: translateY(-28px); opacity: 0; } }
.prop-vial:hover { filter: drop-shadow(0 0 32px rgba(111,195,212,0.95)); }

/* ---------- The Players We Were: the sunlit court ---------- */
.world-players { background: #c76a3c; overflow: hidden; isolation: isolate; color: #fff; padding-bottom: 5rem; }
.world-players::before {
  content: ""; position: absolute; inset: 0; z-index: -2; opacity: 0.5;
  background:
    repeating-radial-gradient(circle at 20% 30%, rgba(255,255,255,0.05) 0 1px, transparent 1px 4px),
    repeating-radial-gradient(circle at 70% 60%, rgba(90,30,10,0.08) 0 1px, transparent 1px 5px);
}
/* afternoon light sweeping slowly across the clay */
.world-players::after {
  content: ""; position: absolute; inset: -20%; z-index: -1; pointer-events: none;
  background: linear-gradient(115deg, transparent 35%, rgba(255,240,200,0.16) 50%, transparent 65%);
  animation: sunSweep 14s ease-in-out infinite alternate;
}
@keyframes sunSweep { from { transform: translateX(-20%); } to { transform: translateX(20%); } }
.court { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.court-lines { position: absolute; left: 7%; right: 7%; top: 5%; bottom: 5%; border: 4px solid rgba(255,255,255,0.85); }
.court-lines::before { content: ""; position: absolute; top: -4px; bottom: -4px; left: 12%; right: 12%; border-left: 4px solid rgba(255,255,255,0.85); border-right: 4px solid rgba(255,255,255,0.85); }
.court-lines::after {
  content: ""; position: absolute; left: 12%; right: 12%; top: 24%; bottom: 24%;
  border-top: 4px solid rgba(255,255,255,0.85); border-bottom: 4px solid rgba(255,255,255,0.85);
  background: linear-gradient(90deg, transparent calc(50% - 2px), rgba(255,255,255,0.85) calc(50% - 2px) calc(50% + 2px), transparent calc(50% + 2px));
}
.court-net { position: absolute; left: 4%; right: 4%; top: 50%; height: 6px; margin-top: -3px; background: repeating-linear-gradient(90deg, #1d1d1d 0 6px, #f4f4f4 6px 8px); box-shadow: 0 6px 10px rgba(0,0,0,0.25); }
.world-players .eyebrow { color: #fff4d9; }
.world-players .world-head { position: relative; z-index: 2; }
.world-players .world-head h2, .world-players .world-head p { text-shadow: 0 2px 18px rgba(90,30,10,0.6); }
.world-players .world-head p { color: #fff6ea; }

/* the rally: the ball flies baseline to baseline over the net, rising in the
   middle of each shot (bigger, its shadow smaller and fainter) */
.rally { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.rally-ball, .rally-shadow { position: absolute; left: 34%; top: 9%; }
.rally-ball {
  width: 46px; height: 46px; margin: -23px 0 0 -23px; border: 0; padding: 0; background: none;
  pointer-events: auto; cursor: pointer; animation: rallyPath 3.4s ease-in-out infinite;
}
.rally-ball i {
  display: block; width: 100%; height: 100%; border-radius: 50%; position: relative; overflow: hidden;
  background: radial-gradient(circle at 35% 30%, #f2ff8a, #cde02c 55%, #9fb21a);
  animation: rallyLift 1.7s ease-in-out infinite;
}
.rally-ball i::before, .rally-ball i::after { content: ""; position: absolute; width: 48px; height: 48px; border-radius: 50%; border: 2.5px solid rgba(255,255,255,0.9); top: -3px; }
.rally-ball i::before { left: -32px; } .rally-ball i::after { right: -32px; }
.rally-shadow {
  width: 40px; height: 16px; margin: -8px 0 0 -20px; border-radius: 50%; background: rgba(60,20,5,0.35); filter: blur(3px);
  animation: rallyPath 3.4s ease-in-out infinite, shadowSpread 1.7s ease-in-out infinite;
}
@keyframes rallyPath {
  0%   { left: 34%; top: 9%; }
  50%  { left: 64%; top: 91%; }
  100% { left: 34%; top: 9%; }
}
@keyframes rallyLift { 0%, 100% { transform: scale(0.85) translateY(0); } 50% { transform: scale(1.35) translateY(-40px); } }
@keyframes shadowSpread { 0%, 100% { scale: 1; opacity: 0.6; } 50% { scale: 0.7; opacity: 0.25; } }
.rally-ball:hover, .rally-ball:hover i { animation-play-state: paused; }

.court-table { position: relative; z-index: 2; max-width: 1200px; height: 860px; margin: 0 auto; }
.court-table > * { position: absolute; }
.court-table > :nth-child(1) { left: 5%;  top: 3%; }   /* alex */
.court-table > :nth-child(2) { left: 26%; top: 22%; }  /* madison */
.court-table > :nth-child(3) { right: 5%; top: 3%; }   /* scoreboard */
.court-table > :nth-child(4) { left: 52%; top: 34%; }  /* rivals */
.court-table > :nth-child(5) { left: 8%; top: 58%; }   /* california */
.court-table > :nth-child(6) { right: 9%; top: 60%; }  /* book */
.prop-book.on-court { bottom: auto; }

.polaroid { width: clamp(150px, 16vw, 224px); padding: 10px 10px 0; background: #fbf8f1; box-shadow: 0 22px 44px rgba(60,20,5,0.45); }
.polaroid img { width: 100%; aspect-ratio: 4/5; object-fit: cover; object-position: top; display: block; }
.polaroid span { display: block; padding: 0.7rem 0.3rem 0.9rem; text-align: center; font-family: var(--font-display); font-style: italic; font-size: 1rem; color: #2a2116; }
.polaroid.wide { width: clamp(180px, 19vw, 260px); }
.polaroid:hover, .polaroid:focus-visible { box-shadow: 0 30px 60px rgba(60,20,5,0.5), 0 0 0 3px rgba(255,255,255,0.8); }

.scoreboard { display: block; min-width: 15rem; padding: 1rem 1.2rem 1.1rem; text-align: left; background: #1f3d2c; color: #f4eddf; border: 6px solid #e9e4d6; box-shadow: 0 22px 44px rgba(60,20,5,0.45); }
.sb-title { display: block; font-size: 0.62rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: #f7c86b; }
.sb-row { display: flex; justify-content: space-between; gap: 1.5rem; margin-top: 0.7rem; font-family: var(--font-display); font-size: 1.25rem; }
.sb-row i { font-style: normal; font-family: var(--font-body); font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(244,237,223,0.7); align-self: center; }
.sb-star { display: block; margin-top: 0.8rem; padding-top: 0.6rem; border-top: 1px solid rgba(244,237,223,0.2); font-size: 0.7rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; animation: starGlow 3s ease-in-out infinite; }
@keyframes starGlow { 50% { color: #f7c86b; text-shadow: 0 0 12px rgba(247,200,107,0.7); } }

@media (max-width: 900px) {
  .court-table { height: auto; display: flex; flex-wrap: wrap; justify-content: center; gap: 1.5rem 0.9rem; padding: 1rem 0.75rem 3rem; }
  .court-table > * { position: relative; left: auto !important; right: auto !important; top: auto !important; }
  .polaroid, .polaroid.wide { width: min(42vw, 210px); }
  .scoreboard { order: 10; }
  .prop-book.on-court { width: min(40vw, 160px); }
  .rally-ball { width: 34px; height: 34px; margin: -17px 0 0 -17px; }
}

/* ---------- Her writing room ---------- */
.props-room .polaroid { left: 5%; bottom: 7%; width: clamp(130px, 13vw, 190px); }
.medals { left: 19%; bottom: 3%; width: clamp(150px, 16vw, 250px); filter: drop-shadow(0 16px 22px rgba(0,0,0,0.7)); }
.medals img { width: 100%; display: block; transform-origin: 50% 0; animation: swingSet 4.5s ease-in-out infinite; }
@keyframes swingSet { 0%, 100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
.medals:hover, .medals:focus-visible { filter: drop-shadow(0 16px 22px rgba(0,0,0,0.7)) drop-shadow(0 0 18px rgba(247,200,107,0.6)); }
.medals i {
  position: relative; display: block; width: clamp(34px, 3.4vw, 48px); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff2c4, #e2b44f 45%, #9a7020);
  box-shadow: 0 10px 16px rgba(0,0,0,0.55), inset 0 0 0 3px rgba(122,84,24,0.6);
  transform-origin: 50% -60%; animation: swing 4s ease-in-out infinite;
}
.medals i::before { content: ""; position: absolute; left: 30%; right: 30%; bottom: 85%; height: 120%; background: linear-gradient(90deg, #8e1f2a 0 50%, #b8323a 50%); z-index: -1; }
.medals i::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: linear-gradient(120deg, transparent 40%, rgba(255,255,255,0.7) 50%, transparent 60%); background-size: 300% 100%; animation: shine 5s ease-in-out infinite; }
.medals i:nth-child(2) { animation-delay: -0.8s; margin-top: -10px; }
.medals i:nth-child(3) { animation-delay: -1.6s; }
.medals i:nth-child(4) { animation-delay: -2.4s; margin-top: -6px; }
.medals i:nth-child(5) { animation-delay: -3.2s; }
.medals i:nth-child(2)::after { animation-delay: 1s; } .medals i:nth-child(4)::after { animation-delay: 2s; }
@keyframes swing { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(5deg); } }
@keyframes shine { 0%, 70% { background-position: 100% 0; } 100% { background-position: -50% 0; } }
.notebook {
  right: 22%; bottom: 6%; width: clamp(150px, 15vw, 210px); padding: 1rem 1rem 1.4rem 1.6rem; text-align: left;
  background: #f3ecdc repeating-linear-gradient(180deg, transparent 0 25px, rgba(90,110,160,0.35) 25px 26px);
  border-left: 3px solid rgba(184,50,58,0.55); box-shadow: 0 22px 44px rgba(0,0,0,0.65); color: #2a2116;
}
.nb-title { display: block; font-family: var(--font-display); font-size: 1.05rem; line-height: 26px; }
.nb-line { display: block; font-family: var(--font-display); font-style: italic; font-size: 0.92rem; line-height: 26px; color: #3b4a7a; clip-path: inset(0 100% 0 0); }
/* the lines write themselves in when the room arrives */
.in .nb-line { animation: write 1.2s steps(18) forwards; }
.in .nb-line:nth-child(2) { animation-delay: 1.2s; }
.in .nb-line:nth-child(3) { animation-delay: 2.3s; }
.in .nb-line:nth-child(4) { animation-delay: 3.3s; }
@keyframes write { to { clip-path: inset(0 0 0 0); } }
.letter { right: 4%; bottom: 10%; width: clamp(130px, 13vw, 200px); filter: drop-shadow(0 18px 24px rgba(0,0,0,0.7)); }
.letter img { width: 100%; display: block; animation: letterFloat 5s ease-in-out infinite; }
@keyframes letterFloat { 50% { transform: translateY(-6px) rotate(1.5deg); } }
.letter:hover, .letter:focus-visible { filter: drop-shadow(0 18px 24px rgba(0,0,0,0.7)) drop-shadow(0 0 18px rgba(216,80,90,0.5)); }

@media (max-width: 700px) {
  .stage { --sh: 78vh; }
  .prop-clipping { width: 150px; bottom: 5%; }
  .prop-book { width: 96px; bottom: 5%; }
  .props-room .polaroid { width: 112px; bottom: 4%; }
  .medals { left: 32%; bottom: 2%; width: 130px; }
  .notebook { display: none; }
  .letter { width: 100px; right: 4%; bottom: 20%; }
}

/* ---------- figures who move through the scenes (art made in ChatGPT) ---------- */
.walker { position: absolute; z-index: 3; border: 0; padding: 0; background: none; cursor: pointer; opacity: 0; }
.walker img { height: 100%; width: auto; display: block; }
/* Invidia crosses the wet street, keys in hand, every so often */
.walker-invidia { bottom: 4%; height: 36%; left: -12%; animation: walkRight 24s linear infinite 3s; }
.walker-invidia img { filter: brightness(0) drop-shadow(0 0 14px rgba(255,214,140,0.35)); animation: step 0.9s ease-in-out infinite; }
@keyframes walkRight {
  0% { left: -12%; opacity: 0; } 4% { opacity: 0.92; } 52% { opacity: 0.92; }
  56% { left: 104%; opacity: 0; } 100% { left: 104%; opacity: 0; }
}
/* a waker slinks right to left through the green fog */
.walker-waker { bottom: 14%; height: 32%; left: 102%; animation: walkLeft 20s linear infinite 6s; }
.walker-waker img { animation: step 1.3s ease-in-out infinite; filter: drop-shadow(0 0 10px rgba(150,255,120,0.25)); }
@keyframes walkLeft {
  0% { left: 102%; opacity: 0; } 6% { opacity: 0.85; } 48% { opacity: 0.85; }
  54% { left: -14%; opacity: 0; } 100% { left: -14%; opacity: 0; }
}
@keyframes step { 50% { transform: translateY(-2.5%) rotate(0.6deg); } }
.walker:hover img, .walker:focus-visible img { filter: brightness(0) drop-shadow(0 0 22px rgba(255,214,140,0.8)); }
.walker-waker:hover img, .walker-waker:focus-visible img { filter: drop-shadow(0 0 22px rgba(150,255,120,0.8)); }
.walker:hover, .walker:focus-visible { animation-play-state: paused; outline: none; }

/* character polaroids standing in the scenes */
.prop-pol { width: clamp(104px, 9.5vw, 150px); }
.prop-pol img { aspect-ratio: 4/5; }
.prop-pol span { font-size: 0.85rem; padding: 0.5rem 0.2rem 0.7rem; }
.pol-orphans { left: 31%; bottom: 4%; }
.pol-neve    { right: 18%; bottom: 9%; }
.pol-tarian  { right: 30%; bottom: 5%; }
.pol-audrey  { left: 25%; bottom: 4%; }

/* Invidia's keys hang and swing */
.prop-keys { left: 19%; bottom: 3%; width: clamp(70px, 7vw, 112px); filter: drop-shadow(0 16px 20px rgba(0,0,0,0.7)); }
.prop-keys img { width: 100%; display: block; transform-origin: 50% 8%; animation: keys 3.6s ease-in-out infinite; }
@keyframes keys { 0%, 100% { transform: rotate(-9deg); } 50% { transform: rotate(9deg); } }
.prop-keys:hover img { animation-duration: 0.9s; }

/* a racket at each baseline, swinging as the ball arrives */
.racket { position: absolute; width: clamp(100px, 10vw, 150px); pointer-events: none; filter: drop-shadow(0 14px 14px rgba(60,20,5,0.35)); }
.racket-top { left: calc(34% - 7vw); top: calc(9% - 5vw); transform-origin: 85% 85%; animation: swingTop 3.4s ease-in-out infinite; }
.racket-bottom { left: calc(64% + 1vw); top: calc(91% - 3vw); transform-origin: 15% 15%; animation: swingBottom 3.4s ease-in-out infinite; }
@keyframes swingTop {
  0%, 100% { transform: rotate(150deg); } 6% { transform: rotate(185deg); }
  20% { transform: rotate(140deg); } 88% { transform: rotate(120deg); }
}
@keyframes swingBottom {
  0% { transform: rotate(-30deg); } 38% { transform: rotate(-60deg); }
  50% { transform: rotate(-30deg); } 56% { transform: rotate(5deg); } 70% { transform: rotate(-40deg); } 100% { transform: rotate(-30deg); }
}

/* the quill writes in the notebook */
.notebook { position: absolute; }
.quill { position: absolute; right: -38%; top: -42%; width: 62%; pointer-events: none; filter: drop-shadow(0 12px 14px rgba(0,0,0,0.6)); transform-origin: 30% 90%; }
.in .quill { animation: scribble 0.5s ease-in-out 8 alternate, rest 1s ease-out 4s forwards; }
@keyframes scribble { from { transform: rotate(-4deg) translate(-4%, 2%); } to { transform: rotate(3deg) translate(4%, -2%); } }
@keyframes rest { to { transform: rotate(-8deg) translate(4%, 4%); } }

@media (max-width: 700px) {
  .pol-orphans, .prop-keys, .pol-audrey { display: none; }
  .pol-neve { right: 30%; width: 96px; } .pol-tarian { right: 34%; width: 96px; }
  .racket { width: 60px; }
}

/* ---------- the story card ---------- */
.card {
  --accent: #b8323a; --accent-ink: #fbf6ec;
  width: min(32rem, calc(100% - 2rem)); max-height: calc(100vh - 3rem); overflow: auto;
  margin: auto; padding: 2.3rem 2.2rem 2rem; border: 0;
  background: #f3ead7; color: #1d1710; box-shadow: 0 40px 90px rgba(0,0,0,0.6);
}
.card[data-theme="players"]    { --accent: #c4561f; }
.card[data-theme="firstborn"]  { --accent: #2c7d8d; }
.card[data-theme="awakened"]   { --accent: #5a7a26; }
.card[data-theme="lastchance"] { --accent: #b23c1c; }
.card::backdrop { background: rgba(5, 7, 13, 0.72); }
.card[open] { animation: cardIn 0.5s cubic-bezier(0.22, 0.9, 0.3, 1.15); }
.card[open]::backdrop { animation: fadeIn 0.3s ease; }
@keyframes cardIn { from { opacity: 0; transform: translateY(30px) scale(0.9) rotate(-3deg); } to { opacity: 1; transform: none; } }
@keyframes fadeIn { from { opacity: 0; } }
.card-close { position: absolute; right: 0.9rem; top: 0.6rem; border: 0; background: none; cursor: pointer; font-size: 1.8rem; line-height: 1; color: rgba(29,23,16,0.6); padding: 0.3rem; }
.card-close:hover, .card-close:focus-visible { color: var(--accent); outline: none; }
.card-img { width: 100%; max-height: 240px; object-fit: cover; object-position: center 30%; margin-bottom: 1.4rem; box-shadow: 0 10px 24px rgba(0,0,0,0.25); }
.card-kicker { display: block; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); }
.card h3 { font-size: clamp(1.6rem, 4vw, 2.1rem); line-height: 1.1; margin: 0.5rem 0 0.9rem; color: #1d1710; }
.card p { color: #3a3024; margin-bottom: 0.9rem; }
.card strong { color: #1d1710; font-weight: 600; }
.card-list { list-style: none; margin: 0.4rem 0 0; }
.card-list li { padding: 0.55rem 0; border-bottom: 1px solid rgba(29,23,16,0.12); color: #3a3024; }
.card-list li::before { content: "✦ "; color: var(--accent); }
.card .btn { margin-top: 0.6rem; }
.card .btn.ghost { color: #1d1710; border-color: rgba(29,23,16,0.3); }
.card .btn-row { display: flex; gap: 0.8rem; flex-wrap: wrap; }

/* ---------- calmer for people who ask for less motion ---------- */
.reduced-motion .world *, .reduced-motion .world *::before, .reduced-motion .world *::after,
.reduced-motion .hello *, .reduced-motion .hello-sky { animation: none !important; }
.reduced-motion .props > *, .reduced-motion .court-table > * { opacity: 1; }
.reduced-motion .nb-line { clip-path: none; }
.reduced-motion [data-depth] { translate: none; }
.reduced-motion .fx { display: none; }

/* ============================================================
   Living paintings (js/living.js) and seamless scene changes
   ============================================================ */
.living { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 1; }
/* the painting now does this itself; the old overlays only show if WebGL is unavailable */
.living-on .win, .living-on .lamp, .living-on .fog, .living-on .shade, .living-on .door-spill,
.living-on .candle, .living-on .moon, .living-on .twinkle, .living-on .burn, .living-on .fire,
.living-on .flame, .living-on .eyes, .living-on .pall-mist, .living-on .steam { display: none; }
.stage-frame .spot { z-index: 3; }
/* the scene answers the cursor itself; no boxes drawn on the picture */
.spot:hover, .spot:focus-visible, .spot-soft:hover, .spot-soft:focus-visible { background: transparent; box-shadow: none; }
.spot:focus-visible { outline: 2px solid rgba(255,226,160,0.7); outline-offset: 2px; }

/* --- one scene melts into the next ---
   Each painting fades out at its top and bottom edges and overlaps its
   neighbours, so scrolling cross-dissolves from place to place instead of
   dropping into an empty gap. Titles float over the dissolve. */
.stage {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%);
}
.stage::after { display: none; }
.world-head {
  position: relative; z-index: 5;
  padding-top: clamp(3rem, 8vh, 5rem); padding-bottom: 0;
  margin-bottom: calc(-1 * clamp(150px, 24vh, 240px));
  pointer-events: none;
}
.world-head a, .world-head button { pointer-events: auto; }
.world-head h2, .world-head p, .world-head .eyebrow { text-shadow: 0 2px 24px rgba(0,0,0,0.95), 0 0 2px rgba(0,0,0,0.6); }
.chapter-label {
  position: relative; z-index: 5; pointer-events: none;
  padding: 0 1.5rem; margin: calc(-1 * clamp(110px, 17vh, 170px)) 0 calc(-1 * clamp(110px, 17vh, 170px));
  text-shadow: 0 2px 24px rgba(0,0,0,0.95);
}
.chapter-label a { pointer-events: auto; }
.world-stanton .world-head { margin-top: calc(-1 * clamp(80px, 14vh, 140px)); }
.head-cta { display: flex; gap: 0.8rem; justify-content: center; flex-wrap: wrap; margin-top: 1.4rem; }
.head-cta .btn { box-shadow: 0 10px 28px rgba(0,0,0,0.5); }
.head-cta .btn.ghost { background: rgba(5,7,13,0.45); }
.chapter-cta { display: block; margin-top: 0.5rem; font-family: var(--font-body); font-size: 0.7rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.chapter-cta a { color: var(--cream); text-decoration: none; border-bottom: 1px solid var(--accent); padding-bottom: 2px; }
.chapter-cta a:hover { color: var(--accent); }

/* the opening fades into Stanton Street */
.hello { -webkit-mask-image: linear-gradient(180deg, #000 82%, transparent 100%); mask-image: linear-gradient(180deg, #000 82%, transparent 100%); }

/* the sunlit court fades in and out of the night scenes around it */
.world-players {
  margin: calc(-1 * clamp(80px, 12vh, 130px)) 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 clamp(80px, 12vh, 130px), #000 calc(100% - clamp(80px, 12vh, 130px)), transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 clamp(80px, 12vh, 130px), #000 calc(100% - clamp(80px, 12vh, 130px)), transparent 100%);
  padding-top: clamp(80px, 12vh, 130px); padding-bottom: calc(5rem + clamp(80px, 12vh, 130px));
}
.world-players .world-head { margin-bottom: 0; padding-bottom: 2.5rem; pointer-events: auto; }
.world-firstborn > .world-head { margin-bottom: calc(-1 * clamp(60px, 10vh, 110px)); }

/* the stages run a touch taller so the dissolves have room */
.stage { --sh: clamp(560px, 62vw, 108vh); }
@media (max-width: 700px) {
  .stage { --sh: 86vh; }
  .world-head { margin-bottom: calc(-1 * 18vh); }
  .chapter-label { margin: -12vh 0; }
}
.world-firstborn > .world-head { margin-bottom: 0; padding-bottom: 1rem; }
.world-firstborn > .world-head + .chapter-label { margin-top: 1rem; }
.world-players { padding-top: calc(clamp(80px, 12vh, 130px) + 4rem); }

/* ---------- titles on the paintings ----------
   Each book's title sits in its own scene, in the dark band near the top of
   the picture, with a soft pool of shadow behind it. The scenes overlap one
   another directly, so they still dissolve from place to place. */
.stage-title {
  position: absolute; left: 50%; top: 23%; z-index: 5;
  transform: translateX(-50%); width: min(44rem, 92%);
  text-align: center; pointer-events: none;
}
.stage-title::before {
  content: ""; position: absolute; inset: -30% -18%; z-index: -1;
  background: radial-gradient(closest-side, rgba(5,7,13,0.62), rgba(5,7,13,0.3) 60%, transparent);
}
.stage-title a { pointer-events: auto; }
.stage-title .eyebrow { display: block; text-shadow: 0 2px 18px rgba(0,0,0,0.95); }
.stage-title h2, .stage-title h3 {
  font-size: clamp(2rem, 5vw, 3.8rem); line-height: 1.05; margin-top: 0.5rem;
  text-shadow: 0 4px 34px rgba(0,0,0,0.95), 0 0 2px rgba(0,0,0,0.7);
}
.stage-title p { margin: 0.9rem auto 0; max-width: 34rem; color: var(--cream); text-shadow: 0 2px 18px rgba(0,0,0,0.95); }
.stage-title .series-name { margin: 0.2rem auto 1.1rem; font-family: var(--font-display); font-style: italic; font-size: clamp(1.05rem, 2vw, 1.35rem); color: var(--cream-dim); }
.stage-title .chapter-cta { margin-top: 0.9rem; text-shadow: 0 2px 12px rgba(0,0,0,0.95); }

/* consecutive scenes overlap and cross-dissolve */
.stage + .stage, .world-firstborn > .stage:first-of-type, .world-room > .stage, .world-stanton > .stage { margin-top: calc(var(--sh) * -0.2); }
.world-stanton > .stage { margin-top: calc(var(--sh) * -0.12); }

@media (max-width: 700px) {
  .stage-title { top: 20%; }
  .stage-title p:not(.series-name) { display: none; }
  .stage-title .head-cta .btn { padding: 0.8rem 1.1rem; font-size: 0.66rem; }
}

/* ============================================================
   Round three: layered walkers, scenes that unveil, titles on the
   paintings, a rally you can see being hit
   ============================================================ */

/* --- titles sit on the painting, not above it --- */
.stage-title { top: 46%; transform: translate(-50%, -50%); opacity: 0; transition: opacity 1.2s var(--ease-out) 0.9s; }
.stage.in .stage-title { opacity: 1; }
@media (max-width: 700px) { .stage-title { top: 44%; } }

/* --- each scene starts under a dark cover that lifts as you arrive --- */
.stage::before {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background: linear-gradient(180deg, rgba(10,14,25,1) 0%, rgba(10,14,25,0.94) 55%, rgba(10,14,25,0) 100%);
  transform: translateY(0); opacity: 1;
  transition: transform 1.9s cubic-bezier(0.7, 0, 0.2, 1), opacity 1.9s ease;
}
.stage.in::before { transform: translateY(-110%); opacity: 0; }
.stage .stage-frame { filter: blur(10px) brightness(0.55); transition: filter 1.8s ease 0.25s; }
.stage.in .stage-frame { filter: none; }
.reduced-motion .stage::before { display: none; }
.reduced-motion .stage .stage-frame, .reduced-motion .stage-title { filter: none; opacity: 1; transition: none; }

/* --- walkers live inside the scene: fog drifts in front of them --- */
.walker { z-index: 3; }
.walker-invidia { height: 30%; bottom: 6%; -webkit-box-reflect: below -2px linear-gradient(transparent 62%, rgba(255,255,255,0.22)); }
.walker-invidia img { filter: brightness(0.06) drop-shadow(0 0 12px rgba(255,214,140,0.3)); }
.walker-waker { height: 30%; bottom: 16%; }
.walker-child { bottom: 9%; height: 24%; left: -12%; animation: walkRight 34s linear infinite 5s; }
.walker-child img { animation: step 0.8s ease-in-out infinite; filter: drop-shadow(0 0 16px rgba(255,190,90,0.45)); }
.walker-child:hover img, .walker-child:focus-visible img { filter: drop-shadow(0 0 26px rgba(255,200,110,0.9)); }
.front-fog {
  position: absolute; left: -25%; right: -25%; bottom: -6%; height: 34%; z-index: 4; pointer-events: none;
  background: radial-gradient(50% 55% at 30% 60%, rgba(150,160,180,0.32), transparent 70%),
              radial-gradient(45% 50% at 72% 70%, rgba(150,160,180,0.26), transparent 70%);
  filter: blur(18px); animation: frontFog 28s ease-in-out infinite alternate;
}
.front-fog.green { background: radial-gradient(50% 55% at 30% 60%, rgba(110,200,120,0.34), transparent 70%), radial-gradient(45% 50% at 72% 70%, rgba(110,200,120,0.28), transparent 70%); height: 42%; }
.front-fog.ash { background: radial-gradient(50% 55% at 40% 70%, rgba(20,8,6,0.55), transparent 70%), radial-gradient(45% 50% at 80% 60%, rgba(60,20,10,0.35), transparent 70%); }
@keyframes frontFog { from { transform: translateX(-8%); } to { transform: translateX(8%); } }

/* --- the Players heading reads clearly on the clay --- */
.world-players .world-head {
  width: min(40rem, calc(100% - 2rem)); margin-left: auto; margin-right: auto;
  padding: 1.8rem 2rem 2rem; border-radius: 6px;
  background: rgba(38, 14, 4, 0.55); box-shadow: 0 20px 50px rgba(60, 20, 5, 0.35);
}

/* --- the rally: each racket swings from the wrist and meets the ball --- */
.rally { --R: clamp(90px, 9vw, 140px); --D: calc(var(--R) * 0.8); }
.rally-ball, .rally-shadow { animation-timing-function: linear !important; }
.racket-arm { position: absolute; width: 0; height: 0; pointer-events: none; }
.racket-arm img {
  position: absolute; width: var(--R); max-width: none;
  left: calc(var(--R) * -0.32); top: calc(var(--D) * -1 - var(--R) * 0.31);
  transform-origin: 32% 31%; transform: rotate(45deg);
  filter: drop-shadow(0 12px 12px rgba(60,20,5,0.35));
}
/* top player: the wrist sits above the contact point, the head swings down to meet the ball */
.racket-arm.top { left: 34%; top: calc(9% - var(--D)); animation: armTop 3.4s infinite; }
/* bottom player: the wrist sits below, the head swings up */
.racket-arm.bottom { left: 64%; top: calc(91% + var(--D)); animation: armBottom 3.4s infinite; }
@keyframes armTop {
  0%   { transform: rotate(180deg); animation-timing-function: ease-out; }   /* contact */
  10%  { transform: rotate(140deg); animation-timing-function: ease-in-out; }
  35%  { transform: rotate(170deg); animation-timing-function: ease-in-out; }
  82%  { transform: rotate(218deg); animation-timing-function: ease-in; }   /* backswing */
  100% { transform: rotate(180deg); }
}
@keyframes armBottom {
  0%   { transform: rotate(-12deg); animation-timing-function: ease-in-out; }
  32%  { transform: rotate(-40deg); animation-timing-function: ease-in; }    /* backswing */
  50%  { transform: rotate(0deg); animation-timing-function: ease-out; }     /* contact */
  60%  { transform: rotate(40deg); animation-timing-function: ease-in-out; }
  85%  { transform: rotate(8deg); animation-timing-function: ease-in-out; }
  100% { transform: rotate(-12deg); }
}
.racket { display: none; }
@media (max-width: 900px) { .rally { --R: 64px; } }

/* ---------- round four ---------- */
/* a softer top edge on each scene, so nothing near the top of the next
   painting (like the fog scene's moon) shows through the one before it */
.stage {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, transparent 7%, #000 32%, #000 78%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, transparent 7%, #000 32%, #000 78%, transparent 100%);
}
/* the rally stays well inside the court so a racket never swings into the next scene */
@keyframes rallyPath { 0% { left: 34%; top: 13%; } 50% { left: 64%; top: 76%; } 100% { left: 34%; top: 13%; } }
.racket-arm.top { top: calc(13% - var(--D)); }
.racket-arm.bottom { top: calc(76% + var(--D)); }
/* walkers come back on screen sooner after they walk off (same walking pace) */
.walker-invidia { animation: walkRightSoon 17s linear infinite 2s; }
.walker-waker { animation: walkLeftSoon 14s linear infinite 3s; }
.walker-child { animation: walkRightSoonSlow 23s linear infinite 3s; }
@keyframes walkRightSoon { 0% { left: -12%; opacity: 0; } 4% { opacity: 0.92; } 75% { opacity: 0.92; } 79% { left: 104%; opacity: 0; } 100% { left: 104%; opacity: 0; } }
@keyframes walkLeftSoon { 0% { left: 102%; opacity: 0; } 5% { opacity: 0.85; } 73% { opacity: 0.85; } 77% { left: -14%; opacity: 0; } 100% { left: -14%; opacity: 0; } }
@keyframes walkRightSoonSlow { 0% { left: -12%; opacity: 0; } 4% { opacity: 0.95; } 79% { opacity: 0.95; } 83% { left: 104%; opacity: 0; } 100% { left: 104%; opacity: 0; } }
/* the writing room is the last scene: a gentler top edge keeps the shelf and its goblet in view */
.world-room > .stage {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 16%, #000 84%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 16%, #000 84%, transparent 100%);
}
@media (min-width: 901px) { .world-room .stage-frame { left: auto; right: 0; transform: translate(0, -50%); } }
.chapter-cta a + a { margin-left: 1.5rem; }
