/* B2 Networks Group - motion layer.
   Separate file so it drops into the WP child theme on its own, and so it can
   be removed wholesale if the client ever wants the site still.

   Three rules govern everything here:

   1. Zero JavaScript. Scroll-driven CSS animations run on the compositor, so
      they cannot jank the main thread the way Elementor's waypoint JS does.
   2. Only `transform` and `opacity` are animated. Both are compositor-only,
      so nothing here triggers layout or paint.
   3. Content is never trapped. Everything is wrapped in @supports, so a
      browser without scroll-driven timelines renders the page fully visible
      and static rather than blank. Same for reduced-motion. */

@keyframes b2-rise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

@keyframes b2-rise-sm {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

@keyframes b2-wipe-right {
  from { opacity: 0; clip-path: inset(0 100% 0 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {

    /* Cards and panels rise as they enter. `entry 5% cover 30%` finishes the
       move well before the element reaches reading position, so nothing is
       still moving while it is being read. */
    .service,
    .duo__item,
    .project,
    .coverage__map,
    .band__media,
    .band__body {
      animation: b2-rise linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 30%;
    }

    /* Figures animate one step behind their heading, which reads as the
       section assembling rather than everything twitching at once. */
    .section__head {
      animation: b2-rise-sm linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 22%;
    }

    /* The process strip is a sequence, so it wipes left to right in the same
       direction the chevrons point. The motif does the explaining. */
    .process__strip img {
      animation: b2-wipe-right linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 40%;
    }

    /* Stat figures land individually, staggered by shifting each one's range
       rather than with animation-delay, which scroll timelines ignore. */
    .stats__item {
      animation: b2-rise-sm linear both;
      animation-timeline: view();
    }
    .stats__item:nth-child(1) { animation-range: entry 8%  cover 26%; }
    .stats__item:nth-child(2) { animation-range: entry 12% cover 30%; }
    .stats__item:nth-child(3) { animation-range: entry 16% cover 34%; }
    .stats__item:nth-child(4) { animation-range: entry 20% cover 38%; }

    /* Service cards stagger by column so a row assembles left to right. */
    .service:nth-child(3n+2) { animation-range: entry 8%  cover 33%; }
    .service:nth-child(3n)   { animation-range: entry 11% cover 36%; }
  }
}

/* Hover and focus micro-interactions.
   These need no @supports guard - a browser that ignores them simply has no
   hover response, which costs the reader nothing. */
@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .service,
  .duo__item img {
    transition: transform .28s cubic-bezier(.2, .7, .3, 1),
                filter .28s ease;
  }
  /* filter, matching the clipped card. A box-shadow here would leak a square
     corner into the diagonal cut on hover. */
  .service:hover {
    transform: translateY(-4px);
    filter: drop-shadow(0 20px 34px rgba(7, 59, 87, .20));
  }
  .duo__item img:hover { transform: scale(1.02); }

  /* The service icon leans in slightly when its card is hovered. One small
     reward, not six competing ones. */
  .service__icon { transition: transform .32s cubic-bezier(.2, .7, .3, 1); }
  .service:hover .service__icon { transform: translateY(-3px) rotate(-3deg); }

  .partners li { transition: border-color .2s ease, background-color .2s ease; }
  .partners li:hover {
    border-color: var(--b2-orange);
    background: rgba(240, 111, 34, .12);
  }
}

/* Keyboard users get the same card lift as mouse users. */
.service:focus-within { transform: translateY(-4px); filter: drop-shadow(0 20px 34px rgba(7, 59, 87, .20)); }
