/* ==========================================================================
   IP Cleaning Group — entrance & scroll animations
   --------------------------------------------------------------------------
   Progressive enhancement:
   · hidden start states apply only when <html> has the "js" class;
   · everything is skipped for users who prefer reduced motion;
   · if animations.js fails to run, content is revealed by a CSS fallback.

   Markup API (handled by assets/js/animations.js):
     data-animate="fade-up | fade | words | img | img-left"
     data-animate-delay="150"      optional, ms
     data-parallax="0.15"          optional, on images
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

  /* ---------- Fallback when the script did not start ---------- */

  .js:not(.anim-ready) [data-animate],
  .js:not(.anim-ready) [data-animate^="img"] img {
    animation: anim-fallback 0.6s var(--ease) 2.5s forwards;
  }

  /* Headings stay hidden until the script splits them into words */
  .js:not(.anim-ready) [data-animate="words"] {
    opacity: 0;
  }

  @keyframes anim-fallback {
    to {
      opacity: 1;
      transform: none;
      clip-path: inset(0 0 0 0);
      scale: 1;
    }
  }


  /* ---------- Page load ---------- */

  .js .header {
    animation: header-in 1s var(--ease-out) 0.1s backwards;
  }

  @keyframes header-in {
    from {
      translate: 0 -100%;
    }
  }

  .js .hero__img,
  .js .page-hero__img {
    scale: 1.12;
    transition: scale 2.8s var(--ease-out);
  }

  .js.is-loaded .hero__img,
  .js.is-loaded .page-hero__img {
    scale: 1;
  }


  /* ---------- Generic reveal ---------- */

  .js [data-animate] {
    --animate-delay: 0ms;
  }

  .js [data-animate="fade-up"] {
    transition:
      opacity 1s var(--ease-out) var(--animate-delay),
      transform 1.2s var(--ease-out) var(--animate-delay);
  }

  .js [data-animate="fade-up"]:not(.is-inview) {
    opacity: 0;
    transform: translate3d(0, 40px, 0);
  }

  .js [data-animate="fade"] {
    transition: opacity 1.2s var(--ease-out) var(--animate-delay);
  }

  .js [data-animate="fade"]:not(.is-inview) {
    opacity: 0;
  }


  /* ---------- Image reveal: the photo wipes open and settles ----------
     The clip is applied to the <img>, not to the observed wrapper:
     IntersectionObserver treats a fully clipped target as not visible. */

  .js [data-animate^="img"] img {
    clip-path: inset(0 0 0 0); /* explicit end state, so the clip can interpolate */
    transition:
      clip-path 1.3s var(--ease-out) var(--animate-delay),
      scale 1.8s var(--ease-out) var(--animate-delay),
      transform 1.2s var(--ease-out),
      opacity 0.45s var(--ease);
  }

  .js [data-animate="img"]:not(.is-inview) img {
    clip-path: inset(100% 0 0 0);
    scale: 1.2;
  }

  .js [data-animate="img-left"]:not(.is-inview) img {
    clip-path: inset(0 0 0 100%);
    scale: 1.2;
  }


  /* ---------- Headings: words rise from a mask ---------- */

  .js [data-animate="words"] .word {
    display: inline-block;
    margin: -0.1em -0.05em -0.24em;
    padding: 0.1em 0.05em 0.24em;
    overflow: hidden;
    vertical-align: top;
  }

  .js [data-animate="words"] .word__inner {
    display: inline-block;
    transition:
      transform 1.1s var(--ease-out),
      opacity 1.1s var(--ease-out);
    transition-delay: calc(var(--animate-delay) + var(--i, 0) * 65ms);
  }

  .js [data-animate="words"]:not(.is-inview) .word__inner {
    opacity: 0;
    transform: translate3d(0, 105%, 0);
  }


  /* ---------- Section label lines draw from the text outwards ---------- */

  .js .section-label[data-animate]::before,
  .js .section-label[data-animate]::after {
    transition: transform 0.9s var(--ease-out) calc(var(--animate-delay) + 0.25s);
  }

  .js .section-label[data-animate]::before {
    transform-origin: right center;
  }

  .js .section-label[data-animate]::after {
    transform-origin: left center;
  }

  .js .section-label[data-animate]:not(.is-inview)::before,
  .js .section-label[data-animate]:not(.is-inview)::after {
    transform: scaleX(0);
  }


  /* ---------- Features: numbers lag behind, dividers grow ---------- */

  .js .feature__num {
    transition:
      opacity 1.4s var(--ease-out) calc(var(--animate-delay) + 0.15s),
      transform 1.4s var(--ease-out) calc(var(--animate-delay) + 0.15s);
  }

  .js .feature:not(.is-inview) .feature__num {
    opacity: 0;
    transform: translate3d(0, 30px, 0);
  }

  .js .feature::before {
    transition: transform 1s var(--ease-out) calc(var(--animate-delay) + 0.3s);
  }

  .js .feature:not(.is-inview)::before {
    transform: scaleX(0);
  }

  @media (min-width: 768px) {
    .js .feature:not(.is-inview)::before {
      transform: scaleY(0);
    }
  }


  /* ---------- Service area: frames draw in ---------- */

  .js .area__item {
    transition:
      opacity 1s var(--ease-out) var(--animate-delay),
      transform 1.2s var(--ease-out) var(--animate-delay),
      border-color 1s var(--ease) calc(var(--animate-delay) + 0.2s);
  }

  .js .area__item:not(.is-inview) {
    border-color: transparent;
  }
}
