/*
  animations.css — Phase 2: homepage animation system.

  Two families of motion, matching the master's own split:

  1. VIEWPORT-TRIGGERED (.reveal / .grow-line) — fire once when scrolled
     into view. Driven by js/animations.js's IntersectionObserver
     (mirrors Reveal.tsx / GrowLine.tsx's `whileInView`).
  2. SCROLL-LINKED (data-scroll-* elements) — continuously track scroll
     position while a section is in view. Driven by js/animations.js's
     shared rAF progress engine (mirrors useScroll/useTransform in
     HeroClient, ManifestoClient, EnergyPortal, FloatingArchitecture,
     ScrollCue). These get their computed values written directly as
     inline styles by JS, not toggled via class here.

  All @keyframes below are ported verbatim (same names, timings, easing)
  from the master's app/globals.css.
*/

/* ---------------------------------------------------------------
   1. Viewport-triggered reveal primitives
   --------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(var(--reveal-y, 28px));
  transition:
    opacity 0.7s var(--ease-editorial),
    transform 0.7s var(--ease-editorial);
  transition-delay: var(--reveal-delay, 0s);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.grow-line {
  transform: scaleX(0);
  transition: transform var(--grow-duration, 1.1s) var(--ease-editorial);
  transition-delay: var(--grow-delay, 0s);
}

.grow-line[data-axis="y"] {
  transform: scaleY(0);
}

.grow-line[data-axis="xy"] {
  transform: scale(0);
}

.grow-line.is-visible[data-axis="x"] {
  transform: scaleX(1);
}

.grow-line.is-visible[data-axis="y"] {
  transform: scaleY(1);
}

.grow-line.is-visible[data-axis="xy"] {
  transform: scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .grow-line {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------------------------------------------------------------
   2. Master project keyframes — ported verbatim from app/globals.css
   --------------------------------------------------------------- */
@keyframes glowFloat {
  to {
    transform: translate(-30px, 30px) scale(1.15);
  }
}

@keyframes drawPath {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes pulseIn {
  from {
    opacity: 0;
    transform: scale(0.6);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes ringPulse {
  0%,
  100% {
    opacity: 0.5;
  }
  50% {
    opacity: 1;
  }
}

@keyframes nodePulse {
  0%,
  100% {
    opacity: 0.35;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes scrollMarker {
  0% {
    transform: translateY(-100%);
    opacity: 0;
  }
  15% {
    opacity: 1;
  }
  85% {
    opacity: 1;
  }
  100% {
    transform: translateY(220%);
    opacity: 0;
  }
}

@keyframes slowSpin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes portalBreathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.015);
  }
}

@keyframes envGlow {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 1;
  }
}

@keyframes mistDriftA {
  0% {
    transform: translateX(-3%) translateY(0);
  }
  100% {
    transform: translateX(3%) translateY(-1.5%);
  }
}

@keyframes mistDriftB {
  0% {
    transform: translateX(2%) translateY(0);
  }
  100% {
    transform: translateX(-4%) translateY(1%);
  }
}

@keyframes particleRise {
  0% {
    transform: translate(0, 0);
    opacity: 0;
  }
  12% {
    opacity: var(--particle-opacity, 0.6);
  }
  85% {
    opacity: var(--particle-opacity, 0.6);
  }
  100% {
    transform: translate(var(--particle-drift, 6px), -140px);
    opacity: 0;
  }
}

@keyframes microDrift {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}

@keyframes floatDown {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(5px);
  }
}

@keyframes floatTilt {
  0%,
  100% {
    transform: rotate(-0.4deg);
  }
  50% {
    transform: rotate(0.4deg);
  }
}

@keyframes floatDrift {
  0%,
  100% {
    transform: translateX(0);
  }
  50% {
    transform: translateX(3px);
  }
}

@keyframes floatBreathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.015);
  }
}

@keyframes energyTravel {
  to {
    stroke-dashoffset: -201;
  }
}

