@ko_studio · 6/9/2026, 8:17:47 PM
Initial version — all lines are new.
+<style>+ html,body{height:100%;margin:0;overflow:hidden;background:#160f24;}+ *{box-sizing:border-box;}+ #wrap{position:relative;height:100%;width:100%;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;-webkit-tap-highlight-color:transparent;touch-action:none;user-select:none;-webkit-user-select:none;cursor:crosshair;}+ canvas{display:block;width:100%;height:100%;position:absolute;inset:0;}+ #head{position:absolute;top:0;left:0;right:0;z-index:2;padding:1.15rem 1.25rem;pointer-events:none;display:flex;justify-content:space-between;align-items:flex-start;}+ #head h1{margin:0;font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-weight:400;font-size:2.35rem;line-height:1;color:#F3EEFF;}+ #head p{margin:.2rem 0 0;font-size:.8rem;color:#b3a6d6;font-weight:500;}+ #clear{position:absolute;bottom:1.1rem;right:1.1rem;z-index:3;pointer-events:auto;border:0;background:rgba(255,255,255,.1);color:#EBE4FF;border:1px solid rgba(255,255,255,.16);border-radius:999px;font-size:.72rem;font-weight:700;padding:.4rem .8rem;cursor:pointer;backdrop-filter:blur(6px);}+ #clear:active{transform:scale(.95);}+ #hint{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);z-index:2;pointer-events:none;font-family:"Instrument Serif",Georgia,serif;font-size:1.25rem;color:#b3a6d6;opacity:.85;transition:opacity .6s;text-align:center;}+</style>+<div id="wrap">+ <canvas id="cv"></canvas>+ <div id="head">+ <div><h1>Kaleido</h1><p>Drag to draw. It mirrors into a mandala.</p></div>+ </div>+ <button id="clear">clear</button>+ <div id="hint">drag anywhere</div>+</div>+<script>+(function(){+ var LL=window.liveloop||null;+ var muted = LL ? LL.muted : true;+ if(LL && LL.onMute){ try{ LL.onMute(function(m){ muted=m; }); }catch(e){} }+ if(LL && LL.declareMedia){ try{ LL.declareMedia({sound:true}); }catch(e){} }+ var _ac=null;+ function actx(){ if(!_ac){ try{ _ac=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){ _ac=null; } } return _ac; }+ function chime(freq){+ if(muted) return; var c=actx(); if(!c) return;+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();+ o.type='sine'; o.frequency.setValueAtTime(freq,t);+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(0.07,t+0.01);+ g.gain.exponentialRampToValueAtTime(0.0001,t+0.5);+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+0.55);+ }+ var SCALE=[523.25,587.33,659.25,783.99,880.0,1046.5,1174.7];++ var wrap=document.getElementById('wrap');+ var cv=document.getElementById('cv'), ctx=cv.getContext('2d');+ var hint=document.getElementById('hint');+ var W=0,H=0,dpr=1,cx=0,cy=0,T=0,raf=0,paused=false,rot=0;+ var SEG=6; // wedges; mirrored => 12-fold symmetry+ var COLS=['#7C5CFF','#6B4EFE','#E14C8F','#FF5A1F','#F6A93B','#3C9A6A','#9B7BFF'];+ var last=null, soundT=0;++ function size(){+ var r=wrap.getBoundingClientRect();+ W=Math.max(180,r.width); H=Math.max(240,r.height);+ dpr=Math.min(window.devicePixelRatio||1,2.5);+ cv.width=Math.round(W*dpr); cv.height=Math.round(H*dpr);+ ctx.setTransform(dpr,0,0,dpr,0,0); cx=W/2; cy=H/2;+ fillBg();+ }+ function fillBg(){+ var g=ctx.createRadialGradient(cx,cy,0,cx,cy,Math.max(W,H)*0.75);+ g.addColorStop(0,'#241634'); g.addColorStop(1,'#140d20');+ ctx.fillStyle=g; ctx.fillRect(0,0,W,H);+ }++ function paint(x,y){+ var dx=x-cx, dy=y-cy;+ var rad=Math.sqrt(dx*dx+dy*dy), ang=Math.atan2(dy,dx);+ var hue=COLS[Math.floor((rad/ (Math.min(W,H)*0.5) )*COLS.length)%COLS.length];+ var size=4+Math.min(16, rad*0.05);+ ctx.globalCompositeOperation='lighter';+ for(var s=0;s<SEG;s++){+ var a=ang + rot + s*(Math.PI*2/SEG);+ drawDot(cx+Math.cos(a)*rad, cy+Math.sin(a)*rad, size, hue);+ // mirror+ var a2=-ang + rot + s*(Math.PI*2/SEG);+ drawDot(cx+Math.cos(a2)*rad, cy+Math.sin(a2)*rad, size, hue);+ }+ ctx.globalCompositeOperation='source-over';+ var now=performance.now();+ if(now-soundT>110){ soundT=now; chime(SCALE[Math.min(SCALE.length-1, Math.floor(rad/(Math.min(W,H)*0.5)*SCALE.length))]); }+ if(hint.style.opacity!=='0') hint.style.opacity='0';+ }+ function drawDot(x,y,r,col){+ var g=ctx.createRadialGradient(x,y,0,x,y,r);+ g.addColorStop(0,col); g.addColorStop(1,'rgba(0,0,0,0)');+ ctx.fillStyle=g; ctx.beginPath(); ctx.arc(x,y,r,0,Math.PI*2); ctx.fill();+ }++ function frame(now){+ raf=requestAnimationFrame(frame);+ if(paused) return;+ var dt=Math.min(2.4,(now-T)/16.67); T=now;+ rot+=0.0009*dt; // slow drift so the mandala breathes+ // gentle fade so it stays alive and never fully clogs+ ctx.globalCompositeOperation='source-over';+ ctx.fillStyle='rgba(20,13,32,0.018)';+ ctx.fillRect(0,0,W,H);+ }++ function at(e){ var r=cv.getBoundingClientRect(), t=e.touches?e.touches[0]:e; return {x:t.clientX-r.left,y:t.clientY-r.top}; }+ function move(e){ e.preventDefault(); var p=at(e); if(last){ var steps=Math.max(1,Math.floor(Math.hypot(p.x-last.x,p.y-last.y)/6)); for(var i=1;i<=steps;i++){ paint(last.x+(p.x-last.x)*i/steps, last.y+(p.y-last.y)*i/steps); } } else paint(p.x,p.y); last=p; }+ wrap.addEventListener('pointerdown',function(e){ last=null; move(e); });+ wrap.addEventListener('pointermove',function(e){ if(e.buttons||e.pressure>0||(e.touches&&e.touches.length)) move(e); });+ wrap.addEventListener('pointerup',function(){ last=null; });+ wrap.addEventListener('pointerleave',function(){ last=null; });+ document.getElementById('clear').addEventListener('pointerdown',function(e){ e.stopPropagation(); fillBg(); hint.style.opacity='.85'; });++ if(LL && LL.onPause){ try{ LL.onPause(function(p){ paused=p; if(!p) T=performance.now(); }); }catch(e){} }+ document.addEventListener('visibilitychange',function(){ paused=document.hidden; if(!paused) T=performance.now(); });+ window.addEventListener('resize',size);+ size();+ // a faint starter mandala so it isn't empty+ for(var k=0;k<70;k++){ var a=Math.random()*Math.PI*2, rr=Math.random()*Math.min(W,H)*0.42; paint(cx+Math.cos(a)*rr, cy+Math.sin(a)*rr); }+ hint.style.opacity='.85';+ T=performance.now(); raf=requestAnimationFrame(frame);+})();+</script>