/* Component: the voyage stage and its scenes (C9, docs/roadmap/C9-voyage-scenes-sound.md; src/ui/components/scene.js).
   The ship nested 1 : 1 in a wider stage, the quays behind her, the crane or the crew, the pile on the dock; a
   card's picture (the pirate boat, the storm's waves) and the sky (clouds, rain, the sun); the rival ships with
   their cargo tags; the caption under the status line, the 🗺️ view's strip (styles/screens/voyage.css places
   them) and the card's own strip.
   CSS keyframes only (no SVG <animate>, which no CSS rule stops), every one with `animation-fill-mode: both`:
   base.css's reduced-motion rules cut each one to 1 ms, so it shows its end state at once, and this sheet sets
   every scene delay to 0 there (base.css cuts durations, not delays). Neutral colors only, never red. */

.scene-stage {
  display: block;
  overflow: hidden;
}

/* The nested ship keeps her own size: the shared `.ship-art { max-width: 100%; height: auto }` would let Chrome
   size the inner <svg> to the stage's viewport. Her width and height are inline too (scene.js placeShip). */
.voyage-stage > .ship-art {
  max-width: none;
}

/* ── A day's sailing: the quay she leaves slides out to the left, the next stop's slides in to its berth ── */
.scene-stage.is-sailing .scene-quay > .scene-slide {
  animation: scene-slide var(--scene-day, 1200ms) linear both;
}

@keyframes scene-slide {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(var(--slide, -600px));
  }
}

/* ── Unloading: her boxes rise off the deck and go back toward the quay (crane, her own crane), or go down the
   plank (by hand); the pile lands as they arrive ── */
.voyage-stage .ship-slot.is-lifted {
  animation: scene-box-lift var(--scene-lift, 900ms) ease-in-out both;
}

.voyage-stage .ship-slot.is-carried {
  animation: scene-box-carry var(--scene-lift, 900ms) ease-in both;
}

@keyframes scene-box-lift {
  0% {
    transform: translate(0, 0);
    opacity: 1;
  }
  35% {
    transform: translate(0, -26px);
    opacity: 1;
  }
  85% {
    transform: translate(var(--lift-dx, -80px), -26px);
    opacity: 1;
  }
  100% {
    transform: translate(var(--lift-dx, -80px), -12px);
    opacity: 0;
  }
}

@keyframes scene-box-carry {
  0% {
    transform: translate(0, 0);
    opacity: 1;
  }
  100% {
    transform: translate(var(--lift-dx, -80px), 34px);
    opacity: 0;
  }
}

.scene-pile.is-landing {
  animation: scene-pile-land var(--scene-land, 300ms) ease-out var(--scene-lift, 900ms) both;
}

@keyframes scene-pile-land {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* The harbor crane's hook dips to her stacks and rises while it lifts (once, not a loop). */
.scene-crane.is-lifting .scene-crane__hook {
  animation: scene-hook-dip var(--scene-lift, 900ms) ease-in-out both;
}

@keyframes scene-hook-dip {
  0%,
  100% {
    transform: translateY(0);
  }
  30% {
    transform: translateY(12px);
  }
}

.scene-pile__emoji {
  font-family: var(--font);
}

/* ── The caption under the status line (no digits; at most 2 lines) ── */
.voyage-scene__caption {
  align-self: center;
  max-width: calc(100% - 2 * var(--sp-3));
  margin: 0 !important;
  color: var(--ink-soft);
  font-weight: 700;
  font-size: var(--fs-sm);
  line-height: 1.35;
  text-align: center;
}

.voyage-scene__line {
  display: block;
}

.voyage-scene__caption[hidden] {
  display: none;
}

/* ── The 🗺️ view's strip (≤ 48em, map view only; voyage.css shows it there) ── */
.voyage-scene-strip {
  display: none;
}

.voyage-scene-strip .scene-strip {
  width: 100%;
  height: 56px;
}

/* ── The pirate boat (§4.2): it comes in over the lead before its card, waits right behind her in the chase,
   and after the answer turns and falls behind, out of the picture (with boxes taken it first comes alongside).
   Its rest place is its transform attribute; these move its inner groups, in its own units. ── */
.scene-pirate__turn {
  transform-box: fill-box;
  transform-origin: center;
}

/* Coming: it waits off-stage behind her stern until the lead before the card (`is-coming`, voyage.js). */
.scene-pirate.is-entering .scene-pirate__move {
  transform: translateX(var(--pirate-off, -200px));
}

.scene-stage.is-coming .scene-pirate.is-entering .scene-pirate__move {
  animation: scene-pirate-in var(--scene-lead, 1200ms) ease-out both;
}

@keyframes scene-pirate-in {
  from {
    transform: translateX(var(--pirate-off, -200px));
  }
  to {
    transform: translateX(0);
  }
}

.scene-pirate.is-leaving .scene-pirate__move {
  animation: scene-pirate-away 1800ms ease-in-out both;
}

.scene-pirate.is-leaving .scene-pirate__turn {
  animation: scene-pirate-turn 1800ms ease-in-out both;
}

.scene-pirate.is-leaving.is-lost .scene-pirate__move {
  animation-name: scene-pirate-away-lost;
}

.scene-pirate.is-leaving.is-lost .scene-pirate__turn {
  animation-name: scene-pirate-turn-lost;
}

@keyframes scene-pirate-away {
  0%,
  25% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(var(--pirate-off, -200px));
  }
}

