/*
 * 留声世界：播放时，页面退成一段由云南抵达上海的月光航线。
 * All motion is gated by data-world-mode="listen" and has a low-power path.
 */

body {
  --voice-energy: 0;
  --voice-progress: 0;
}

.voice-world {
  --voice-energy: 0;
  --voice-progress: 0;
  position: fixed;
  z-index: 3;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  color: #e9e2d5;
  background:
    radial-gradient(circle at 78% 17%, rgb(228 222 203 / calc(0.09 + var(--voice-energy) * 0.12)), transparent 19%),
    radial-gradient(ellipse at 19% 72%, rgb(41 72 79 / 0.23), transparent 32%),
    linear-gradient(116deg, #071015 0%, #0c1820 48%, #18222a 73%, #25282c 100%);
  filter: saturate(calc(0.84 + var(--voice-energy) * 0.2));
  transition:
    opacity 1100ms cubic-bezier(.18, .74, .16, 1),
    visibility 0s linear 1100ms,
    filter 240ms linear;
  pointer-events: none;
}

body[data-world-mode="listen"] .voice-world,
.voice-world.is-afterglow {
  visibility: visible;
  transition-delay: 0s;
}

body[data-world-mode="listen"] .voice-world {
  opacity: 1;
}

.voice-world.is-afterglow {
  opacity: 0;
  transition-duration: 1700ms;
}

.voice-world__sky,
.voice-world__sky::before,
.voice-world__sky::after {
  position: absolute;
  inset: 0;
}

.voice-world__sky::before {
  content: "";
  opacity: calc(0.12 + var(--voice-energy) * 0.1);
  background-image:
    radial-gradient(circle at 8% 20%, #fff 0 1px, transparent 1.5px),
    radial-gradient(circle at 29% 31%, #fff 0 0.7px, transparent 1.2px),
    radial-gradient(circle at 48% 14%, #fff 0 1px, transparent 1.5px),
    radial-gradient(circle at 62% 27%, #fff 0 0.8px, transparent 1.3px),
    radial-gradient(circle at 87% 38%, #fff 0 0.7px, transparent 1.2px);
  background-size: 19rem 13rem, 27rem 21rem, 31rem 18rem, 23rem 29rem, 37rem 24rem;
  transform: translate3d(calc(var(--voice-energy) * -5px), calc(var(--voice-energy) * 3px), 0);
  transition: opacity 250ms linear, transform 250ms linear;
}

.voice-world__sky::after {
  content: "";
  background:
    linear-gradient(90deg, rgb(0 0 0 / 0.26), transparent 28% 72%, rgb(9 9 14 / 0.18)),
    linear-gradient(180deg, transparent 55%, rgb(4 9 12 / 0.74));
}

.voice-world__moon {
  position: absolute;
  z-index: 2;
  top: clamp(4.5rem, 12vh, 8.5rem);
  right: clamp(8%, 15vw, 18%);
  width: clamp(3.8rem, 8vw, 7.4rem);
  aspect-ratio: 1;
  border-radius: 50%;
  opacity: calc(0.64 + var(--voice-energy) * 0.3);
  background:
    radial-gradient(circle at 38% 36%, rgb(255 252 235 / 0.38), transparent 11%),
    radial-gradient(circle at 62% 66%, rgb(111 121 125 / 0.13), transparent 18%),
    #e8e2cf;
  box-shadow:
    0 0 calc(2.4rem + var(--voice-energy) * 4rem) rgb(225 226 211 / calc(0.17 + var(--voice-energy) * 0.16)),
    0 0 calc(8rem + var(--voice-energy) * 8rem) rgb(142 170 177 / 0.08);
  transform: scale(calc(0.98 + var(--voice-energy) * 0.035));
  transition: opacity 180ms linear, transform 180ms linear, box-shadow 180ms linear;
}

.voice-world__cloud {
  position: absolute;
  z-index: 3;
  width: 42vw;
  height: 13vh;
  border-radius: 50%;
  opacity: 0.12;
  filter: blur(24px);
  background: linear-gradient(90deg, transparent, #b2bec0 35% 62%, transparent);
  animation-play-state: paused;
}

body[data-world-mode="listen"] .voice-world__cloud {
  animation-play-state: running;
}

.voice-world__cloud--one {
  top: 17%;
  left: -8%;
  animation: voice-cloud-drift 18s ease-in-out infinite alternate;
}

.voice-world__cloud--two {
  top: 34%;
  right: -12%;
  opacity: 0.08;
  animation: voice-cloud-drift-reverse 24s ease-in-out infinite alternate;
}

.voice-world__cloud--one,
.voice-world__cloud--two {
  animation-play-state: paused;
}

body[data-world-mode="listen"] .voice-world__cloud--one,
body[data-world-mode="listen"] .voice-world__cloud--two {
  animation-play-state: running;
}

.voice-world__mountains {
  position: absolute;
  z-index: 4;
  left: -5%;
  bottom: 0;
  width: 59%;
  height: 53%;
  opacity: 0.86;
  background:
    linear-gradient(151deg, transparent 0 37%, #17292c 37.3% 52%, transparent 52.4%) 8% 80% / 54% 83% no-repeat,
    linear-gradient(136deg, transparent 0 41%, #0e1f23 41.4% 62%, transparent 62.4%) 29% 92% / 54% 94% no-repeat,
    linear-gradient(146deg, transparent 0 39%, #09171b 39.4% 68%, transparent 68.4%) 0 100% / 83% 96% no-repeat;
  filter: drop-shadow(1rem -1rem 2.2rem rgb(54 84 83 / 0.14));
  transform: translate3d(calc(var(--voice-energy) * -3px), calc(var(--voice-energy) * 2px), 0);
}

.voice-world__water {
  position: absolute;
  z-index: 3;
  left: 22%;
  right: 0;
  bottom: 0;
  height: 36%;
  opacity: 0.42;
  background:
    repeating-linear-gradient(176deg, transparent 0 12px, rgb(176 194 192 / 0.045) 13px 14px),
    linear-gradient(180deg, rgb(50 73 76 / 0.02), rgb(11 23 28 / 0.75));
  clip-path: polygon(19% 0, 100% 14%, 100% 100%, 0 100%);
}

.voice-world__skyline {
  position: absolute;
  z-index: 5;
  right: -1%;
  bottom: 4%;
  width: 42%;
  height: 40%;
  opacity: calc(0.42 + var(--voice-progress) * 0.34);
  background:
    linear-gradient(#afb4a9, #afb4a9) 77% 5% / 1px 68% no-repeat,
    radial-gradient(circle, rgb(226 183 111 / 0.65) 0 1px, transparent 1.6px) 0 0 / 21px 28px,
    linear-gradient(90deg,
      transparent 0 4%, #172127 4% 11%, transparent 11% 14%,
      #121d23 14% 23%, transparent 23% 27%, #1a252a 27% 34%,
      transparent 34% 38%, #101b21 38% 54%, transparent 54% 57%,
      #172229 57% 66%, transparent 66% 70%, #111b21 70% 82%,
      transparent 82% 85%, #172229 85% 96%, transparent 96%);
  background-position: 77% 5%, 2px 13px, 0 100%;
  background-size: 1px 68%, 21px 28px, 100% 76%;
  mask-image: linear-gradient(to right, transparent, #000 13% 100%);
  transition: opacity 400ms linear;
}

.voice-world__route {
  position: absolute;
  z-index: 6;
  inset: 24% 3% auto;
  width: 94%;
  height: 48%;
  overflow: visible;
}

.voice-world__route-shadow,
.voice-world__route-line {
  fill: none;
  vector-effect: non-scaling-stroke;
}

.voice-world__route-shadow {
  stroke: rgb(163 185 184 / 0.15);
  stroke-width: 1;
  stroke-dasharray: 2 10;
}

.voice-world__route-line {
  stroke: rgb(234 221 190 / calc(0.52 + var(--voice-energy) * 0.32));
  stroke-width: calc(1.1px + var(--voice-energy) * 0.8px);
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--voice-progress));
  filter: drop-shadow(0 0 calc(4px + var(--voice-energy) * 7px) rgb(218 209 179 / 0.44));
  transition: stroke-dashoffset 280ms linear;
}

.voice-world__traveller {
  opacity: calc(0.58 + var(--voice-energy) * 0.4);
  transition: transform 280ms linear, opacity 180ms linear;
}

.voice-world__traveller-halo {
  fill: rgb(222 219 196 / 0.08);
  stroke: rgb(230 220 191 / 0.22);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  transform: scale(calc(0.8 + var(--voice-energy) * 0.6));
}

.voice-world__traveller-core,
.voice-world__arrival {
  fill: #e9dfc2;
  filter: drop-shadow(0 0 7px rgb(231 215 174 / 0.7));
}

.voice-world__arrival--to {
  opacity: calc(0.2 + var(--voice-progress) * 0.8);
}

.voice-world__places {
  position: absolute;
  z-index: 7;
  inset: auto clamp(1.4rem, 7vw, 7rem) clamp(5.5rem, 13vh, 9rem);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
}

.voice-world__place {
  display: grid;
  gap: 0.34rem;
  margin: 0;
  color: rgb(223 220 207 / 0.58);
  font: 400 0.66rem/1.5 system-ui, sans-serif;
  letter-spacing: 0.14em;
}

.voice-world__place b {
  color: rgb(242 235 215 / 0.86);
  font: 450 clamp(1rem, 2.2vw, 1.5rem)/1.3 "Noto Serif SC", "Songti SC", serif;
  letter-spacing: 0.2em;
}

.voice-world__place--to {
  text-align: right;
}

.voice-world__caption {
  position: absolute;
  z-index: 8;
  left: 50%;
  bottom: clamp(1.8rem, 5vh, 3.4rem);
  display: flex;
  gap: 1rem;
  align-items: center;
  margin: 0;
  color: rgb(229 224 210 / 0.65);
  font: 400 0.68rem/1.5 system-ui, sans-serif;
  letter-spacing: 0.14em;
  transform: translateX(-50%);
  white-space: nowrap;
}

.voice-world__caption span {
  color: rgb(232 199 143 / 0.74);
  font-variant-numeric: tabular-nums;
}

.voice-world__caption b {
  font-weight: 400;
}

.voice-world__control {
  position: absolute;
  z-index: 10;
  top: max(1.15rem, env(safe-area-inset-top));
  left: 50%;
  display: grid;
  grid-template-columns: auto auto auto;
  gap: 0.62rem;
  align-items: center;
  min-height: 2.65rem;
  padding: 0.2rem 0.75rem;
  color: rgb(232 226 211 / 0.7);
  border: 0;
  border-bottom: 1px solid rgb(228 213 180 / 0.22);
  border-radius: 0;
  background: rgb(5 12 16 / 0.12);
  box-shadow: none;
  backdrop-filter: blur(6px);
  font: 400 0.64rem/1.4 system-ui, sans-serif;
  letter-spacing: 0.12em;
  transform: translateX(-50%);
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: color 250ms ease, border-color 250ms ease, background 250ms ease;
}

.voice-world__control:hover,
.voice-world__control:focus-visible {
  color: rgb(248 239 216 / 0.94);
  border-color: rgb(228 203 155 / 0.58);
  background: rgb(7 16 20 / 0.38);
}

.voice-world__control:focus-visible {
  outline: 1px solid rgb(231 207 163 / 0.72);
  outline-offset: 4px;
}

.voice-world__control i {
  position: relative;
  display: block;
  width: 0.65rem;
  height: 0.8rem;
  border-inline: 1px solid currentColor;
}

.voice-world__control time {
  color: rgb(225 190 128 / 0.75);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.voice-world__star {
  position: absolute;
  z-index: 2;
  width: 3px;
  aspect-ratio: 1;
  border-radius: 50%;
  opacity: calc(0.18 + var(--voice-energy) * 0.54);
  background: #eee6cb;
  box-shadow: 0 0 10px rgb(237 225 194 / 0.55);
  transform: scale(calc(0.7 + var(--voice-energy) * 1.1));
}

.voice-world__star--1 { left: 13%; top: 21%; }
.voice-world__star--2 { left: 32%; top: 14%; }
.voice-world__star--3 { left: 54%; top: 27%; }
.voice-world__star--4 { left: 69%; top: 12%; }
.voice-world__star--5 { left: 88%; top: 31%; }

/* The interface withdraws; the pause control remains the only active object. */
body[data-world-mode="listen"] :is(
  .site-chrome,
  .chapter-nav,
  .chapter-scroll-seal,
  .memory-map,
  .scene-ritual-hint,
  .section-heading--letter
) {
  opacity: 0 !important;
  visibility: hidden;
  pointer-events: none !important;
  transition: opacity 650ms ease, visibility 0s linear 650ms;
}

body[data-world-mode="listen"] .letter__shell > :not(.voice-keepsake) {
  opacity: 0.035;
  filter: blur(2px);
  transition: opacity 850ms ease, filter 850ms ease;
  pointer-events: none;
}

body[data-world-mode="listen"] :is(
  .chapter-backdrop--paper,
  .two-city-world,
  .living-scroll-background
),
body[data-world-mode="listen"] .letter::before,
body[data-world-mode="listen"] .letter::after {
  opacity: 0.04 !important;
  transition: opacity 900ms ease;
}

body[data-world-mode="listen"] .voice-keepsake {
  --voice-ink: #ede7da;
  --voice-muted: rgb(223 219 208 / 0.62);
  --voice-cinnabar: #d5b077;
  --voice-gold: #dec08d;
  z-index: 8;
  width: min(100%, 64rem);
  color: var(--voice-ink);
  border-color: rgb(222 209 182 / 0.2);
  background: linear-gradient(90deg, transparent, rgb(7 14 18 / 0.24) 34% 66%, transparent);
  box-shadow: none;
  contain: layout;
  transition: color 800ms ease, border-color 800ms ease, background 800ms ease;
}

body[data-world-mode="listen"] .voice-keepsake::before {
  opacity: calc(0.12 + var(--voice-energy) * 0.18);
  background: linear-gradient(90deg, transparent, rgb(225 217 192 / 0.3), transparent);
}

body[data-world-mode="listen"] .voice-keepsake::after {
  color: rgb(225 199 151 / 0.64);
  border-color: rgb(225 199 151 / 0.3);
}

body[data-world-mode="listen"] .voice-keepsake :is(h3, strong) {
  color: var(--voice-ink);
}

body[data-world-mode="listen"] .voice-keepsake__toggle,
body[data-world-mode="listen"] #voiceKeepsakeToggle {
  border-color: rgb(224 213 190 / 0.25);
  background: rgb(8 16 20 / 0.18);
  box-shadow:
    0 1.4rem 4rem rgb(0 0 0 / 0.12),
    inset 0 0 0 1px rgb(255 255 255 / 0.025);
  backdrop-filter: blur(7px);
}

body[data-world-mode="listen"] .voice-keepsake__toggle::after,
body[data-world-mode="listen"] #voiceKeepsakeToggle::after {
  background:
    linear-gradient(
      90deg,
      rgb(222 194 145 / 0.82) calc(var(--voice-progress) * 100%),
      rgb(228 223 207 / 0.16) 0
    );
}

body[data-world-mode="listen"] .voice-keepsake__disc {
  border-color: rgb(224 213 190 / 0.38);
  background:
    radial-gradient(circle at 39% 35%, rgb(255 252 235 / 0.54), transparent 10%),
    radial-gradient(circle, #e7dfc9 0 42%, rgb(212 206 188 / 0.64) 43% 48%, transparent 49%);
  box-shadow:
    0 0 calc(1.6rem + var(--voice-energy) * 2.2rem) rgb(226 221 199 / 0.28),
    inset 0 0 0 1px rgb(255 255 255 / 0.14);
  animation-duration: 22s;
}

body[data-world-mode="listen"] .voice-keepsake__wave {
  background: rgb(12 22 26 / 0.86);
}

body[data-world-mode="listen"] .voice-keepsake__wave i {
  background: #d7b578;
}

body[data-world-mode="listen"] .voice-keepsake__track {
  background: rgb(228 223 207 / 0.16);
}

body[data-world-mode="listen"] progress#voiceKeepsakeProgress::-webkit-progress-value {
  background: #d7b578;
}

body[data-world-mode="listen"] progress#voiceKeepsakeProgress::-moz-progress-bar {
  background: #d7b578;
}

@keyframes voice-cloud-drift {
  from { transform: translate3d(-3%, 0, 0) scaleX(0.94); }
  to { transform: translate3d(11%, -5%, 0) scaleX(1.04); }
}

@keyframes voice-cloud-drift-reverse {
  from { transform: translate3d(8%, -3%, 0) scaleX(1.05); }
  to { transform: translate3d(-9%, 4%, 0) scaleX(0.93); }
}

@media (max-width: 720px) {
  .voice-world__moon {
    top: 10svh;
    right: 10vw;
    width: clamp(3.5rem, 19vw, 5.4rem);
  }

  .voice-world__mountains {
    left: -19%;
    width: 88%;
    height: 49%;
  }

  .voice-world__skyline {
    right: -14%;
    bottom: 10%;
    width: 67%;
    height: 34%;
  }

  .voice-world__route {
    inset: 28% -8% auto;
    width: 116%;
    height: 40%;
  }

  .voice-world__places {
    inset-inline: 1.15rem;
    bottom: 6.3rem;
  }

  .voice-world__place {
    max-width: 7.5rem;
    font-size: 0.56rem;
    letter-spacing: 0.08em;
  }

  .voice-world__place b {
    font-size: 0.95rem;
  }

  .voice-world__caption {
    bottom: 2.3rem;
    gap: 0.65rem;
    font-size: 0.57rem;
    letter-spacing: 0.08em;
  }

  .voice-world__control {
    top: max(0.8rem, env(safe-area-inset-top));
    min-height: 2.55rem;
    font-size: 0.59rem;
  }

  body[data-world-mode="listen"] .voice-keepsake {
    width: calc(100% - 0.25rem);
    background: linear-gradient(180deg, transparent, rgb(7 14 18 / 0.32), transparent);
  }
}

.voice-world--lite .voice-world__cloud,
.voice-world--lite .voice-world__star {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .voice-world,
  .voice-world *,
  body[data-world-mode="listen"] .voice-keepsake,
  body[data-world-mode="listen"] .voice-keepsake * {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }

  .voice-world__route-line {
    stroke-dashoffset: 0;
    opacity: calc(0.24 + var(--voice-progress) * 0.7);
  }
}

@media (forced-colors: active) {
  .voice-world {
    display: none;
  }

  body[data-world-mode="listen"] :is(
    .site-chrome,
    .chapter-nav,
    .chapter-scroll-seal,
    .section-heading--letter
  ) {
    opacity: 1 !important;
    visibility: visible;
  }

  body[data-world-mode="listen"] .letter__shell > :not(.voice-keepsake) {
    opacity: 1;
    filter: none;
  }

  body[data-world-mode="listen"] .voice-keepsake {
    color: CanvasText;
    border: 1px solid CanvasText;
    background: Canvas;
    box-shadow: none;
  }

  body[data-world-mode="listen"] :is(.voice-keepsake__toggle, #voiceKeepsakeToggle) {
    color: ButtonText;
    border: 1px solid ButtonText;
    background: ButtonFace;
    box-shadow: none;
  }
}
