diff --git a/src/App.tsx b/src/App.tsx
index 3a38d6b..177d7a3 100755
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
import PetDisplay from './components/PetDisplay';
import InteractionMenu from './components/InteractionMenu';
import PetRegister from './components/PetRegister';
+import AnimatedBackground from './components/AnimatedBackground';
import { Pet } from './types/Pet';
import { fetchPets } from './services/api/api';
@@ -32,19 +33,29 @@ export default function App() {
};
if (!pet) {
- return ;
+ return (
+ <>
+
+
+ >
+ );
}
return (
-
-
+ >
);
}
\ No newline at end of file
diff --git a/src/components/AnimatedBackground.tsx b/src/components/AnimatedBackground.tsx
new file mode 100644
index 0000000..38bda65
--- /dev/null
+++ b/src/components/AnimatedBackground.tsx
@@ -0,0 +1,105 @@
+import { useEffect, useRef } from 'react';
+
+export default function AnimatedBackground() {
+ const canvasRef = useRef
(null);
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+
+ const ctx = canvas.getContext('2d');
+ if (!ctx) return;
+
+ canvas.width = window.innerWidth;
+ canvas.height = window.innerHeight;
+
+ const particles: Particle[] = [];
+ const particleCount = 50;
+
+ class Particle {
+ x: number;
+ y: number;
+ size: number;
+ speedX: number;
+ speedY: number;
+ opacity: number;
+
+ constructor() {
+ this.x = Math.random() * canvas.width;
+ this.y = Math.random() * canvas.height;
+ this.size = Math.random() * 3 + 1;
+ this.speedX = Math.random() * 1 - 0.5;
+ this.speedY = Math.random() * 1 - 0.5;
+ this.opacity = Math.random() * 0.5 + 0.2;
+ }
+
+ update() {
+ this.x += this.speedX;
+ this.y += this.speedY;
+
+ if (this.x > canvas.width) this.x = 0;
+ if (this.x < 0) this.x = canvas.width;
+ if (this.y > canvas.height) this.y = 0;
+ if (this.y < 0) this.y = canvas.height;
+ }
+
+ draw() {
+ if (!ctx) return;
+ ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity})`;
+ ctx.beginPath();
+ ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
+ ctx.fill();
+ }
+ }
+
+ // Create particles
+ for (let i = 0; i < particleCount; i++) {
+ particles.push(new Particle());
+ }
+
+ function connectParticles() {
+ for (let i = 0; i < particles.length; i++) {
+ for (let j = i + 1; j < particles.length; j++) {
+ const dx = particles[i].x - particles[j].x;
+ const dy = particles[i].y - particles[j].y;
+ const distance = Math.sqrt(dx * dx + dy * dy);
+
+ if (distance < 100) {
+ if (!ctx) return;
+ ctx.strokeStyle = `rgba(255, 255, 255, ${0.2 * (1 - distance/100)})`;
+ ctx.lineWidth = 0.5;
+ ctx.beginPath();
+ ctx.moveTo(particles[i].x, particles[i].y);
+ ctx.lineTo(particles[j].x, particles[j].y);
+ ctx.stroke();
+ }
+ }
+ }
+ }
+
+ function animate() {
+ if (!ctx) return;
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ particles.forEach(particle => {
+ particle.update();
+ particle.draw();
+ });
+
+ connectParticles();
+ requestAnimationFrame(animate);
+ }
+
+ animate();
+
+ const handleResize = () => {
+ canvas.width = window.innerWidth;
+ canvas.height = window.innerHeight;
+ };
+
+ window.addEventListener('resize', handleResize);
+ return () => window.removeEventListener('resize', handleResize);
+ }, []);
+
+ return ;
+}
diff --git a/src/components/InteractionMenu.tsx b/src/components/InteractionMenu.tsx
index 5828780..cf2e1ef 100755
--- a/src/components/InteractionMenu.tsx
+++ b/src/components/InteractionMenu.tsx
@@ -137,7 +137,7 @@ export default function InteractionMenu({ pet, onPetUpdate }: InteractionMenuPro
};
return (
-
+
{remainingCooldown !== null && (
Cooldown: {formatCooldownTime(remainingCooldown)}
diff --git a/src/index.css b/src/index.css
index b5c61c9..ce68609 100755
--- a/src/index.css
+++ b/src/index.css
@@ -1,3 +1,18 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
+
+body {
+ margin: 0;
+ overflow-x: hidden;
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
+}
+
+.backdrop-blur-sm {
+ backdrop-filter: blur(8px);
+}
+
+/* Add smooth transitions */
+.transition-all {
+ transition: all 0.3s ease-in-out;
+}