/*
 * animations.css — Mazin Lab Motion & Animation System
 *
 * Scroll-triggered reveal animations, keyframe definitions, stagger
 * delays, decorative motion effects, and a comprehensive
 * prefers-reduced-motion override.
 *
 * Depends on: main.css (design tokens must be loaded first)
 * JavaScript counterpart: static/js/animations.js adds .visible class
 * when elements enter the viewport.
 */


/* ============================================================
   SCROLL-TRIGGERED REVEAL
   Initial hidden state — JS adds .visible when in viewport
   ============================================================ */

.animate-on-scroll {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
  will-change: opacity, transform;
}

.animate-on-scroll.visible {
  opacity: 1;
  transform: translateY(0);
}


/* ============================================================
   FADE-UP — Hero and page-load animations
   Auto-plays on load (not scroll-triggered)
   ============================================================ */

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-fade-up {
  opacity: 0;
  animation: fadeInUp 0.7s ease-out forwards;
}

/* Directional variants */
.animate-slide-left {
  opacity: 0;
  transform: translateX(-40px);
  transition: opacity 0.65s ease-out, transform 0.65s ease-out;
  will-change: opacity, transform;
}

.animate-slide-left.visible {
  opacity: 1;
  transform: translateX(0);
}

.animate-slide-right {
  opacity: 0;
  transform: translateX(40px);
  transition: opacity 0.65s ease-out, transform 0.65s ease-out;
  will-change: opacity, transform;
}

.animate-slide-right.visible {
  opacity: 1;
  transform: translateX(0);
}

.animate-fade {
  opacity: 0;
  transition: opacity 0.7s ease-out;
  will-change: opacity;
}

.animate-fade.visible {
  opacity: 1;
}

/* Scale-in variant (good for cards, images) */
.animate-scale {
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 0.55s ease-out, transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
  will-change: opacity, transform;
}

.animate-scale.visible {
  opacity: 1;
  transform: scale(1);
}


/* ============================================================
   STAGGER DELAYS
   Apply alongside any animate-on-scroll class to sequence
   sibling elements.

   Usage: <div class="animate-on-scroll animate-delay-2">
   ============================================================ */

.animate-delay-1 { transition-delay: 0.1s; }
.animate-delay-2 { transition-delay: 0.2s; }
.animate-delay-3 { transition-delay: 0.3s; }
.animate-delay-4 { transition-delay: 0.4s; }
.animate-delay-5 { transition-delay: 0.5s; }
.animate-delay-6 { transition-delay: 0.6s; }

/* Finer stagger for dense grids */
.animate-delay-05  { transition-delay: 0.05s; }
.animate-delay-15  { transition-delay: 0.15s; }
.animate-delay-25  { transition-delay: 0.25s; }


/* ============================================================
   @KEYFRAMES — ENTRY ANIMATIONS
   ============================================================ */

/* Plain opacity */
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Slide from left */
@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-40px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* Slide from right */
@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(40px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* Scale into view */
@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Clip / curtain reveal — for ruled lines and dividers */
@keyframes clipReveal {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0% 0 0); }
}


/* ============================================================
   @KEYFRAMES — DECORATIVE / CONTINUOUS ANIMATIONS
   ============================================================ */

/* Gentle floating — for decorative elements, icons */
@keyframes float {
  0%, 100% { transform: translateY(0px); }
  50%       { transform: translateY(-10px); }
}

/* Slow drift used for starfield overlays */
@keyframes drift {
  0%   { transform: translate(0, 0) rotate(0deg); }
  33%  { transform: translate(8px, -6px) rotate(1deg); }
  66%  { transform: translate(-5px, 4px) rotate(-0.5deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}

/* Pulsing glow — for active project badges, accent elements */
@keyframes pulse-glow {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(77, 166, 255, 0);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(77, 166, 255, 0.15),
                0 0 20px rgba(77, 166, 255, 0.2);
  }
}

/* Amber glow variant — for star/detector elements */
@keyframes pulse-glow-amber {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(244, 162, 97, 0);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(244, 162, 97, 0.15),
                0 0 20px rgba(244, 162, 97, 0.2);
  }
}

/* Drawing a line progressively — timeline, chart axes */
@keyframes draw-line {
  from {
    transform: scaleY(0);
    transform-origin: top center;
  }
  to {
    transform: scaleY(1);
    transform-origin: top center;
  }
}

/* Spin — loading spinners */
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Bounce — scroll indicator (also defined in main.css for hero) */
@keyframes bounce {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%       { transform: translateX(-50%) translateY(8px); }
}

/* Ticker / marquee motion */
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Orbit — for decorative circular motion around a center */
@keyframes orbit {
  from { transform: rotate(0deg) translateX(60px) rotate(0deg); }
  to   { transform: rotate(360deg) translateX(60px) rotate(-360deg); }
}

/* Shimmer — skeleton loading placeholder */
@keyframes shimmer {
  0%   { background-position: -800px 0; }
  100% { background-position: 800px 0; }
}

/* Typing cursor blink */
@keyframes blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}


/* ============================================================
   UTILITY ANIMATION CLASSES
   Apply directly to elements for one-shot or looping effects
   ============================================================ */

/* Entry: use with JS-triggered class or on-load */
.anim-fade-in-up {
  animation: fadeInUp 0.7s ease-out both;
}

.anim-fade-in {
  animation: fadeIn 0.6s ease-out both;
}

.anim-slide-in-left {
  animation: slideInLeft 0.65s ease-out both;
}

.anim-slide-in-right {
  animation: slideInRight 0.65s ease-out both;
}

