* { margin: 0; padding: 0; box-sizing: border-box; }

[hidden] { display: none !important; }

@font-face {
  font-family: 'SimonHandwriting';
  src: url('assets/SimonHandwriting-Regular.otf') format('opentype'),
       url('assets/SimonHandwriting-Regular.ttf') format('truetype');
  font-display: swap;
}

:root {
  --ink: #f1ead9;
  --fire: #e8763a;
  --fire-glow: #ffb066;
  --parchment: #ead9b8;
  --parchment-ink: #3a2a1a;
  --letter-ink: #2b1e12;
  --font-hand: 'SimonHandwriting', 'Homemade Apple', cursive;
  --font-caption: 'SimonHandwriting', 'Caveat', cursive;
}

html {
  background: #050912;
  /* Deliberately no overflow here. Horizontal containment lives in the
     max-width: 899.98px block instead — see the note there. */
}

body {
  color: var(--ink);
  font-family: 'Cormorant Garamond', serif;
  overflow-x: hidden;
  scroll-behavior: smooth;
  /* Scroll anchoring auto-adjusts scroll position when it detects content
     shifting near the viewport, to prevent visual jumps — but on a page this
     dynamic (reveal transitions, IntersectionObserver toggles all firing in
     clusters at section boundaries) its own heuristics can misfire and cause
     the exact jump it's meant to prevent. Nothing on this page needs it. */
  overflow-anchor: none;
}

#bg-glow {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: #050912;
  pointer-events: none;
}

.bg-glow-layer {
  position: absolute;
  inset: 0;
}

body {
  overflow-x: hidden;
}

section {
  min-height: 100svh;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
}

/* ---------- HERO ---------- */

.hero {
  background:
    linear-gradient(180deg, rgba(5,9,18,0.1) 0%, rgba(5,9,18,0.3) 55%, rgba(5,9,18,0.8) 100%),
    url('assets/starry-sky.jpg') center 20% / cover no-repeat;
  z-index: 1;
}

/* Deep-forest ground: fills the space between the far and near treeline bases
   so the two silhouettes read as sitting on the same hillside, not floating.
   Transparent at the top (blends with the sky), solidifies through the forest
   band, ends fully opaque at the very bottom of the hero. */
.hero::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 42%;
  background: linear-gradient(180deg,
    rgba(4,7,13,0) 0%,
    rgba(4,7,13,0.35) 18%,
    rgba(4,7,13,0.72) 42%,
    rgba(3,6,11,0.95) 70%,
    rgba(2,4,9,1) 100%);
  z-index: 0;
  pointer-events: none;
}

.fire-scene {
  z-index: 2;
}

.diary,
.letter-scene {
  position: relative;
  z-index: 3;
  background: transparent;
}

.hero h1 {
  font-family: 'Press Start 2P', monospace;
  font-size: clamp(1.8rem, 6vw, 3.2rem);
  letter-spacing: 0.05em;
  white-space: nowrap;
  text-shadow: 0 0 20px rgba(232, 118, 58, 0.4);
}

.hero-sub {
  margin-top: 1.2rem;
  font-size: 1.4rem;
  font-style: italic;
  opacity: 0.75;
}

.scroll-prompt {
  position: absolute;
  bottom: 3rem;
  font-family: 'Press Start 2P', monospace;
  font-size: 0.7rem;
  opacity: 0.6;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

.scroll-prompt span {
  animation: bob 1.6s ease-in-out infinite;
}

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(8px); }
}

/* ---------- FIRE SCENE ---------- */

.fire-scene .scene {
  position: relative;
  width: 100%;
  height: 72svh;
  overflow: hidden;
}

/* No pin/parallax below 900px (see script.js) means the dead space below each
   section's vertically-centered content is fully exposed instead of being
   hidden by the scroll-driven illusion. Fire-scene gets shrunk and pulled to
   the top to close that gap. The hero's heading stays exactly as it always
   was — vertically centered — only its height shrinks a little. */
