const c = document.createElement('canvas');
document.body.appendChild(c);
c.style.width = '100%'; c.style.height = '100%';
const ctx = c.getContext('2d');
const cs = getComputedStyle(document.documentElement);
const palette = [cs.getPropertyValue('--accent').trim(), cs.getPropertyValue('--accent-2').trim(), cs.getPropertyValue('--accent-3').trim()].map(x => x || '#5b5bf7');
function shade(hex, k) {
const n = parseInt(hex.replace('#', ''), 16);
const r = Math.min(255, (n >> 16) * k), g = Math.min(255, ((n >> 8) & 255) * k), b = Math.min(255, (n & 255) * k);
return 'rgb(' + (r | 0) + ',' + (g | 0) + ',' + (b | 0) + ')';
}
let w, h;
function resize() {
const dpr = Math.min(devicePixelRatio || 1, 2);
w = innerWidth; h = innerHeight;
c.width = w * dpr; c.height = h * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
addEventListener('resize', resize);
resize();
const N = 14;
const seeds = Array.from({ length: N }, (_, i) => ({
x: Math.random() * w, y: Math.random() * h,
vx: (Math.random() - 0.5) * 14, vy: (Math.random() - 0.5) * 14,
c: shade(palette[i % palette.length], 0.55 + 0.45 * Math.random()),
}));
const STEP = 9;
function draw() {
for (let y = 0; y < h; y += STEP) {
for (let x = 0; x < w; x += STEP) {
let best = 0, bd = Infinity;
for (let i = 0; i < seeds.length; i++) {
const s = seeds[i], d = (s.x - x) * (s.x - x) + (s.y - y) * (s.y - y);
if (d < bd) { bd = d; best = i; }
}
ctx.fillStyle = seeds[best].c;
ctx.fillRect(x, y, STEP + 1, STEP + 1);
}
}
ctx.fillStyle = 'rgba(13,13,18,0.85)';
for (const s of seeds) { ctx.beginPath(); ctx.arc(s.x, s.y, 3, 0, 7); ctx.fill(); }
}
function step(dt) {
for (const s of seeds) {
s.x += s.vx * dt; s.y += s.vy * dt;
if (s.x < 0 || s.x > w) s.vx *= -1;
if (s.y < 0 || s.y > h) s.vy *= -1;
s.x = Math.max(0, Math.min(w, s.x)); s.y = Math.max(0, Math.min(h, s.y));
}
}
draw(); // 초기 상태부터 바로 보이게
(function loop() { step(0.03); draw(); requestAnimationFrame(loop); })();