/* Cybereum · motion-refined.css
   A craft pass over the signature motion: same energy, one shared beat.

   Applied from a design handoff after checking each claim against the code.
   Twelve of the thirteen sections described the shipped behaviour correctly.
   Section 6 (marquee seam) did not and is not here: it held that the track
   travels -50% minus var(--s-2) while the row gap is var(--s-5). The travel is
   right, the gap is var(--s-4) — 1rem, exactly twice the 0.5rem of --s-2 — so
   the loop is already seamless. Its "fix" would have widened the row gap by
   half a rem to restore a relationship that already holds.

   The handoff also re-declared motion at a higher specificity than the
   reduced-motion suppressions already in the stylesheets, without restoring
   them, which would have handed animation back to the visitors who asked for
   less of it. Everything this file re-declares is re-suppressed at the end.

   Scoped under .motion-v2 so the shipped behaviour stays reachable, and because
   the Distributed Management hero CSS is injected at runtime — specificity
   decides there, not source order. */
.motion-v2{--beat:8s;--ease-settle:cubic-bezier(.16,1,.3,1);--ease-glide:cubic-bezier(.45,0,.18,1)}

/* 1 · Hero mark — five loops ran at 6/7/7/8/8.5s and drifted out of phase within a
   minute. Everything now breathes on one 8s beat; the sweep and the orbiting signal
   take exactly one and two beats, so the mark reads as a single instrument. */
.motion-v2 .hero-body.in .hero-mark::before,
.motion-v2 .hero-body.in .hero-mark .ticks,
.motion-v2 .hero-body.in .hero-mark .ring:not(.r2),
.motion-v2 .hero-body.in .hero-mark .brk{animation-duration:var(--beat);animation-delay:2.4s}
.motion-v2 .hero-body.in .hero-mark .sweep{animation:hero-sweep-v2 var(--beat) var(--ease-glide) 2.4s infinite}
.motion-v2 .hero-body.in .hero-mark::after{animation-duration:calc(var(--beat) * 2);animation-delay:2.4s}
@keyframes hero-sweep-v2{
  0%{transform:rotate(-28deg);opacity:0}
  7%{opacity:.24}
  20%{opacity:.95}
  64%{opacity:.6}
  90%{opacity:.1}
  100%{transform:rotate(332deg);opacity:0}
}

/* 2 · Lifecycle runner — it spun 1080° and looped forever while the stages it had
   already lit sat still. Now it travels once with the progress line (5.4s), lands on
   the last node and rests with a soft pulse; stage/node lighting is retimed to the
   runner's actual arrival at each node (.18s + i·1.35s). */
.motion-v2 .lifecycle.in .stages.on .runner{animation:lifecycle-run-v2 5.4s var(--ease-glide) .18s 1 forwards}
.motion-v2 .lifecycle.in .stages.on .runner::before{animation:runner-rest-v2 var(--beat) ease-in-out 5.6s infinite}
.motion-v2 .lifecycle.in .stages.on .stage{animation-delay:calc(.18s + var(--i) * 1.35s)}
.motion-v2 .lifecycle.in .stages.on .stage::before{animation-delay:calc(.22s + var(--i) * 1.35s)}
@keyframes lifecycle-run-v2{
  0%{left:var(--track-x0);opacity:0;transform:scale(.8)}
  6%{opacity:1;transform:scale(1)}
  100%{left:var(--track-x1);opacity:1;transform:scale(1)}
}
@keyframes runner-rest-v2{
  0%,100%{transform:scale(.92);opacity:.55}
  50%{transform:scale(1.12);opacity:.85}
}

/* 3 · Hub — the core glowed on its own 2s clock. Flows arrive at 13% of a 12s cycle,
   one every 2s; the glow peaks at 52% of its 2s loop, so a .52s offset makes the core
   light exactly when a packet lands. Zero new motion, one delay. */
.motion-v2 .hub .hub-core{animation-delay:.52s}

/* 4 · Compass — rose and needle started .24s apart and fought. Rose calibrates first,
   needle acquires once the rose has settled, corrections then share one 9s clock. */
.motion-v2 .gps.in .compass .needle{animation:compass-acquire 2.25s var(--ease-settle) .6s both,compass-correct 9s ease-in-out 3.4s infinite}
.motion-v2 .gps.in .compass .nn{animation-delay:3.4s}

/* 5 · Scroll reveals — fade lands before the move finishes (opacity .55s / transform .9s)
   so content is readable early and the motion trails it; stagger is capped at 360ms so
   long lists don't wait on their tail. */