@media (max-width: 899.98px) {
  /* Sideways-scroll containment, deliberately scoped to the same breakpoint the
     pin is gated behind. Scenery sprites are placed to spill past the viewport,
     which widens the document and lets a phone scroll sideways. Clipping it on
     <html> fixes that — but above 900px the pinned hero runs with
     pinSpacing: false, so document scroll advances underneath a position: fixed
     element, and a clip on the root disturbs that: scroll stalled at the pin
     release point (940px, exactly where the diary and dirt path start) and every
     direction change needed a second gesture. Below 900px there is no pin at
     all, so the clip and the pin never coexist.
     `clip` not `hidden`: `hidden` alongside `visible` on the other axis is
     illegal, so it silently promotes overflow-y to `auto` and makes <html> a
     scroll container. No `hidden` fallback for pre-2022 engines for the same
     reason — they just get sideways scroll. */
  html { overflow-x: clip; }

  .hero {
    min-height: 100svh;
  }
  .fire-scene {
    min-height: 78svh;
    justify-content: flex-start;
    padding-top: 8svh;
  }
  .fire-scene .scene {
    height: 62svh;
  }
}

.firepit-glow {
  position: absolute;
  width: min(720px, 92vw);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, 50%);
  background: radial-gradient(circle at center,
    rgba(255,196,120,0.6) 0%,
    rgba(255,138,60,0.32) 22%,
    rgba(255,110,50,0.1) 45%,
    transparent 65%);
  mix-blend-mode: screen;
  pointer-events: none;
  z-index: 1;
}

/* ---------- GROUND TEXTURE (bg color IS the ground, seen oblique) ---------- */

.fire-scene {
  position: relative;
}

.diary::before,
.fire-scene::after {
  content: '';
  position: absolute;
  pointer-events: none;
  z-index: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cg fill='none' stroke='rgba(255,255,255,0.05)' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M22 36l2-6M27 37v-7M32 36l-2-6'/%3E%3Cpath d='M120 98l2-6M125 99v-7M130 98l-2-6'/%3E%3Cpath d='M64 158l2-5M68 159v-6M72 158l-2-5'/%3E%3C/g%3E%3Cg fill='none' stroke='rgba(0,0,0,0.07)' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M96 22l2-5M100 23v-6M104 22l-2-5'/%3E%3Cpath d='M30 116l2-5M34 117v-6M38 116l-2-5'/%3E%3Cpath d='M148 58l2-5M152 59v-6M156 58l-2-5'/%3E%3C/g%3E%3Cg fill='rgba(255,255,255,0.045)'%3E%3Ccircle cx='58' cy='62' r='1.3'/%3E%3Ccircle cx='142' cy='136' r='1.1'/%3E%3Ccircle cx='12' cy='150' r='1.2'/%3E%3C/g%3E%3Cg fill='rgba(0,0,0,0.06)'%3E%3Ccircle cx='86' cy='84' r='1.4'/%3E%3Ccircle cx='154' cy='14' r='1.2'/%3E%3Ccircle cx='46' cy='10' r='1.1'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 180px 180px;
}

.diary::before {
  inset: 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 4%, #000 97%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 4%, #000 97%, transparent 100%);
}

.fire-scene::after {
  left: 0;
  right: 0;
  bottom: 0;
  height: 40%;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 70%);
  mask-image: linear-gradient(180deg, transparent 0, #000 70%);
}

/* ---------- DIARY ---------- */

.diary {
  min-height: auto;
  display: block;
  position: relative;
  padding: 8svh 0;
}

.diary-track {
  position: relative;
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 4vw;
}

