/* Motion is progressive enhancement: without the .js class, content remains visible. */
.js .reveal {
  opacity: 0;
  transform: translateY(30px);
  filter: blur(3px);
  transition:
    opacity 1s var(--ease-out),
    transform 1.15s var(--ease-out),
    filter 1.05s ease;
}
.js .reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

.js .story-frame.reveal { transform: translateY(42px) scale(.985); }
.js .story-frame.reveal.is-visible { transform: translateY(0) scale(1); }
.js .story-word.reveal { transform: translateY(32px) skewY(.5deg); }
.js .story-word.reveal.is-visible { transform: translateY(0) skewY(0); }
.js .poem-line.reveal { transform: translateY(26px) scale(.985); }
.js .poem-line.reveal.is-visible { transform: translateY(0) scale(1); }

.page-intro {
  animation: intro-curtain 2.65s var(--ease-inout) .2s forwards;
}
.intro-mark { animation: intro-mark 1.65s var(--ease-out) .18s both; }
.intro-mark i { animation: intro-heartbeat 1.25s ease-in-out .45s 2; }
.intro-line--top { animation: intro-line-top 1.2s var(--ease-out) .1s both; }
.intro-line--bottom { animation: intro-line-bottom 1.2s var(--ease-out) .1s both; }

.hero-backdrop {
  animation: hero-backdrop-breathe 18s ease-in-out infinite alternate;
}
.hero-media img {
  transform-origin: 50% 50%;
  animation: hero-photo-breathe 16s ease-in-out 2.2s infinite alternate;
}
.hero h1 span:first-child { animation: hero-name-left 1.25s var(--ease-out) 2.05s both; }
.hero h1 span:last-child { animation: hero-name-right 1.25s var(--ease-out) 2.15s both; }
.hero h1 i { animation: hero-ampersand 1.5s var(--ease-out) 2.25s both; }
.hero-orbit { animation: orbit-turn 34s linear infinite; }
.hero-orbit::before { animation: orbit-counter 25s linear infinite; }
.hero-orbit::after { animation: orbit-counter 41s linear infinite reverse; }
.scroll-cue b { animation: cue-drift 1.8s ease-in-out infinite; }

.story-photo-shell::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.24) 48%, transparent 64%);
  transform: translateX(-130%);
  opacity: 0;
}
.story-frame.is-visible .story-photo-shell::after {
  animation: photo-glint 1.35s var(--ease-out) .45s both;
}
.story-only i { animation: soft-heartbeat 2.4s ease-in-out infinite; }
.chapter-transition span { animation: transition-twinkle 2.8s ease-in-out infinite; }
.poem-glow--one { animation: glow-drift-one 12s ease-in-out infinite alternate; }
.poem-glow--two { animation: glow-drift-two 15s ease-in-out infinite alternate; }
.poem-kicker > span { animation: transition-twinkle 2.4s ease-in-out infinite; }
.finale-rings span:nth-child(1) { animation: ring-breathe 6s ease-in-out infinite; }
.finale-rings span:nth-child(2) { animation: ring-breathe 6s ease-in-out .9s infinite; }
.finale-rings span:nth-child(3) { animation: ring-breathe 6s ease-in-out 1.8s infinite; }
.final-trigger span { animation: soft-heartbeat 2.4s ease-in-out infinite; }

.ambient-spark {
  position: absolute;
  left: var(--left, 50%);
  top: 105%;
  width: var(--size, 4px);
  height: var(--size, 4px);
  border-radius: 50%;
  color: var(--spark-color, rgba(201,170,114,.8));
  background: currentColor;
  box-shadow: 0 0 16px currentColor;
  opacity: 0;
  animation: ambient-rise var(--duration, 10s) linear var(--delay, 0s) infinite;
}
.ambient-spark--heart {
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
  box-shadow: none;
  font-size: var(--heart-size, .7rem);
  line-height: 1;
  color: rgba(207,161,170,.62);
}

.scroll-progress span { transition: width .08s linear; }

.lightbox { animation: lightbox-in .34s ease both; }
.lightbox-stage { animation: lightbox-stage-in .58s var(--ease-out) both; }
.lightbox-image.is-changing { animation: lightbox-swap .45s var(--ease-out) both; }

.final-message {
  opacity: 0;
  transform: translateY(12px) scale(.985);
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
}
.final-message.is-visible { opacity: 1; transform: translateY(0) scale(1); }
.final-trigger.is-celebrated span { animation: celebrated-heart .9s var(--ease-out) both; }

.particle {
  position: absolute;
  left: 50%; top: 50%;
  width: var(--size, 6px);
  height: var(--size, 6px);
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 18px currentColor;
  opacity: 0;
  pointer-events: none;
  animation: particle-rise var(--duration, 2.8s) var(--ease-out) forwards;
}
.particle--heart {
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
  box-shadow: none;
  font-size: var(--size, 12px);
  line-height: 1;
}

