/* ===================== CHAPTER 3 — THE MEMORY MAP ===================== */

#chapter3 {
  background: var(--color-bg);
  overflow: hidden;
}

/* same ID-vs-[hidden] specificity fix as Chapter 2 */
#chapter3[hidden] {
  display: none;
}

/* ---- the map ---- */
.map-viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.map-world {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  will-change: transform;
}

.map-sky {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 30%, rgba(79, 158, 255, 0.16) 0%, rgba(6, 8, 13, 0) 55%),
    linear-gradient(180deg, #060a12 0%, #081018 45%, #050810 100%);
}

/* per-leg sky mood — GSAP fades this toward the destination island's
   palette while sailing, back to 0 once she's home on the neutral map */
.map-sky-tint {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}

.map-sky-tint--beginning {
  background: radial-gradient(ellipse at 50% 35%, rgba(79, 158, 255, 0.24) 0%, rgba(6, 8, 13, 0) 58%),
    linear-gradient(180deg, rgba(16, 34, 64, 0.5), rgba(6, 12, 24, 0.55));
}

.map-sky-tint--comfort {
  background: radial-gradient(ellipse at 50% 32%, rgba(255, 184, 112, 0.26) 0%, rgba(20, 12, 6, 0) 60%),
    linear-gradient(180deg, rgba(58, 36, 14, 0.55), rgba(24, 15, 7, 0.6));
}

.map-sky-tint--adventure {
  background: radial-gradient(ellipse at 50% 68%, rgba(90, 210, 180, 0.2) 0%, rgba(4, 12, 12, 0) 60%),
    linear-gradient(180deg, rgba(8, 42, 44, 0.5), rgba(4, 20, 20, 0.55));
}

.map-sky-tint--concert {
  background: radial-gradient(ellipse at 50% 30%, rgba(110, 140, 255, 0.26) 0%, rgba(6, 8, 20, 0) 58%),
    linear-gradient(180deg, rgba(17, 21, 58, 0.55), rgba(8, 10, 30, 0.6));
}

.map-sky-tint--relive {
  background: radial-gradient(ellipse at 50% 24%, rgba(150, 120, 255, 0.16) 0%, rgba(8, 6, 18, 0) 55%),
    linear-gradient(180deg, rgba(22, 15, 42, 0.6), rgba(7, 5, 15, 0.65));
}

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

/* ---- the ship on the map ---- */
.map-ship {
  position: absolute;
  left: 0;
  top: 0;
  width: 66px;
  pointer-events: none;
  will-change: transform;
  z-index: 1;
}

/* bob lives on the inner wrapper so GSAP's tilt on the outer never fights it */
.map-ship-inner {
  animation: ship-bob 7s ease-in-out infinite;
}

.map-ship svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* keepsakes the ship quietly collects, one per finished island */
.map-ship .memento {
  opacity: 0;
  transition: opacity 1.6s var(--ease-soft);
}

.map-ship.has-m1 .memento--1,
.map-ship.has-m2 .memento--2,
.map-ship.has-m3 .memento--3,
.map-ship.has-m4 .memento--4 {
  opacity: 1;
}

/* ---- wake foam trailing the ship ---- */
.map-wake {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.wake-dot {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(190, 225, 255, 0.45) 0%, rgba(190, 225, 255, 0) 70%);
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
}