.diary-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 170px, #000 calc(100% - 60px), transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 170px, #000 calc(100% - 60px), transparent 100%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* dirt path layers are fully attribute-driven by map.js */
.diary-svg path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.day-block {
  position: relative;
  width: min(50%, 480px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
  padding: 3.5rem 0;
}

.day-block[data-side="left"] {
  margin-right: auto;
}

.day-block[data-side="right"] {
  margin-left: auto;
  flex-direction: row-reverse;
  text-align: right;
  justify-content: flex-end;
}

.diary-text {
  max-width: 360px;
}

.diary-text p {
  font-size: 1.4rem;
  line-height: 1.55;
  color: #f1ead9;
  text-shadow: 0 1px 2px rgba(0,0,0,0.35);
}

.diary-close {
  text-align: center;
  padding: 4rem 0 2rem;
  position: relative;
}

.diary-close p {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 2rem;
  opacity: 0.85;
}

/* ---------- POLAROIDS (SX-70 geometry) ---------- */

.polaroid {
  --rot: 0deg;
  /* Rotating a box widens the space it occupies: a 350x420 polaroid turned 13deg
     needs ~25% more width than its layout box. On narrow screens that surplus is
     what pushed past the gutter and made the page scrollable sideways. Scaling
     the angle down is cheaper than shrinking the photo — see the mobile block. */
  --rot-scale: 1;
  flex-shrink: 0;
  width: 350px;
  max-width: 100%;
  aspect-ratio: 350 / 420;
  opacity: 0;
  transform: translateY(50px) rotate(calc((var(--rot) * 2.2 - 14deg) * var(--rot-scale))) scale(0.9);
  transition: opacity 0.6s ease, transform 0.75s cubic-bezier(0.31, 1.6, 0.55, 1);
  margin: 0 -10px;
}

.polaroid.is-visible {
  opacity: 1;
  transform: translateY(0) rotate(calc(var(--rot) * var(--rot-scale))) scale(1);
}

.fire-scene .scene {
  opacity: 0;
  transition: opacity 1.4s ease;
}

.fire-scene .scene.is-visible { opacity: 1; }

.polaroid.has-photo {
  background: #f4efe3;
  border: none;
  border-radius: 2px;
  padding: 14px 14px 0 14px;
  display: flex;
  flex-direction: column;
  position: relative;
  box-shadow:
    0 1px 2px rgba(0,0,0,0.35),
    0 12px 28px rgba(0,0,0,0.45),
    0 30px 60px rgba(0,0,0,0.25);
}

.polaroid.has-photo img {
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  object-fit: cover;
  display: block;
  filter: contrast(0.92) saturate(0.88) sepia(0.08);
}

/* day 4 jam photo: keep the guitarist on the left edge in frame */
.day-block[data-day="4"] .polaroid.has-photo img {
  object-position: left center;
}

.polaroid.has-photo .polaroid-tag {
  flex: 0 0 68px;
  background: #f4efe3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-caption);
  font-weight: 700;
  font-size: 1.45rem;
  color: #3a2a1a;
  opacity: 0.85;
  text-align: center;
}

/* ---------- LETTER SCENE ---------- */

.letter-scene {
  background: #0d0705;
  padding: 2svh 0 14svh 0;
  overflow: visible;
}

.letter-scene::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -14svh;
  height: 14svh;
  background: linear-gradient(180deg, rgba(13,7,5,0) 0%, #0d0705 100%);
  pointer-events: none;
}

.envelope-wrap {
  position: relative;
  width: min(92vw, 640px);
  aspect-ratio: 640 / 420;
  opacity: 0;
}

.envelope {
  position: absolute;
  inset: 0;
  background: #d8c39a;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

.envelope-flap {
  position: absolute;
  inset: 0;
  background: #c9b183;
  clip-path: polygon(0 0, 100% 0, 50% 62%);
  z-index: 2;
}

.seal {
  position: absolute;
  left: 50%;
  top: 62%;
  transform: translate(-50%, -50%);
  width: 130px;
  height: 130px;
  background: url('assets/wax-seal-cutout.png') center / contain no-repeat;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,0.5));
  cursor: pointer;
  transition: transform 0.2s ease;
  z-index: 3;
}

