/* ============================================================
   Squadra — Motion vocabulary (CSS half)

   Base styles are ALWAYS the finished state. We animate FROM
   hidden only when (a) JS adds html.motion and (b) the user has
   not requested reduced motion. So no-JS, reduced-motion, and
   print all simply show finished content.

   Tokens (from colors_and_type.css):
     --ease-out / --ease-standard / --ease-exit / --ease-signature
     --dur-reveal / --dur-draw / --dur-count / --dur-fast / --dur-slow
     --rise / --rise-lg / --stagger

   Primitives (attribute-driven so markup stays declarative):
     [data-m]            fade + rise            (--i = stagger index)
     [data-m="rise"]     emphasis rise (--rise-lg)
     [data-rule]         hairline draws L->R (scaleX)
     [data-draw] .mk-*   signature mark draw-on (JS arms dashes)
     [data-count]        number counts up (JS)
   A container with [data-io] is the trigger; .is-in is added once
   it enters the viewport. PLAY ONCE: .is-in is not removed on exit
   unless the trigger opts in with [data-replay].
   ============================================================ */

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

  /* ---- reveal: fade + rise ---- */
  html.motion [data-m] {
    opacity: 0;
    transform: translateY(var(--rise, 18px));
    transition: opacity var(--dur-reveal, 640ms) var(--ease-out),
                transform var(--dur-reveal, 640ms) var(--ease-out);
    transition-delay: calc(var(--i, 0) * var(--stagger, 70ms));
    will-change: opacity, transform;
  }
  html.motion [data-m="rise"] { transform: translateY(var(--rise-lg, 32px)); }
  html.motion .is-in [data-m] { opacity: 1; transform: none; }

  /* safety net: a section in view ~1s force-shows regardless of whether the
     transition timeline advanced (covers throttled / backgrounded tabs).
     Invisible in a normal tab — the transition has already settled by then. */
  html.motion .mshown [data-m]    { opacity: 1 !important; transform: none !important; }
  html.motion .mshown [data-rule] { transform: scaleX(1) !important; }

  /* ---- hairline rule draw-in ---- */
  html.motion [data-rule] {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur-draw, 720ms) var(--ease-out);
    transition-delay: calc(var(--i, 0) * var(--stagger, 70ms));
  }
  html.motion .is-in [data-rule] { transform: scaleX(1); }

  /* ---- SIGNATURE: ASSEMBLY — frame settles in, then the accent slab
         wipes into place (the symbol's core "built" move). The single
         ownable Squadra gesture. Invoke by wrapping a mark in [data-draw]. ---- */
  html.motion [data-draw] .mk-line {
    opacity: 0;
    transform: translateY(3px);
    transform-box: fill-box;
    transform-origin: center;
    transition: opacity calc(var(--dur-draw, 720ms) * 0.5) var(--ease-out),
                transform calc(var(--dur-draw, 720ms) * 0.62) var(--ease-out);
  }
  html.motion [data-draw].is-in .mk-line,
  html.motion .is-in [data-draw] .mk-line { opacity: 1; transform: none; }

  html.motion [data-draw] .mk-accent {
    opacity: 0;
    clip-path: inset(0 100% 0 0);
    transition: clip-path var(--dur-draw, 720ms) var(--ease-signature) calc(var(--dur-draw, 720ms) * 0.34),
                opacity 100ms linear calc(var(--dur-draw, 720ms) * 0.34);
  }
  html.motion [data-draw].is-in .mk-accent,
  html.motion .is-in [data-draw] .mk-accent { opacity: 1; clip-path: inset(0 0 0 0); }

  html.motion .mshown [data-draw] .mk-line { opacity: 1 !important; transform: none !important; }
  html.motion .mshown [data-draw] .mk-accent { opacity: 1 !important; clip-path: inset(0 0 0 0) !important; }
}

/* ---- micro-interactions (no JS; pure CSS, respect reduced-motion via short durations) ---- */
.m-arrow { display: inline-block; transition: transform var(--dur-cta-move) var(--ease-cta); }
.m-nudge:hover .m-arrow,
.m-nudge:focus-visible .m-arrow { transform: translateX(4px); }

.m-lift { transition: transform var(--dur-cta) var(--ease-cta),
                      box-shadow var(--dur-cta) var(--ease-cta); }
.m-lift:hover { transform: translateY(-3px); }

/* underline that wipes in from the left */
.m-underline { position: relative; text-decoration: none; }
.m-underline::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1.5px;
  background: currentColor; transform: scaleX(0); transform-origin: left center;
  transition: transform var(--dur-cta) var(--ease-cta);
}
.m-underline:hover::after,
.m-underline:focus-visible::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .m-arrow, .m-lift, .m-underline::after { transition: none; }
}
