/* Scroll reveal animations — robust, fail-safe.
   The hidden initial state ONLY applies when JS is active (html.js, set synchronously
   in <head>). With JS disabled or broken, content stays fully visible.
   The .reveal-all failsafe (set on a timer in <head>) force-shows everything in case
   the IntersectionObserver never fires. */
@media (prefers-reduced-motion: no-preference) {
  html.js [data-reveal] {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 500ms ease, transform 500ms ease;
  }
  html.js [data-reveal="left"]  { transform: translateX(-20px); }
  html.js [data-reveal="right"] { transform: translateX(20px); }
  html.js [data-reveal].revealed {
    opacity: 1;
    transform: translate(0);
  }
  html.js [data-reveal-delay="1"] { transition-delay: 100ms; }
  html.js [data-reveal-delay="2"] { transition-delay: 200ms; }
  html.js [data-reveal-delay="3"] { transition-delay: 300ms; }
  html.js [data-reveal-delay="4"] { transition-delay: 400ms; }
}

/* Failsafe: if reveal never fires, show everything. */
html.reveal-all [data-reveal] {
  opacity: 1 !important;
  transform: none !important;
}