.seal:hover {
  transform: translate(-50%, -50%) scale(1.07);
}

.seal-patch {
  position: absolute;
  width: 36px;
  height: 28px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at 40% 35%, rgba(224,100,101,0.98) 45%, rgba(213,88,90,0.95) 70%, rgba(213,88,90,0) 85%);
}

.seal-patch-left { left: 37%; top: 58%; }
.seal-patch-right { left: 68%; top: 57%; }

.seal-letter {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: 'Cormorant Garamond', serif;
  font-weight: 700;
  color: rgba(165, 25, 30, 0.92);
  text-shadow: -1px -1px 1px rgba(80,0,0,0.55), 1px 1px 1px rgba(255,195,195,0.5);
  pointer-events: none;
}

.seal-letter-left {
  left: 37%;
  top: 57%;
  font-size: 22px;
}

.seal-letter-right {
  left: 68%;
  top: 56%;
  font-size: 20px;
}

/* ---------- LETTER SHEETS (two-page format wrapping Simon's letter PNGs) ---------- */

.letter-stack {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

.sheet {
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(90vw, 620px);
  background: var(--parchment);
  color: var(--parchment-ink);
  border-radius: 4px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.6);
  opacity: 0;
  visibility: hidden;
  pointer-events: auto;
}

.sheet-2 { z-index: 2; }

.sheet-body {
  padding: 1.5rem 0 0.6rem;
}

.letter-photo-wrap {
  position: relative;
  line-height: 0;
}

.letter-photo {
  width: 100%;
  height: auto;
  display: block;
}

.fate-line {
  position: absolute;
  left: 5%;
  right: 5%;
  top: 89%;
  height: 7%;
  cursor: pointer;
}

.signoff {
  position: absolute;
  left: 5%;
  right: 45%;
  top: 7%;
  height: 20%;
  cursor: pointer;
}

.tree-seal-stamp {
  position: absolute;
  right: 4%;
  bottom: 3%;
  left: auto;
  top: auto;
  width: 20%;
  height: auto;
  transform: rotate(-8deg);
  transition: transform 0.2s ease;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  z-index: 2;
}

.tree-seal-stamp:hover,
.tree-seal-stamp:focus-visible {
  transform: rotate(-8deg) scale(1.06);
}

.tree-seal-stamp img {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0.85;
  mix-blend-mode: multiply;
}

/* ---------- VIDEO MODAL ---------- */

.video-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(5, 5, 8, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4svh 4vw;
}

.video-modal-frame {
  position: relative;
  width: min(90vw, 960px);
  aspect-ratio: 16 / 9;
}

.video-modal-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
}

.video-modal-close {
  position: absolute;
  top: 3svh;
  right: 3vw;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.1);
  color: #f1ead9;
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
}

.video-modal-close:hover {
  background: rgba(255, 255, 255, 0.2);
}

/* ---------- THOUGHT BUBBLES ---------- */

.thought-bubble {
  position: absolute;
  top: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  background: var(--parchment-ink);
  color: var(--parchment);
  border: none;
  border-radius: 60% 60% 55% 55% / 90% 90% 60% 60%;
  padding: 1.5rem 2.8rem;
  width: max-content;
  max-width: 360px;
  font-family: 'SimonHandwriting', 'Cormorant Garamond', serif;
  font-style: normal;
  font-size: 3.8rem;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  z-index: 4;
  box-shadow:
    0 10px 26px rgba(0,0,0,0.4),
    -28px 9px 0 -13px var(--parchment-ink),
    28px 9px 0 -13px var(--parchment-ink),
    0 -22px 0 -15px var(--parchment-ink);
}

.thought-bubble.bubble-right {
  left: 100%;
  transform: translateX(-25%) scale(0.85);
}

