/* motion.css — Pearl Construction motion layer.
   Character: stately heritage (MOTION_INTENSITY 2). Slow crossfade-rise reveals
   on a gentle stagger; a gold/red struck line draws in under headings; the hero
   photo never moves. Nothing bounces.

   Contract:
   - Every hidden/offset state is scoped under html.has-motion, so with JS off or
     under reduced motion the site is fully static and visible.
   - Animates ONLY opacity + the individual `translate`/`scale` properties, never
     `transform` — that leaves main.css's component hover/active transforms
     (card lift, button press, area-list nudge) completely free, so a revealed
     element's hover stays crisp and never inherits the slow reveal easing.
   - No layout shift; durations/easings/distances come from main.css --motion-* tokens.
   - Reveals fire once (the .is-revealed class is never removed).
   ------------------------------------------------------------------------- */

/* ---- Crossfade-rise reveal: the workhorse (single elements) ------------- */
/* The hero card/badge deliberately carry no data-reveal (they animate on load
   by class, below), so this rule needs no :not() exclusions — keeping the
   reveal rule below at higher specificity so .is-revealed always wins. */
html.has-motion [data-reveal] {
  opacity: 0;
  translate: 0 var(--motion-distance);
  transition:
    opacity var(--motion-duration-slow) var(--motion-ease),
    translate var(--motion-duration-slow) var(--motion-ease);
}
html.has-motion [data-reveal].is-revealed {
  opacity: 1;
  translate: 0 0;
}

/* ---- Staggered group reveal (direct children cascade in) --------------- */
html.has-motion [data-reveal-group] > * {
  opacity: 0;
  translate: 0 var(--motion-distance);
  transition:
    opacity var(--motion-duration-slow) var(--motion-ease),
    translate var(--motion-duration-slow) var(--motion-ease);
}
html.has-motion [data-reveal-group].is-revealed > * {
  opacity: 1;
  translate: 0 0;
}
/* Gentle 70ms cascade; total settle stays short. Capped past the 8th child. */
html.has-motion [data-reveal-group].is-revealed > *:nth-child(1)  { transition-delay: 0ms;   }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(2)  { transition-delay: 70ms;  }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(3)  { transition-delay: 140ms; }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(4)  { transition-delay: 210ms; }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(5)  { transition-delay: 280ms; }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(6)  { transition-delay: 350ms; }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(7)  { transition-delay: 420ms; }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(8)  { transition-delay: 490ms; }
html.has-motion [data-reveal-group].is-revealed > *:nth-child(n+9){ transition-delay: 560ms; }

/* ---- Struck-line draw-in (signature flourish) -------------------------- */
/* The 58px rule under section headings draws left-to-right when its heading
   comes into view. Subtle, no overshoot. ::after has no component hover, so
   transform is safe to drive here. */
html.has-motion .struck::after {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--motion-duration-base) var(--motion-ease);
}
html.has-motion .struck.is-revealed::after {
  transform: scaleX(1);
}

/* ---- Hero: photo never moves; card + badge settle once on load --------- */
/* The h1 lives in .hero__card and must read immediately: a short, zero-delay
   fade-up (base duration), not the slow scroll reveal. */
@keyframes pearl-hero-card {
  from { opacity: 0; translate: 0 var(--motion-distance); }
  to   { opacity: 1; translate: 0 0; }
}
html.has-motion .hero__card {
  animation: pearl-hero-card var(--motion-duration-base) var(--motion-ease) both;
}

/* ---- Hero video ---------------------------------------------------------- */
/* No CSS zoom here on purpose: the supplied clip already pulls back from a
   doorway close-up to the full elevation. Adding a scale on top double-zoomed
   the opening and cropped the first frame to an unreadable detail. The clip
   plays once (no loop attribute) so it rests on its final wide frame. */

/* ---- Reduced-motion safety net ----------------------------------------- */
/* The pre-paint script in each page's <head> already withholds has-motion under
   reduced motion; these rules are a belt-and-suspenders reset. */
@media (prefers-reduced-motion: reduce) {
  html.has-motion [data-reveal],
  html.has-motion [data-reveal-group] > *,
  html.has-motion .hero__card {
    opacity: 1 !important;
    translate: none !important;
    animation: none !important;
    transition: none !important;
  }
  html.has-motion .struck::after {
    transform: none !important;
  }
}
