const cv = document.getElementById('cv'), ctx = cv.getContext('2d');
function fit() { const dpr = Math.min(devicePixelRatio || 1, 2); cv.width = innerWidth * dpr; cv.height = innerHeight * dpr; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); }
addEventListener('resize', fit); fit();
function mulberry32(a) { return function () { a |= 0; a = a + 0x6D2B79F5 | 0; let t = Math.imul(a ^ a >>> 15, 1 | a); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; return ((t ^ t >>> 14) >>> 0) / 4294967296; }; }
function paintScene(c, w, h, detail) {
const r = mulberry32(6);
const g = c.createLinearGradient(0, 0, 0, h);
g.addColorStop(0, 'hsl(205 50% 58%)'); g.addColorStop(1, 'hsl(205 35% 28%)');
c.fillStyle = g; c.fillRect(0, 0, w, h);
c.beginPath(); c.arc(w * 0.72, h * 0.22, Math.min(w, h) * 0.08, 0, Math.PI * 2); c.fillStyle = 'hsl(45 90% 75%)'; c.fill();
for (let l = 0; l < 3; l++) {
const pts = [];
c.beginPath(); c.moveTo(0, h);
for (let i = 0; i <= 7; i++) { const x = w * i / 7; const y = h * (0.5 + l * 0.13) - r() * h * 0.1; pts.push([x, y]); c.lineTo(x, y); }
c.lineTo(w, h); c.closePath();
c.fillStyle = 'hsl(' + (150 - l * 10) + ' 40% ' + (20 + l * 10) + '%)'; c.fill();
if (detail) {
c.strokeStyle = 'rgba(255,255,255,0.22)'; c.lineWidth = 0.6;
c.beginPath(); pts.forEach(([x, y], i) => (i ? c.lineTo(x, y) : c.moveTo(x, y))); c.stroke();
for (let i = 0; i < 14; i++) c.fillRect(r() * w, h * (0.5 + l * 0.13) - r() * h * 0.08, 1.2, 1.2);
}
}
}
function render(dividerX) {
const w = innerWidth, h = innerHeight;
ctx.clearRect(0, 0, w, h);
ctx.imageSmoothingEnabled = true;
paintScene(ctx, w, h, true);
ctx.save(); ctx.beginPath(); ctx.rect(0, 0, dividerX, h); ctx.clip();
const SW = 22, SH = 14;
const small = document.createElement('canvas'); small.width = SW; small.height = SH;
paintScene(small.getContext('2d'), SW, SH, false);
ctx.imageSmoothingEnabled = false;
ctx.drawImage(small, 0, 0, w, h);
ctx.restore();
ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(dividerX, 0); ctx.lineTo(dividerX, h); ctx.stroke();
ctx.beginPath(); ctx.arc(dividerX, h / 2, 9, 0, Math.PI * 2); ctx.fillStyle = '#fff'; ctx.fill();
}
let x = 0.5, dir = 1;
setInterval(() => {
render(innerWidth * x);
x += dir * 0.006;
if (x >= 0.82) dir = -1; if (x <= 0.18) dir = 1;
}, 40);
render(innerWidth * 0.5);