.thought-bubble.bubble-left {
  right: 100%;
  transform: translateX(8%) scale(0.85);
}

.thought-bubble::after,
.thought-bubble::before {
  content: "";
  position: absolute;
  bottom: -20px;
  width: 30px;
  height: 30px;
  background: var(--parchment-ink);
  border-radius: 50%;
}

.thought-bubble.bubble-right::after { left: 22%; }
.thought-bubble.bubble-right::before { left: 8%; bottom: -38px; width: 16px; height: 16px; }
.thought-bubble.bubble-left::after { right: 22%; }
.thought-bubble.bubble-left::before { right: 8%; bottom: -38px; width: 16px; height: 16px; }

.thought-bubble.shown {
  opacity: 0.9;
  pointer-events: auto;
}

.thought-bubble.bubble-right.shown { transform: translateX(-25%) scale(1); }
.thought-bubble.bubble-left.shown { transform: translateX(8%) scale(1); }

/* ---------- I CHING ---------- */

.sheet-2 .sheet-body {
  font-family: 'SimonHandwriting', 'Cormorant Garamond', serif;
  font-size: 1.9rem;
  line-height: 1.4;
}

.fate-intro-photo {
  opacity: 0.85;
}

.reading {
  opacity: 0.9;
  padding: 0 8%;
  margin-bottom: 1.5rem;
  font-family: 'Special Elite', 'Courier New', monospace;
  font-size: 1.15rem;
  line-height: 1.7;
  letter-spacing: 0.02em;
}

.hexagram {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 7px;
  margin: 1.5rem 0;
  padding: 0 8%;
}

.hex-line {
  width: 100px;
  height: 8px;
  display: flex;
  justify-content: space-between;
}

.hex-line .bar {
  background: var(--parchment-ink);
  height: 100%;
  transform-origin: left center;
}

.hex-line.yang .bar { width: 100%; }
.hex-line.yin .bar { width: 44%; }

/* ---------- MAP DECOR ---------- */

.zone-tint {
  --s-dark:  #0b0f1c;
  --s-mid:   #131b30;
  --s-light: #1c2742;
  --s-rim:   rgba(157,180,212,0.5);
  --s-glow:  #ffcf8f;
}
.zone-tint[data-zone="firelit"] {
  --s-dark:  #182138;
  --s-mid:   #263354;
  --s-light: #364a74;
  --s-rim:   rgba(255,199,145,0.6);
}
.zone-tint[data-zone="predawn"] {
  --s-dark:  #0d1424;
  --s-mid:   #182339;
  --s-light: #24324e;
  --s-rim:   rgba(170,195,230,0.5);
}
.zone-tint[data-zone="dawn"] {
  --s-dark:  #221420;
  --s-mid:   #35202a;
  --s-light: #4a2e33;
  --s-rim:   rgba(255,176,120,0.55);
}
.zone-tint[data-zone="day"] {
  --s-dark:  #2a3324;
  --s-mid:   #3c4a30;
  --s-light: #50613c;
  --s-rim:   rgba(255,240,200,0.55);
}
.zone-tint[data-zone="golden"] {
  --s-dark:  #33200f;
  --s-mid:   #4a2f16;
  --s-light: #61401f;
  --s-rim:   rgba(255,200,130,0.6);
}
.zone-tint[data-zone="dusk"] {
  --s-dark:  #170f1e;
  --s-mid:   #241830;
  --s-light: #332244;
  --s-rim:   rgba(255,150,120,0.5);
}
.zone-tint[data-zone="night2"] {
  --s-dark:  #0a0e1a;
  --s-mid:   #111a2c;
  --s-light: #19253d;
  --s-rim:   rgba(150,175,210,0.45);
}

.decor {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Never clip this box. Most .decor containers are attached to individual
     day-blocks, not to full-width sections (map.js prepends them to each
     anchor), and sprites are deliberately placed from -14% to 114% of their
     anchor to spill past it. Clipping here therefore slices sprites in the
     middle of the screen rather than at the screen edge. Horizontal overflow
     is contained on <html> instead, where the cut lands off-screen. */
  overflow: visible;
}

