/* ==========================================================================
   Dual Internet — Motion layer
   Every animation is transform/opacity only (no layout thrash, CLS-safe).
   All of it collapses under prefers-reduced-motion at the bottom of this file.
   ========================================================================== */

/* ==========================================================================
   1. Scroll reveal — driven by IntersectionObserver adding .in-view
   ========================================================================== */
[data-reveal] {
  opacity: 0;
  will-change: transform, opacity;
  transition:
    opacity var(--dur-slower) var(--ease-out),
    transform var(--dur-slower) var(--ease-out),
    filter var(--dur-slower) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal="up"]      { transform: translate3d(0, 28px, 0); }
[data-reveal="down"]    { transform: translate3d(0, -22px, 0); }
[data-reveal="left"]    { transform: translate3d(34px, 0, 0); }
[data-reveal="right"]   { transform: translate3d(-34px, 0, 0); }
[data-reveal="scale"]   { transform: scale(0.94); }
[data-reveal="blur"]    { filter: blur(9px); transform: translate3d(0, 16px, 0); }
[data-reveal="rise"]    { transform: translate3d(0, 44px, 0) scale(0.975); }
[data-reveal="fade"]    { transform: none; }
[data-reveal="clip"]    { clip-path: inset(0 0 100% 0); transform: none; transition-property: clip-path, opacity; }

[data-reveal].in-view {
  opacity: 1;
  transform: none;
  filter: none;
  clip-path: inset(0 0 0 0);
}

/* Once revealed, drop the compositing hint */
[data-reveal].reveal-done { will-change: auto; }

/* Stagger — set as inline --reveal-delay by JS, but these are fallbacks */
[data-stagger] > * { --reveal-delay: 0ms; }

/* ==========================================================================
   2. Word / char text reveal (hero headline)
   ========================================================================== */
.split-line { display: block; overflow: hidden; padding-bottom: 0.06em; }
.split-word {
  display: inline-block;
  transform: translate3d(0, 108%, 0) rotate(3deg);
  opacity: 0;
  transition:
    transform 820ms var(--ease-out),
    opacity 620ms var(--ease-out);
  transition-delay: var(--wd, 0ms);
  will-change: transform, opacity;
}
.split-ready .split-word { transform: translate3d(0, 0, 0) rotate(0); opacity: 1; }

/* ==========================================================================
   3. Scroll-linked progress + parallax (CSS scroll-driven where supported)
   ========================================================================== */
.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--lane-a), var(--lane-b));
  z-index: var(--z-toast);
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  .scroll-progress {
    animation: sp-grow linear;
    animation-timeline: scroll(root block);
  }
  @keyframes sp-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* JS-driven parallax fallback sets --py */
[data-parallax] { will-change: transform; transform: translate3d(0, var(--py, 0px), 0); }

/* Scroll-driven fade+rise for section media, where supported */
@supports (animation-timeline: view()) {
  .view-rise {
    animation: view-rise linear both;
    animation-timeline: view();
    animation-range: entry 8% cover 34%;
  }
  @keyframes view-rise {
    from { opacity: 0; transform: translate3d(0, 46px, 0) scale(0.972); }
    to   { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
  }
  .view-scale {
    animation: view-scale linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 42%;
  }
  @keyframes view-scale {
    from { transform: scale(0.9); opacity: 0.4; }
    to   { transform: scale(1); opacity: 1; }
  }
}

/* ==========================================================================
   4. Ambient loops
   ========================================================================== */
@keyframes float-y {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50% { transform: translate3d(0, -18px, 0); }
}
.anim-float { animation: float-y 7s var(--ease-smooth) infinite; }
.anim-float-slow { animation: float-y 11s var(--ease-smooth) infinite; }

@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  33%  { transform: translate3d(38px, -26px, 0) scale(1.09); }
  66%  { transform: translate3d(-24px, 22px, 0) scale(0.94); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}
.anim-drift { animation: drift 22s var(--ease-smooth) infinite; }
.anim-drift-rev { animation: drift 27s var(--ease-smooth) infinite reverse; }

@keyframes pulse-soft {
  0%, 100% { opacity: 0.42; }
  50% { opacity: 0.82; }
}
.anim-pulse { animation: pulse-soft 3.6s var(--ease-smooth) infinite; }

@keyframes shimmer-sweep {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

/* Packet travelling along a lane */
@keyframes packet-run {
  0%   { offset-distance: 0%; opacity: 0; }
  8%   { opacity: 1; }
  92%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}

/* Dash flow along SVG paths */
@keyframes dash-flow { to { stroke-dashoffset: -240; } }
.flow-line {
  stroke-dasharray: 7 11;
  animation: dash-flow 3.4s linear infinite;
}
.flow-line-slow { animation-duration: 5.6s; }
.flow-line-fast { animation-duration: 2.1s; }

/* Radar sweep for speed test */
@keyframes sweep-rot { to { transform: rotate(360deg); } }

/* Caret blink for terminal */
@keyframes caret-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.caret {
  display: inline-block;
  width: 8px; height: 1.05em;
  background: var(--accent);
  vertical-align: text-bottom;
  animation: caret-blink 1.06s steps(1) infinite;
}

/* Gradient text/border travel */
@keyframes hue-travel { to { background-position: 200% center; } }
.anim-gradient {
  background-size: 200% auto;
  animation: hue-travel 6s linear infinite;
}

/* Marquee */
@keyframes marquee { to { transform: translate3d(-50%, 0, 0); } }
.marquee { overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent); -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent); }
.marquee-track { display: flex; width: max-content; animation: marquee 42s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }

/* Conic border rotation for featured cards */
@keyframes conic-spin { to { transform: rotate(360deg); } }
.conic-ring { position: relative; isolation: isolate; overflow: hidden; }
.conic-ring::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -140%;
  background: conic-gradient(from 0deg, transparent 0%, var(--lane-b) 12%, var(--lane-a) 24%, transparent 38%, transparent 100%);
  animation: conic-spin 7s linear infinite;
  opacity: 0.85;
}
.conic-ring::after {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 1px;
  border-radius: inherit;
  background: var(--surface);
}

/* ==========================================================================
   5. Entrance keyframes (for JS-triggered elements)
   ========================================================================== */
@keyframes pop-in {
  from { opacity: 0; transform: scale(0.86) translateY(8px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes slide-down-in { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ==========================================================================
   6. Hover micro-interactions
   ========================================================================== */
.hov-lift { transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out); }
.hov-lift:hover { transform: translateY(-3px); box-shadow: var(--shadow-3); }

.hov-tilt { transition: transform var(--dur-base) var(--ease-out); transform-style: preserve-3d; }

.press { transition: transform var(--dur-instant) var(--ease-spring); }
.press:active { transform: scale(0.955); }

/* Underline grow */
.hov-underline { position: relative; }
.hov-underline::after {
  content: '';
  position: absolute;
  left: 0; bottom: -3px;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-base) var(--ease-out);
}
.hov-underline:hover::after, .hov-underline[aria-current="page"]::after { transform: scaleX(1); }

/* ==========================================================================
   7. Number counters — reserve space so there is zero CLS
   ========================================================================== */
.counter { font-variant-numeric: tabular-nums; display: inline-block; }

/* ==========================================================================
   8. Accordion (FAQ) — grid-template-rows animation, no max-height hacks
   ========================================================================== */
.acc-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-smooth);
}
.acc-item.is-open .acc-panel { grid-template-rows: 1fr; }
.acc-panel > div { overflow: hidden; }
.acc-inner {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--dur-base) var(--ease-smooth) 40ms,
              transform var(--dur-base) var(--ease-smooth) 40ms;
}
.acc-item.is-open .acc-inner { opacity: 1; transform: translateY(0); }

/* ==========================================================================
   9. Reduced motion — kill everything decorative, keep state legible
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; clip-path: none !important; }
  .split-word { opacity: 1 !important; transform: none !important; }
  .anim-float, .anim-float-slow, .anim-drift, .anim-drift-rev,
  .anim-pulse, .anim-gradient, .marquee-track, .conic-ring::before,
  .flow-line, .caret { animation: none !important; }
  [data-parallax] { transform: none !important; }
  .scroll-progress { animation: none !important; }
  .acc-panel { transition: none !important; }
  .acc-inner { opacity: 1 !important; transform: none !important; }
  .btn::after { display: none !important; }
  .card-hover:hover, .hov-lift:hover, .btn-primary:hover, .btn-secondary:hover { transform: none !important; }
  .view-rise, .view-scale { animation: none !important; opacity: 1 !important; transform: none !important; }
}