/* ---- distant birds crossing the water ---- */
.map-birds {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.map-bird {
  position: absolute;
  width: 15px;
  color: rgba(205, 225, 245, 0.55);
  opacity: 0;
  will-change: transform, opacity;
}

.map-bird svg {
  display: block;
  width: 100%;
  height: auto;
}

@keyframes cloud-drift {
  from { transform: translateX(0); }
  to { transform: translateX(var(--c-drift, 60px)); }
}

.map-cloud {
  position: absolute;
  left: var(--c-left);
  top: var(--c-top);
  width: var(--c-size, 140px);
  height: calc(var(--c-size, 140px) * 0.4);
  border-radius: 50%;
  background: rgba(200, 225, 255, var(--c-opacity, 0.05));
  filter: blur(18px);
  animation: cloud-drift var(--c-duration, 40s) ease-in-out infinite alternate;
}

/* ---- islands ---- */
.map-islands {
  position: absolute;
  inset: 0;
  /* enabled by JS once the arrival narration finishes, so an early click
     doesn't get its response stomped by the still-playing intro lines */
  pointer-events: none;
}

.map-island {
  position: absolute;
  width: 110px;
  color: var(--color-mint);
  filter: drop-shadow(0 0 14px rgba(109, 240, 194, 0.4));
  transition: filter 0.4s var(--ease-soft), color 0.4s var(--ease-soft);
  cursor: pointer;
}

.map-island svg {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}

.island-underglow {
  fill: rgba(79, 158, 255, 0.25);
}

.island-land {
  fill: currentColor;
}

.island-tree {
  fill: var(--color-bg-soft);
  opacity: 0.9;
  transition: opacity 0.4s var(--ease-soft);
}

.island-fog {
  position: absolute;
  inset: -30%;
  background: radial-gradient(circle, rgba(8, 10, 16, 0.6) 0%, rgba(8, 10, 16, 0) 70%);
  opacity: 0;
  transition: opacity 0.4s var(--ease-soft);
  pointer-events: none;
}

.map-island:hover {
  filter: drop-shadow(0 0 22px rgba(109, 240, 194, 0.65));
}

.map-island.is-locked {
  color: #3a4550;
  filter: drop-shadow(0 0 6px rgba(79, 158, 255, 0.15));
}

.map-island.is-locked .island-tree {
  opacity: 0;
}

.map-island.is-locked .island-fog {
  opacity: 1;
}

.map-island.is-locked:hover {
  filter: drop-shadow(0 0 10px rgba(79, 158, 255, 0.25));
}

/* island 2 reads as "closer now" once island 1 completes — still locked,
   just visibly less asleep than islands 3-5 */
.map-island.is-softened {
  color: #5b7690;
}

.map-island.is-softened .island-fog {
  opacity: 0.55;
}

.map-island.is-complete {
  color: var(--color-blue);
  filter: drop-shadow(0 0 18px rgba(79, 158, 255, 0.5));
}

@keyframes island-shake {
  0%, 100% { transform: rotate(0); }
  20% { transform: rotate(-4deg); }
  40% { transform: rotate(4deg); }
  60% { transform: rotate(-3deg); }
  80% { transform: rotate(2deg); }
}

.map-island.is-shaking {
  animation: island-shake 0.4s ease-in-out;
}

/* ---- the companion, catching back up from wherever Ch2 sent it off ---- */
.map-companion {
  position: absolute;
  left: 62%;
  top: 74%;
  width: 60px;
  height: 60px;
}

/* ---- map dialogue ---- */
.map-dialogue {
  position: absolute;
  left: 50%;
  bottom: 12%;
  transform: translateX(-50%);
  width: min(90vw, 560px);
  text-align: center;
  font-size: clamp(1rem, 2.4vw, 1.3rem);
  color: var(--color-text);
  opacity: 0;
  z-index: 2;
  pointer-events: none;
}

/* ---- the island scene ---- */
.island-scene {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2rem;
  opacity: 0;
  padding: 2rem;
}

.island-backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 40%, rgba(79, 158, 255, 0.14) 0%, rgba(6, 8, 13, 0) 60%),
    linear-gradient(180deg, #0a121c 0%, #050810 100%);
}

.island-mist {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at 50% 55%,
    rgba(180, 210, 230, 0.24) 0%,
    rgba(180, 210, 230, 0.09) 45%,
    rgba(6, 8, 13, 0) 75%
  );
  transition: opacity 0.6s var(--ease-soft);
}

