/* =============================================================================
 *  animations.css  —  keyframes + scroll-reveal + ambient motion
 *  All motion is opacity/transform only (GPU-friendly) and is neutralized by
 *  the prefers-reduced-motion block in base.css.
 * ========================================================================== */

/* ---- scroll reveal (toggled to .is-visible by animations.js) -------- */
.reveal {
  opacity: 0;
  transform: translateY(28px) scale(0.985);
  transition:
    opacity 0.7s var(--ease-out),
    transform 0.7s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 70ms);
  will-change: opacity, transform;
}
.reveal.is-visible { opacity: 1; transform: none; }

/* If JS never runs, never trap content invisible. */
.no-js .reveal,
html:not(.js) .reveal { opacity: 1; transform: none; }

/* ---- status pulse ring ---------------------------------------------- */
@keyframes pulse-ring {
  0%   { transform: scale(0.7); opacity: 0.9; }
  70%  { transform: scale(1.8); opacity: 0; }
  100% { transform: scale(1.8); opacity: 0; }
}

/* ---- ambient blob drift --------------------------------------------- */
@keyframes drift-1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(6%, 8%) scale(1.08); }
}
@keyframes drift-2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(-7%, 5%) scale(1.12); }
}
@keyframes drift-3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(4%, -6%) scale(0.94); }
}
.blob--1 { animation: drift-1 22s var(--ease-inout) infinite; }
.blob--2 { animation: drift-2 27s var(--ease-inout) infinite; }
.blob--3 { animation: drift-3 31s var(--ease-inout) infinite; }

/* ---- hero gradient drift -------------------------------------------- */
@keyframes grad-shift {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
.hero__title.text-grad { animation: grad-shift 14s var(--ease-inout) infinite; }

/* ---- terminal caret (status strips) --------------------------------- */
@keyframes blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.caret { display: inline-block; width: 8px; }
.caret::after { content: "▌"; color: var(--accent-tertiary); animation: blink 1.1s steps(1) infinite; }

/* ---- shimmer for primary button (very subtle) ----------------------- */
.btn--primary { animation: grad-shift 8s var(--ease-inout) infinite; }

/* ---- dock entrance --------------------------------------------------- */
@keyframes dock-rise {
  from { opacity: 0; transform: translateX(-50%) translateY(28px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.dock-wrap { animation: dock-rise 0.8s var(--ease-spring) 0.4s both; }

/* ---- topbar entrance (opacity only — transform is owned by the chase JS) -- */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.topbar { animation: fade-in 0.6s var(--ease-out) both; }

/* ---- Lenis smooth scroll (required hooks) --------------------------- */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

/* ---- title "settle" — a brief retro-futurist boot-in (once, on reveal) -- */
@keyframes title-settle {
  0%   { opacity: 0; transform: translateY(6px) skewX(-7deg); clip-path: inset(0 0 64% 0); }
  38%  { opacity: 1; clip-path: inset(0 0 0 0); }
  46%  { transform: translateX(-2px) skewX(2deg); }
  56%  { transform: translateX(2px) skewX(0); }
  100% { transform: none; clip-path: inset(0 0 0 0); }
}
.section-head.is-visible .section-head__title { animation: title-settle 0.6s var(--ease-out) both; }

/* ---- background parallax (scroll-driven; graceful fallback) ---------
   parallax the CONTAINERS so the wireframes' own spin/float keep running */
@supports (animation-timeline: scroll()) {
  @keyframes parallax-up   { to { transform: translateY(-80px); } }
  @keyframes parallax-down { to { transform: translateY(60px); } }
  .wire-field { animation: parallax-up linear; animation-timeline: scroll(root); will-change: transform; }
  .blob-field { animation: parallax-down linear; animation-timeline: scroll(root); will-change: transform; }
}
