/* ============================================================
   ANIMATIONS STYLESHEET - Steam-like Game Platform
   All animations use transform/opacity for GPU-accelerated
   performance. will-change hints are added where appropriate.
   ============================================================ */

/* ------------------------------------------------------------
   Fade In Up
   Element fades in while moving upward
   ------------------------------------------------------------ */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-fade-in-up {
  animation: fadeInUp 0.5s ease both;
  will-change: opacity, transform;
}

/* ------------------------------------------------------------
   Fade In
   Simple opacity transition from hidden to visible
   ------------------------------------------------------------ */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.animate-fade-in {
  animation: fadeIn 0.4s ease both;
  will-change: opacity;
}

/* ------------------------------------------------------------
   Slide In From Left
   Element slides in from the left side
   ------------------------------------------------------------ */
@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.animate-slide-in-left {
  animation: slideInLeft 0.4s ease both;
  will-change: opacity, transform;
}

/* ------------------------------------------------------------
   Slide In From Right
   Element slides in from the right side
   ------------------------------------------------------------ */
@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.animate-slide-in-right {
  animation: slideInRight 0.4s ease both;
  will-change: opacity, transform;
}

/* ------------------------------------------------------------
   Scale Up
   Element grows from a smaller scale to full size
   ------------------------------------------------------------ */
@keyframes scaleUp {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.animate-scale-up {
  animation: scaleUp 0.3s ease both;
  will-change: opacity, transform;
}

/* ------------------------------------------------------------
   Pulse
   Gentle pulsing glow effect, useful for notifications
   ------------------------------------------------------------ */
@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.6;
  }
}

.animate-pulse {
  animation: pulse 2s ease-in-out infinite;
}

/* Secondary pulse with scale */
@keyframes pulseScale {
  0%, 100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.05);
    opacity: 0.85;
  }
}

.animate-pulse-scale {
  animation: pulseScale 2s ease-in-out infinite;
  will-change: transform, opacity;
}

/* ------------------------------------------------------------
   Skeleton Loading Shimmer
   Horizontal light sweep across skeleton placeholder
   ------------------------------------------------------------ */
@keyframes skeletonShimmer {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

.skeleton--animated {
  position: relative;
  overflow: hidden;
}

.skeleton--animated::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.04) 50%,
    transparent 100%
  );
  animation: skeletonShimmer 1.5s ease-in-out infinite;
  will-change: transform;
}

/* ------------------------------------------------------------
   Loading Spinner
   Rotating circle spinner
   ------------------------------------------------------------ */
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  will-change: transform;
}

.spinner--sm {
  width: 18px;
  height: 18px;
  border-width: 2px;
}

.spinner--lg {
  width: 48px;
  height: 48px;
  border-width: 4px;
}

