/* ===== Goose FL scroll-reveal layer =====================================
   Promoted 23 Oct 2026 from the 20 Oct homepage trial.
   Values copied from the sentientinnovationlab.com Reveal component:
   opacity 0 -> 1, 22px rise, .9s, cubic-bezier(.16,1,.3,1), once only.
   The hidden state is gated on html.js, so a script failure, JS-off, print,
   or reduced motion always shows the content. reveal.js removes the
   attributes on animationend, so card hover transitions keep their own timing.
   Targets are marked in the HTML with data-rv / data-rv-d (stagger, ms).
   ===== */

html.js [data-rv] { opacity: 0; }
html.js [data-rv].rv-in {
  animation: rvUp .9s cubic-bezier(.16, 1, .3, 1) both;
  animation-delay: var(--rvd, 0ms);
}
/* Keyboard first: anything receiving focus is visible at once, even before the
   observer runs, and even mid-animation (!important outranks the animation). */
html.js [data-rv]:focus-within { opacity: 1 !important; }
@keyframes rvUp {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

/* Hero headline: masked line rise on load (homepage only; JS-gated by
   body[data-rv-hero]) */
.hero h1 .w { display: inline-block; }
html.js .hero h1 .ln { display: block; overflow: hidden; }
html.js .hero h1 .ln-i {
  display: block;
  transform: translateY(110%);
  transition: transform .95s cubic-bezier(.16, 1, .3, 1);
}
html.js.hero-in .hero h1 .ln-i { transform: none; }

@media (prefers-reduced-motion: reduce) {
  html.js [data-rv] { opacity: 1 !important; animation: none !important; }
  html.js .hero h1 .ln { overflow: visible; }
  html.js .hero h1 .ln-i { transform: none !important; transition: none !important; }
}
@media print {
  html.js [data-rv] { opacity: 1 !important; animation: none !important; }
  html.js .hero h1 .ln { overflow: visible; }
  html.js .hero h1 .ln-i { transform: none !important; transition: none !important; }
}
