/* ==========================================================================
   Maxer Photonics — Motion
   Timing/easing calibrated against the Scale.com homepage's motion language
   (micro-interactions ~0.15–0.3s on a standard-decelerate curve, larger
   reveals ~0.5–1s on an ease-out curve; no native smooth-scroll, no header
   hide/show — polish lives in per-element choreography). Visuals below are
   original to Maxer. GPU-friendly properties only (transform/opacity/
   clip-path); everything here is neutralised under prefers-reduced-motion
   at the bottom of this file.
   ========================================================================== */

/* ---------------------------------- Page load ---------------------------- */
/* Pure CSS: the animation's own `from` keyframe (plus `both` fill mode)
   holds each element at opacity:0 through its delay, so this runs correctly
   on first paint with no JS gating required. */

/* Hero entrance order: 1 background (already present, ambient) → 2 visual
   frame appears → 3 eyebrow → 4 headline → 5 description → 6 CTAs →
   7 visual reaches its active state (the spectrum's grid, axis and curves
   draw in — see .spectrum-graph__* below, timed to land after every text
   element). */

.load-in > * {
  animation: load-in-up 0.8s var(--ease-out) both;
}
.load-in > *:nth-child(1) { animation-delay: 0.15s; }  /* eyebrow */
.load-in > *:nth-child(2) { animation-delay: 0.28s; }  /* h1 (line-mask handles the inner reveal) */
.load-in > *:nth-child(3) { animation-delay: 0.52s; }  /* lead */
.load-in > *:nth-child(4) { animation-delay: 0.64s; }  /* actions */

@keyframes load-in-up {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

.load-in-visual {
  opacity: 0;
  transform: scale(0.96);
  animation: load-in-visual 0.9s var(--ease-out) 0.05s both;
}
@keyframes load-in-visual {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

/* Step 8 — the spectrum reaching its active state: grid fades in, the
   primary curve draws left-to-right, the secondary curve follows shortly
   after (its own glow is a static filter, not animated — "glow remains"),
   the axis labels land, then the four technical readouts settle in one at
   a time, and the caption last of all. Curves use pathLength="1" in the
   markup so stroke-dasharray/dashoffset can just work in 0–1 units. */
.spectrum-graph__grid {
  opacity: 0;
  animation: fade-in 0.45s var(--ease-out) 0.45s both;
}
.spectrum-graph__trace-a {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: spectrum-draw 0.8s var(--ease-out) 0.5s both;
}
.spectrum-graph__trace-b {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: spectrum-draw 0.8s var(--ease-out) 0.65s both;
}
.spectrum-graph__ticks {
  opacity: 0;
  animation: fade-in 0.35s var(--ease-out) 1.3s both;
}
.data-readout {
  opacity: 0;
  transform: translate(-50%, -50%) translateY(6px);
  animation: readout-in 0.5s var(--ease-out) both;
}
.data-readout-layer .data-readout:nth-child(1) { animation-delay: 1.45s; }
.data-readout-layer .data-readout:nth-child(2) { animation-delay: 1.53s; }
.data-readout-layer .data-readout:nth-child(3) { animation-delay: 1.61s; }
.data-readout-layer .data-readout:nth-child(4) { animation-delay: 1.69s; }
.spectrum-caption {
  opacity: 0;
  animation: fade-in 0.35s var(--ease-out) 1.95s both;
}
.spectrum-caption--osa {
  animation: none;
  opacity: 0;
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes spectrum-draw {
  to { stroke-dashoffset: 0; }
}
@keyframes readout-in {
  to { opacity: 1; transform: translate(-50%, -50%) translateY(0); }
}

/* Headline line-mask reveal: outer clips, inner translates up into view */
.line-mask { display: block; overflow: hidden; }
.line-inner {
  display: block;
  transform: translateY(112%);
  animation: line-reveal 0.9s var(--ease-out) both;
}
.line-mask:nth-of-type(1) .line-inner { animation-delay: 0.3s; }
.line-mask:nth-of-type(2) .line-inner { animation-delay: 0.42s; }
@keyframes line-reveal {
  to { transform: translateY(0); }
}

/* ---------------------------------- Scroll reveal ------------------------ */

.reveal {
  opacity: 0;
  transform: translateY(28px) scale(0.985);
  clip-path: inset(8% 0 0 0 round 4px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out),
              clip-path var(--dur-slow) var(--ease-out);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  clip-path: inset(0 0 0 0 round 4px);
}

.reveal-stagger > * {
  opacity: 0;
  transform: translateY(24px) scale(0.985);
  clip-path: inset(8% 0 0 0 round 4px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out),
              clip-path var(--dur-slow) var(--ease-out);
}
.reveal-stagger.is-visible > * { opacity: 1; transform: translateY(0) scale(1); clip-path: inset(0 0 0 0 round 4px); }
.reveal-stagger.is-visible > *:nth-child(1) { transition-delay: 0ms; }
.reveal-stagger.is-visible > *:nth-child(2) { transition-delay: 70ms; }
.reveal-stagger.is-visible > *:nth-child(3) { transition-delay: 140ms; }
.reveal-stagger.is-visible > *:nth-child(4) { transition-delay: 210ms; }
.reveal-stagger.is-visible > *:nth-child(5) { transition-delay: 280ms; }
.reveal-stagger.is-visible > *:nth-child(6) { transition-delay: 350ms; }
.reveal-stagger.is-visible > *:nth-child(7) { transition-delay: 420ms; }
.reveal-stagger.is-visible > *:nth-child(8) { transition-delay: 490ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-stagger > *, .load-in > *, .load-in-visual, .line-inner,
  .spectrum-graph__grid, .spectrum-graph__ticks, .spectrum-caption {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
    animation: none !important;
  }
  .spectrum-graph__trace-a, .spectrum-graph__trace-b {
    animation: none !important;
    stroke-dashoffset: 0 !important;
  }
  .data-readout {
    opacity: 1 !important;
    transform: translate(-50%, -50%) !important;
    animation: none !important;
  }
}

/* Marquee-style fact ticker (optional use) */
@keyframes drift-x {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
.drift-track { animation: drift-x 32s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .drift-track { animation: none; }
}
