/* ============================================================
   animations.css — Scroll reveal system
   Rule: content is ALWAYS visible. Animation enhances only.
   Safety: 3s fallback forces visibility if JS is slow/missing.
   ============================================================ */

.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity  0.7s calc(var(--reveal-delay, 0s)) ease,
    transform 0.7s calc(var(--reveal-delay, 0s)) ease;
}

/* JS adds .visible via IntersectionObserver */
.reveal.visible {
  opacity: 1;
  transform: translateY(0);
}

/* Safety net: if JS is blocked or slow, show everything after 3s */
@keyframes forceVisible {
  to { opacity: 1; transform: translateY(0); }
}
.reveal {
  animation: forceVisible 0.001ms 3s forwards;
}
.reveal.visible {
  animation: none;
}

/* No-JS: <noscript> in index.html sets opacity:1 directly */

/* Prefers-reduced-motion: skip entirely */
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal.visible {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }
}
