/*
  Motion layer (ANIMATION_SPEC). Only transform / opacity / stroke-dashoffset animate.
  Reduced-motion is a single global override — not per-component JS (ANIMATION_SPEC §1).
*/

/* ---- Reveal (A2): opacity + 12px rise, staggered by --reveal-index ----
   Gated behind html.js so content stays visible with no JavaScript
   (progressive enhancement — content is never hidden by animation). */
html.js [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--dur-entrance) var(--ease-out),
    transform var(--dur-entrance) var(--ease-out);
  transition-delay: calc(var(--reveal-index, 0) * 60ms);
}
html.js [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

/* ---- Trace draw (A1) ---- */
@keyframes trace-draw {
  from {
    stroke-dashoffset: var(--trace-len, 600);
  }
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes dot-blink {
  0%,
  100% {
    opacity: 1;
  }
  40% {
    opacity: 0.2;
  }
}
.trace-line {
  stroke-dasharray: var(--trace-len, 600);
  stroke-dashoffset: var(--trace-len, 600);
  animation: trace-draw var(--dur-signature) var(--ease-in-out) forwards;
}
[data-seen] .trace-line {
  animation: none;
  stroke-dashoffset: 0;
}
.trace-dot {
  animation: dot-blink 900ms var(--ease-out) 700ms 1;
}

/* ---- Status chip pulse (A4): 2 iterations, ~1Hz ---- */
@keyframes chip-pulse {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.4);
    opacity: 0.55;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}
.is-revealed .status-dot--active {
  animation: chip-pulse 900ms var(--ease-out) 2;
}

/* ---- Timeline spine grow (A8) ---- */
html.js .timeline-spine {
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--dur-entrance) var(--ease-out);
}
.is-revealed .timeline-spine {
  transform: scaleY(1);
}

/* ---- 404 fray (A10) ---- */
@keyframes fray {
  from {
    stroke-dashoffset: 0;
  }
  to {
    stroke-dashoffset: 8;
  }
}

/* ---- Check-draw for form success (A9) ---- */
@keyframes check-draw {
  to {
    stroke-dashoffset: 0;
  }
}
.check-path {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
  animation: check-draw var(--dur-standard) var(--ease-out) forwards;
}

/* ---- View-transition language/route cross-fade (A6/A7) ---- */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--dur-quick);
}

/* ============================================================
   Reduced motion: durations collapse, translations disabled,
   animated states render at their final frame (no content lost).
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  html.js [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
  .trace-line {
    stroke-dashoffset: 0;
  }
  .timeline-spine {
    transform: scaleY(1) !important;
  }
}
