.wrap{position:relative;width:100%;height:100%}
#cv{position:absolute;inset:0;width:100%;height:100%}
.promptbar{position:absolute;top:10px;left:10px;right:10px;z-index:2;display:flex;align-items:center;gap:7px;
padding:7px 10px;border-radius:10px;background:rgba(13,13,18,0.55);backdrop-filter:blur(6px);
border:1px solid rgba(255,255,255,0.15);font-size:11px;color:#f1f0ec;font-family:ui-monospace,monospace}
.dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex-shrink:0}
.caret{color:var(--accent);animation:blink 1s step-end infinite}
@keyframes blink{50%{opacity:0}}
const cv = document.getElementById('cv'), ctx = cv.getContext('2d');
const ptxt = document.getElementById('ptxt');
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 paintSunset(w, h) {
const r = mulberry32(7);
const g = ctx.createLinearGradient(0, 0, 0, h);
g.addColorStop(0, 'hsl(28 80% 62%)'); g.addColorStop(0.55, 'hsl(345 70% 48%)'); g.addColorStop(1, 'hsl(255 45% 18%)');
ctx.fillStyle = g; ctx.fillRect(0, 0, w, h);
ctx.beginPath(); ctx.arc(w * 0.5, h * 0.42, Math.min(w, h) * 0.09, 0, Math.PI * 2); ctx.fillStyle = 'hsl(45 95% 78%)'; ctx.fill();
for (let l = 0; l < 3; l++) {
ctx.beginPath(); ctx.moveTo(0, h);
for (let i = 0; i <= 6; i++) { const x = w * i / 6; const y = h * (0.58 + l * 0.09) - r() * h * 0.08 - Math.sin(i + l) * h * 0.02; ctx.lineTo(x, y); }
ctx.lineTo(w, h); ctx.closePath();
ctx.fillStyle = 'hsl(' + (280 + l * 10) + ' 30% ' + (14 + l * 7) + '%)'; ctx.fill();
}
}
function paintAurora(w, h) {
const r = mulberry32(7);
ctx.fillStyle = 'hsl(250 45% 8%)'; ctx.fillRect(0, 0, w, h);
for (let i = 0; i < 50; i++) { ctx.fillStyle = 'rgba(255,255,255,' + (0.2 + r() * 0.6) + ')'; ctx.beginPath(); ctx.arc(r() * w, r() * h * 0.7, r() * 1.4 + 0.3, 0, Math.PI * 2); ctx.fill(); }
for (let b = 0; b < 3; b++) {
ctx.beginPath();
for (let i = 0; i <= 20; i++) { const x = w * i / 20; const y = h * (0.25 + b * 0.08) + Math.sin(i * 0.5 + b) * h * 0.05; i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y); }
ctx.strokeStyle = 'hsla(' + (150 + b * 30) + ' 80% 60% / 0.5)'; ctx.lineWidth = h * 0.05; ctx.stroke();
}
ctx.beginPath(); ctx.moveTo(0, h);
for (let i = 0; i <= 6; i++) { const x = w * i / 6; const y = h * 0.9 - r() * h * 0.06; ctx.lineTo(x, y); }
ctx.lineTo(w, h); ctx.closePath(); ctx.fillStyle = 'hsl(250 30% 6%)'; ctx.fill();
}
const prompts = ['노을 지는 산과 호수', '별이 가득한 밤하늘과 오로라'];
let pi = 0, ci = 0;
function typeAndRender() {
const full = prompts[pi]; ci = 0; ptxt.textContent = '';
(function step() { ptxt.textContent = full.slice(0, ci); ci++; if (ci <= full.length) setTimeout(step, 55); else setTimeout(render, 300); })();
}
function render() {
const w = innerWidth, h = innerHeight;
if (pi === 0) paintSunset(w, h); else paintAurora(w, h);
setTimeout(() => { pi = (pi + 1) % prompts.length; typeAndRender(); }, 2400);
}
typeAndRender();