/* Motion, added last (spec §9). Only transform, opacity and filter move.
   Frequency rules: nav links, the countdown and keyboard actions never animate. */

/* The hero video fades in over its poster (an opacity fade, kept under reduced motion,
   though reduced motion never loads the video anyway). */
.hero__video { transition: opacity 400ms ease; }

/* Dialog: in from 0.96 + fade (220ms), out faster (150ms). It stays centred. */
.dialog { transition: opacity 150ms ease, transform 150ms var(--ease-out), overlay 150ms allow-discrete, display 150ms allow-discrete; }
.dialog:not([open]) { opacity: 0; transform: scale(0.98); }
.dialog[open] { opacity: 1; transform: none; transition-duration: 220ms; }
@starting-style { .dialog[open] { opacity: 0; transform: scale(0.96); } }
.dialog::backdrop { transition: opacity 220ms ease, overlay 220ms allow-discrete, display 220ms allow-discrete; }
.dialog:not([open])::backdrop { opacity: 0; }
@starting-style { .dialog[open]::backdrop { opacity: 0; } }

/* Choice dot fills quickly. */
.choice__dot::after { transition: opacity 120ms ease, transform 120ms var(--ease-out); }

@media (prefers-reduced-motion: no-preference) {
  /* Hero text settles in once. */
  .hero__text > * { animation: rise 700ms var(--ease-out) both; }
  .hero__text > :nth-child(2) { animation-delay: 60ms; }
  .hero__text > :nth-child(3) { animation-delay: 120ms; }
  .hero__text > :nth-child(4) { animation-delay: 180ms; }
  .hero__text > :nth-child(5) { animation-delay: 240ms; }

  /* Press feedback: the interface heard you. */
  .btn, .choice { transition: transform var(--press) var(--ease-out); }
  .btn:active:not([disabled]), .choice:active { transform: scale(0.97); }

  /* Menu links stagger in; closing is instant. */
  .menu[open] .menu__links li { animation: rise 320ms var(--ease-out) both; }
  .menu[open] .menu__links li:nth-child(2) { animation-delay: 30ms; }
  .menu[open] .menu__links li:nth-child(3) { animation-delay: 60ms; }
  .menu[open] .menu__links li:nth-child(4) { animation-delay: 90ms; }
  .menu[open] .menu__links li:nth-child(5) { animation-delay: 120ms; }
  .menu[open] .menu__links li:nth-child(6) { animation-delay: 150ms; }
  .menu[open] .menu__links li:nth-child(7) { animation-delay: 180ms; }

  /* RSVP steps arrive with a slight blur so the swap reads as one change. */
  .step:not([hidden]) { animation: step-in 220ms var(--ease-out); }

  /* FAQ answer fades in on open. */
  .faq details[open] .faq__a { animation: fade 200ms ease; }
}

@media (prefers-reduced-motion: reduce) {
  .step:not([hidden]) { animation: fade 150ms ease; }
}

@keyframes rise { from { opacity: 0; transform: translateY(8px); } }
@keyframes step-in { from { opacity: 0; filter: blur(2px); } }
@keyframes fade { from { opacity: 0; } }

/* Petal shower (easter egg, spec §15). petals.js only adds it when motion is allowed. */
.petals { position: fixed; inset: 0; z-index: 70; overflow: hidden; pointer-events: none; }
.petal { position: absolute; top: -24px; left: var(--left); width: var(--size); height: calc(var(--size) * 0.72); border-radius: 80% 0 80% 0; background: var(--color); box-shadow: inset -1px -1px 0 rgb(0 0 0 / 0.06); animation: petal-fall var(--dur) linear var(--delay) both; }
@keyframes petal-fall {
  0% { transform: translate(0, 0) rotate(0deg); opacity: 0; }
  10%, 85% { opacity: 1; }
  100% { transform: translate(var(--drift), 110vh) rotate(var(--spin)); opacity: 0; }
}

/* The couple's two answers slide as they swap; under reduced motion rsvp.js never swaps them. */
@media (prefers-reduced-motion: no-preference) {
  .reply-row--runaway .choice { transition: transform var(--press) var(--ease-out), translate 260ms var(--ease-out); }
}
