/* ============================================================
   MOTION — three levels, nothing moves "just because".

   MICRO       (100–300ms)  link and button feedback. Lives in components.css.
   EDITORIAL   (400–1400ms) lettering written by hand, doodles drawn, photos
               revealed, the hero's stop-motion loop.
   SCROLL      the Journey only: route, dot and odometer follow your scroll
               (driven by js/journey.js).

   Everything here is an enhancement. Without JavaScript, or with
   "reduce motion" switched on, all content is simply visible.
   ============================================================ */

/* ---------- Day → night: the page background eases between tones ---------- */
body { transition: background-color var(--dur-tone) var(--ease-inout), color var(--dur-tone) var(--ease-inout); }

@media (prefers-reduced-motion: no-preference) {

  /* ---------- EDITORIAL: the hero photos play as stop-motion, one held at a time ----------
     Pure CSS. Each of the five photos is visible for one fifth of the loop. */
  .hero__frames img {
    animation: hero-frame calc(var(--hero-frame) * 5) step-end infinite;
    animation-delay: calc((var(--n) - 5) * var(--hero-frame));
  }

  /* ---------- EDITORIAL: marker lettering and doodles are written once, as they arrive ---------- */
  .js [data-draw] :is(.lettering, .doodle) path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }
  .js .rsvp__thanks:not(.is-in) .lettering path { stroke-dasharray: 1; stroke-dashoffset: 1; }
  .js [data-draw].is-in :is(.lettering, .doodle) path,
  .js .rsvp__thanks.is-in .lettering path {
    stroke-dashoffset: 0;
    /* every phrase takes about the same time to write, however long it is */
    transition: stroke-dashoffset 600ms var(--ease-inout) calc(var(--i, 0) / var(--n, 1) * 1000ms + 150ms);
  }

  /* ---------- EDITORIAL: image reveal masks (each image opens differently) ---------- */
  .js [data-reveal] picture { clip-path: inset(100% 0 0 0); }
  .js [data-reveal="left"] picture { clip-path: inset(0 100% 0 0); }
  .js [data-reveal="center"] picture { clip-path: inset(0 50% 0 50%); }
  .js [data-reveal].is-in picture {
    clip-path: inset(0);
    transition: clip-path var(--dur-slow) var(--ease-out);
  }

  /* ---------- EDITORIAL: the route mark draws itself once ---------- */
  .js [data-draw] .routemark__line {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }
  .js [data-draw].is-in .routemark__line {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset var(--dur-slow) var(--ease-inout) 200ms;
  }

  /* ---------- SCROLL NARRATIVE: Journey labels appear as you pass them ---------- */
  .journey.is-live .map__label[data-at] {
    opacity: 0;
    transition: opacity var(--dur-editorial) var(--ease-out);
  }
  .journey.is-live .map__label[data-at].is-passed { opacity: 1; }

  /* ---------- EDITORIAL: photos drift very slightly against the scroll ----------
     Pure CSS; browsers without scroll-driven animation simply keep the image still. */
  @supports (animation-timeline: view()) {
    .drift img {
      animation: drift linear both;
      animation-timeline: view();
      animation-range: cover;
    }
  }
}

@keyframes hero-frame {
  0%   { opacity: 1; }
  20%  { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes drift {
  from { transform: translate3d(0, -4%, 0); }
  to   { transform: translate3d(0, 4%, 0); }
}

/* ---------- Reduced motion: a complete, considered static version ---------- */
@media (prefers-reduced-motion: reduce) {
  /* The couple's animated doodles and hero photos are left out of this on purpose:
     they asked for them to move on every phone. Everything else still stops. */
  *:not(.doodle):not(.doodle *):not(.map__arrow):not(.map__arrow *):not(.map__route):not(.yr__a):not(.yr__b):not(.yr__burst):not(.yr__burst *):not(.hero__frames img):not(.day__frame),
  *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Hero stop-motion: the couple want it to play on every phone ----------
   Like the photo reel, this keeps playing even when "reduce motion" is on, because it is the
   first thing guests see and a stuck photo looked broken. It is a slow cross-fade of five photos,
   one every 1.2 s, with no sliding or zooming. */
.hero__frames img {
  animation-name: hero-frame !important;
  animation-duration: calc(var(--hero-frame) * 5) !important;
  animation-timing-function: step-end !important;
  animation-iteration-count: infinite !important;
  animation-delay: calc((var(--n) - 5) * var(--hero-frame)) !important;
}
