/* tt-motion — scroll reveal, counters, sticky CTA. No && or || anywhere. */ (function(){ var reduce = false; try { reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch(e){} /* JS is alive: only now may the reveal state hide anything. No JS = fully visible. */ document.documentElement.classList.add('tt-js'); /* ---- scroll reveal ---- */ function reveal(){ var els = document.querySelectorAll('.tt-rv'); if (!els.length) { return; } if (reduce) { for (var i=0;i 0) { return; } var all = document.querySelectorAll('.tt-rv:not(.is-in)'); for (var n=0;n 0 ? n.toFixed(dec) : String(Math.round(n)); var parts = v.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); return parts.join('.'); } function runCount(el){ var raw = el.getAttribute('data-count'); if (!raw) { return; } var target = parseFloat(raw); if (isNaN(target)) { return; } var dRaw = el.getAttribute('data-dec'); var dec = dRaw ? parseInt(dRaw, 10) : 0; var pre = el.getAttribute('data-pre') ? el.getAttribute('data-pre') : ''; var suf = el.getAttribute('data-suf') ? el.getAttribute('data-suf') : ''; if (reduce) { el.textContent = pre + fmt(target, dec) + suf; return; } var t0 = null, dur = 1250; function step(ts){ if (t0 === null) { t0 = ts; } var p = (ts - t0) / dur; if (p > 1) { p = 1; } var eased = 1 - Math.pow(1 - p, 3); el.textContent = pre + fmt(target * eased, dec) + suf; if (p < 1) { requestAnimationFrame(step); } } requestAnimationFrame(step); } function counters(){ var els = document.querySelectorAll('[data-count]'); if (!els.length) { return; } if (!('IntersectionObserver' in window)) { for (var i=0;i trigger) { bar.classList.add('is-in'); } else { bar.classList.remove('is-in'); } } window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); } function boot(){ reveal(); counters(); sticky(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); } })();