/* ============================================================
   animations.css — keyframes, scroll-driven, reveal patterns
   ============================================================ */

/* ─── Reveal pattern (eyebrow → headline) ───
   Content is visible by default. The opacity-0 hidden state is gated on the
   `.js` class on <html> — added synchronously by js/main.js BEFORE any element
   paints — so a fresh page navigation never flashes a blank black viewport
   waiting for the IntersectionObserver. Users with JS disabled see everything
   immediately too. */
.reveal {
  transition:
    opacity var(--dur-slow) var(--ease-out-quart),
    transform var(--dur-slow) var(--ease-out-quart);
  transition-delay: calc(var(--reveal-delay, 0) * 1ms);
}
.js .reveal:not(.is-in) {
  opacity: 0;
  transform: translateY(20px);
}
.reveal.is-in {
  opacity: 1;
  transform: translateY(0);
}

/* Eyebrow + headline sibling pair: eyebrow first (50ms), headline next (200ms) */
.reveal-pair > .eyebrow         { --reveal-delay: 50; }
.reveal-pair > .section__heading { --reveal-delay: 200; }
.reveal-pair > .section__body    { --reveal-delay: 350; }

/* ─── Letter-spaced display (line-by-line stagger) ───
   Same `.js` gating as .reveal — visible by default, only hidden once JS runs. */
.stagger-lines > * {
  transition:
    opacity var(--dur-base) var(--ease-out-quart),
    transform var(--dur-base) var(--ease-out-quart);
}
.js .stagger-lines:not(.is-in) > * {
  opacity: 0;
  transform: translateY(12px);
}
.stagger-lines.is-in > *:nth-child(1) { transition-delay: 0ms; }
.stagger-lines.is-in > *:nth-child(2) { transition-delay: var(--stagger-line); }
.stagger-lines.is-in > *:nth-child(3) { transition-delay: calc(var(--stagger-line) * 2); }
.stagger-lines.is-in > *:nth-child(4) { transition-delay: calc(var(--stagger-line) * 3); }
.stagger-lines.is-in > * {
  opacity: 1;
  transform: translateY(0);
}

/* ─── Stars row (sequentially fill from 0) ───
   Stars are decorative — visible by default; JS dims pre-reveal and pops them in. */
.stars-row svg {
  transition:
    opacity var(--dur-base) var(--ease-out-quart),
    transform var(--dur-base) var(--ease-spring);
}
.js .stars-row:not(.is-in) svg {
  opacity: 0.25;
  transform: scale(0.85);
}
.stars-row.is-in svg { opacity: 1; transform: scale(1); }
.stars-row.is-in svg:nth-child(1) { transition-delay: 0ms; }
.stars-row.is-in svg:nth-child(2) { transition-delay: 80ms; }
.stars-row.is-in svg:nth-child(3) { transition-delay: 160ms; }
.stars-row.is-in svg:nth-child(4) { transition-delay: 240ms; }
.stars-row.is-in svg:nth-child(5) { transition-delay: 320ms; }

/* ─── Card stagger (room cards) ───
   Cards are visible by default; JS hides + reveals when their parent enters view. */
.cards-stagger > * {
  transition:
    opacity var(--dur-slow) var(--ease-out-quart),
    transform var(--dur-slow) var(--ease-out-quart);
}
.js .cards-stagger:not(.is-in) > * {
  opacity: 0;
  transform: translateY(24px);
}
.cards-stagger.is-in > *:nth-child(1) { transition-delay: 0ms; }
.cards-stagger.is-in > *:nth-child(2) { transition-delay: var(--stagger-card); }
.cards-stagger.is-in > *:nth-child(3) { transition-delay: calc(var(--stagger-card) * 2); }
.cards-stagger.is-in > * {
  opacity: 1;
  transform: translateY(0);
}

/* The homepage room section becomes a sticky horizontal slide on tablet/phone.
   Keep each card's internal layers stable while the rail itself is transformed;
   otherwise Safari can briefly re-apply reveal compositing and hide text/gradient. */
@media (max-width: 1279px) {
  .rooms-pin .cards-stagger > *,
  .rooms-pin .room-card {
    opacity: 1 !important;
    transform: translateZ(0) !important;
    transition: none !important;
  }

  .rooms-pin .stars-row svg {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ─── Crossfade headline (eyebrow text → big headline) ─── */
.crossfade {
  position: relative;
  display: inline-block;
  min-height: 1em;
}
.crossfade > .crossfade__from,
.crossfade > .crossfade__to {
  position: absolute; inset: 0;
  transition: opacity var(--dur-slow) var(--ease-out-quart);
}
.crossfade > .crossfade__from { opacity: 1; }
.crossfade > .crossfade__to   { opacity: 0; }
.crossfade.is-flipped > .crossfade__from { opacity: 0; }
.crossfade.is-flipped > .crossfade__to   { opacity: 1; }

/* ─── Reduced motion respect ─── */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .stagger-lines > *,
  .stars-row svg,
  .cards-stagger > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