@keyframes pathTravel {
  0% {
    stroke-dashoffset: 240;
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    stroke-dashoffset: 0;
    opacity: 0;
  }
}

@keyframes marquee-left {
  from {
    transform: translate3d(0%, 0, 0);
  }
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

@keyframes marquee-right {
  from {
    transform: translate3d(-50%, 0, 0);
  }
  to {
    transform: translate3d(0%, 0, 0);
  }
}

/* ---------------------------------------------------------------
   3. Hero mount entrance (mirrors HeroClient's Framer `variants`:
      staggerChildren 0.14s/delayChildren 0.05s container, 0.7s
      opacity+y items, 0.8s clip-path mask-reveal on each headline
      line). Fires once on load — no IntersectionObserver needed
      since the hero is always in view on load.
   --------------------------------------------------------------- */
.hero__eyebrow,
.hero__lead,
.hero__ctas {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 0.7s var(--ease-editorial),
    transform 0.7s var(--ease-editorial);
}

.hero__eyebrow {
  transition-delay: 0.05s;
}

.hero__lead {
  transition-delay: 0.33s;
}

.hero__ctas {
  transition-delay: 0.47s;
}

.hero__mask-line {
  display: block;
  overflow: hidden;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.8s var(--ease-editorial);
}

.hero__mask-line:nth-child(1) {
  transition-delay: 0.19s;
}

.hero__mask-line:nth-child(2) {
  transition-delay: 0.33s;
}

.hero.is-loaded .hero__eyebrow,
.hero.is-loaded .hero__lead,
.hero.is-loaded .hero__ctas {
  opacity: 1;
  transform: translateY(0);
}

.hero.is-loaded .hero__mask-line {
  clip-path: inset(0 0 0% 0);
}

@media (prefers-reduced-motion: reduce) {
  .hero__eyebrow,
  .hero__lead,
  .hero__ctas {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero__mask-line {
    clip-path: inset(0 0 0% 0) !important;
  }
}

/* ---------------------------------------------------------------
   4. Cinematic environment — idle motion (each layer on its own
      timing, see js/animations.js for the pointer-parallax and
      scroll-progress values these are combined with).
   --------------------------------------------------------------- */
.cine__mist-a {
  animation: mistDriftA 28s ease-in-out infinite alternate;
}

.cine__mist-b {
  animation: mistDriftB 34s ease-in-out infinite alternate;
}

.cine__particle {
  animation: particleRise var(--dur) ease-in-out infinite;
}

.cine__path-travel {
  animation: pathTravel 9s ease-in-out infinite;
  animation-delay: 2s;
}

.portal__glow {
  animation: envGlow 8s ease-in-out infinite;
}

.portal__breathe {
  animation: portalBreathe 7s ease-in-out infinite;
}

.portal__ring-outer {
  animation: slowSpin 28s linear infinite;
}

.portal__ring-technical {
  transform-origin: 50px 50px;
  animation: slowSpin 35s linear infinite reverse;
}

.portal__energy {
  transform-origin: 50px 50px;
  filter: drop-shadow(0 0 14px rgba(215, 25, 32, 0.55));
  animation: energyTravel 9s linear infinite;
}

.portal__marker {
  animation: nodePulse 4s ease-in-out infinite;
}

.panel__glow {
  animation: envGlow 9s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .cine__mist-a,
  .cine__mist-b,
  .cine__particle,
  .cine__path-travel,
  .portal__glow,
  .portal__breathe,
  .portal__ring-outer,
  .portal__ring-technical,
  .portal__energy,
  .portal__marker,
  .panel__glow,
  .panel__anim {
    animation: none !important;
  }
}

.panel__anim {
  animation: var(--panel-anim) var(--panel-dur) ease-in-out infinite;
  animation-delay: var(--panel-delay, 0s);
}

/* ---------------------------------------------------------------
   5. Scroll cue marker loop (ScrollCue.tsx)
   --------------------------------------------------------------- */
.scroll-cue__marker {
  animation: scrollMarker 2.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .scroll-cue__marker {
    animation: none !important;
  }
}

/* ---------------------------------------------------------------
   6. Service visual mount-in accents (Transformation/Cybersecurity/AI/
      Event/Contracting/Robotics visuals used by the Capability Universe stage)
   --------------------------------------------------------------- */
.visual__pulse {
  animation: pulseIn 0.7s ease-out backwards;
}

.visual__ring-pulse {
  animation: ringPulse 3s ease-in-out infinite;
}

.visual__ring-pulse-fast {
  animation: ringPulse 2.4s ease-in-out infinite;
}

.visual__draw {
  animation: drawPath 2.6s ease-out forwards;
}

.visual__spin-slow {
  transform-origin: 50px 50px;
  animation: slowSpin 22s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .visual__pulse,
  .visual__ring-pulse,
  .visual__ring-pulse-fast,
  .visual__draw,
  .visual__spin-slow {
    animation: none !important;
  }
}

/* ---------------------------------------------------------------
   7. Capability Universe — desktop crossfade stage + mobile accordion
   --------------------------------------------------------------- */
.cap-stage__panel {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity 0.5s var(--ease-editorial),
    transform 0.5s var(--ease-editorial);
  pointer-events: none;
}

.cap-stage__panel.is-active {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

.cap-stage__blurb {
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 0.4s var(--ease-editorial),
    transform 0.4s var(--ease-editorial);
  position: absolute;
  inset-inline: 0;
}

.cap-stage__blurb.is-active {
  position: relative;
  opacity: 1;
  transform: translateY(0);
}

.cap-row__preview {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition:
    grid-template-rows 0.45s var(--ease-editorial),
    opacity 0.45s var(--ease-editorial);
}

.cap-row__preview.is-expanded {
  grid-template-rows: 1fr;
  opacity: 1;
}

.cap-row__preview-inner {
  overflow: hidden;
  min-height: 0;
}

@media (prefers-reduced-motion: reduce) {
  .cap-stage__panel,
  .cap-stage__blurb,
  .cap-row__preview {
    transition: none !important;
  }
}

/* ---------------------------------------------------------------
   8. Partners marquee — ported verbatim from app/globals.css,
      including its own comment explaining the seamless-loop math
      and why the animation lives in the stylesheet (not inline).
   --------------------------------------------------------------- */
.marquee-track {
  display: flex;
  width: max-content;
}

@media (prefers-reduced-motion: no-preference) {
  .marquee-track {
    animation-name: var(--marquee-name);
    animation-duration: var(--marquee-duration);
    animation-delay: var(--marquee-delay, 0s);
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
}

.marquee-row:hover .marquee-track {
  animation-play-state: paused;
}

.partner-marquee-fade {
  mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black 6%,
    black 94%,
    transparent
  );
}

/* ---------------------------------------------------------------
   9. Phase 3 — service pages

   ChapterFocus: the shared UPCOMING -> ACTIVE -> COMPLETED attention
   model (ported from components/services/scroll-focus/ChapterFocus.tsx).
   js/services.js drives --chapter-opacity via the same shared
   scroll-progress technique used on the homepage; reduced-motion
   freezes it at full opacity, matching the master's CSS-only approach.

   offsetTravel: a single shared keyframe for every "signal traveling
   along a path" effect across the original four service heroes (DT's beam,
   CS's orbit dots, AI's stream signals, CE's red light path) — each
   element supplies its own path via the `offset-path` custom
   property and its own duration/delay inline, so one keyframe rule
   serves all of them.
   --------------------------------------------------------------- */
.chapter-focus {
  opacity: var(--chapter-opacity, 1);
}

@media (prefers-reduced-motion: reduce) {
  .chapter-focus {
    opacity: 1 !important;
  }
}

@keyframes offsetTravel {
  0% {
    offset-distance: 0%;
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    offset-distance: 100%;
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dt-scene__signal,
  .cs-orbit-dot,
  .ai-stream-signal,
  .ce-red-path-signal {
    display: none;
  }
}
