/* Site-wide scroll-reveal + parallax system. Additive only -- elements
   without .reveal/.parallax-img classes are completely unaffected. Respects
   prefers-reduced-motion throughout. */

.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--reveal-index, 0) * 80ms);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.reveal--left { transform: translateX(-32px); }
.reveal--left.is-visible { transform: translateX(0); }

.reveal--right { transform: translateX(32px); }
.reveal--right.is-visible { transform: translateX(0); }

.reveal--scale { transform: scale(0.95); }
.reveal--scale.is-visible { transform: scale(1); }

.reveal--fade { transform: none; }
.reveal--fade.is-visible { transform: none; }

/* Parallax image containers: wrap an existing img/card so it drifts gently
   on scroll. overflow:hidden is enforced here (not left to each container's
   own CSS) so the scaled/translated image never bleeds past its box.
   Deliberately NOT forcing position:relative here -- several containers
   this is applied to (e.g. .platform-card) already rely on their own
   position:absolute for layout, and this class must never fight that. */
.parallax-img {
  overflow: hidden;
}
.parallax-img img {
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal--left, .reveal--right, .reveal--scale, .reveal--fade {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .parallax-img img {
    transform: none !important;
  }
}
