class ParticleBackground extends HTMLElement { connectedCallback() { this.style.position = 'absolute'; this.style.top = '0'; this.style.left = '0'; this.style.width = '100%'; this.style.height = '100%'; this.style.zIndex = '-1'; this.style.overflow = 'hidden'; this.style.pointerEvents = 'none'; const canvas = document.createElement('canvas'); this.appendChild(canvas); const ctx = canvas.getContext('2d'); canvas.width = this.offsetWidth; canvas.height = this.offsetHeight; const particles = []; const particleCount = Math.floor(window.innerWidth / 10); for (let i = 0; i < particleCount; i++) { particles.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, size: Math.random() * 3 + 1, speedX: Math.random() * 1 - 0.5, speedY: Math.random() * 1 - 0.5, color: `rgba(139, 92, 246, ${Math.random() * 0.2 + 0.1})` }); } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < particles.length; i++) { const p = particles[i]; ctx.fillStyle = p.color; ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fill(); p.x += p.speedX; p.y += p.speedY; if (p.x < 0 || p.x > canvas.width) p.speedX *= -1; if (p.y < 0 || p.y > canvas.height) p.speedY *= -1; } requestAnimationFrame(animate); } animate(); window.addEventListener('resize', () => { canvas.width = this.offsetWidth; canvas.height = this.offsetHeight; }); } } customElements.define('particle-background', ParticleBackground);