/* ==========================================================================
   Scroll-driven motion — served verbatim from public/, never bundled.

   WHY THIS FILE EXISTS: Astro's CSS minifier merges
     animation: reveal-in linear both;
     animation-timeline: view();
   into `animation: linear both reveal-in view()`, which is invalid — `view()`
   is not a legal value in the animation shorthand — so browsers drop it and
   every scroll animation silently dies in production while working perfectly
   in dev. Files in public/ are copied byte-for-byte, so this cannot happen.

   `npm run build` asserts the bug hasn't returned.
   ========================================================================== */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Scroll timelines have no time-based delay, so a stagger is built by
       shifting each item's range with --i rather than animation-delay. */
    .reveal {
      animation: reveal-in linear both;
      animation-timeline: view();
      animation-range:
        entry calc(6% + var(--i, 0) * 4%)
        cover calc(24% + var(--i, 0) * 4%);
    }
    @keyframes reveal-in {
      from { opacity: 0; transform: translateY(1.4rem); }
      to   { opacity: 1; transform: none; }
    }

    /* Signal blocks arrive from below — heavier, more mechanical than Field. */
    .rise {
      animation: rise-in linear both;
      animation-timeline: view();
      animation-range:
        entry calc(4% + var(--i, 0) * 5%)
        entry calc(58% + var(--i, 0) * 5%);
    }
    @keyframes rise-in {
      from { opacity: 0; transform: translateY(2.2rem); }
      to   { opacity: 1; transform: none; }
    }

    /* A rule that draws itself across as the section arrives. */
    .draw-rule {
      animation: draw-rule linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 34%;
      transform-origin: left center;
    }
    @keyframes draw-rule {
      from { transform: scaleX(0); }
      to   { transform: scaleX(1); }
    }

    /* The craft half recedes as the seam takes over — makes the handoff
       feel authored rather than abrupt. */
    .recede {
      animation: recede-out linear both;
      animation-timeline: view();
      animation-range: exit 20% exit 100%;
    }
    @keyframes recede-out {
      from { opacity: 1; }
      to   { opacity: 0.34; }
    }
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .seam-label {
      animation: seam-pass linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes seam-pass {
      0%   { opacity: 0; letter-spacing: 0.6em; }
      45%  { opacity: 1; letter-spacing: 0.3em; }
      100% { opacity: 0; letter-spacing: 0.1em; }
    }
  }
}

/* --------------------------------------------------------------------------
   The accent rule draws itself as a card arrives.

   Mike singled this out as the best thing on the page, so it earns a scroll
   timeline rather than only firing on hover — hover does nothing on a phone,
   and nothing at all until someone is already interested. Length is driven by
   scroll; thickness is driven by hover. Two axes, no conflict.
   -------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .card-rule {
      animation: rule-draw linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 32%;
    }
    @keyframes rule-draw {
      from { transform: scaleX(0); }
      to   { transform: scaleX(1); }
    }

    /* The card itself lifts in behind it. */
    .card {
      animation: card-in linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 28%;
    }
    @keyframes card-in {
      from { opacity: 0; transform: translateY(1.6rem); }
      to   { opacity: 1; transform: none; }
    }
  }
}
