/* fx 2afd664a4b809285 */ if (window.__fxs0) throw 'fx: this script already ran inline'; document.documentElement.classList.add('js'); (function () { 'use strict'; var mq = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)') : null; var reduce = mq ? mq.matches : false; /* ---------- mobile navigation (closed state is CSS-owned) ---------- */ var btn = document.getElementById('menuBtn'); var nav = document.getElementById('primary-nav'); function closeNav() { if (!nav || !btn) return; nav.classList.remove('open'); btn.setAttribute('aria-expanded', 'false'); } if (btn && nav) { btn.addEventListener('click', function () { var open = nav.classList.toggle('open'); btn.setAttribute('aria-expanded', open ? 'true' : 'false'); }); nav.addEventListener('click', function (e) { if (e.target.closest('a')) closeNav(); }); document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && nav.classList.contains('open')) { closeNav(); btn.focus(); } }); window.addEventListener('resize', function () { if (window.innerWidth > 920) closeNav(); }); } /* ---------- sticky header height -> anchor offset ---------- */ var header = document.querySelector('.site-header'); function syncHeader() { if (!header) return; document.documentElement.style.setProperty('--hdr', header.offsetHeight + 'px'); } syncHeader(); window.addEventListener('resize', syncHeader); window.addEventListener('load', syncHeader); /* ---------- shared reveal utility (stagger via --delay) ---------- */ var items = Array.prototype.slice.call(document.querySelectorAll('.anim')); function revealAll() { items.forEach(function (el) { el.classList.add('in'); }); } if (reduce || !('IntersectionObserver' in window)) { revealAll(); } else { var io = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.classList.add('in'); io.unobserve(entry.target); } }); }, { rootMargin: '0px 0px -8% 0px', threshold: 0.08 }); items.forEach(function (el) { io.observe(el); }); window.addEventListener('load', function () { items.forEach(function (el) { var r = el.getBoundingClientRect(); if (r.top < window.innerHeight && r.bottom > 0) el.classList.add('in'); }); }); } /* ---------- scroll progress hairline (transform only) ---------- */ var bar = document.getElementById('progressBar'); var ticking = false; function paintProgress() { ticking = false; if (!bar) return; var doc = document.documentElement; var max = doc.scrollHeight - window.innerHeight; var p = max > 0 ? Math.min(1, Math.max(0, window.pageYOffset / max)) : 0; bar.style.transform = 'scaleX(' + p.toFixed(4) + ')'; } function onScroll() { if (!ticking) { ticking = true; window.requestAnimationFrame(paintProgress); } } window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', onScroll); paintProgress(); /* ---------- pause the tools marquee on hidden tabs ---------- */ var track = document.getElementById('marqueeTrack'); document.addEventListener('visibilitychange', function () { if (!track) return; track.style.animationPlayState = document.hidden ? 'paused' : 'running'; }); })();