@keyframes intro-curtain {
  0%, 67% { opacity: 1; transform: translateY(0); }
  82% { opacity: 1; }
  100% { opacity: 0; visibility: hidden; transform: translateY(-100%); }
}
@keyframes intro-mark {
  from { opacity: 0; transform: translateY(18px) scale(.96); letter-spacing: .04em; }
  to { opacity: 1; transform: translateY(0) scale(1); letter-spacing: -.055em; }
}
@keyframes intro-heartbeat {
  0%,100% { transform: scale(1); }
  45% { transform: scale(1.16); }
}
@keyframes intro-line-top { from { transform: scaleY(0); transform-origin: bottom; } to { transform: scaleY(1); transform-origin: bottom; } }
@keyframes intro-line-bottom { from { transform: scaleY(0); transform-origin: top; } to { transform: scaleY(1); transform-origin: top; } }
@keyframes hero-backdrop-breathe { from { transform: scale(1.08); } to { transform: scale(1.14) translate3d(-.8%, -.5%, 0); } }
@keyframes hero-photo-breathe { from { transform: scale(1); } to { transform: scale(1.018); } }
@keyframes hero-name-left { from { opacity: 0; transform: translateX(-24px); filter: blur(5px); } to { opacity: 1; transform: translateX(0); filter: blur(0); } }
@keyframes hero-name-right { from { opacity: 0; transform: translateX(24px); filter: blur(5px); } to { opacity: 1; transform: translateX(0); filter: blur(0); } }
@keyframes hero-ampersand { 0% { opacity: 0; transform: scale(.7) rotate(-12deg); } 70% { opacity: 1; transform: scale(1.12) rotate(3deg); } 100% { opacity: 1; transform: scale(1) rotate(0); } }
@keyframes orbit-turn { to { transform: rotate(360deg); } }
@keyframes orbit-counter { to { transform: rotate(-360deg); } }
@keyframes cue-drift { 0%,100% { transform: translateY(0); opacity: .62; } 50% { transform: translateY(6px); opacity: 1; } }
@keyframes photo-glint { 0% { opacity: 0; transform: translateX(-130%); } 25% { opacity: .8; } 100% { opacity: 0; transform: translateX(130%); } }
@keyframes transition-twinkle { 0%,100% { opacity: .55; transform: scale(.85) rotate(0); } 50% { opacity: 1; transform: scale(1.12) rotate(18deg); } }
@keyframes soft-heartbeat { 0%,100% { transform: scale(1); } 45% { transform: scale(1.14); } 60% { transform: scale(1.04); } }
@keyframes glow-drift-one { from { transform: translate3d(0,0,0) scale(1); } to { transform: translate3d(9%,6%,0) scale(1.12); } }
@keyframes glow-drift-two { from { transform: translate3d(0,0,0) scale(1.08); } to { transform: translate3d(-8%,-5%,0) scale(.96); } }
@keyframes ring-breathe { 0%,100% { transform: scale(.96); opacity: .35; } 50% { transform: scale(1.045); opacity: 1; } }
@keyframes ambient-rise {
  0% { opacity: 0; transform: translate3d(0,0,0) scale(.65) rotate(0deg); }
  12% { opacity: .45; }
  72% { opacity: .32; }
  100% { opacity: 0; transform: translate3d(var(--drift, 35px), -120vh, 0) scale(1.1) rotate(120deg); }
}
@keyframes lightbox-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes lightbox-stage-in { from { opacity: 0; transform: translateY(18px) scale(.985); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes lightbox-swap { 0% { opacity: .25; transform: scale(.99); filter: blur(2px); } 100% { opacity: 1; transform: scale(1); filter: blur(0); } }
@keyframes celebrated-heart { 0% { transform: scale(1); } 45% { transform: scale(1.5) rotate(8deg); } 100% { transform: scale(1.08) rotate(0); } }
@keyframes particle-rise {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.35) rotate(0); }
  18% { opacity: .85; }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--x, 0px)), calc(-50% + var(--y, -120px))) scale(1.2) rotate(var(--spin, 90deg));
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }

  .page-intro { display: none !important; }
  .ambient-spark { display: none !important; }
  .js .reveal,
  .js .story-frame.reveal,
  .js .story-word.reveal,
  .js .poem-line.reveal,
  .js .reveal.is-visible,
  .js .story-frame.reveal.is-visible,
  .js .story-word.reveal.is-visible,
  .js .poem-line.reveal.is-visible,
  .final-message,
  .final-message.is-visible,
  .memory-card__button,
  .memory-card__button:hover,
  .hero-media img,
  .hero-backdrop,
  .hero h1 span,
  .hero h1 i,
  .hero-orbit,
  .scroll-cue b {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }

  .particle { display: none !important; }
}
