/* ==========================================================================
   SHIFT AI YOUTH — MOTION SYSTEM
   Purposeful, quick, weighted. No bounce. Every animation earns its place.
   ========================================================================== */

/* --------------------------------------------------------------------------
   KEYFRAMES
   -------------------------------------------------------------------------- */

/* Hero headline — words rise out of a mask */
@keyframes maskRise {
  from { transform: translateY(108%); }
  to   { transform: translateY(0); }
}

/* Icon stroke draw (inherited dash offset) */
@keyframes drawStroke {
  from { stroke-dashoffset: 80; }
  to   { stroke-dashoffset: 0; }
}

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

@keyframes barFill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes pulseRing {
  0%   { box-shadow: 0 0 0 0 rgba(255, 46, 147, 0.5); }
  70%  { box-shadow: 0 0 0 7px rgba(255, 46, 147, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 46, 147, 0); }
}

@keyframes pulseRingCyan {
  0%   { box-shadow: 0 0 0 0 rgba(0, 229, 255, 0.45); }
  70%  { box-shadow: 0 0 0 7px rgba(0, 229, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 229, 255, 0); }
}

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

@keyframes driftA {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(70px, 55px) scale(1.14); }
}
@keyframes driftB {
  0%, 100% { transform: translate(0, 0) scale(1.06); }
  50%      { transform: translate(-60px, -45px) scale(0.94); }
}
@keyframes driftC {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(45px, -60px) scale(1.1); }
}

/* Ticker — translate by exactly half the track for a seamless loop */
@keyframes tickerScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Gradient shimmer on serif-italic accents */
@keyframes shimmer {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

@keyframes numberPop {
  0%   { transform: translateY(6px) scale(0.97); opacity: 0.4; }
  100% { transform: none; opacity: 1; }
}

@keyframes slideDown {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   SCROLL REVEAL
   The hidden start-state is scoped to .js (set by an inline script in <head>)
   so that if JavaScript is unavailable or fails, every element - images
   included - stays visible instead of being stuck at opacity: 0.
   -------------------------------------------------------------------------- */
.js .reveal-up {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity 0.95s var(--ease) var(--d, 0s),
    transform 0.95s var(--ease) var(--d, 0s);
  will-change: opacity, transform;
}
.js .reveal-up.is-in {
  opacity: 1;
  transform: none;
}

.js .reveal-clip {
  opacity: 0;
  clip-path: inset(0 0 100% 0);
  transform: translateY(26px);
  transition:
    clip-path 1.25s var(--ease) var(--d, 0s),
    opacity 0.8s var(--ease) var(--d, 0s),
    transform 1.05s var(--ease) var(--d, 0s);
  will-change: clip-path, opacity, transform;
}
.js .reveal-clip.is-in {
  opacity: 1;
  clip-path: inset(0 0 0 0);
  transform: none;
}

/* Section eyebrow rule draws itself in */
.js .reveal-up .eyebrow-rule {
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.9s var(--ease) 0.25s;
}
.js .reveal-up.is-in .eyebrow-rule { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   HERO ENTRANCE (fires on load, not on scroll)
   -------------------------------------------------------------------------- */
.hero-title .mask {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}
.hero-title .mask-in {
  display: block;
  transform: translateY(108%);
  animation: maskRise 1.15s var(--ease) both;
  animation-delay: var(--d, 0s);
}
.hero-title em {
  background-size: 220% 100%;
  animation: shimmer 9s linear infinite 1.4s;
}

/* --------------------------------------------------------------------------
   CONTINUOUS AMBIENCE
   -------------------------------------------------------------------------- */
.ambient-a { animation: driftA 26s var(--ease-io) infinite alternate; }
.ambient-b { animation: driftB 32s var(--ease-io) infinite alternate; }
.ambient-c { animation: driftC 30s var(--ease-io) infinite alternate; }

.float-slow { animation: floatY 7s var(--ease-io) infinite; }

.ticker-track { animation: tickerScroll 42s linear infinite; }
.ticker:hover .ticker-track { animation-play-state: paused; }
.pulse-dot { animation: pulseRing 2.4s var(--ease-io) infinite; }

/* --------------------------------------------------------------------------
   MICRO-INTERACTIONS
   -------------------------------------------------------------------------- */

/* Stat numbers get a one-shot tick when they enter view */
.stat-num.is-ticking { animation: numberPop 0.6s var(--ease); }

/* Button press */
.btn:active { transform: translateY(0) scale(0.985); }

/* Focus reveal on inputs — the label lifts slightly */
.form-field:focus-within label { color: var(--ink); }

/* Hero CTA hover: underline sweep on the phone link */
.hero-call { position: relative; }
.hero-call::after {
  content: '';
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform 0.42s var(--ease);
}
.hero-call:hover::after { transform: scaleX(1); transform-origin: 0 50%; }

/* --------------------------------------------------------------------------
   REDUCED MOTION
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .js .reveal-up,
  .js .reveal-clip {
    opacity: 1 !important;
    clip-path: none !important;
    transform: none !important;
  }
  .hero-title .mask-in { transform: none; }
  .grain { display: none; }
  .sparkle-layer { display: none; }
}
