/* ==========================================================================
   NuclearBench — Motion layer
   Techniques borrowed from atomic-canyon.com (acwebsitev2): fade-up scroll
   reveals with cubic-bezier(0.16, 1, 0.3, 1), staggered delays, count-up
   stats. Visuals stay NuclearBench's own (no reactor canvas).
   Everything is gated on html.motion (set by /js/motion.js) so no-JS and
   reduced-motion visitors get the static page.
   ========================================================================== */

:root {
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}

/* --- Scroll reveal ------------------------------------------------------ */
.motion [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.7s var(--ease-out-expo),
    transform 0.7s var(--ease-out-expo),
    translate 0.25s ease,
    box-shadow 0.25s ease,
    border-color 0.25s ease;
  transition-delay: var(--reveal-delay, 0s), var(--reveal-delay, 0s), 0s, 0s, 0s;
}
.motion [data-reveal='left'] { transform: translateX(-28px); }
.motion [data-reveal='right'] { transform: translateX(28px); }
.motion [data-reveal='scale'] { transform: scale(0.94); }
.motion [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* --- Hero: slow drifting glows ---------------------------------------- */
@keyframes nb-drift-a {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-60px, 40px) scale(1.12); }
}
@keyframes nb-drift-b {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(70px, -30px) scale(1.18); }
}
.motion .hero--nb::before { animation: nb-drift-a 16s ease-in-out infinite; }
.motion .hero--nb::after { animation: nb-drift-b 20s ease-in-out infinite; }

/* Faint instrument grid that breathes behind the hero title */
@keyframes nb-grid-breathe {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 0.7; }
}
.motion .hero--nb > .container { position: relative; z-index: 1; }
.motion .hero--nb .nb-hero-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(125, 151, 238, 0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(125, 151, 238, 0.07) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse 60% 55% at 50% 45%, #000 20%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 60% 55% at 50% 45%, #000 20%, transparent 75%);
  animation: nb-grid-breathe 7s ease-in-out infinite;
}

/* --- Leaderboard: bars fill, points pop -------------------------------- */
@keyframes nb-bar-fill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
.motion .score__fill {
  transform-origin: left center;
}
.motion .nb-drawn .score__fill {
  animation: nb-bar-fill 1.1s var(--ease-out-expo) both;
  animation-delay: calc(var(--i, 0) * 60ms + 150ms);
}
.motion #results:not(.nb-drawn) .score__fill { transform: scaleX(0); }

@keyframes nb-pop {
  0% { opacity: 0; transform: scale(0.3); }
  70% { opacity: 1; transform: scale(1.08); }
  100% { opacity: 1; transform: scale(1); }
}
.motion .lb-pt {
  transform-box: fill-box;
  transform-origin: center;
}
.motion .nb-drawn .lb-pt {
  animation: nb-pop 0.6s var(--ease-out-expo) both;
  animation-delay: calc(var(--i, 0) * 70ms + 150ms);
}
.motion #results:not(.nb-drawn) .lb-pt { opacity: 0; }

/* Document-length dots slide in from the left, row by row */
@keyframes nb-slide-in {
  from { opacity: 0; transform: translateX(-40px); }
  to { opacity: 1; transform: none; }
}
.motion .nb-drawn .dl-pt {
  animation: nb-slide-in 0.8s var(--ease-out-expo) both;
  animation-delay: calc(var(--i, 0) * 25ms);
}
.motion .doclen:not(.nb-drawn) .dl-pt { opacity: 0; }

/* --- Sunburst: segments bloom outward ---------------------------------- */
@keyframes nb-bloom {
  from { opacity: 0; transform: scale(0.6) rotate(-20deg); }
  to { opacity: 1; transform: none; }
}
.motion .sunburst .seg {
  transform-box: view-box;
  transform-origin: 50% 50%;
}
.motion .nb-drawn .seg {
  animation: nb-bloom 0.9s var(--ease-out-expo) both;
  animation-delay: calc(var(--i, 0) * 35ms);
}
.motion .sunburst-wrap:not(.nb-drawn) .seg { opacity: 0; }
/* Numbers and labels wait for the segments, so they never float over an
   empty wheel. `backwards` holds them hidden through the delay, then hands
   opacity back to the hover styles. */
@keyframes nb-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.motion .nb-drawn .sunburst text {
  animation: nb-fade-in 0.5s ease-out backwards;
  animation-delay: 1.1s;
}
.motion .sunburst-wrap:not(.nb-drawn) .sunburst text { opacity: 0; }

/* --- Facsimile: highlighter sweeps across the marked phrases ---------- */
.motion .facsimile .mk {
  --mk-fill: 18%;
  background: linear-gradient(
      color-mix(in srgb, var(--mk-c) var(--mk-fill), transparent),
      color-mix(in srgb, var(--mk-c) var(--mk-fill), transparent)
    )
    left / 0% 100% no-repeat;
}
/* A keyframe (not a transition) so the hover spotlight's own transitions on
   .mk aren't overridden by this one-off sweep. */
@keyframes nb-sweep {
  from { background-size: 0% 100%; }
  to { background-size: 100% 100%; }
}
.motion .facsimile.nb-drawn .mk {
  animation: nb-sweep 0.9s var(--ease-out-expo) both;
  animation-delay: calc(var(--i, 0) * 180ms + 300ms);
}
@keyframes nb-pin-ping {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--co-c) 70%, transparent); }
  100% { box-shadow: 0 0 0 10px transparent; }
}
.motion .facsimile.nb-drawn .callout__pin {
  animation: nb-pin-ping 1.2s ease-out both;
  animation-delay: calc(var(--i, 0) * 180ms + 500ms);
}

/* --- Scoring plane: goal target pulses ------------------------------- */
@keyframes nb-target-pulse {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50% { transform: scale(1.6); opacity: 0.35; }
}
.motion .sp-target-glow {
  transform-box: fill-box;
  transform-origin: center;
  animation: nb-target-pulse 2.8s ease-in-out infinite;
}

/* --- Hover lift on cards --------------------------------------------- */
.motion .download,
.motion .credit,
.motion .benchmark-lane,
.motion .judge,
.motion .manifest__card {
  transition:
    opacity 0.7s var(--ease-out-expo),
    transform 0.7s var(--ease-out-expo),
    translate 0.25s ease,
    box-shadow 0.25s ease;
}
.motion .download:hover,
.motion .credit:hover,
.motion .benchmark-lane:hover,
.motion .manifest__card:hover {
  translate: 0 -4px;
  box-shadow: 0 14px 32px -16px rgba(20, 30, 80, 0.45);
}

/* Primary CTA: soft glow pulse to draw the eye */
@keyframes nb-cta-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(59, 96, 228, 0); }
  50% { box-shadow: 0 0 28px 2px rgba(59, 96, 228, 0.45); }
}
.motion .hero--nb .btn--primary {
  animation: nb-cta-glow 3.2s ease-in-out 1.6s infinite;
}

@media (prefers-reduced-motion: reduce) {
  .motion *,
  .motion *::before,
  .motion *::after {
    animation: none !important;
    transition: none !important;
  }
  .motion [data-reveal] { opacity: 1; transform: none; }
}