/* ================= per-land atmospheres =================
   Each land gets its own light, colour and mood. "beginning" (Land 1)
   uses the cool default above; the rest override backdrop, mist and the
   trace accent so every place she travels to genuinely feels different. */

/* Land 2 — Comfort: golden hour, warm and soft */
.island-scene--comfort .island-backdrop {
  background: radial-gradient(ellipse at 50% 42%, rgba(255, 190, 120, 0.18) 0%, rgba(20, 12, 6, 0) 60%),
    linear-gradient(180deg, #241706 0%, #1a1108 55%, #0a0805 100%);
}
.island-scene--comfort .island-mist {
  background: radial-gradient(circle at 50% 55%, rgba(255, 216, 168, 0.26) 0%, rgba(255, 205, 150, 0.1) 45%, rgba(20, 12, 6, 0) 75%);
}
.island-scene--comfort #tracePath {
  stroke: #ffce8a;
  filter: drop-shadow(0 0 6px rgba(255, 196, 120, 0.75));
}
.island-scene--comfort .trace-point.is-connected {
  background: #ffce8a;
  box-shadow: 0 0 16px rgba(255, 196, 120, 0.85);
}

/* Land 3 — Adventure: cool open night air, free and breezy */
.island-scene--adventure .island-backdrop {
  background: radial-gradient(ellipse at 50% 80%, rgba(90, 210, 180, 0.16) 0%, rgba(4, 12, 12, 0) 62%),
    linear-gradient(180deg, #04141a 0%, #06181a 50%, #04100f 100%);
}
.island-scene--adventure .island-mist {
  background: radial-gradient(circle at 50% 60%, rgba(150, 230, 210, 0.22) 0%, rgba(120, 210, 200, 0.08) 45%, rgba(4, 12, 12, 0) 75%);
}
.island-scene--adventure #tracePath {
  stroke: #7fead0;
  filter: drop-shadow(0 0 6px rgba(120, 230, 200, 0.75));
}
.island-scene--adventure .trace-point.is-connected {
  background: #7fead0;
  box-shadow: 0 0 16px rgba(120, 230, 200, 0.85);
}

/* Land 4 — Concert: electric night, alive with stage light */
.island-scene--concert .island-backdrop {
  background: radial-gradient(ellipse at 50% 36%, rgba(90, 140, 255, 0.22) 0%, rgba(6, 8, 20, 0) 58%),
    radial-gradient(ellipse at 78% 82%, rgba(120, 90, 230, 0.14) 0%, rgba(6, 8, 20, 0) 55%),
    linear-gradient(180deg, #070b1e 0%, #0a0f28 50%, #05060f 100%);
}
.island-scene--concert .island-mist {
  background: radial-gradient(circle at 50% 50%, rgba(150, 190, 255, 0.24) 0%, rgba(130, 160, 255, 0.09) 45%, rgba(6, 8, 20, 0) 75%);
}
.island-scene--concert #tracePath {
  stroke: #9fc6ff;
  filter: drop-shadow(0 0 8px rgba(120, 170, 255, 0.9));
}
.island-scene--concert .trace-point.is-connected {
  background: #cfe3ff;
  box-shadow: 0 0 18px rgba(150, 190, 255, 0.95);
}

.trace-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  touch-action: none;
}

#tracePath {
  fill: none;
  stroke: var(--color-mint);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 6px rgba(109, 240, 194, 0.7));
}

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

.trace-point {
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: rgba(143, 163, 179, 0.55);
  box-shadow: 0 0 8px rgba(143, 163, 179, 0.3);
  transform: translate(-50%, -50%);
  transition: background-color 0.3s var(--ease-soft), box-shadow 0.3s var(--ease-soft), transform 0.3s var(--ease-soft);
}

.trace-point.is-connected {
  background: var(--color-mint);
  box-shadow: 0 0 16px rgba(109, 240, 194, 0.8);
  transform: translate(-50%, -50%) scale(1.3);
}

