1/* DPDP Theme â New Home template: 2 1. "How it works" timeline: the central rail fills as the page scrolls and each 3 step node lights up once it passes the middle of the viewport. 4 2. Transparent navbar that turns solid once the dark hero scrolls away. */ 5 6document.addEventListener('DOMContentLoaded', function () { 7 var timeline = document.querySelector('[data-nh-timeline]'); 8 9 if (timeline) { 10 var steps = Array.prototype.slice.call(timeline.querySelectorAll('[data-nh-step]')); 11 var railTicking = false; 12 13 function updateRail() { 14 railTicking = false; 15 var rect = timeline.getBoundingClientRect(); 16 if (!rect.height) { 17 return; 18 } 19 /* The "now" line sits a little below the viewport centre so a step lights up as you read it. */ 20 var probe = window.innerHeight * 0.58; 21 var progress = Math.max(0, Math.min(1, (probe - rect.top) / rect.height)); 22 timeline.style.setProperty('--nh-rail-progress', progress.toFixed(4)); 23 24 steps.forEach(function (step) { 25 var node = step.querySelector('.nh-step-node') || step; 26 var nodeRect = node.getBoundingClientRect(); 27 step.classList.toggle('is-active', nodeRect.top + nodeRect.height / 2 <= probe); 28 }); 29 } 30 31 function requestRailUpdate() { 32 if (!railTicking) { 33 railTicking = true; 34 window.requestAnimationFrame(updateRail); 35 } 36 } 37 38 updateRail(); 39 window.addEventListener('scroll', requestRailUpdate, { passive: true }); 40 window.addEventListener('resize', requestRailUpdate); 41 window.addEventListener('load', updateRail); 42 } 43 44 var body = document.body; 45 var navbar = document.querySelector('.navbar'); 46 var hero = document.querySelector('.nh-hero'); 47 48 if (!body.classList.contains('nh-transparent-header') || !navbar || !hero) { 49 return; 50 } 51 52 var ticking = false; 53 54 function update() { 55 ticking = false; 56 var navHeight = navbar.offsetHeight || 68; 57 var heroBottom = hero.getBoundingClientRect().bottom; 58 navbar.classList.toggle('nh-nav-solid', heroBottom <= navHeight); 59 navbar.classList.toggle('nh-nav-blurred', window.scrollY > 12 && heroBottom > navHeight); 60 } 61 62 function requestUpdate() { 63 if (!ticking) { 64 ticking = true; 65 window.requestAnimationFrame(update); 66 } 67 } 68 69 update(); 70 window.addEventListener('scroll', requestUpdate, { passive: true }); 71 window.addEventListener('resize', requestUpdate); 72 window.addEventListener('load', update); 73 74 /* Subtle pointer parallax gives the hero's light field a live, responsive feel. */ 75 if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 76 hero.addEventListener('pointermove', function (event) { 77 var rect = hero.getBoundingClientRect(); 78 var x = ((event.clientX - rect.left) / rect.width - 0.5) * 2; 79 var y = ((event.clientY - rect.top) / rect.height - 0.5) * 2; 80 hero.style.setProperty('--nh-shift-x', (x * 18).toFixed(2) + 'px'); 81 hero.style.setProperty('--nh-shift-y', (y * 12).toFixed(2) + 'px'); 82 }); 83 hero.addEventListener('pointerleave', function () { 84 hero.style.setProperty('--nh-shift-x', '0px'); 85 hero.style.setProperty('--nh-shift-y', '0px'); 86 }); 87 } 88});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.