/* ============================================================
   19logiX — animations.css
   Companion motion utilities for style.css.
   Uses the same design tokens (--primary, --accent, --ease, --t)
   so nothing here overrides or conflicts with what style.css
   already defines (floatShape, [data-reveal], bounceSoft, etc.
   live in style.css — not duplicated here).
   ============================================================ */

/* ── Fade in ── */
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.fade-in { animation: fadeIn .5s var(--ease) both; }

/* ── Zoom / scale in ── */
@keyframes zoomIn {
  from { opacity: 0; transform: scale(.92); }
  to   { opacity: 1; transform: scale(1); }
}
.zoom-in { animation: zoomIn .45s var(--ease) both; }

/* ── Slide in (directional) ── */
@keyframes slideInUp {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes slideInDown {
  from { opacity: 0; transform: translateY(-24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes slideInLeft {
  from { opacity: 0; transform: translateX(-24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes slideInRight {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}
.slide-in-up    { animation: slideInUp .5s var(--ease) both; }
.slide-in-down  { animation: slideInDown .5s var(--ease) both; }
.slide-in-left  { animation: slideInLeft .5s var(--ease) both; }
.slide-in-right { animation: slideInRight .5s var(--ease) both; }

/* Shared stagger delays (also used by [data-delay] in style.css) */
.delay-100 { animation-delay: .1s; }
.delay-150 { animation-delay: .15s; }
.delay-200 { animation-delay: .2s; }
.delay-250 { animation-delay: .25s; }
.delay-300 { animation-delay: .3s; }
.delay-400 { animation-delay: .4s; }
.delay-500 { animation-delay: .5s; }
.delay-600 { animation-delay: .6s; }

/* ── Pulse ring — echoes hero/badge accents ── */
@keyframes pulseRing {
  0%   { transform: scale(1); opacity: .45; }
  100% { transform: scale(1.9); opacity: 0; }
}
.pulse-ring { position: relative; }
.pulse-ring::before {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: inherit;
  border: 2px solid var(--accent);
  animation: pulseRing 2s var(--ease) infinite;
}

/* ── Soft glow pulse — for badges, dots, live indicators ── */
@keyframes pulseGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), .5); }
  50%       { box-shadow: 0 0 0 8px rgba(var(--accent-rgb), 0); }
}
.pulse-glow { animation: pulseGlow 2.2s ease-in-out infinite; }

/* ── Shimmer — loading / skeleton states ── */
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.shimmer {
  background: linear-gradient(90deg, var(--surface) 25%, var(--border) 50%, var(--surface) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
  border-radius: var(--r-md);
}

/* ── Gradient text animation — matches .services-category-title span style ── */
@keyframes gradientShift {
  0%, 100% { background-position: 0% 50%; }
  50%       { background-position: 100% 50%; }
}
.gradient-text-anim {
  background: linear-gradient(270deg, var(--primary), var(--accent), var(--primary-dark), var(--primary));
  background-size: 300% 300%;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  animation: gradientShift 6s ease infinite;
}

/* ── Animated gradient border — for highlighted cards ── */
@keyframes borderFlow {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}
.gradient-border {
  position: relative;
  border-radius: var(--r-lg);
}
.gradient-border::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  padding: 2px;
  background: linear-gradient(90deg, var(--primary), var(--accent), var(--primary));
  background-size: 200% 100%;
  animation: borderFlow 4s linear infinite;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* ── Spin ── */
@keyframes spin { to { transform: rotate(360deg); } }
.spin { animation: spin 8s linear infinite; }
.spin-fast { animation: spin 1s linear infinite; }

/* ── Progress / loader fill — echoes .loader-bar-fill ── */
@keyframes fillBar { to { width: 100%; } }
.fill-bar { animation: fillBar 1.5s var(--ease) forwards; }

/* ── Card lift on hover (utility class, uses shared shadow tokens) ── */
.hover-lift {
  transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.hover-lift:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}

/* ── Icon pop on hover ── */
.hover-pop {
  transition: transform var(--t) var(--ease);
}
.hover-pop:hover { transform: scale(1.08); }

/* ── Ripple (for buttons / clickable chips) ── */
@keyframes ripple {
  0%   { transform: scale(0); opacity: .45; }
  100% { transform: scale(2.4); opacity: 0; }
}
.ripple { position: relative; overflow: hidden; }
.ripple::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 100%; padding-top: 100%;
  background: rgba(255, 255, 255, .5);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  pointer-events: none;
}
.ripple:active::after { animation: ripple .5s ease-out; }

/* ── Typewriter cursor blink ── */
@keyframes blinkCursor { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
.cursor-blink { animation: blinkCursor .9s step-end infinite; }

/* ── Counter tick (subtle number update pulse) ── */
@keyframes tickPulse {
  0%   { transform: scale(1); }
  30%  { transform: scale(1.12); color: var(--primary); }
  100% { transform: scale(1); }
}
.tick-pulse { display: inline-block; animation: tickPulse .35s var(--ease); }

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}