.motion-v2 [data-reveal]{transform:translateY(16px);transition:opacity .55s var(--ease-out),transform .9s var(--ease-settle);transition-delay:min(calc(var(--i,0) * 60ms),360ms)}
.motion-v2 [data-reveal="scale"]{transform:scale(.97)}
.motion-v2 [data-reveal="left"]{transform:translateX(-18px)}
.motion-v2 [data-reveal].in{opacity:1;transform:none}

/* 7 · Distributed Management — the dawn, halo and wordmark started at page load, under
   the loader, so visitors caught the tail of the sunrise. They now hold until the loader
   is dismissed (.dm-hero.is-live) and the loader hands off with a lift instead of a fade. */
.motion-v2 .dm-hero:not(.is-live) .dm-hero__dawn,
.motion-v2 .dm-hero:not(.is-live) .dm-hero__core-lift,
.motion-v2 .dm-hero:not(.is-live) .dm-hero__core::after,
.motion-v2 .dm-hero:not(.is-live) .dm-hero__core::before,
.motion-v2 .dm-hero:not(.is-live) .dm-hero__sync,
.motion-v2 .dm-hero:not(.is-live) .dm-hero__wordmark,
.motion-v2 .dm-hero:not(.is-live) .dm-hero__identity span{animation-play-state:paused}
.motion-v2 .dm-loader{transition:opacity .45s var(--ease-glide),visibility .45s}
.motion-v2 .dm-loader__ring,.motion-v2 .dm-loader p{transition:transform .45s var(--ease-glide),opacity .4s ease}
.motion-v2 .dm-loader.is-done .dm-loader__ring{transform:scale(1.14);opacity:0}
.motion-v2 .dm-loader.is-done p{transform:translateY(6px);opacity:0}

/* 8 · Assessment diagnostic — five bars rose on ad-hoc negative delays and all five
   scan-lines swept in unison. Bars now rise left→right on a .35s cadence and each
   scan inherits its bar's delay, so the read is "diagnosis moving through the schedule". */
.motion-v2 .assessment-diagnostic i{animation:diagnosticRise 7s var(--ease-settle) infinite}
.motion-v2 .assessment-diagnostic i:nth-child(1){animation-delay:0s}
.motion-v2 .assessment-diagnostic i:nth-child(2){animation-delay:.35s}
.motion-v2 .assessment-diagnostic i:nth-child(3){animation-delay:.7s}
.motion-v2 .assessment-diagnostic i:nth-child(4){animation-delay:1.05s}
.motion-v2 .assessment-diagnostic i:nth-child(5){animation-delay:1.4s}
.motion-v2 .assessment-diagnostic i::after{animation:assessmentScan 2.8s ease-in-out infinite alternate;animation-delay:inherit}

/* 9 · Technology instrument — the JS choreography runs a 10.5s loop, but the ambient
   CSS fallbacks (scan 9s, graph 8s, model 7s, pulses 3.4/3.6s) beat against it before
   the script takes over and whenever it is unavailable. All loops now share the 10.5s
   cycle, phased left→right to follow the scan: sources → graph → model → outputs. */
.motion-v2 .system-instrument::before{animation-duration:10.5s;animation-timing-function:var(--ease-glide)}
.motion-v2 .system-instrument .dag{animation-duration:10.5s;animation-delay:-1s}
.motion-v2 .system-instrument .band,.motion-v2 .system-instrument .band-fill{animation-duration:10.5s;animation-delay:-1.2s}
.motion-v2 .system-instrument .ai-ring{animation-duration:3.5s}
.motion-v2 .system-instrument .win-ring{animation-duration:3.5s;animation-delay:1.75s}
.motion-v2 .system-instrument .out{animation-delay:2.4s}

/* 10 · Preloader curtain — content lifted 28px in .5s while the curtain took 1s on a
   different curve, so the exit read as two events. Content now leaves on the curtain's
   own curve and timing; the scan-line eases with the same glide. */
.motion-v2 .preloader{transition:clip-path .95s cubic-bezier(.76,0,.24,1) .1s}
.motion-v2 .preloader>*{transition:opacity .45s ease .05s,transform .95s cubic-bezier(.76,0,.24,1) .1s}
.motion-v2 .preloader.done>*{transform:translateY(-6vh)}
.motion-v2 .pl-scan{animation-timing-function:var(--ease-glide)}

/* 11 · Split-text — word rise capped so long statements don't trail for seconds
   (45ms × 30 words = 1.35s before the last word moved). Rotation eased to 2° and the
   rise settles rather than snapping. */
.motion-v2 .split .w>i{transform:translateY(var(--split-rise,112%)) rotate(2deg);transition:transform 1.05s var(--ease-settle);transition-delay:min(calc(var(--d,0) * 42ms + var(--o,0ms)),.9s)}
.motion-v2 .split.in .w>i,.motion-v2 .in .split .w>i{transform:none}