/* ===================== PER-LAND ATMOSPHERE =====================
   Land 1 ("beginning") uses the default cool-blue look above.
   Each theme below repaints the backdrop, mist, and trace accent so the
   land reads as a genuinely different place — not the same scene recolored
   by accident. New lands add one block here + a `theme` in islands.js. */

/* Land 2 — "Comfort": golden hour. Warm, soft, unhurried. */
.island-scene--comfort .island-backdrop {
  background: radial-gradient(ellipse at 50% 42%, rgba(255, 190, 120, 0.2) 0%, rgba(20, 12, 6, 0) 60%),
    linear-gradient(180deg, #2a1c0c 0%, #150d05 100%);
}

.island-scene--comfort .island-mist {
  background: radial-gradient(
    circle at 50% 55%,
    rgba(255, 216, 170, 0.26) 0%,
    rgba(255, 205, 150, 0.1) 45%,
    rgba(20, 12, 6, 0) 75%
  );
}

.island-scene--comfort #tracePath {
  stroke: #ffcf8f;
  filter: drop-shadow(0 0 6px rgba(255, 190, 110, 0.75));
}

.island-scene--comfort .trace-point.is-connected {
  background: #ffcf8f;
  box-shadow: 0 0 16px rgba(255, 190, 110, 0.85);
}

.island-dialogue {
  position: absolute;
  top: 12%;
  left: 50%;
  transform: translateX(-50%);
  width: min(90vw, 560px);
  text-align: center;
  font-size: clamp(1rem, 2.4vw, 1.3rem);
  color: var(--color-text);
  opacity: 0;
  z-index: 2;
}

/* ---- the polaroid ---- */
.polaroid {
  display: none;
  position: relative;
  width: 220px;
  padding: 14px 14px 40px;
  background: #f4f1ea;
  border-radius: 4px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
  opacity: 0;
  transform: scale(0.6) rotate(-4deg);
  z-index: 2;
}

.polaroid-photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  background: linear-gradient(135deg, #1c2733, #0d141c);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  filter: grayscale(1) brightness(0.35) contrast(1.15);
  transition: filter 1.8s var(--ease-soft);
}

.polaroid.is-developed .polaroid-photo {
  filter: grayscale(0) brightness(1) contrast(1);
}

.polaroid-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.polaroid-photo-placeholder {
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.45);
  font-style: italic;
  padding: 0 0.75rem;
  text-align: center;
}

/* ---- the handwritten message ---- */
/* ---- the envelope ---- */
.envelope {
  display: none;
  position: relative;
  width: 130px;
  opacity: 0;
  transform: scale(0.6);
  color: var(--color-mint);
  z-index: 2;
  pointer-events: none;
}

.envelope svg {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}

.envelope-body {
  fill: #f4f1ea;
  stroke: rgba(109, 240, 194, 0.4);
  stroke-width: 1;
}

.envelope-flap {
  fill: #e7e2d5;
  stroke: rgba(109, 240, 194, 0.4);
  stroke-width: 1;
  transition: transform 0.6s var(--ease-soft), opacity 0.4s var(--ease-soft);
}

.envelope-glow {
  position: absolute;
  inset: -20%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(109, 240, 194, 0.35) 0%, rgba(109, 240, 194, 0) 70%);
  filter: blur(4px);
  animation: envelope-pulse 2.4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes envelope-pulse {
  0%, 100% { opacity: 0.5; transform: scale(1); }
  50% { opacity: 0.9; transform: scale(1.08); }
}

.envelope.is-open .envelope-flap {
  transform: translateY(-14px);
  opacity: 0;
}

/* ---- the letter ---- */
.letter {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  max-width: 420px;
  opacity: 0;
  transform: scale(0.85);
  z-index: 3;
}