/* Dots variant */
@keyframes dotBounce {
  0%, 80%, 100% {
    transform: scale(0.6);
    opacity: 0.4;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

.loading-dots {
  display: flex;
  gap: 6px;
  align-items: center;
  justify-content: center;
}

.loading-dots__dot {
  width: 8px;
  height: 8px;
  background: var(--color-accent);
  border-radius: 50%;
  animation: dotBounce 1.4s ease-in-out infinite;
  will-change: transform, opacity;
}

.loading-dots__dot:nth-child(2) {
  animation-delay: 0.16s;
}

.loading-dots__dot:nth-child(3) {
  animation-delay: 0.32s;
}

/* ------------------------------------------------------------
   Card Hover Transitions
   Applied via CSS transitions rather than keyframes for
   interactive hover states (complements .game-card in styles.css)
   ------------------------------------------------------------ */

/* Cards entrance — staggered via animation-delay on children */
.game-grid .game-card {
  opacity: 0;
  animation: fadeInUp 0.5s ease both;
}

.game-grid .game-card:nth-child(1) { animation-delay: 0.05s; }
.game-grid .game-card:nth-child(2) { animation-delay: 0.1s; }
.game-grid .game-card:nth-child(3) { animation-delay: 0.15s; }
.game-grid .game-card:nth-child(4) { animation-delay: 0.2s; }
.game-grid .game-card:nth-child(5) { animation-delay: 0.25s; }
.game-grid .game-card:nth-child(6) { animation-delay: 0.3s; }
.game-grid .game-card:nth-child(7) { animation-delay: 0.35s; }
.game-grid .game-card:nth-child(8) { animation-delay: 0.4s; }
.game-grid .game-card:nth-child(9) { animation-delay: 0.45s; }
.game-grid .game-card:nth-child(10) { animation-delay: 0.5s; }
.game-grid .game-card:nth-child(11) { animation-delay: 0.55s; }
.game-grid .game-card:nth-child(12) { animation-delay: 0.6s; }

/* ------------------------------------------------------------
   Button Press Effects
   Scale down on active/click for tactile feedback
   ------------------------------------------------------------ */
.btn {
  transition:
    transform 0.1s ease,
    background 0.2s ease,
    box-shadow 0.2s ease,
    color 0.2s ease;
}

.btn:active {
  transform: scale(0.95);
  transition-duration: 0.05s;
}

/* Ripple-like press effect */
@keyframes buttonRipple {
  0% {
    box-shadow: 0 0 0 0 var(--color-accent-glow);
  }
  100% {
    box-shadow: 0 0 0 12px transparent;
  }
}

.btn--ripple:active {
  animation: buttonRipple 0.4s ease-out;
}

/* ------------------------------------------------------------
   Page Transition
   Fade and slide up the main content area
   ------------------------------------------------------------ */
@keyframes pageEnter {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.page-transition {
  animation: pageEnter 0.35s ease both;
  will-change: opacity, transform;
}

/* Content area fades on route change */
@keyframes pageFadeOut {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-8px);
  }
}

.page-transition--exit {
  animation: pageFadeOut 0.2s ease both;
  will-change: opacity, transform;
}

/* ------------------------------------------------------------
   Staggered Entrance Animations
   Adds delayed entrance to a list of items.
   Apply .stagger-container to the parent and each direct child
   gets a cascading delay automatically.
   ------------------------------------------------------------ */
.stagger-container > * {
  opacity: 0;
  animation: fadeInUp 0.4s ease both;
}

/* Each child gets an incremental delay (up to 20 items) */
.stagger-container > *:nth-child(1)  { animation-delay: 0.03s; }
.stagger-container > *:nth-child(2)  { animation-delay: 0.06s; }
.stagger-container > *:nth-child(3)  { animation-delay: 0.09s; }
.stagger-container > *:nth-child(4)  { animation-delay: 0.12s; }
.stagger-container > *:nth-child(5)  { animation-delay: 0.15s; }
.stagger-container > *:nth-child(6)  { animation-delay: 0.18s; }
.stagger-container > *:nth-child(7)  { animation-delay: 0.21s; }
.stagger-container > *:nth-child(8)  { animation-delay: 0.24s; }
.stagger-container > *:nth-child(9)  { animation-delay: 0.27s; }
.stagger-container > *:nth-child(10) { animation-delay: 0.3s; }
.stagger-container > *:nth-child(11) { animation-delay: 0.33s; }
.stagger-container > *:nth-child(12) { animation-delay: 0.36s; }
.stagger-container > *:nth-child(13) { animation-delay: 0.39s; }
.stagger-container > *:nth-child(14) { animation-delay: 0.42s; }
.stagger-container > *:nth-child(15) { animation-delay: 0.45s; }
.stagger-container > *:nth-child(16) { animation-delay: 0.48s; }
.stagger-container > *:nth-child(17) { animation-delay: 0.51s; }
.stagger-container > *:nth-child(18) { animation-delay: 0.54s; }
.stagger-container > *:nth-child(19) { animation-delay: 0.57s; }
.stagger-container > *:nth-child(20) { animation-delay: 0.6s; }

/* ------------------------------------------------------------
   Scroll-Triggered Animations
   Elements with .animate-on-scroll start hidden and animate
   into view when they enter the viewport. JavaScript toggles
   the .animated class when the element is visible.
   ------------------------------------------------------------ */
.animate-on-scroll {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.6s ease,
    transform 0.6s ease;
  will-change: opacity, transform;
}

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

/* Variant: slide from left */
.animate-on-scroll--left {
  transform: translateX(-24px);
}

.animate-on-scroll--left.animated {
  transform: translateX(0);
}

/* Variant: slide from right */
.animate-on-scroll--right {
  transform: translateX(24px);
}

.animate-on-scroll--right.animated {
  transform: translateX(0);
}

/* Variant: scale in */
.animate-on-scroll--scale {
  transform: scale(0.92);
}

.animate-on-scroll--scale.animated {
  transform: scale(1);
}

/* Staggered scroll animation — add delays based on nth-child */
.animate-on-scroll.stagger > *:nth-child(1)  { transition-delay: 0.05s; }
.animate-on-scroll.stagger > *:nth-child(2)  { transition-delay: 0.1s; }
.animate-on-scroll.stagger > *:nth-child(3)  { transition-delay: 0.15s; }
.animate-on-scroll.stagger > *:nth-child(4)  { transition-delay: 0.2s; }
.animate-on-scroll.stagger > *:nth-child(5)  { transition-delay: 0.25s; }
.animate-on-scroll.stagger > *:nth-child(6)  { transition-delay: 0.3s; }

/* ------------------------------------------------------------
   Toast Notification Animations
   Toasts slide in from the right and stack vertically
   ------------------------------------------------------------ */
@keyframes toastSlideIn {
  from {
    opacity: 0;
    transform: translateX(100%) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

@keyframes toastSlideOut {
  from {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateX(100%) scale(0.95);
  }
}

.toast-container {
  position: fixed;
  top: var(--space-lg);
  right: var(--space-lg);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md) var(--space-lg);
  min-width: 300px;
  max-width: 420px;
  box-shadow: var(--shadow-lg);
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  animation: toastSlideIn 0.35s ease both;
  will-change: opacity, transform;
}

.toast--exit {
  animation: toastSlideOut 0.3s ease both;
}

.toast--success {
  border-left: 3px solid var(--color-success);
}

.toast--error {
  border-left: 3px solid var(--color-error);
}

.toast--warning {
  border-left: 3px solid var(--color-warning);
}

.toast--info {
  border-left: 3px solid var(--color-info);
}

.toast__icon {
  font-size: 1.2rem;
  flex-shrink: 0;
  margin-top: 1px;
}

.toast__content {
  flex: 1;
  min-width: 0;
}

.toast__title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin-bottom: 2px;
}

.toast__message {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  line-height: 1.4;
}

.toast__close {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  cursor: pointer;
  transition: background var(--transition-fast);
}

.toast__close:hover {
  background: var(--color-hover);
  color: var(--color-text);
}

/* Progress bar inside toast (auto-dismiss timer) */
.toast__progress {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 2px;
  background: var(--color-accent);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  animation: toastProgress linear forwards;
}

@keyframes toastProgress {
  from { width: 100%; }
  to { width: 0%; }
}

/* ------------------------------------------------------------
   Modal Open / Close Animations
   Backdrop fades in, modal scales up from center
   ------------------------------------------------------------ */
@keyframes modalBackdropIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes modalBackdropOut {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes modalOpen {
  from {
    opacity: 0;
    transform: scale(0.92) translateY(16px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

@keyframes modalClose {
  from {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
  to {
    opacity: 0;
    transform: scale(0.92) translateY(16px);
  }
}

/* These classes are toggled by JavaScript */
.modal-backdrop--enter {
  animation: modalBackdropIn 0.25s ease both;
}

.modal-backdrop--exit {
  animation: modalBackdropOut 0.2s ease both;
}

.modal--enter {
  animation: modalOpen 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  will-change: opacity, transform;
}

.modal--exit {
  animation: modalClose 0.2s ease both;
  will-change: opacity, transform;
}

/* Mobile bottom-sheet modal */
@media (max-width: 768px) {
  @keyframes modalSheetIn {
    from {
      transform: translateY(100%);
    }
    to {
      transform: translateY(0);
    }
  }

  @keyframes modalSheetOut {
    from {
      transform: translateY(0);
    }
    to {
      transform: translateY(100%);
    }
  }

  .modal-backdrop--enter {
    animation: modalBackdropIn 0.2s ease both;
  }

  .modal--enter {
    animation: modalSheetIn 0.35s cubic-bezier(0.22, 1, 0.36, 1) both;
    will-change: transform;
  }

  .modal--exit {
    animation: modalSheetOut 0.25s ease both;
    will-change: transform;
  }
}

/* ------------------------------------------------------------
   Sidebar Toggle Animation
   Smooth width transition and content reveal
   ------------------------------------------------------------ */
@keyframes sidebarExpand {
  from {
    width: var(--sidebar-collapsed-width);
  }
  to {
    width: var(--sidebar-width);
  }
}

@keyframes sidebarCollapse {
  from {
    width: var(--sidebar-width);
  }
  to {
    width: var(--sidebar-collapsed-width);
  }
}

@keyframes sidebarMobileOpen {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}

@keyframes sidebarMobileClose {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
}

/* Sidebar expand/collapse handled via width transition in styles.css.
   These classes provide explicit animation control when needed. */
.sidebar--expanding {
  animation: sidebarExpand 0.3s ease both;
  will-change: width;
}

.sidebar--collapsing {
  animation: sidebarCollapse 0.3s ease both;
  will-change: width;
}

.sidebar--mobile-enter {
  animation: sidebarMobileOpen 0.3s ease both;
  will-change: transform;
}

.sidebar--mobile-exit {
  animation: sidebarMobileClose 0.3s ease both;
  will-change: transform;
}

/* Nav item icon bounce on sidebar toggle */
@keyframes iconBounce {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.2); }
}

.sidebar--collapsing .nav-icon,
.sidebar--expanding .nav-icon {
  animation: iconBounce 0.3s ease;
}

/* ------------------------------------------------------------
   Utility Animation Classes
   Apply these for one-off animation needs
   ------------------------------------------------------------ */

/* Shake — for error feedback */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
  20%, 40%, 60%, 80% { transform: translateX(4px); }
}

.animate-shake {
  animation: shake 0.5s ease;
  will-change: transform;
}

/* Bounce — attention-grabbing */
@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
  }
  50% {
    transform: translateY(-8px);
    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
  }
}

.animate-bounce {
  animation: bounce 1s infinite;
}

/* Float — subtle hovering effect for decorative elements */
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

.animate-float {
  animation: float 3s ease-in-out infinite;
  will-change: transform;
}

/* Glow pulse — accent glow that pulses */
@keyframes glowPulse {
  0%, 100% {
    box-shadow: 0 0 10px var(--color-accent-glow);
  }
  50% {
    box-shadow: 0 0 25px var(--color-accent-glow), 0 0 40px rgba(102, 192, 244, 0.1);
  }
}

.animate-glow {
  animation: glowPulse 2s ease-in-out infinite;
  will-change: box-shadow;
}

/* Gradient shift — animated background gradient */
@keyframes gradientShift {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

.animate-gradient {
  background-size: 200% 200%;
  animation: gradientShift 4s ease infinite;
}

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

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

/* Number count-up placeholder style (pair with JS) */
@keyframes countUp {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.animate-count-up {
  animation: countUp 0.3s ease both;
}

/* ------------------------------------------------------------
   Reduced Motion
   Respect user preference for minimal animations
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .animate-on-scroll {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .game-grid .game-card {
    opacity: 1;
    animation: none;
  }

  .stagger-container > * {
    opacity: 1;
    animation: none;
  }
}
