(() => { const {createTimeline, stagger} = anime; const reduced = matchMedia('(prefers-reduced-motion: reduce)'); const printMode = location.search.includes('print-pdf'); const seen = new Set(), timelines = new Map(); let motion = !reduced.matches; const motionButton = document.querySelector('#motion'); // Explicit paused instances: Reveal owns slide navigation; one clock owns motion. // Targets are dedicated motion wrappers, not positioned/rotated diagram parts. document.querySelectorAll('.slides>section').forEach(slide=>{ const targets=[...slide.querySelectorAll('[data-motion]')]; if(!targets.length)return; const tl=createTimeline({autoplay:false,defaults:{duration:300,ease:'outCubic'}}); if(slide.id==='sequence') { ['observe','interpret','act'].forEach((label,i)=>{ tl.label(label,i*180).add(targets[i],{opacity:[0,1],translateY:[12,0]},label); }); } else tl.add(targets,{opacity:[0,1],translateY:[12,0],delay:stagger(70),duration:400},0); tl.seek(tl.duration);tl.pause();timelines.set(slide,tl); }); const allowed=()=>motion&&!reduced.matches&&!printMode&&!Reveal.isOverview(); function settle() { timelines.forEach(tl=>{tl.pause();tl.seek(tl.duration);}); } function replay() { settle();const tl=timelines.get(Reveal.getCurrentSlide()); if(!tl||!allowed())return false; tl.seek(0);tl.play();return true; } function seek(timeMs) { if(!Number.isFinite(timeMs))throw new TypeError('seek requires finite milliseconds'); const tl=timelines.get(Reveal.getCurrentSlide()); if(!tl)return false; tl.pause();tl.seek(allowed()?Math.max(0,Math.min(timeMs,tl.duration)):tl.duration); return true; } function run() { settle();const slide=Reveal.getCurrentSlide(); if(!slide||seen.has(slide.id)||!allowed())return; seen.add(slide.id);replay(); } function motionLabel(){motionButton.textContent=motion&&!reduced.matches?'Motion on':'Motion off';motionButton.setAttribute('aria-pressed',String(motion&&!reduced.matches));} motionButton.onclick=()=>{motion=!motion;settle();motionLabel();}; reduced.addEventListener('change',()=>{if(reduced.matches)settle();motionLabel();});motionLabel(); addEventListener('beforeprint',settle); const fs=document.querySelector('#fullscreen'); async function fullscreen(){try{if(document.fullscreenElement)await document.exitFullscreen();else await document.documentElement.requestFullscreen();}catch{fs.textContent='Fullscreen unavailable';}} fs.onclick=fullscreen; document.addEventListener('fullscreenchange',()=>{fs.textContent=document.fullscreenElement?'Exit fullscreen':'Enter fullscreen';fs.setAttribute('aria-pressed',String(!!document.fullscreenElement));}); document.addEventListener('keydown',e=>{if(e.key.toLowerCase()==='f'&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&!e.target.matches('input,textarea,[contenteditable]')){e.preventDefault();e.stopPropagation();fullscreen();}},true); document.querySelectorAll('[data-node]').forEach(node=>{ function select(){const was=node.getAttribute('aria-pressed')==='true';document.querySelectorAll('[data-node]').forEach(n=>n.setAttribute('aria-pressed','false'));node.setAttribute('aria-pressed',String(!was));document.querySelector('#detail').textContent=was?'Select a source to reveal its role. Tab + Enter or Space also works.':node.dataset.detail;} node.addEventListener('click',select); node.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();e.stopPropagation();select();}}); }); Reveal.initialize({width:1240,height:700,margin:.08,center:false,hash:true,transition:'none',backgroundTransition:'none',slideNumber:'c/t',view:'slide',keyboard:{70:null},autoAnimate:false}).then(()=>{ if(!location.hash){try{const i=Number(localStorage.getItem('presentation-html-demo-slide'));if(Number.isInteger(i)&&i>=0&&i{try{localStorage.setItem('presentation-html-demo-slide',String(Reveal.getIndices().h));}catch{}run();}); Reveal.on('overviewshown',settle); document.addEventListener('visibilitychange',()=>{if(document.hidden)settle();}); window.presentationQA={settle,seek,replay,reduced:()=>reduced.matches,active:()=>[...timelines.values()].filter(tl=>!tl.paused&&!tl.completed).length}; })();