/* =============================================================
   Scroll-reveal v1
   Apply data-reveal to any element to fade+lift it into view as
   it enters the viewport. Mirrors the home page's reveal feel.

   Markup-authored: each section opts in via the attribute, no
   per-page JS config to drift out of sync.

   No-JS fallback: a <noscript> block in <head> overrides
   opacity/transform back to visible so JS-failed users see content.
   ============================================================= */

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition:
    opacity 700ms cubic-bezier(.2, .6, .1, 1),
    transform 700ms cubic-bezier(.2, .6, .1, 1);
  will-change: opacity, transform;
}

/* Reveal trigger — set by JS on intersect, AND by :focus-within so
   keyboard users tabbing into a not-yet-revealed block don't lose
   focus inside an opacity:0 element. */
[data-reveal].is-in,
[data-reveal]:focus-within {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* Mobile: gentler lift + faster timing so the cumulative reveal
   doesn't drag on a phone. */
@media (max-width: 720px) {
  [data-reveal] {
    transform: translate3d(0, 10px, 0);
    transition:
      opacity 500ms cubic-bezier(.2, .6, .1, 1),
      transform 500ms cubic-bezier(.2, .6, .1, 1);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
