/* ───────── js/main.js ───────── Dynamically builds the project grid + injects about/contact/crew copy. -----------------------------------------------------------------*/ // Page loader overlay (function(){ const overlay=document.createElement('div'); overlay.id='loader-overlay'; overlay.innerHTML='
'; document.addEventListener('DOMContentLoaded',()=>document.body.appendChild(overlay)); window.addEventListener('load',()=>{ overlay.classList.add('hide'); setTimeout(()=>overlay.remove(),700); }); })(); // Mobile 100‑vh fix function setVh(){document.documentElement.style.setProperty('--vh',window.innerHeight*0.01);}setVh();window.addEventListener('resize',setVh); // Header height fix function setHeaderOffset(){ const headerEl = document.querySelector('header.nav'); if(!headerEl) return; // Header not in DOM yet – abort and wait const h = headerEl.offsetHeight; document.documentElement.style.setProperty('--header-h', `${h}px`); } setHeaderOffset(); // Run once more after a short delay to catch late-injected nav fragments setTimeout(setHeaderOffset, 500); window.addEventListener('resize', setHeaderOffset); // Fade‑in intersection observer const reveal = new IntersectionObserver((entries,o)=>{ entries.forEach(e=>{if(e.isIntersecting){e.target.classList.add('loaded');o.unobserve(e.target);}}); },{threshold:.3}); // Grab the grid once so every scope has it const grid = document.getElementById('projects'); // Only run project-grid logic on pages that actually have the grid element if(grid){ // Build card element function card({id,title,thumbnail,size='small'}){ const a = document.createElement('a'); a.href = `project.html?id=${encodeURIComponent(id)}`; a.className = 'item'; a.dataset.span = size; // <— MAGIC LINE a.innerHTML = `No projects manifest found.
`; }); } // Inject About & Contact copy ['about','contact'].forEach(key=>{ const el=document.getElementById(key); if(!el)return; fetch(`written/${key}_us.txt`) .then(r=>r.ok?r.text():Promise.reject()) .then(txt=>{ el.innerHTML=`${txt.replace(/\n/g,'
')}
${txt.replace(/\n/g,'
')}