.letter-paper {
  background: #f8f5ec;
  border-radius: 6px;
  padding: 2rem 2.25rem;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.letter-paper .line {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1.15rem;
  font-weight: 500;
  line-height: 1.6;
  color: #1c1c1c;
  opacity: 0;
  text-align: center;
}

.letter-hint {
  font-size: 0.8rem;
  color: var(--color-text-whisper);
  opacity: 0;
  font-style: italic;
}

/* ---- wipe-the-mist interaction ---- */
.wipe-stage {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(68vw, 340px);
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(109, 240, 194, 0.14);
  z-index: 2;
}

.wipe-stage img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}

.wipe-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  touch-action: none; /* a finger-wipe must never turn into a page scroll */
  cursor: grab;
}

/* ---- bonus / easter-egg reveal ---- */
.bonus-reveal {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  opacity: 0;
  z-index: 3;
}

.bonus-photo {
  width: 200px;
  aspect-ratio: 4 / 5;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
  background: #10151c;
  transform: rotate(2deg);
}

.bonus-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.bonus-caption {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 1rem;
  font-weight: 500;
  color: var(--color-text-dim);
  opacity: 0;
}

/* ---- responsive tightening ---- */
@media (max-width: 480px) {
  .map-island {
    width: 84px;
  }

  .map-ship {
    width: 50px;
  }

  .polaroid {
    width: 180px;
  }

  .letter-paper .line {
    font-size: 1.4rem;
  }

  .letter-paper {
    padding: 1.5rem 1.5rem;
  }
}

/* ===================== LAND 5 — THE CONCERT VIDEOS ===================== */

.video-scene {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  opacity: 0;
  z-index: 4;
}

.video-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(3, 5, 10, 0.94);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.video-dialogue {
  z-index: 5;
}

.video-stage {
  position: relative;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  max-width: 92vw;
}

.video-player {
  display: block;
  max-width: 92vw;
  max-height: 78vh;
  border-radius: 14px;
  background: #000;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(109, 240, 194, 0.16);
}

.video-play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 88px;
  height: 88px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-mint);
  background: rgba(6, 8, 13, 0.5);
  border: 1px solid rgba(109, 240, 194, 0.5);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  transition: transform 0.25s var(--ease-soft), opacity 0.3s var(--ease-soft),
    background-color 0.25s var(--ease-soft);
}

.video-play-btn svg {
  margin-left: 4px; /* optically centre the triangle */
}

.video-play-btn:hover {
  transform: translate(-50%, -50%) scale(1.08);
  background: rgba(6, 8, 13, 0.72);
}

.video-play-btn.is-hidden {
  opacity: 0;
  pointer-events: none;
}

.video-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 0 0 14px 14px;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0));
  opacity: 0;
  transition: opacity 0.3s var(--ease-soft);
}

.video-stage:hover .video-controls,
.video-controls.is-visible {
  opacity: 1;
}

.video-progress {
  flex: 1;
  /* thin visible track + generous invisible padding so it's easy to tap/drag on a phone */
  padding: 14px 0;
  cursor: pointer;
  display: flex;
  align-items: center;
}

.video-progress-track {
  width: 100%;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.22);
  overflow: hidden;
}

.video-progress-bar {
  height: 100%;
  width: 0%;
  background: var(--gradient-accent);
}

.video-fs-btn {
  color: #fff;
  opacity: 0.85;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px; /* 16px icon + padding = ~44px touch target */
  margin: -14px; /* offsets the padding so visual layout/spacing is unchanged */
}

.video-fs-btn:hover {
  opacity: 1;
}

/* ===================== THE FINAL ISLAND — ARRIVAL ===================== */

/* The world itself says "this is the end of the journey": colder than
   every other place, emptier, slower. Nothing warm here except the
   ship's own small lantern. */
.final-island {
  position: absolute;
  inset: 0;
  display: none;
  opacity: 0;
  background: #04060a; /* the darkness she arrives into */
  z-index: 5;
  overflow: hidden;
}

