const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; const canvas = document.getElementById('heroWave'); let typingTimer = null; if (canvas) { const ctx = canvas.getContext('2d'); let t = 0; function resizeWave(){const ratio=Math.max(1,window.devicePixelRatio||1);const rect=canvas.getBoundingClientRect();canvas.width=rect.width*ratio;canvas.height=rect.height*ratio;ctx.setTransform(ratio,0,0,ratio,0,0)} function drawWave(){const w=canvas.clientWidth,h=canvas.clientHeight;ctx.clearRect(0,0,w,h);const cy=h*.53;for(let x=0;x<=w;x+=12){const n=x/w,e=Math.pow(Math.sin(Math.PI*n),1.75),bar=Math.sin(x*.03+t*1.2)*.55+Math.sin(x*.09-t*.85)*.3,amp=Math.max(12,Math.abs(bar)*h*.42*e);ctx.strokeStyle=`rgba(185,255,0,${.08+e*.17})`;ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(x,cy-amp);ctx.lineTo(x,cy+amp);ctx.stroke()}const g=ctx.createLinearGradient(0,0,w,0);g.addColorStop(0,'rgba(185,255,0,0)');g.addColorStop(.14,'rgba(185,255,0,.48)');g.addColorStop(.5,'rgba(220,255,120,1)');g.addColorStop(.86,'rgba(185,255,0,.48)');g.addColorStop(1,'rgba(185,255,0,0)');ctx.lineWidth=2.6;ctx.strokeStyle=g;ctx.shadowColor='rgba(185,255,0,.95)';ctx.shadowBlur=16;ctx.beginPath();for(let x=0;x<=w;x+=2){const n=x/w,e=Math.pow(Math.sin(Math.PI*n),1.9),c=Math.sin(x*.055+t)*.62+Math.sin(x*.12-t*1.5)*.34+Math.sin(x*.22+t*.65)*.18,y=cy+c*h*.33*e;x===0?ctx.moveTo(x,y):ctx.lineTo(x,y)}ctx.stroke();ctx.shadowBlur=0;t+=.026;if(!reduceMotion)requestAnimationFrame(drawWave)} resizeWave();drawWave();window.addEventListener('resize',resizeWave); } const heroSection = document.querySelector('.hero'); const liveText = document.getElementById('liveText'); const mailText = document.getElementById('mailText'); const demoButton = document.getElementById('demoButton'); let demoRunId = 0; function runDemo() { if (!heroSection || !liveText || !mailText) return; clearTimeout(typingTimer); const runId = ++demoRunId; const sentence = heroSection.dataset.demoText || ''; liveText.textContent = ''; mailText.textContent = ''; let liveIndex = 0; const typeLive = () => { if (runId !== demoRunId) return; liveText.textContent = sentence.slice(0, liveIndex++); if (liveIndex <= sentence.length) { typingTimer = setTimeout(typeLive, 35); return; } typingTimer = setTimeout(() => { let mailIndex = 0; const typeMail = () => { if (runId !== demoRunId) return; mailText.textContent = sentence.slice(0, mailIndex++); if (mailIndex <= sentence.length) { typingTimer = setTimeout(typeMail, 20); } }; typeMail(); }, 420); }; typeLive(); } if (heroSection && liveText && mailText) { const sentence = heroSection.dataset.demoText || ''; if (reduceMotion) { liveText.textContent = sentence; mailText.textContent = sentence; } else { setTimeout(runDemo, 850); setInterval(() => { if (!document.hidden) runDemo(); }, 11000); } } if (demoButton) { demoButton.addEventListener('click', runDemo); } const toggle=document.querySelector('.menu-toggle');const nav=document.querySelector('.main-nav'); if(toggle&&nav){toggle.addEventListener('click',()=>{const open=nav.classList.toggle('open');toggle.setAttribute('aria-expanded',String(open))})} const siteHeader = document.querySelector('.site-header'); if (siteHeader) { const updateHeaderState = () => { siteHeader.classList.toggle('scrolled', window.scrollY > 24); }; updateHeaderState(); window.addEventListener('scroll', updateHeaderState, { passive: true }); }