'use strict'; const themeButton = document.querySelector('[data-theme-toggle]'); let theme = 'light'; try { if(localStorage.getItem('datumwell.theme') === 'dark') theme = 'dark'; } catch {} function applyTheme() { document.documentElement.dataset.theme=theme; if(themeButton){themeButton.setAttribute('aria-label',`Switch to ${theme==='light'?'dark':'light'} theme`);themeButton.innerHTML=theme==='light'?'◐':'◑';} } applyTheme(); themeButton?.addEventListener('click',()=>{theme=theme==='light'?'dark':'light';applyTheme();try{localStorage.setItem('datumwell.theme',theme);}catch{}}); const background = document.createElement('canvas'); background.className='observation-field';background.setAttribute('aria-hidden','true'); document.body.prepend(background); const context = background.getContext('2d'); const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)'); let width=0,height=0,points=[],frame,lastTime=0; function resizeField(){ width=innerWidth;height=innerHeight; const ratio=Math.min(devicePixelRatio||1,2);background.width=width*ratio;background.height=height*ratio; context?.setTransform(ratio,0,0,ratio,0,0); points=Array.from({length:Math.min(200,Math.floor(width*height/4800))},(_,i)=>({x:((i*0.61803398875)%1)*width,y:((i*0.754877666)%1)*height,size:2+i%3,phase:i*1.3})); drawField(0); } function drawField(time){ if(!context)return; context.clearRect(0,0,width,height); context.fillStyle=theme==='dark'?'rgba(164,188,174,.11)':'rgba(110,133,119,.14)'; for(const p of points){const drift=reduceMotion.matches?0:Math.sin(time/11000+p.phase)*8;context.fillRect(p.x+drift,p.y+drift*.6,p.size,p.size);} } function animateField(time){ if(time-lastTime>65){drawField(time);lastTime=time;} frame=requestAnimationFrame(animateField); } function startField(){cancelAnimationFrame(frame);drawField(0);if(!reduceMotion.matches&&!document.hidden)frame=requestAnimationFrame(animateField);} resizeField();startField(); addEventListener('resize',resizeField); reduceMotion.addEventListener('change',startField); document.addEventListener('visibilitychange',startField); themeButton?.addEventListener('click',()=>drawField(0));