/*
 * Every layer has an explicit tile width: browsers disagree on the width of an SVG without
 * its own size, so the bridge looked twice as busy in Firefox.
 *
 * The demo episode, below the horizon: mountains, city, overhead line poles, the bridge, the
 * river and the train. stage.js moves them from the episode time (--far, --city, --poles,
 * --rail, --train), so a pause freezes the picture and a seek makes it jump in both windows.
 */
.layer {
  left: 0;
  right: 0;
  background-repeat: repeat-x;
  background-size: auto 100%;
}

.far {
  bottom: 20%;
  height: 40%;
  background-size: 110cqw 100%;
  background-position-x: var(--far, 0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 100' preserveAspectRatio='none'%3E%3Cpath d='M0 100V62l38-24 34 18 52-36 44 30 40-20 48 34 46-30 52 26 46-14v104z' fill='%23361849'/%3E%3C/svg%3E");
}

.city {
  bottom: 13%;
  height: 34%;
  background-size: 58cqw 100%;
  background-position-x: var(--city, 0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 100' preserveAspectRatio='none'%3E%3Cg fill='%231a0e26'%3E%3Crect x='4' y='40' width='26' height='60'/%3E%3Crect x='34' y='18' width='22' height='82'/%3E%3Crect x='60' y='52' width='30' height='48'/%3E%3Crect x='96' y='30' width='18' height='70'/%3E%3Crect x='118' y='60' width='34' height='40'/%3E%3Crect x='158' y='8' width='20' height='92'/%3E%3Crect x='182' y='44' width='28' height='56'/%3E%3Crect x='214' y='26' width='24' height='74'/%3E%3Crect x='244' y='56' width='30' height='44'/%3E%3Crect x='278' y='36' width='20' height='64'/%3E%3C/g%3E%3Cg fill='%23ffc66b'%3E%3Crect x='40' y='28' width='4' height='5'/%3E%3Crect x='48' y='44' width='4' height='5'/%3E%3Crect x='10' y='52' width='4' height='5'/%3E%3Crect x='164' y='20' width='4' height='5'/%3E%3Crect x='170' y='40' width='4' height='5'/%3E%3Crect x='220' y='36' width='4' height='5'/%3E%3Crect x='228' y='58' width='4' height='5'/%3E%3Crect x='102' y='42' width='4' height='5'/%3E%3Crect x='284' y='48' width='4' height='5'/%3E%3C/g%3E%3C/svg%3E");
}

.city-lights {
  bottom: 13%;
  height: 34%;
  background-size: 58cqw 100%;
  background-position-x: var(--city, 0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 100' preserveAspectRatio='none'%3E%3Cg fill='%23ffd88f'%3E%3Crect x='24' y='60' width='4' height='5'/%3E%3Crect x='70' y='70' width='4' height='5'/%3E%3Crect x='136' y='72' width='4' height='5'/%3E%3Crect x='192' y='62' width='4' height='5'/%3E%3Crect x='250' y='74' width='4' height='5'/%3E%3C/g%3E%3C/svg%3E");
  animation: flicker 5s steps(1) infinite;
}

.rail {
  bottom: 0;
  height: 22%;
  background-size: 40cqw 100%;
  background-position-x: var(--rail, 0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 40' preserveAspectRatio='none'%3E%3Cg fill='%230c0714'%3E%3Crect y='6' width='120' height='7'/%3E%3Crect x='14' y='12' width='9' height='28'/%3E%3Crect x='74' y='12' width='9' height='28'/%3E%3C/g%3E%3Crect y='5' width='120' height='1.5' fill='%23ff3b5c' opacity='.55'/%3E%3C/svg%3E");
}

/* Overhead line poles close to the camera: the fastest layer, it sells the speed. */
.poles {
  top: 30%;
  bottom: 20%;
  left: 0;
  right: 0;
  background-repeat: repeat-x;
  background-size: 64cqw 100%;
  background-position-x: var(--poles, 0);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 100' preserveAspectRatio='none'%3E%3Cg fill='%2308050f'%3E%3Crect x='0' width='8' height='100'/%3E%3Crect x='0' y='6' width='46' height='3'/%3E%3C/g%3E%3C/svg%3E");
}

.wire {
  top: calc(30% + 0.35cqw);
  left: 0;
  right: 0;
  height: 1px;
  background: rgba(8, 5, 15, 0.85);
}

/* Under the bridge the river: ripples drift with the episode, the moon shimmers in it. */
.water {
  left: 0;
  right: 0;
  bottom: 0;
  height: 17%;
  background:
    repeating-linear-gradient(90deg, transparent 0 6cqw, rgba(255, 200, 220, 0.16) 6cqw 9cqw) var(--rail, 0) 30% / 18cqw 1px repeat-x,
    repeating-linear-gradient(90deg, transparent 0 4cqw, rgba(255, 200, 220, 0.1) 4cqw 6cqw) var(--city, 0) 70% / 13cqw 1px repeat-x,
    linear-gradient(180deg, #431434, #120a1e);
}

.reflection {
  bottom: 0;
  right: 17%;
  width: 7cqw;
  height: 15%;
  background: repeating-linear-gradient(180deg, rgba(255, 225, 238, 0.5) 0 0.3cqw, transparent 0.3cqw 1cqw);
  mask-image: linear-gradient(90deg, transparent, #000 30%, #000 70%, transparent), linear-gradient(180deg, #000, transparent);
  mask-composite: intersect;
  animation: shimmer 1.4s ease-in-out infinite alternate;
}

/* The train runs on the bridge deck, its headlight lighting the way ahead. */
.train {
  bottom: calc(22% - 0.25cqw);
  left: 0;
  display: flex;
  align-items: flex-end;
  gap: 0.4cqw;
  height: 5.4cqw;
  transform: translateX(calc(var(--train, 0) * 190cqw - 90cqw));
}

.car {
  width: 19cqw;
  height: 100%;
  border-radius: 1cqw 1cqw 0.3cqw 0.3cqw;
  background:
    linear-gradient(#ff3b5c, #ff3b5c) 0 84% / 100% 0.35cqw no-repeat,
    repeating-linear-gradient(90deg, transparent 0 1.2cqw, #ffd68a 1.2cqw 3.1cqw, transparent 3.1cqw 3.6cqw) 0 30% / 100% 32% no-repeat,
    linear-gradient(180deg, #2a1636, #130a1c);
  box-shadow: 0 0 2.5cqw rgba(255, 190, 110, 0.22), inset 0 -0.7cqw 0 #0a0510;
}

.car:nth-child(3) {
  border-top-right-radius: 4.5cqw 75%;
  border-bottom-right-radius: 0.3cqw 20%;
}

.beam {
  position: relative;
  width: 24cqw;
  height: 140%;
  margin-left: -0.6cqw;
  background: linear-gradient(90deg, rgba(255, 232, 190, 0.45), transparent);
  clip-path: polygon(0 62%, 100% 20%, 100% 100%, 0 78%);
}

/* Cherry petals drift down on their own clock, and stop when the episode pauses. */
.petal {
  top: -6%;
  width: 1.6cqw;
  height: 1cqw;
  border-radius: 100% 0;
  background: #ff9fb6;
  opacity: 0.85;
  animation: petal 7s linear infinite;
}

.p1 { left: 18%; }
.p2 { left: 42%; animation-duration: 9s; animation-delay: -3s; }
.p3 { left: 66%; animation-duration: 8s; animation-delay: -5s; }
.p4 { left: 86%; animation-duration: 10s; animation-delay: -1.5s; }

.paused-mark {
  inset: 0;
  margin: auto;
  width: 8cqw;
  height: 9cqw;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.2s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.paused-mark::before,
.paused-mark::after {
  content: '';
  position: absolute;
  top: 0;
  width: 34%;
  height: 100%;
  border-radius: 0.8cqw;
  background: #fff;
  box-shadow: 0 0 3cqw rgba(0, 0, 0, 0.4);
}

.paused-mark::before { left: 0; }
.paused-mark::after { right: 0; }

.window.is-paused .paused-mark {
  opacity: 0.94;
  transform: none;
}

.window.is-paused .scene {
  filter: brightness(0.8) saturate(0.85);
}

/* A seek is a cut: a quick flash makes the jump read in both windows. */
.window.is-jumping .scene {
  filter: brightness(1.45) blur(1.5px);
  transition: none;
}

.window.is-paused .stars,
.window.is-paused .shooting,
.window.is-paused .reflection,
.window.is-paused .city-lights,
.window.is-paused .petal {
  animation-play-state: paused;
}

@keyframes flicker {
  0%, 18%, 41%, 77% { opacity: 1; }
  12%, 35%, 63% { opacity: 0.15; }
}

@keyframes shimmer {
  from { opacity: 0.55; transform: scaleX(0.85); }
  to { opacity: 1; transform: scaleX(1.1); }
}

@keyframes petal {
  from { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(-4cqw, 32cqw) rotate(200deg); }
  to { transform: translate(2cqw, 62cqw) rotate(380deg); }
}

@media (prefers-reduced-motion: reduce) {
  .city-lights,
  .reflection,
  .petal {
    animation: none;
  }

  .petal {
    display: none;
  }

  .window.is-jumping .scene {
    filter: none;
  }
}