.fi-sky {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: radial-gradient(ellipse at 50% 20%, rgba(120, 140, 165, 0.1) 0%, rgba(4, 6, 10, 0) 55%),
    linear-gradient(180deg, #0a0f18 0%, #090d15 55%, #04060a 100%);
}

/* slow, cold fog banks — they drift on their own, and sink past her
   during the climb */
.fi-fog {
  position: absolute;
  left: -20%;
  width: 140%;
  height: 26%;
  border-radius: 50%;
  background: rgba(150, 170, 190, 0.05);
  filter: blur(28px);
  opacity: 0;
  will-change: transform;
  animation: fi-fog-drift 26s ease-in-out infinite alternate;
}

.fi-fog-1 { top: 18%; animation-duration: 30s; }
.fi-fog-2 { top: 44%; animation-duration: 24s; animation-delay: -9s; }
.fi-fog-3 { top: 68%; animation-duration: 34s; animation-delay: -17s; }

@keyframes fi-fog-drift {
  from { transform: translateX(-3%); }
  to { transform: translateX(3%); }
}

.fi-shore {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 40%;
  opacity: 0;
  will-change: transform;
}

/* a bare dock: one dark plank line, one post, one cold lamp */
.fi-dock {
  position: absolute;
  left: 50%;
  bottom: 22%;
  width: min(46vw, 320px);
  height: 7px;
  transform: translateX(-8%);
  background: #060a12;
  border-radius: 3px;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.6);
}

.fi-dock-post {
  position: absolute;
  right: 8%;
  bottom: 4px;
  width: 5px;
  height: 40px;
  background: #060a12;
  border-radius: 2px;
}

.fi-dock-lamp {
  position: absolute;
  top: -7px;
  left: 50%;
  transform: translateX(-50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(190, 215, 235, 0.55); /* cold light — not the ship's warm gold */
  box-shadow: 0 0 12px 3px rgba(170, 200, 230, 0.25);
}

.fi-ship {
  position: absolute;
  left: 24%;
  bottom: 22.5%;
  width: min(30vw, 150px);
  opacity: 0;
  will-change: transform;
}

.fi-ship svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.fi-line {
  position: absolute;
  top: 16%;
  left: 50%;
  transform: translateX(-50%);
  width: min(88vw, 520px);
  text-align: center;
  font-size: clamp(1rem, 2.4vw, 1.25rem);
  color: rgba(214, 226, 238, 0.85);
  opacity: 0;
  z-index: 2;
}

/* ---- the nakama moment: typography only, deliberately paced ---- */
.nakama {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.2rem, 4vh, 2.2rem);
  padding: 2rem;
  text-align: center;
  z-index: 3;
}

.nakama p {
  display: none;
  opacity: 0;
  margin: 0;
}

.nakama-jp {
  font-size: clamp(1.7rem, 7vw, 3.4rem);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: #f2f7fb;
  text-shadow: 0 0 26px rgba(109, 240, 194, 0.35), 0 0 60px rgba(79, 158, 255, 0.2);
}

.nakama-romaji {
  font-size: clamp(0.85rem, 2.4vw, 1.05rem);
  letter-spacing: 0.22em;
  text-transform: lowercase;
  color: rgba(168, 186, 202, 0.7);
}

.nakama-en {
  font-size: clamp(1.15rem, 3.4vw, 1.7rem);
  font-style: italic;
  font-weight: 500;
  color: #eaf4ff;
  text-shadow: 0 0 30px rgba(109, 240, 194, 0.3);
}

/* ===================== THE EPILOGUE ===================== */

/* darkness closes in around the departing ship; waves linger in the
   black; one whispered line; then the world quietly returns */
.epilogue-veil {
  position: absolute;
  inset: 0;
  display: none;
  opacity: 0;
  background: #000;
  z-index: 12;
  pointer-events: none;
}

