/* ============================================================
   animation.css — Viewport-triggered entrance animations
   Matt The Carpet Guy — standalone animation library

   HOW TO USE
   ──────────
   1. Link this file in your page <head>:
        <link rel="stylesheet" href="/css/animation.css">

   2. Add two classes to any element you want to animate:
        class="animate fade-in"
        class="animate slide-in-left"
        class="animate slide-in-right"
        class="animate scale-in"

   3. Add the JS trigger snippet (see bottom of this file or
      copy animation-trigger.js). It uses IntersectionObserver
      to add `.is-visible` when the element enters the viewport,
      which fires the animation.

   OPTIONAL STAGGER
   ────────────────
   Chain .animate-delay-* classes to offset items in a group:
        <div class="animate fade-in animate-delay-100">…</div>
        <div class="animate fade-in animate-delay-200">…</div>
        <div class="animate fade-in animate-delay-300">…</div>
   ============================================================ */


/* ------------------------------------------------------------
   @keyframes definitions
   ------------------------------------------------------------ */

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(60px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-60px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.88);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}


/* ------------------------------------------------------------
   Base state
   Elements start hidden. JS adds .is-visible on viewport entry.
   ------------------------------------------------------------ */

.animate {
  opacity: 0;
  will-change: opacity, transform;
}

/* Shared animation settings applied when element becomes visible */
.animate.is-visible {
  animation-duration: 0.65s;
  animation-timing-function: cubic-bezier(0.22, 0.61, 0.36, 1);
  animation-fill-mode: both;
}


/* ------------------------------------------------------------
   Animation variants
   ------------------------------------------------------------ */

.animate.fade-in.is-visible {
  animation-name: fadeIn;
}

.animate.slide-in-right.is-visible {
  animation-name: slideInRight;
}

.animate.slide-in-left.is-visible {
  animation-name: slideInLeft;
}

.animate.scale-in.is-visible {
  animation-name: scaleIn;
}


/* ------------------------------------------------------------
   Delay helpers — use to stagger sibling elements
   ------------------------------------------------------------ */

.animate-delay-100 { animation-delay: 0.10s; }
.animate-delay-200 { animation-delay: 0.20s; }
.animate-delay-300 { animation-delay: 0.30s; }
.animate-delay-400 { animation-delay: 0.40s; }
.animate-delay-500 { animation-delay: 0.50s; }


/* ------------------------------------------------------------
   Reduced-motion — respect the user's OS preference
   ------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .animate,
  .animate.is-visible {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}


/* ============================================================
   JS TRIGGER SNIPPET
   Copy the block below into your page (before </body>) or
   into a separate animation-trigger.js file.

   <script>
   (function () {
     var observer = new IntersectionObserver(function (entries) {
       entries.forEach(function (entry) {
         if (entry.isIntersecting) {
           entry.target.classList.add('is-visible');
           observer.unobserve(entry.target); // fire once only
         }
       });
     }, { threshold: 0.15 });

     document.querySelectorAll('.animate').forEach(function (el) {
       observer.observe(el);
     });
   })();
   </script>

   threshold: 0.15 means the animation fires when 15% of the
   element is in view. Raise it (e.g. 0.3) for a later trigger,
   lower it (e.g. 0.05) for an earlier one.
   ============================================================ */