.decor.anim-paused,
.decor.anim-paused * {
  animation-play-state: paused !important;
}

.decor-layer {
  position: absolute;
  inset: 0;
}

.sprite {
  position: absolute;
  overflow: visible;
}

.path-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: visible;
}

.terrain-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: visible;
}

.scatter-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
}

/* ledge geometry (left/top/width/height) is set by map.js */
.ledge {
  position: absolute;
  pointer-events: none;
  overflow: visible;
}

.compose-group {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* content rides above decor */
.hero h1, .hero-sub { position: relative; z-index: 1; }
.scroll-prompt { z-index: 1; }
.fire-scene .scene { z-index: 1; }
.day-block > .polaroid, .day-block > .diary-text { z-index: 1; }
.polaroid { position: relative; }
.diary-text { position: relative; }

/* ---------- PARTICLES ---------- */

.sparks {
  position: absolute;
  left: 50%;
  bottom: 28%;
  width: 0;
  height: 0;
}

.sparks span {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--fire-glow);
  box-shadow: 0 0 6px 1px rgba(255,176,102,0.7);
  opacity: 0;
  animation: spark-rise 3.2s linear infinite;
}

.sparks span:nth-child(1)  { left: -30px; animation-delay: 0s;    animation-duration: 2.8s; }
.sparks span:nth-child(2)  { left: 14px;  animation-delay: 0.4s;  animation-duration: 3.4s; }
.sparks span:nth-child(3)  { left: -8px;  animation-delay: 0.9s;  animation-duration: 2.6s; }
.sparks span:nth-child(4)  { left: 32px;  animation-delay: 1.3s;  animation-duration: 3.8s; }
.sparks span:nth-child(5)  { left: -46px; animation-delay: 1.7s;  animation-duration: 3.0s; }
.sparks span:nth-child(6)  { left: 4px;   animation-delay: 2.1s;  animation-duration: 2.9s; }
.sparks span:nth-child(7)  { left: 44px;  animation-delay: 2.5s;  animation-duration: 3.5s; }
.sparks span:nth-child(8)  { left: -20px; animation-delay: 2.9s;  animation-duration: 2.7s; }
.sparks span:nth-child(9)  { left: 22px;  animation-delay: 3.3s;  animation-duration: 3.1s; }
.sparks span:nth-child(10) { left: -36px; animation-delay: 3.7s;  animation-duration: 3.6s; }

@keyframes spark-rise {
  0%   { transform: translate(0, 0) scale(1); opacity: 0; }
  8%   { opacity: 0.9; }
  60%  { opacity: 0.5; }
  100% { transform: translate(18px, -180px) scale(0.3); opacity: 0; }
}

.fireflies {
  position: absolute;
  inset: 0;
}

.fireflies span {
  position: absolute;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #ffe9a8;
  box-shadow: 0 0 8px 2px rgba(255,225,150,0.6);
  opacity: 0;
  animation: firefly-wander 7s ease-in-out infinite;
}