.anim-scale-in {
  animation: scaleIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Continuous loops */
.anim-float {
  animation: float 5s ease-in-out infinite;
}

.anim-float-slow {
  animation: float 8s ease-in-out infinite;
}

.anim-drift {
  animation: drift 14s ease-in-out infinite;
}

.anim-spin {
  animation: spin 1s linear infinite;
}

.anim-spin-slow {
  animation: spin 3s linear infinite;
}

.anim-pulse-glow {
  animation: pulse-glow 3s ease-in-out infinite;
}

.anim-pulse-glow-amber {
  animation: pulse-glow-amber 3s ease-in-out infinite;
}

.anim-blink {
  animation: blink 1s step-end infinite;
}

/* Stagger helpers for JS-triggered batch reveals */
.anim-delay-100 { animation-delay: 0.1s; }
.anim-delay-200 { animation-delay: 0.2s; }
.anim-delay-300 { animation-delay: 0.3s; }
.anim-delay-400 { animation-delay: 0.4s; }
.anim-delay-500 { animation-delay: 0.5s; }
.anim-delay-600 { animation-delay: 0.6s; }
.anim-delay-700 { animation-delay: 0.7s; }
.anim-delay-800 { animation-delay: 0.8s; }


/* ============================================================
   COMPONENT-SPECIFIC ANIMATION BINDINGS
   ============================================================ */

/* Active badge: pulsing glow ring */
.badge-active {
  animation: pulse-glow 3.5s ease-in-out infinite;
}

/* Hero scroll indicator bounce — uses .hero-scroll defined in main.css */
.hero-scroll {
  animation: bounce 2.5s ease-in-out infinite;
}

/* Timeline vertical rule draw-in on page load */
.timeline::before {
  animation: draw-line 1.2s ease-out 0.3s both;
}

/* Timeline dot pop-in: applied when item is .visible */
.timeline-item .timeline-dot {
  opacity: 0;
  transform: scale(0);
  transition: opacity 0.35s ease, transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
  transition-delay: 0.15s;
}

.timeline-item.visible .timeline-dot {
  opacity: 1;
  transform: scale(1);
}

/* Skeleton loading shimmer */
.skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-surface) 25%,
    var(--bg-card) 50%,
    var(--bg-surface) 75%
  );
  background-size: 800px 100%;
  animation: shimmer 1.8s linear infinite;
  border-radius: var(--radius-md);
}

/* Typing cursor */
.typing-cursor::after {
  content: '|';
  animation: blink 1s step-end infinite;
  color: var(--accent-blue);
  margin-left: 1px;
}

/* Nav link underline slide */
.nav-link {
  position: relative;
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background: var(--accent-blue);
  border-radius: 1px;
  transition: width var(--transition-base);
}

.nav-link:hover::after,
.nav-link.active::after {
  width: 100%;
}

/* Card image zoom is handled via transition in main.css;
   this makes the overflow clip work with the transition: */
.card .card-image-wrapper {
  overflow: hidden;
}

/* Science card paper-link reveal already on .science-card:hover
   in components.css — no additional keyframe needed. */

/* Press item arrow transition */
.press-item:hover .press-read-more::after {
  animation: none; /* override any inherited animation */
}

/* Marquee / ticker for partner logos or news tickers */
.marquee-track {
  display: flex;
  gap: var(--space-12);
  animation: marquee 28s linear infinite;
  width: max-content;
}

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

.marquee-wrapper {
  overflow: hidden;
  mask-image: linear-gradient(
    to right,
    transparent,
    black 10%,
    black 90%,
    transparent
  );
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    black 10%,
    black 90%,
    transparent
  );
}

/* Decorative floating orbs */
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.08;
  pointer-events: none;
  animation: drift 20s ease-in-out infinite;
}

.orb-blue {
  background: var(--accent-blue);
}

.orb-amber {
  background: var(--accent-amber);
  animation-delay: -7s;
  animation-duration: 18s;
}

.orb-violet {
  background: var(--accent-violet);
  animation-delay: -12s;
  animation-duration: 24s;
}

/* Page transition — body class toggled by JS router */
.page-enter {
  animation: fadeIn 0.4s ease-out both;
}

.page-exit {
  animation: fadeIn 0.25s ease-in reverse both;
}


/* ============================================================
   REDUCED MOTION — respect user accessibility preference
   Disables ALL animations and transitions for users who
   have enabled "Reduce Motion" in their OS settings.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  /* Disable all transitions */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Reveal elements immediately — they would otherwise stay hidden */
  .animate-on-scroll,
  .animate-slide-left,
  .animate-slide-right,
  .animate-fade,
  .animate-scale {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* Timeline dot — show immediately */
  .timeline-item .timeline-dot {
    opacity: 1;
    transform: scale(1);
    transition: none;
  }

  /* Timeline line — show immediately */
  .timeline::before {
    animation: none;
    transform: scaleY(1);
  }

  /* Stop all looping decorative animations */
  .badge-active,
  .hero-scroll,
  .anim-float,
  .anim-float-slow,
  .anim-drift,
  .anim-spin,
  .anim-spin-slow,
  .anim-pulse-glow,
  .anim-pulse-glow-amber,
  .anim-blink,
  .orb,
  .marquee-track,
  .typing-cursor::after {
    animation: none !important;
  }

  /* Stop skeleton shimmer (static placeholder is fine) */
  .skeleton {
    animation: none;
    background: var(--bg-surface);
  }

  /* No hover transforms on cards */
  .card:hover,
  .science-card:hover,
  .press-item:hover {
    transform: none;
  }

  /* No image zoom on hover */
  .card:hover .card-image,
  .facility-item:hover .facility-image,
  .science-card:hover .science-card-image {
    transform: none;
  }

  /* Reveal paper link immediately rather than on hover */
  .science-card-paper-link {
    opacity: 1;
    transform: none;
  }
}
