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');
let w, h, leaves;
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);
leaves = [{ x: 0, y: 0, w, h, col: Math.random() < 0.3 ? palette[Math.floor(Math.random() * 3)] : null }];
for (let i = 0; i < 16; i++) split(); // 초기 상태부터 꽤 나뉘어 있도록
}
function split() {
if (leaves.length > 46) return;
const candidates = leaves.filter((r) => r.w > 40 && r.h > 40);
if (!candidates.length) return;
const r = candidates[Math.floor(Math.random() * candidates.length)];
const idx = leaves.indexOf(r);
const vertical = r.w > r.h;
const ratio = 0.32 + Math.random() * 0.36;
const col = () => (Math.random() < 0.22 ? palette[Math.floor(Math.random() * 3)] : null);
let a, b;
if (vertical) {
const cut = r.w * ratio;
a = { x: r.x, y: r.y, w: cut, h: r.h, col: col() };
b = { x: r.x + cut, y: r.y, w: r.w - cut, h: r.h, col: col() };
} else {
const cut = r.h * ratio;
a = { x: r.x, y: r.y, w: r.w, h: cut, col: col() };
b = { x: r.x, y: r.y + cut, w: r.w, h: r.h - cut, col: col() };
}
leaves.splice(idx, 1, a, b);
}
addEventListener('resize', resize);
resize();
function draw() {
ctx.fillStyle = '#0d0d12'; ctx.fillRect(0, 0, w, h);
for (const r of leaves) {
if (r.col) { ctx.fillStyle = r.col; ctx.fillRect(r.x, r.y, r.w, r.h); }
ctx.strokeStyle = 'rgba(241,240,236,0.7)'; ctx.lineWidth = 2; ctx.strokeRect(r.x, r.y, r.w, r.h);
}
}
draw();
let last = 0;
(function loop(t) {
if (t - last > 140) { split(); draw(); last = t; }
if (leaves.length >= 46 && t - last > 3200) { resize(); draw(); last = t; }
requestAnimationFrame(loop);
})(0);