1(function(){ 2 const header=document.getElementById('siteHeader'); 3 const menu=document.querySelector('.menu-toggle'); 4 const nav=document.getElementById('primaryNav'); 5 const onScroll=()=>header&&header.classList.toggle('is-scrolled',window.scrollY>24); 6 onScroll(); window.addEventListener('scroll',onScroll,{passive:true}); 7 if(menu&&nav){menu.addEventListener('click',()=>{const open=nav.classList.toggle('is-open');menu.setAttribute('aria-expanded',open?'true':'false')});nav.querySelectorAll('a').forEach(a=>a.addEventListener('click',()=>{nav.classList.remove('is-open');menu.setAttribute('aria-expanded','false')}));} 8 9 const canvas=document.getElementById('ritual-field'); 10 if(!canvas) return; 11 const reduced=window.matchMedia('(prefers-reduced-motion: reduce)').matches; 12 const ctx=canvas.getContext('2d'); 13 let w=0,h=0,dpr=Math.min(window.devicePixelRatio||1,2),raf=0,t=0; 14 const particles=[]; 15 function resize(){w=canvas.clientWidth;h=canvas.clientHeight;canvas.width=w*dpr;canvas.height=h*dpr;ctx.setTransform(dpr,0,0,dpr,0,0);particles.length=0;const count=Math.min(64,Math.max(26,Math.floor(w/24)));for(let i=0;i<count;i++){particles.push({a:Math.random()*Math.PI*2,r:70+Math.random()*Math.min(w,h)*.46,s:.0007+Math.random()*.0014,z:.3+Math.random()*.8})}} 16 function draw(){ctx.clearRect(0,0,w,h);const cx=w*.72,cy=h*.43;const pulse=1+Math.sin(t*.012)*.035; 17 const grad=ctx.createRadialGradient(cx,cy,20,cx,cy,Math.min(w,h)*.42);grad.addColorStop(0,'rgba(188,169,255,.13)');grad.addColorStop(.45,'rgba(110,166,255,.045)');grad.addColorStop(1,'rgba(8,10,13,0)');ctx.fillStyle=grad;ctx.fillRect(0,0,w,h); 18 for(let i=0;i<5;i++){ctx.beginPath();ctx.strokeStyle=`rgba(255,255,255,${.06-i*.008})`;ctx.lineWidth=1;ctx.arc(cx,cy,(76+i*54)*pulse,0,Math.PI*2);ctx.stroke()} 19 particles.forEach((p,idx)=>{if(!reduced)p.a+=p.s*16;const x=cx+Math.cos(p.a)*(p.r*pulse),y=cy+Math.sin(p.a)*(p.r*.58*pulse);ctx.beginPath();ctx.fillStyle=idx%5===0?'rgba(188,169,255,.55)':'rgba(220,236,255,.28)';ctx.arc(x,y,1.1*p.z,0,Math.PI*2);ctx.fill();}); 20 ctx.beginPath();ctx.strokeStyle='rgba(188,169,255,.22)';ctx.moveTo(cx-Math.min(w,500)*.46,cy);ctx.bezierCurveTo(cx-160,cy-120,cx+120,cy+115,cx+Math.min(w,500)*.48,cy-24);ctx.stroke(); 21 t++;if(!reduced)raf=requestAnimationFrame(draw)} 22 resize();draw();window.addEventListener('resize',()=>{cancelAnimationFrame(raf);resize();draw()},{passive:true}); 23})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.