.fireflies span:nth-child(1) { left: 12%; top: 30%; animation-delay: 0s; }
.fireflies span:nth-child(2) { left: 82%; top: 45%; animation-delay: 0.9s; }
.fireflies span:nth-child(3) { left: -15%; top: 60%; animation-delay: 1.8s; }
.fireflies span:nth-child(4) { left: 105%; top: 25%; animation-delay: 2.7s; animation-duration: 8.5s; }
.fireflies span:nth-child(5) { left: 40%; top: 70%; animation-delay: 3.6s; }
.fireflies span:nth-child(6) { left: 65%; top: 15%; animation-delay: 4.5s; animation-duration: 9s; }
.fireflies span:nth-child(7) { left: -8%; top: 20%; animation-delay: 5.4s; }
.fireflies span:nth-child(8) { left: 95%; top: 75%; animation-delay: 6.3s; animation-duration: 8s; }
.fireflies span:nth-child(9)  { left: 25%; top: 50%; animation-delay: 1.4s; animation-duration: 9.5s; }
.fireflies span:nth-child(10) { left: 55%; top: 35%; animation-delay: 3.1s; }
.fireflies span:nth-child(11) { left: 118%; top: 55%; animation-delay: 4.9s; animation-duration: 8.2s; }
.fireflies span:nth-child(12) { left: -22%; top: 40%; animation-delay: 5.8s; }
.fireflies span:nth-child(13) { left: 72%; top: 65%; animation-delay: 2.2s; animation-duration: 10s; }
.fireflies span:nth-child(14) { left: 8%; top: 12%; animation-delay: 6.9s; }

@keyframes firefly-wander {
  0%   { transform: translate(0, 0); opacity: 0; }
  15%  { opacity: 0.9; }
  40%  { transform: translate(24px, -18px); opacity: 0.3; }
  60%  { transform: translate(-12px, -34px); opacity: 0.8; }
  85%  { opacity: 0.2; }
  100% { transform: translate(10px, -50px); opacity: 0; }
}

.shooting-star {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.shooting-star span {
  position: absolute;
  top: 14%;
  left: 78%;
  width: 90px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(235,240,255,0.9) 100%);
  transform: rotate(-35deg);
  opacity: 0;
  animation: star-streak 9s linear infinite;
  animation-delay: 3s;
}

@keyframes star-streak {
  0%    { transform: translate(0, 0) rotate(-35deg); opacity: 0; }
  1%    { opacity: 0.9; }
  4%    { transform: translate(-220px, 154px) rotate(-35deg); opacity: 0; }
  100%  { transform: translate(-220px, 154px) rotate(-35deg); opacity: 0; }
}

/* ---------- FLAIR ---------- */