/* 12 · Dyēŭs — mostly not applicable. The handoff retimed eleven .dycore
   selectors (central core, three reasoning rings, two spin rings, three data
   flows, pulse nodes) onto a 6/12/18s beat. None of those elements exist: the
   page's #logo-container is filled at runtime with a static .webp, so the
   rules in dyeus.css that they mirror are dead too, and copying them here
   would only have added eleven more. Left for whoever revives that artwork.
   .sp-pulse is likewise in no page's markup.

   The one element of the group that does render is the hero core, and it takes
   the 6s beat. */
.motion-v2 .dyeus-hero-core{animation-duration:6s}

/* 13 · Slides — the deck slid .74s but slide content was simply there. The active
   slide's blocks now settle in after the pan (opacity + 14px rise, 70ms stagger), the
   progress bar and dots move on the deck's curve. */
.motion-v2 .deck{transition:transform .8s var(--ease-glide)}
.motion-v2 .slide>*{opacity:0;transform:translateY(14px);transition:opacity .5s ease,transform .8s var(--ease-settle)}
.motion-v2 .slide[aria-hidden="false"]>*{opacity:1;transform:none}
.motion-v2 .slide[aria-hidden="false"]>*:nth-child(1){transition-delay:.3s}
.motion-v2 .slide[aria-hidden="false"]>*:nth-child(2){transition-delay:.37s}
.motion-v2 .slide[aria-hidden="false"]>*:nth-child(3){transition-delay:.44s}
.motion-v2 .slide[aria-hidden="false"]>*:nth-child(4){transition-delay:.51s}
.motion-v2 .slide[aria-hidden="false"]>*:nth-child(n+5){transition-delay:.58s}
.motion-v2 .progress i{transition:width .8s var(--ease-glide)}
.motion-v2 .dot{transition:width .4s var(--ease-settle),background .3s}

/* Reduced motion. Every selector this file gives an animation or a transition
   is listed here, because each of those rules outranks the base stylesheets'
   own reduced-motion blocks — .motion-v2 [data-reveal] beats [data-reveal], and
   .motion-v2 .assessment-diagnostic i::after beats the suppression in
   assessment-concept.css. Re-declaring motion at a higher specificity silently
   revokes the preference unless it is restored, so it is restored. */
@media (prefers-reduced-motion:reduce){
  /* loops: stop them where they are */
  .motion-v2 .hero-body.in .hero-mark::before,
  .motion-v2 .hero-body.in .hero-mark::after,
  .motion-v2 .hero-body.in .hero-mark .ticks,
  .motion-v2 .hero-body.in .hero-mark .ring:not(.r2),
  .motion-v2 .hero-body.in .hero-mark .brk,
  .motion-v2 .hero-body.in .hero-mark .sweep,
  .motion-v2 .hub .hub-core,
  .motion-v2 .gps.in .compass .needle,
  .motion-v2 .gps.in .compass .nn,
  .motion-v2 .lifecycle.in .stages.on .runner::before,
  .motion-v2 .assessment-diagnostic i,
  .motion-v2 .assessment-diagnostic i::after,
  .motion-v2 .system-instrument::before,
  .motion-v2 .system-instrument .dag,
  .motion-v2 .system-instrument .band,
  .motion-v2 .system-instrument .band-fill,
  .motion-v2 .system-instrument .ai-ring,
  .motion-v2 .system-instrument .win-ring,
  .motion-v2 .system-instrument .out,
  .motion-v2 .dyeus-hero-core,
  .motion-v2 .pl-scan{animation:none!important}

  /* entrances: show the end state, do not travel to it */
  .motion-v2 [data-reveal],
  .motion-v2 [data-reveal="scale"],
  .motion-v2 [data-reveal="left"],
  .motion-v2 .split .w>i,
  .motion-v2 .slide>*,
  .motion-v2 .preloader>*,
  .motion-v2 .preloader.done>*{opacity:1;transform:none;transition:none}

  /* transitions that only retime an existing move */
  .motion-v2 .deck,
  .motion-v2 .progress i,
  .motion-v2 .dot,
  .motion-v2 .dm-loader,
  .motion-v2 .dm-loader__ring,
  .motion-v2 .dm-loader p,
  .motion-v2 .preloader{transition:none}

  /* the runner parks at the end of its track rather than travelling */
  .motion-v2 .lifecycle.in .stages.on .runner{animation:none;left:var(--track-x1);opacity:1}

  /* the hold-for-the-loader gate must not become a permanent pause */
  .motion-v2 .dm-hero:not(.is-live) *{animation-play-state:running}
}
