(function () { const canvas = document.getElementById('star-canvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); let w, h; function resize() { w = canvas.width = canvas.parentElement.clientWidth; h = canvas.height = canvas.parentElement.clientHeight; } resize(); window.addEventListener('resize', resize); const STAR_COUNT = 300; const colors = ['#ffffff', '#e0f7fa', '#fff9c4', '#fce4ec', '#4fc3f7']; const stars = []; for (let i = 0; i < STAR_COUNT; i++) { stars.push({ x: Math.random() * w, y: Math.random() * h, baseR: Math.random() * 1.5 + 0.3, phase: Math.random() * Math.PI * 2, speed: Math.random() * 0.02 + 0.005, color: colors[Math.floor(Math.random() * colors.length)], glow: Math.random() > 0.7 }); } function draw() { ctx.clearRect(0, 0, w, h); const t = performance.now() * 0.001; for (const s of stars) { const r = s.baseR + Math.sin(t * s.speed * 10 + s.phase) * s.baseR * 0.6; const alpha = 0.4 + Math.sin(t * s.speed * 8 + s.phase) * 0.35; ctx.globalAlpha = Math.max(0.1, alpha); ctx.beginPath(); ctx.arc(s.x, s.y, Math.max(0.1, r), 0, Math.PI * 2); ctx.fillStyle = s.color; ctx.fill(); if (s.glow) { const gr = ctx.createRadialGradient(s.x, s.y, 0, s.x, s.y, r * 3); gr.addColorStop(0, s.color); gr.addColorStop(1, 'transparent'); ctx.globalAlpha = alpha * 0.15; ctx.beginPath(); ctx.arc(s.x, s.y, r * 3, 0, Math.PI * 2); ctx.fillStyle = gr; ctx.fill(); } } ctx.globalAlpha = 1; requestAnimationFrame(draw); } draw(); // reposition on resize window.addEventListener('resize', () => { for (const s of stars) { s.x = (s.x / w) * canvas.width; s.y = (s.y / h) * canvas.height; } }); })();