.epilogue-line {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 90vw;
  text-align: center;
  font-size: clamp(0.95rem, 2.4vw, 1.15rem);
  font-style: italic;
  letter-spacing: 0.08em;
  color: rgba(214, 226, 238, 0.75);
  opacity: 0;
}

/* ===================== THE FINALE ===================== */

/* the map warms from cold night into golden twilight as the ending begins */
.map-sky {
  transition: background 3.5s var(--ease-soft);
}
.map-viewport.is-twilight .map-sky {
  background: radial-gradient(ellipse at 50% 24%, rgba(255, 200, 130, 0.22) 0%, rgba(10, 8, 14, 0) 55%),
    linear-gradient(180deg, #1a1330 0%, #241a35 30%, #3a2740 60%, #23182e 100%);
}

.ending-layer {
  position: absolute;
  inset: 0;
  display: none;
  opacity: 0;
  z-index: 6;
  pointer-events: none;
}

.fireworks-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.ending-fireflies,
.ending-lanterns,
.ending-polaroids {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* lanterns strung across the world, dark until they light one by one */
.lantern {
  position: absolute;
  width: 10px;
  height: 14px;
  border-radius: 46% 46% 50% 50%;
  background: rgba(120, 110, 90, 0.35);
  transform: translate(-50%, -50%);
  transition: background-color 0.6s var(--ease-soft), box-shadow 0.6s var(--ease-soft);
}
.lantern.is-lit {
  background: #ffd98a;
  box-shadow: 0 0 14px 3px rgba(255, 200, 120, 0.75), 0 0 34px 8px rgba(255, 180, 90, 0.35);
}

/* extra fireflies for the finale */
@keyframes firefly-bob {
  0%, 100% { transform: translate(0, 0); opacity: var(--f-op, 0.5); }
  50% { transform: translate(var(--f-dx, 8px), var(--f-dy, -12px)); opacity: 0.9; }
}
.finale-firefly {
  position: absolute;
  left: var(--f-left);
  top: var(--f-top);
  width: var(--f-size, 3px);
  height: var(--f-size, 3px);
  border-radius: 50%;
  background: #eafff0;
  box-shadow: 0 0 8px 2px rgba(180, 255, 210, 0.8);
  opacity: 0;
  animation: firefly-bob var(--f-dur, 4s) ease-in-out var(--f-delay, 0s) infinite;
}

/* the returning Polaroids */
.return-polaroid {
  position: absolute;
  width: 96px;
  padding: 6px 6px 18px;
  background: #f4f1ea;
  border-radius: 3px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5);
  transform: translate(-50%, -50%) scale(0.2);
  opacity: 0;
  will-change: transform, opacity;
}
.return-polaroid img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 1px;
}

.ending-dialogue {
  position: absolute;
  left: 50%;
  bottom: 11%;
  transform: translateX(-50%);
  width: min(90vw, 620px);
  text-align: center;
  font-size: clamp(1.05rem, 2.5vw, 1.4rem);
  color: #fff5e8;
  opacity: 0;
  z-index: 8;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.5);
}

/* the final, personal letter */
.final-letter {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.88);
  width: min(92vw, 500px);
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  opacity: 0;
  z-index: 9;
}
.final-letter-paper {
  width: 100%;
  background: #f8f5ec;
  border-radius: 8px;
  padding: 2.4rem 2.2rem;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  font-family: var(--font-body);
  font-style: italic;
  font-size: clamp(1.05rem, 2.4vw, 1.25rem);
  font-weight: 500;
  line-height: 1.65;
  color: #1c1c1c;
  text-align: center;
  white-space: pre-wrap;
  max-height: 76vh;
  overflow-y: auto;
}

@media (max-width: 480px) {
  .final-letter-paper {
    padding: 1.6rem 1.4rem;
    font-size: 1rem;
  }
  .return-polaroid {
    width: 70px;
  }
}
