/* =====================================================
   GRAPH WORLDS - Animations
   ===================================================== */

/* =====================================================
   KEYFRAMES
   ===================================================== */

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

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

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

@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.8);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes pulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.05);
    opacity: 0.8;
  }
}

@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translateX(-5px);
  }
  20%,
  40%,
  60%,
  80% {
    transform: translateX(5px);
  }
}

@keyframes bounce {
  0%,
  20%,
  50%,
  80%,
  100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-15px);
  }
  60% {
    transform: translateY(-7px);
  }
}

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

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

@keyframes glow {
  0%,
  100% {
    box-shadow:
      0 0 5px var(--cyan),
      0 0 10px var(--cyan);
  }
  50% {
    box-shadow:
      0 0 20px var(--cyan),
      0 0 40px var(--cyan);
  }
}

@keyframes ripple {
  0% {
    transform: scale(0.8);
    opacity: 1;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

@keyframes nodeVisit {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 var(--cyan);
  }
  50% {
    transform: scale(1.3);
    box-shadow: 0 0 20px 10px var(--cyan);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 transparent;
  }
}

@keyframes pathTrace {
  from {
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes cellInfect {
  0% {
    background-color: var(--orange);
    transform: scale(1);
  }
  50% {
    background-color: var(--red);
    transform: scale(1.1);
  }
  100% {
    background-color: #8b4513;
    transform: scale(1);
  }
}

@keyframes cellHighlight {
  0%,
  100% {
    box-shadow: inset 0 0 0 2px var(--cyan);
  }
  50% {
    box-shadow:
      inset 0 0 0 4px var(--cyan),
      0 0 15px var(--cyan);
  }
}

@keyframes monsterAppear {
  0% {
    transform: scale(0) rotate(-180deg);
    opacity: 0;
  }
  100% {
    transform: scale(1) rotate(0);
    opacity: 1;
  }
}

@keyframes monsterDefeat {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(0);
    opacity: 0;
  }
}

@keyframes confettiFall {
  0% {
    transform: translateY(-100vh) rotate(0deg);
    opacity: 1;
  }
  100% {
    transform: translateY(100vh) rotate(720deg);
    opacity: 0;
  }
}

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

@keyframes blink {
  0%,
  50% {
    opacity: 1;
  }
  51%,
  100% {
    opacity: 0;
  }
}

@keyframes waveGradient {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

/* =====================================================
   ANIMATION CLASSES
   ===================================================== */

.anim-fade-in {
  animation: fadeIn 0.5s ease forwards;
}

.anim-fade-in-up {
  animation: fadeInUp 0.5s ease forwards;
}

.anim-fade-in-down {
  animation: fadeInDown 0.5s ease forwards;
}

.anim-slide-left {
  animation: slideInLeft 0.5s ease forwards;
}

.anim-slide-right {
  animation: slideInRight 0.5s ease forwards;
}

.anim-scale-in {
  animation: scaleIn 0.3s ease forwards;
}

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

.anim-shake {
  animation: shake 0.5s ease;
}

.anim-bounce {
  animation: bounce 1s ease;
}

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

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

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

/* =====================================================
   STAGGER DELAYS
   ===================================================== */

.stagger-1 {
  animation-delay: 0.1s;
}
.stagger-2 {
  animation-delay: 0.2s;
}
.stagger-3 {
  animation-delay: 0.3s;
}
.stagger-4 {
  animation-delay: 0.4s;
}
.stagger-5 {
  animation-delay: 0.5s;
}
.stagger-6 {
  animation-delay: 0.6s;
}
.stagger-7 {
  animation-delay: 0.7s;
}
.stagger-8 {
  animation-delay: 0.8s;
}
.stagger-9 {
  animation-delay: 0.9s;
}
.stagger-10 {
  animation-delay: 1s;
}

/* =====================================================
   GRAPH-SPECIFIC ANIMATIONS
   ===================================================== */

/* Node visited animation */
.node-visited {
  animation: nodeVisit 0.6s ease forwards;
}

/* Edge traced animation */
.edge-traced {
  stroke-dasharray: 1000;
  animation: pathTrace 1s linear forwards;
}

/* BFS wave effect */
.bfs-wave {
  position: absolute;
  border-radius: 50%;
  border: 2px solid var(--cyan);
  animation: ripple 1s ease-out forwards;
  pointer-events: none;
}

/* DFS depth indicator */
.dfs-depth {
  transition: all 0.3s ease;
}

.dfs-depth::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 4px;
  background: var(--purple);
  transform: scaleX(0);
  transform-origin: left;
  animation: depthFill 0.5s ease forwards;
}

@keyframes depthFill {
  to {
    transform: scaleX(1);
  }
}

/* Maze cell animations */
.maze-cell {
  transition:
    background-color 0.2s ease,
    transform 0.2s ease;
}

.maze-cell.visiting {
  animation: cellHighlight 0.5s ease;
}

.maze-cell.path {
  background-color: var(--gold) !important;
  animation: pulse 1s ease-in-out infinite;
}

/* Orange infection animation */
.orange-fresh {
  background: linear-gradient(135deg, #ffa500, #ff8c00);
  border-radius: 50%;
  transition: all 0.3s ease;
}

.orange-rotten {
  background: linear-gradient(135deg, #8b4513, #654321);
  border-radius: 50%;
}

.orange-infecting {
  animation: cellInfect 0.5s ease forwards;
}

/* Course chip animations */
.course-chip {
  transition: all 0.3s ease;
}

.course-chip.dragging {
  transform: scale(1.1);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  z-index: 100;
}

.course-chip.valid-drop {
  border-color: var(--green);
  box-shadow: 0 0 20px var(--green-glow);
}

.course-chip.invalid-drop {
  border-color: var(--red);
  animation: shake 0.3s ease;
}

/* Graph node animations */
.graph-node {
  transition: all 0.3s ease;
}

.graph-node:hover {
  transform: scale(1.2);
  filter: brightness(1.2);
}

.graph-node.selected {
  animation: glow 1s ease-in-out infinite;
}

.graph-node.source {
  box-shadow: 0 0 20px var(--green-glow);
}

.graph-node.target {
  box-shadow: 0 0 20px var(--red-glow);
}

/* Edge animations */
.graph-edge {
  transition:
    stroke 0.3s ease,
    stroke-width 0.3s ease;
}

.graph-edge.highlighted {
  stroke: var(--gold);
  stroke-width: 4;
  filter: drop-shadow(0 0 5px var(--gold));
}

.graph-edge.traversing {
  stroke-dasharray: 10 5;
  animation: edgeDash 0.5s linear infinite;
}

@keyframes edgeDash {
  to {
    stroke-dashoffset: -15;
  }
}

/* Monster animations */
.monster {
  animation: float 2s ease-in-out infinite;
}

.monster.appearing {
  animation: monsterAppear 0.5s ease forwards;
}

.monster.defeated {
  animation: monsterDefeat 0.5s ease forwards;
}

.monster.attacking {
  animation: shake 0.3s ease infinite;
}

/* Player animations */
.player {
  transition: all 0.3s ease;
}

.player.moving {
  animation: bounce 0.3s ease;
}

.player.attacking {
  animation: shake 0.2s ease;
}

/* Stack item animations */
.stack-item {
  animation: fadeInDown 0.3s ease forwards;
}

.stack-item.popping {
  animation: fadeInUp 0.3s ease reverse forwards;
}

/* Queue item animations */
.queue-item {
  animation: slideInRight 0.3s ease forwards;
}

.queue-item.dequeuing {
  animation: slideInLeft 0.3s ease reverse forwards;
}

/* =====================================================
   UI FEEDBACK ANIMATIONS
   ===================================================== */

/* Success flash */
.success-flash {
  animation: successPulse 0.5s ease;
}

@keyframes successPulse {
  0% {
    box-shadow: 0 0 0 0 var(--green);
  }
  50% {
    box-shadow: 0 0 30px 10px var(--green-glow);
  }
  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}

/* Error shake */
.error-shake {
  animation: shake 0.5s ease;
  border-color: var(--red) !important;
}

/* Score popup */
.score-popup {
  position: absolute;
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--gold);
  pointer-events: none;
  animation: scoreFloat 1s ease forwards;
}

@keyframes scoreFloat {
  0% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(-50px) scale(1.5);
  }
}

/* Button click feedback */
.btn-click {
  animation: btnClick 0.2s ease;
}

@keyframes btnClick {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(0.95);
  }
  100% {
    transform: scale(1);
  }
}

/* =====================================================
   LOADING ANIMATIONS
   ===================================================== */

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid var(--bg-tertiary);
  border-top-color: var(--cyan);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.loading-dots {
  display: flex;
  gap: 8px;
}

.loading-dot {
  width: 10px;
  height: 10px;
  background: var(--cyan);
  border-radius: 50%;
  animation: loadingDot 1.4s ease-in-out infinite;
}

.loading-dot:nth-child(1) {
  animation-delay: 0s;
}
.loading-dot:nth-child(2) {
  animation-delay: 0.2s;
}
.loading-dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes loadingDot {
  0%,
  80%,
  100% {
    transform: scale(0.6);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

/* Graph loading animation */
.graph-loading {
  position: relative;
}

.graph-loading::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 60px;
  height: 60px;
  border: 3px solid var(--bg-tertiary);
  border-radius: 50%;
}

.graph-loading::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 60px;
  height: 60px;
  border: 3px solid transparent;
  border-top-color: var(--cyan);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

/* =====================================================
   CONFETTI EFFECT
   ===================================================== */

.confetti-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
}

.confetti {
  position: absolute;
  width: 10px;
  height: 10px;
  animation: confettiFall 3s ease-in forwards;
}

.confetti:nth-child(odd) {
  background: var(--cyan);
}

.confetti:nth-child(even) {
  background: var(--gold);
}

.confetti:nth-child(3n) {
  background: var(--purple);
}

.confetti:nth-child(4n) {
  background: var(--green);
}

/* =====================================================
   TRANSITION CLASSES
   ===================================================== */

.trans-fast {
  transition: all 0.15s ease;
}
.trans-normal {
  transition: all 0.3s ease;
}
.trans-slow {
  transition: all 0.5s ease;
}

/* Screen transitions */
.screen-enter {
  animation: fadeIn 0.5s ease forwards;
}

.screen-exit {
  animation: fadeIn 0.5s ease reverse forwards;
}

/* Card hover effects */
.card-hover {
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
}

.card-hover:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

/* =====================================================
   PARTICLE EFFECTS
   ===================================================== */

.particle {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
}

.particle-cyan {
  background: var(--cyan);
  box-shadow: 0 0 10px var(--cyan);
}

.particle-green {
  background: var(--green);
  box-shadow: 0 0 10px var(--green);
}

.particle-purple {
  background: var(--purple);
  box-shadow: 0 0 10px var(--purple);
}

/* Explosion effect */
.explosion {
  position: absolute;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  animation: explode 0.5s ease forwards;
}

@keyframes explode {
  0% {
    transform: scale(0);
    opacity: 1;
  }
  100% {
    transform: scale(3);
    opacity: 0;
  }
}