.stars {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.stars span {
  position: absolute;
  border-radius: 50%;
  background: #e4ebff;
  opacity: var(--o, 0.6);
  animation: star-twinkle var(--tw-dur, 4s) ease-in-out infinite;
  animation-delay: var(--tw-del, 0s);
}

.stars .constellation-star {
  background: #eef3ff;
  box-shadow: 0 0 6px 1px rgba(210,225,255,0.55);
}

@keyframes star-twinkle {
  0%, 100% { opacity: var(--o, 0.6); }
  50% { opacity: calc(var(--o, 0.6) * 0.3); }
}

.smoke {
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
}

.smoke span {
  position: absolute;
  left: -5px;
  bottom: 0;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: rgba(205,205,215,0.26);
  filter: blur(2px);
  opacity: 0;
  animation: smoke-rise 6.5s ease-out infinite;
}

.smoke span:nth-child(2) { animation-delay: 2.2s; }
.smoke span:nth-child(3) { animation-delay: 4.4s; }

@keyframes smoke-rise {
  0%   { transform: translate(0, 0) scale(0.5); opacity: 0; }
  12%  { opacity: 0.55; }
  55%  { transform: translate(9px, -42px) scale(1.5); opacity: 0.3; }
  100% { transform: translate(20px, -78px) scale(2.4); opacity: 0; }
}

.window-glow {
  position: absolute;
  width: 40px;
  height: 34px;
  transform: translate(-50%, 50%);
  background: radial-gradient(circle, rgba(255,207,143,0.5) 0%, rgba(255,207,143,0) 70%);
  mix-blend-mode: screen;
  pointer-events: none;
  animation: candle-flicker 3.4s linear infinite;
}

@keyframes candle-flicker {
  0%, 100% { opacity: 0.55; }
  7%  { opacity: 0.85; }
  12% { opacity: 0.6; }
  21% { opacity: 0.9; }
  28% { opacity: 0.58; }
  41% { opacity: 0.78; }
  55% { opacity: 0.52; }
  63% { opacity: 0.88; }
  74% { opacity: 0.62; }
  86% { opacity: 0.8; }
}

.fire-rim {
  position: absolute;
  width: 20px;
  height: 40px;
  border-radius: 50%;
  background: linear-gradient(90deg, rgba(255,176,102,0) 0%, rgba(255,176,102,0.42) 85%);
  mix-blend-mode: screen;
  filter: blur(3px);
  pointer-events: none;
  animation: candle-flicker 2.8s linear infinite;
}

.leaves {
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
}

.leaves span {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 7px;
  height: 5px;
  border-radius: 60% 40% 55% 45%;
  background: rgba(216,164,84,0.75);
  opacity: 0;
  animation: leaf-fall 8s ease-in infinite;
}

.leaves span:nth-child(1) { animation-delay: 0s; }
.leaves span:nth-child(2) { left: 18px; animation-delay: 2.9s; animation-duration: 9s; }
.leaves span:nth-child(3) { left: -14px; animation-delay: 5.2s; animation-duration: 7.5s; }
.leaves span:nth-child(4) { left: 30px; animation-delay: 6.8s; animation-duration: 8.6s; }

@keyframes leaf-fall {
  0%   { transform: translate(0, 0) rotate(0deg); opacity: 0; }
  8%   { opacity: 0.85; }
  30%  { transform: translate(14px, 46px) rotate(120deg); }
  55%  { transform: translate(-8px, 92px) rotate(240deg); opacity: 0.7; }
  80%  { transform: translate(10px, 132px) rotate(340deg); opacity: 0.4; }
  100% { transform: translate(2px, 160px) rotate(420deg); opacity: 0; }
}

.tail-flick {
  position: absolute;
  pointer-events: none;
}

.tail-flick svg {
  display: block;
  overflow: visible;
  transform-origin: 85% 95%;
  animation: tail-flick 6s ease-in-out infinite;
}

@keyframes tail-flick {
  0%, 88%, 100% { transform: rotate(0deg); }
  91% { transform: rotate(-14deg); }
  94% { transform: rotate(4deg); }
  97% { transform: rotate(-8deg); }
}

/* ---------- MOBILE ---------- */

@media (max-width: 640px) {
  .day-block { width: 62vw; gap: 1rem; }
  .diary-text p { font-size: 1.15rem; }
  /* Fluid rather than a fixed 280px, so this holds from a 320px-wide phone up
     to the 640px breakpoint instead of being tuned to one handset. The angle is
     dialled back to keep each rotated polaroid inside .diary-track's 4vw gutter
     — enough tilt to still read as scattered snapshots, not enough to break out
     and make the page scroll sideways. Negative margins dropped for the same
     reason: they pulled the outer edge back past the gutter. */
  .polaroid { width: min(280px, 100%); margin: 0; --rot-scale: 0.4; }
  .polaroid.has-photo { padding: 11px 11px 0 11px; }
  .polaroid.has-photo .polaroid-tag { flex-basis: 54px; font-size: 1.4rem; }
  .letter-inner { font-size: 1.2rem; }
  .letter-continued { font-size: 1.4rem; }
  .reading, .hexagram { padding: 0 5%; }
  /* The sheet shrinks to ~90vw here and the handwriting photos scale with it,
     but .reading is sized in rem so it would stay at its desktop size and read
     as oversized next to them. */
  .reading { font-size: 0.95rem; line-height: 1.65; }
  .thought-bubble { max-width: 240px; font-size: 2.8rem; padding: 1.1rem 2rem; }
  .thought-bubble.bubble-right, .thought-bubble.bubble-left {
    left: auto;
    right: auto;
    top: -2.8rem;
    margin: 0;
  }
  .thought-bubble.bubble-right { right: 0.5rem; }
  .thought-bubble.bubble-left { left: 0.5rem; }
}