@keyframes scene-pirate-turn {
  0%,
  12% {
    transform: scaleX(1);
  }
  28%,
  100% {
    transform: scaleX(-1);
  }
}

@keyframes scene-pirate-away-lost {
  0% {
    transform: translateX(0);
  }
  30%,
  48% {
    transform: translateX(var(--pirate-near, 18px));
  }
  100% {
    transform: translateX(var(--pirate-off, -200px));
  }
}

@keyframes scene-pirate-turn-lost {
  0%,
  44% {
    transform: scaleX(1);
  }
  58%,
  100% {
    transform: scaleX(-1);
  }
}

/* ── The sky (§4.3): soft clouds drifting over stormy water; dark clouds and slow rain in a storm; then the
   clouds move on and the sun comes out. No lightning, no flashing; the rain's loop stops under reduced motion
   (base.css: one 1 ms pass, held). ── */
.scene-sky.is-clouds .scene-cloud,
.scene-sky.is-storm .scene-cloud {
  animation: scene-cloud-drift 9s ease-in-out infinite alternate both;
}

.scene-sky .scene-cloud:nth-of-type(even) {
  animation-duration: 11s;
  animation-direction: alternate-reverse;
}

@keyframes scene-cloud-drift {
  from {
    transform: translateX(-4px);
  }
  to {
    transform: translateX(6px);
  }
}

.scene-rain {
  animation: scene-rain-fall 1200ms linear infinite both;
}

@keyframes scene-rain-fall {
  from {
    transform: translate(0, 0);
  }
  to {
    transform: translate(var(--rain-dx, -6px), var(--rain-dy, 20px));
  }
}

.scene-sky.is-clearing.is-moving .scene-cloud {
  animation: scene-cloud-off 2400ms ease-in both;
}

@keyframes scene-cloud-off {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(90px);
    opacity: 0;
  }
}

.scene-sun.is-rising {
  animation: scene-sun-in 1600ms ease-out 600ms both;
}

@keyframes scene-sun-in {
  from {
    transform: translateY(6px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* The storm card's big waves at her waterline roll gently (no loop under reduced motion). */
.scene-waves {
  animation: scene-waves-roll 2600ms ease-in-out infinite alternate both;
}

@keyframes scene-waves-roll {
  from {
    transform: translate(-6px, 0);
  }
  to {
    transform: translate(6px, -2px);
  }
}

.scene-cloud__swirl,
.scene-pirate__flag {
  font-family: var(--font);
}

/* The deck view's own sky darkens under clouds and in a storm, and turns sunny as it clears (CSS only). */
.voyage-ship.is-clouds {
  background: linear-gradient(180deg, #e2e8ed 0%, var(--sea-100) 100%);
}

.voyage-ship.is-storm {
  background: linear-gradient(180deg, #c2cbd4 0%, #c9dce6 100%);
}

.voyage-ship.is-clearing {
  background: linear-gradient(180deg, var(--sand-50) 0%, var(--sea-100) 100%);
}

/* ── The card's own strip, under its title (§4.5): the card's picture, no digits ── */
.event-card__scene {
  /* The box frames the picture exactly (its 300 : 80), so the sea, the rain and a stormy tint reach its edges. */
  width: fit-content;
  margin-inline: auto;
  border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--sea-50) 0%, var(--sea-100) 100%);
  overflow: hidden;
}

.event-card__scene .scene-strip {
  display: block;
  width: 240px;
  height: 64px;
}

@media (max-width: 37.5em) {
  /* A phone: as short as the 🗺️ view's strip, so the answers stay close. */
  .event-card__scene .scene-strip {
    width: 210px;
    height: 56px;
  }
}

/* ── Rival ships (§4.4): a ship in sight on the horizon with her cargo's tag ("8 🌾", her map badge's words),
   a rival at the stop (moored at the quay, or coming in on the horizon). Painted moving she fades in; no loop. ── */
.scene-ship.is-arriving,
.scene-dock-ship.is-arriving {
  animation: scene-ship-in 900ms ease-out both;
}

@keyframes scene-ship-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.scene-ship__face,
.scene-ship__tag-text {
  font-family: var(--font);
}

.scene-ship__tag-text {
  font-weight: 700;
}

/* ── M3 (C4 × C9): the navy convoy (scene.js convoy): navy ships with her on the horizon while C4's convoy sails
   with her through its strait. Painted moving they fade in, as a ship in sight does (after a card that names the
   picture, they fade out); no loop. ── */
.scene-navy.is-arriving {
  animation: scene-ship-in 900ms ease-out both;
}

.scene-navy.is-leaving {
  animation: scene-navy-off 1800ms ease-in both;
}

@keyframes scene-navy-off {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.scene-navy__flag {
  font-family: var(--font);
}

/* ── Reduced motion (the OS setting, or Calm motion): every scene picture at its end state, at once ── */
@media (prefers-reduced-motion: reduce) {
  .scene-stage *,
  .voyage-stage .ship-slot {
    animation-delay: 0ms !important;
  }
}

html.reduce-motion .scene-stage *,
html.reduce-motion .voyage-stage .ship-slot {
  animation-delay: 0ms !important;
}
