$(document).ready(function () { gsap.registerPlugin(ScrollTrigger, ScrollSmoother); let smoother = ScrollSmoother.create({ smooth: 2.5, effects: true, normalizeScroll: true }); // ScrollSmoother fixes #smooth-wrapper as position:fixed on desktop, // hiding anything outside it. Move footer-bottom into smooth-content // at runtime so it appears at the bottom of the scroll content. if (window.innerWidth > 1280) { var footerBottomEl = document.querySelector('.shopify-section-group-footer-group'); if (footerBottomEl) { document.getElementById('smooth-content').appendChild(footerBottomEl); smoother.refresh(); } } // Reload when the desktop ↔ mobile breakpoint is crossed during resize (function () { var wasMobile = window.innerWidth <= 1280; var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { var isMobile = window.innerWidth <= 1280; if (isMobile !== wasMobile) { window.location.reload(); } }, 250); }); })(); if ($(window).innerWidth() > 1280) { // ─── into-section: 4-phase step animation (wheel-event, same pattern as spatial) ── var introSection = document.getElementById('into-section'); if (introSection) { var introContent = introSection.querySelector('.intro-content'); var introPhone = introSection.querySelector('.intro-phone'); var introPara1 = introSection.querySelector('.intro-para-1'); var introPara2 = introSection.querySelector('.intro-para-2'); var introMouseScroll = introSection.querySelector('.mouse-scrolling'); var iPhase = 0; var iLocked = false; var iActive = false; var iSectionTop = 0; var iN = 4; var iVH = window.innerHeight; gsap.set(introContent, { y: iVH, opacity: 0 }); gsap.set(introPhone, { y: iVH, opacity: 0 }); gsap.set(introPara1, { y: iVH, opacity: 0 }); gsap.set(introPara2, { y: iVH, opacity: 0 }); function introGoTo(idx) { var prev = iPhase; iPhase = Math.max(0, Math.min(iN - 1, idx)); function syncScroll() { var syncScroll = iSectionTop + iPhase * window.innerHeight; if (iPhase >= iN - 1) syncScroll -= 1; window.scrollTo({ top: syncScroll, left: 0, behavior: 'auto' }); } if (iPhase > prev) { if (iPhase === 1) { gsap.to(introContent, { y: 0, opacity: 1, duration: 0.9, ease: 'power3.out', overwrite: true, onComplete: function () { syncScroll(); iLocked = false; } }); } else if (iPhase === 2) { gsap.to(introPhone, { y: 0, opacity: 1, duration: 0.9, ease: 'power3.out', overwrite: true }); gsap.to(introPara1, { y: 0, opacity: 1, duration: 0.9, ease: 'power3.out', overwrite: true, onComplete: function () { syncScroll(); iLocked = false; } }); } else if (iPhase === 3) { gsap.to(introPara2, { y: 0, opacity: 1, duration: 0.9, ease: 'power3.out', overwrite: true, onComplete: function () { syncScroll(); iLocked = false; gsap.to(introMouseScroll, { opacity: 0, duration: 0.4, ease: 'power2.in', onComplete: function () { introMouseScroll.style.visibility = 'hidden'; } }); } }); } else { iLocked = false; } } else { if (iPhase === 2) { introMouseScroll.style.visibility = 'visible'; gsap.to(introMouseScroll, { opacity: 1, duration: 0.4, ease: 'power2.out', overwrite: true }); gsap.to(introPara2, { y: iVH, opacity: 0, duration: 0.6, ease: 'power2.in', overwrite: true, onComplete: function () { syncScroll(); iLocked = false; } }); } else if (iPhase === 1) { gsap.to(introPhone, { y: iVH, opacity: 0, duration: 0.6, ease: 'power2.in', overwrite: true }); gsap.to(introPara1, { y: iVH, opacity: 0, duration: 0.6, ease: 'power2.in', overwrite: true, onComplete: function () { syncScroll(); iLocked = false; } }); } else if (iPhase === 0) { gsap.to(introContent, { y: iVH, opacity: 0, duration: 0.6, ease: 'power2.in', overwrite: true, onComplete: function () { syncScroll(); iLocked = false; } }); } else { iLocked = false; } } } var iLockTimer = null; ScrollTrigger.create({ trigger: introSection, start: 'top top', end: '+=' + (iN - 1) * 100 + '%', pin: true, anticipatePin: 1, scrub: 0.5, onEnter: function (self) { iActive = true; iPhase = 0; iSectionTop = self.start; iLocked = false; }, onLeave: function () { iActive = false; if (iLockTimer) { clearTimeout(iLockTimer); iLockTimer = null; } iLocked = false; }, onEnterBack: function (self) { iActive = true; iSectionTop = self.start; iPhase = iN - 1; iLocked = false; }, onLeaveBack: function () { iActive = false; if (iLockTimer) { clearTimeout(iLockTimer); iLockTimer = null; } iLocked = false; } }); introSection.addEventListener('wheel', function (e) { if (!iActive) return; var dir = e.deltaY > 0 ? 1 : -1; var next = iPhase + dir; if (next < 0 || next >= iN) { if (iLocked) e.preventDefault(); // hold boundary until animation finishes return; } e.preventDefault(); e.stopPropagation(); if (iLocked) return; iLocked = true; introGoTo(next); // Safety timeout: unlock after 1.5s to prevent scroll from getting stuck if (iLockTimer) clearTimeout(iLockTimer); iLockTimer = setTimeout(function () { iLocked = false; iLockTimer = null; }, 1500); }, { passive: false }); var iTouchY = 0; introSection.addEventListener('touchstart', function (e) { iTouchY = e.touches[0].clientY; }, { passive: true }); introSection.addEventListener('touchend', function (e) { if (!iActive) return; var dy = iTouchY - e.changedTouches[0].clientY; if (Math.abs(dy) < 40) return; var next = iPhase + (dy > 0 ? 1 : -1); if (next < 0 || next >= iN) return; if (iLocked) return; iLocked = true; introGoTo(next); // Safety timeout for touch events too if (iLockTimer) clearTimeout(iLockTimer); iLockTimer = setTimeout(function () { iLocked = false; iLockTimer = null; }, 1500); }); document.addEventListener('keydown', function (e) { if (!iActive) return; if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; var dir = e.key === 'ArrowDown' ? 1 : -1; var next = iPhase + dir; if (next < 0 || next >= iN) return; e.preventDefault(); if (iLocked) return; iLocked = true; introGoTo(next); if (iLockTimer) clearTimeout(iLockTimer); iLockTimer = setTimeout(function () { iLocked = false; iLockTimer = null; }, 1500); }); } // ─── Spatial Sound 05 — One-scroll-per-slide ──────────────── var spatialSection = document.querySelector('#spatial-sound05-section'); if (spatialSection) { var sTrack = spatialSection.querySelector('.spatial-slides-track'); var sDots = gsap.utils.toArray('.spatial-dot', spatialSection); var sN = 4; var sCurrent = 0; var sLocked = false; var sActive = false; var sSectionTop = 0; var sSlides = gsap.utils.toArray('.spatial-slide', spatialSection); var sLastIdx = sSlides.length - 1; var sLastText = spatialSection.querySelector('.last-text'); var sLastTextTimer = null; var sLastSlide = sSlides[sLastIdx]; var sLastVideo = sLastSlide ? sLastSlide.querySelector('.spatial-last-video') : null; var sLastPlaceholder = sLastSlide ? sLastSlide.querySelector('.spatial-last-placeholder') : null; var sVideoTimer = null; var sTextAnimDone = false; var splitLastText = sLastText ? new SplitText(sLastText, { type: 'words', wordsClass: 'word' }) : null; if (splitLastText) { gsap.set(splitLastText.words, { color: '#818183' }); } if (sLastText) { gsap.set(sLastText, { opacity: 1, y: '20px' }); } function sStartVideoSequence() { sTextAnimDone = false; if (sVideoTimer) { clearTimeout(sVideoTimer); sVideoTimer = null; } if (sLastTextTimer) { clearTimeout(sLastTextTimer); sLastTextTimer = null; } if (sLastVideo) { sLastVideo.style.display = 'block'; sLastVideo.currentTime = 0; sLastVideo.play(); } if (sLastPlaceholder) { gsap.to(sLastPlaceholder, { opacity: 0, duration: 0.1, fade: 'power2.out' }); } if (sLastText) { var lastTextTl = gsap.timeline({ onComplete: function () { sTextAnimDone = true; } }); lastTextTl.fromTo(sLastText, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, duration: 0.1, ease: 'power2.out' } ); if (splitLastText) { lastTextTl.fromTo(splitLastText.words, { color: '#818183' }, { color: '#ffffff', ease: 'power2.out', stagger: { each: 0.01, from: 'start' } }, 0 ); } } else { sTextAnimDone = true; } } function sResetLastSlide() { sTextAnimDone = false; if (sVideoTimer) { clearTimeout(sVideoTimer); sVideoTimer = null; } if (sLastTextTimer) { clearTimeout(sLastTextTimer); sLastTextTimer = null; } if (sLastVideo) { sLastVideo.pause(); sLastVideo.currentTime = 0; sLastVideo.style.display = 'none'; } if (sLastPlaceholder) { gsap.set(sLastPlaceholder, { opacity: 1 }); } if (sLastText) { gsap.set(sLastText, { opacity: 0, y: '100%' }); } if (splitLastText) { gsap.set(splitLastText.words, { color: '#818183' }); } } // Initialise: slide 0 visible, all others off-screen to the right gsap.set(sSlides, { x: '100%' }); gsap.set(sSlides[0], { x: '0%' }); // Pin only — slide animation is driven by wheel events, not scrub ScrollTrigger.create({ trigger: spatialSection, start: 'top top', end: '+=' + (sN - 1) * 100 + '%', pin: true, scrub: 0.5, anticipatePin: 1, onEnter: function (self) { sActive = true; sCurrent = 0; sSectionTop = self.start; sLocked = false; }, onLeave: function () { sActive = false; if (sLockTimer) { clearTimeout(sLockTimer); sLockTimer = null; } sLocked = false; }, onEnterBack: function (self) { sActive = true; sSectionTop = self.start; sCurrent = sN - 1; sLocked = false; // All slides have been visited — all sit at x:0, last on top by DOM order gsap.set(sSlides, { x: '0%' }); sDots.forEach(function (d, i) { d.classList.toggle('active', i === sCurrent); }); // Reset then start video sequence so it re-animates on re-entry sResetLastSlide(); sStartVideoSequence(); }, onLeaveBack: function () { sActive = false; if (sLockTimer) { clearTimeout(sLockTimer); sLockTimer = null; } sLocked = false; } }); function slideTo(idx) { var prev = sCurrent; sCurrent = Math.max(0, Math.min(sN - 1, idx)); var dir = sCurrent > prev ? 1 : -1; sDots.forEach(function (d, i) { d.classList.toggle('active', i === sCurrent); }); // Reset last slide state when navigating away from it if (prev === sLastIdx && sCurrent !== sLastIdx) { sResetLastSlide(); } if (dir === 1) { // New slide slides in from the right, landing on top of the current gsap.set(sSlides[sCurrent], { x: '100%' }); gsap.to(sSlides[sCurrent], { x: '0%', duration: 0.75, ease: 'power2.inOut', overwrite: true, onComplete: function () { // Keep scroll position in sync AFTER animation completes var syncScroll = sSectionTop + sCurrent * window.innerHeight; if (sCurrent >= sN - 1) syncScroll -= 1; window.scrollTo({ top: syncScroll, left: 0, behavior: 'auto' }); sLocked = false; // On reaching the last slide, start the video + text sequence if (sCurrent === sLastIdx) { sStartVideoSequence(); } } }); } else { // Current slide slides back out to the right, revealing the one below gsap.to(sSlides[prev], { x: '100%', duration: 0.75, ease: 'power2.inOut', overwrite: true, onComplete: function () { // Keep scroll position in sync AFTER animation completes var syncScroll = sSectionTop + sCurrent * window.innerHeight; if (sCurrent >= sN - 1) syncScroll -= 1; window.scrollTo({ top: syncScroll, left: 0, behavior: 'auto' }); sLocked = false; // Also start the video + text sequence when arriving via backward nav if (sCurrent === sLastIdx) { sStartVideoSequence(); } } }); } } var sLockTimer = null; spatialSection.addEventListener('wheel', function (e) { if (!sActive) return; var dir = e.deltaY > 0 ? 1 : -1; var next = sCurrent + dir; // At boundaries: block forward exit until text animation completes if (next < 0 || next >= sN) { if (next >= sN && !sTextAnimDone) { e.preventDefault(); e.stopPropagation(); } return; } e.preventDefault(); e.stopPropagation(); if (sLocked) return; sLocked = true; slideTo(next); // Safety timeout: unlock after 1.5s to prevent scroll from getting stuck if (sLockTimer) clearTimeout(sLockTimer); sLockTimer = setTimeout(function () { sLocked = false; sLockTimer = null; }, 1500); }, { passive: false }); // Touch support var sTouchY = 0; spatialSection.addEventListener('touchstart', function (e) { sTouchY = e.touches[0].clientY; }, { passive: true }); spatialSection.addEventListener('touchend', function (e) { if (!sActive || sLocked) return; var dy = sTouchY - e.changedTouches[0].clientY; if (Math.abs(dy) < 40) return; var next = sCurrent + (dy > 0 ? 1 : -1); if (next < 0 || next >= sN) { return; } if (next >= sN && !sTextAnimDone) return; sLocked = true; slideTo(next); // Safety timeout for touch events too if (sLockTimer) clearTimeout(sLockTimer); sLockTimer = setTimeout(function () { sLocked = false; sLockTimer = null; }, 1500); }); document.addEventListener('keydown', function (e) { if (!sActive) return; if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; var dir = e.key === 'ArrowDown' ? 1 : -1; var next = sCurrent + dir; if (next < 0 || next >= sN) return; if (next >= sN && !sTextAnimDone) return; e.preventDefault(); if (sLocked) return; sLocked = true; slideTo(next); if (sLockTimer) clearTimeout(sLockTimer); sLockTimer = setTimeout(function () { sLocked = false; sLockTimer = null; }, 1500); }); } // adaptive-noise-section const adaptiveSection = document.getElementById('adaptive-noise-section'); if (adaptiveSection) { const mainTitle = adaptiveSection.querySelector('.main-title'); if (mainTitle) { gsap.set(mainTitle, { opacity: 0, y: 30 }); ScrollTrigger.create({ trigger: mainTitle, start: 'top 85%', once: true, onEnter: function () { gsap.to(mainTitle, { opacity: 1, y: 0, duration: 1.5, ease: 'power2.out' }); } }); } const bg1 = document.getElementById('bg1'); const bg2 = document.getElementById('bg2'); const part1 = document.getElementById('part1'); const part2 = document.getElementById('part2'); const stickyScene = adaptiveSection.querySelector('.sticky-scene'); let step = -1; function setAdaptiveStep(newStep) { if (newStep === step) return; step = newStep; if (step === 0) { bg1.style.opacity = '1'; bg2.style.opacity = '0'; part1.className = 'cap-part bright'; part2.className = 'cap-part dim'; } else { bg1.style.opacity = '0'; bg2.style.opacity = '1'; part1.className = 'cap-part dim'; part2.className = 'cap-part bright'; } } ScrollTrigger.create({ trigger: stickyScene, start: 'top top', end: '+=' + window.innerHeight, pin: true, anticipatePin: 1, scrub: 0.5, onUpdate: function (self) { setAdaptiveStep(self.progress < 0.5 ? 0 : 1); }, onEnter: function () { setAdaptiveStep(0); }, onLeaveBack: function () { setAdaptiveStep(0); } }); setAdaptiveStep(0); } // Discover Text Section var discoverSection = document.querySelector('.discover-text-section'); var discoverP = discoverSection && discoverSection.querySelector('p'); var discoverBlob = discoverSection && discoverSection.querySelector('.blue-blob-block'); if (discoverSection && discoverP) { var splitDiscover = new SplitText(discoverP, { type: 'words', wordsClass: 'word' }); gsap.set(splitDiscover.words, { color: '#818183' }); gsap.set(discoverP, { opacity: 0, y: '100%' }); var discoverTl = gsap.timeline({ scrollTrigger: { trigger: discoverSection, start: 'top top', end: '+=200%', pin: true, anticipatePin: 1, scrub: 0.5, } }); if (discoverBlob) { discoverTl.fromTo(discoverBlob, { x: window.innerWidth * 0.80, y: window.innerHeight * 0.70, }, { x: 0, y: 0, duration: 3, ease: 'power2.inOut', }, 2.2 ); } // paragraph slides up from bottom (grey) discoverTl.fromTo(discoverP, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }, 0.5 ); // words highlight grey → white discoverTl.fromTo(splitDiscover.words, { color: '#818183' }, { color: '#ffffff', ease: 'power2.out', stagger: { each: 0.15, from: 'start' }, }, 1.2 ); } // product expanded section var productExpandedSection = $(".product-expanded-section"); var driverLine1 = $(".product-expanded-section .driver-line-1"); var driverLine2 = $(".product-expanded-section .driver-line-2"); var productExpandedParagraphs = $(".product-expanded-section .caption-wrap p"); if ( productExpandedSection.length && driverLine1.length ) { var p1 = productExpandedParagraphs[0]; var p2 = productExpandedParagraphs[1]; // split each paragraph into word spans var splitP1 = new SplitText(p1, { type: 'words', wordsClass: 'word' }); var splitP2 = new SplitText(p2, { type: 'words', wordsClass: 'word' }); // initialise words to gray; hide p2 below gsap.set(splitP1.words, { color: '#818183' }); gsap.set(splitP2.words, { color: '#818183' }); gsap.set(p2, { opacity: 0, y: '100%' }); // hide both title lines initially below their container gsap.set(driverLine1, { y: '500', opacity: 0 }); gsap.set(driverLine2, { y: '500', opacity: 0 }); var productExpTl = gsap.timeline({ scrollTrigger: { trigger: productExpandedSection, start: 'top top', end: '+=300%', pin: true, anticipatePin: 1, scrub: 0.5, } }); // line 1 "42 mm driver," slides up first productExpTl.to( driverLine1, { opacity: 1, y: 0, duration: 0.3, ease: 'power2.out' } ); // line 2 "big on detail." slides up after line 1 productExpTl.to( driverLine2, { opacity: 1, y: 0, duration: 0.3, ease: 'power2.out' }, "+=0.1" ); // p1: slides in from bottom productExpTl.fromTo( p1, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }, "+=0.2" ); // p1: word by word gray → white productExpTl.to(splitP1.words, { color: '#ffffff', duration: 0.3, ease: 'power2.out', stagger: { each: 0.05, from: 'start' }, }); // p1 exits upward productExpTl.to(p1, { y: '-110%', opacity: 0, duration: 0.5, ease: 'power2.in' }, "+=0.3"); // p2: slides in from bottom as p1 exits productExpTl.fromTo( p2, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }, "<0.2" ); // p2: word by word gray → white productExpTl.to(splitP2.words, { color: '#ffffff', duration: 0.3, ease: 'power2.out', stagger: { each: 0.05, from: 'start' }, }); } // smart-control-app section (Customizable Sound) var scaSection = document.querySelector('.smart-control-app-section'); var scaEyebrow = document.querySelector('.sca-eyebrow'); var scaHeading = document.querySelector('.sca-heading'); var scaBody = document.querySelector('.sca-body'); if (scaSection && scaEyebrow && scaHeading && scaBody) { var splitScaBody = new SplitText(scaBody, { type: 'words', wordsClass: 'word' }); gsap.set(splitScaBody.words, { color: '#818183' }); gsap.set([scaEyebrow, scaHeading], { opacity: 0, y: 80 }); gsap.set(scaBody, { opacity: 0, y: 40 }); var scaTl = gsap.timeline({ scrollTrigger: { trigger: scaSection, start: 'top top', end: '+=200%', pin: true, anticipatePin: 1, scrub: 0.5, } }); // eyebrow + heading rise together from bottom scaTl.to([scaEyebrow, scaHeading], { opacity: 1, y: 0, duration: 0.5, ease: 'power3.out', stagger: 0.15, }); // paragraph slides in after a pause scaTl.to(scaBody, { opacity: 1, y: 0, duration: 0.4, ease: 'power2.out', }, '+=0.3'); // words highlight gray → white scaTl.to(splitScaBody.words, { color: '#ffffff', duration: 0.3, ease: 'power2.out', stagger: { each: 0.04, from: 'start' }, }, '<0.1'); } // lossless section var losslessSection = $(".lossless-section"); var losslessContent = losslessSection.find(".content-wrap"); var losslessP = document.querySelector('.lossless-section p'); var losslessVideo = document.querySelector('.lossless-section .bg-video video'); if (losslessVideo) losslessVideo.pause(); var losslessVidTriggered = false; if (losslessSection.length && losslessP) { var splitLossless = new SplitText(losslessP, { type: 'words', wordsClass: 'word' }); gsap.set(splitLossless.words, { color: '#818183' }); gsap.set(losslessP, { opacity: 0 }); var losslessTl = gsap.timeline({ scrollTrigger: { trigger: losslessSection, start: 'top top', end: '+=200%', pin: true, anticipatePin: 1, scrub: 0.5, }, onUpdate: function () { if (!losslessVidTriggered && this.progress() >= 0.25) { losslessVidTriggered = true; if (losslessVideo) losslessVideo.play(); } } }); // content-wrap (blue-text + h2) — original slide-up behaviour losslessTl.fromTo(losslessContent, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, ease: 'power2.out', duration: 0.5 } ); // video fades in — original behaviour losslessTl.fromTo(losslessVideo, { opacity: 0 }, { opacity: 1, ease: 'power2.out', duration: 0.5 } ); // paragraph slides up from below with grey words losslessTl.fromTo(losslessP, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, ease: 'power2.out', duration: 0.5 }, '+=0.3' ); // words highlight grey → white word by word losslessTl.fromTo(splitLossless.words, { color: '#818183' }, { color: '#ffffff', ease: 'power2.out', delay: 0.2, stagger: { each: 0.4, from: 'start' }, }, '+=0.3' ); } // ─── sound-revelation-section: 5-phase step animation ──── var srvSection = document.getElementById('sound-revelation-section'); if (srvSection) { gsap.registerPlugin(SplitText); var srvHeadline = srvSection.querySelector('.srv-headline'); var srvPhone = srvSection.querySelector('.srv-phone'); var srvPara = srvSection.querySelector('.srv-para'); var srvBtn = srvSection.querySelector('.srv-btn'); var srvVH = window.innerHeight; var srvPhase = 0; var srvLocked = false; var srvActive = false; var srvSecTop = 0; var srvN = 5; // phases 0-4 var srvLockTimer = null; // Split paragraph words for highlight effect (phase 3) var srvSplit = new SplitText(srvPara, { type: 'words' }); var srvWords = srvSplit.words; gsap.set(srvWords, { color: '#818183' }); // Initial hidden states gsap.set(srvHeadline, { y: srvVH, opacity: 0 }); gsap.set(srvPhone, { y: srvVH, opacity: 0 }); gsap.set(srvPara, { y: srvVH, opacity: 0 }); gsap.set(srvBtn, { y: srvVH, opacity: 0 }); function unlockScrollAfterDelay(duration) { if (srvLockTimer) clearTimeout(srvLockTimer); srvLockTimer = setTimeout(function () { srvLocked = false; srvLockTimer = null; }, duration); } function srvGoTo(idx) { var prev = srvPhase; srvPhase = Math.max(0, Math.min(srvN - 1, idx)); if (srvPhase > prev) { if (srvPhase === 1) { gsap.to(srvHeadline, { y: 0, opacity: 1, duration: 0.5, ease: 'power3.out', overwrite: true }); gsap.to(srvPhone, { y: 0, opacity: 1, duration: 0.5, ease: 'power3.out', overwrite: true }); unlockScrollAfterDelay(1000); } else if (srvPhase === 2) { // Very fast paragraph animation gsap.to(srvPara, { y: 0, opacity: 1, duration: 0.2, ease: 'power3.out', overwrite: true }); unlockScrollAfterDelay(350); } else if (srvPhase === 3) { // Very fast text animation: minimal stagger gsap.to(srvWords, { color: '#fff', stagger: { each: 0.03, from: 'start' }, delay: 0.02, duration: 0.1, ease: 'power2.out', overwrite: true }); unlockScrollAfterDelay(300); } else if (srvPhase === 4) { // Very fast button appearance gsap.to(srvBtn, { y: 0, opacity: 1, duration: 0.1, ease: 'power3.out', overwrite: true }); unlockScrollAfterDelay(70); } else { srvLocked = false; } } else { if (srvPhase === 3) { // Button exits downward - very fast gsap.to(srvBtn, { y: srvVH, opacity: 0, duration: 0.1, ease: 'power2.in', overwrite: true }); unlockScrollAfterDelay(70); } else if (srvPhase === 2) { // Words un-highlight right-to-left very fast gsap.to([].slice.call(srvWords).reverse(), { color: '#818183', stagger: { each: 0.02, from: 'start' }, duration: 0.12, ease: 'power2.out', overwrite: true }); unlockScrollAfterDelay(300); } else if (srvPhase === 1) { // Paragraph exits very fast, reset word colours after exit gsap.to(srvPara, { y: srvVH, opacity: 0, duration: 0.15, ease: 'power2.in', overwrite: true }); gsap.delayedCall(0.15, function () { gsap.set(srvWords, { color: '#818183' }); }); unlockScrollAfterDelay(400); } else if (srvPhase === 0) { gsap.to(srvHeadline, { y: srvVH, opacity: 0, duration: 0.3, ease: 'power2.in', overwrite: true }); gsap.to(srvPhone, { y: srvVH, opacity: 0, duration: 0.6, ease: 'power2.in', overwrite: true }); unlockScrollAfterDelay(200); } else { srvLocked = false; } } var syncScroll = srvSecTop + srvPhase * window.innerHeight; if (srvPhase >= srvN - 1) syncScroll -= 1; window.scrollTo({ top: syncScroll, left: 0, behavior: 'auto' }); } ScrollTrigger.create({ trigger: srvSection, start: 'top top', end: '+=' + (srvN - 1) * 100 + '%', scrub: 0.5, pin: true, anticipatePin: 1, onEnter: function (self) { srvActive = true; srvPhase = 0; srvSecTop = self.start; srvLocked = false; }, onLeave: function () { srvActive = false; if (srvLockTimer) { clearTimeout(srvLockTimer); srvLockTimer = null; } srvLocked = false; }, onEnterBack: function (self) { srvActive = true; srvSecTop = self.start; srvPhase = srvN - 1; srvLocked = false; }, onLeaveBack: function () { srvActive = false; if (srvLockTimer) { clearTimeout(srvLockTimer); srvLockTimer = null; } srvLocked = false; } }); window.addEventListener('wheel', function (e) { if (!srvActive) return; var dir = e.deltaY > 0 ? 1 : -1; var next = srvPhase + dir; if (next < 0 || next >= srvN) { if (srvLocked) e.preventDefault(); return; } e.preventDefault(); e.stopPropagation(); if (srvLocked) return; srvLocked = true; srvGoTo(next); }, { passive: false }); var srvTouchY = 0; srvSection.addEventListener('touchstart', function (e) { srvTouchY = e.touches[0].clientY; }, { passive: true }); srvSection.addEventListener('touchend', function (e) { if (!srvActive || srvLocked) return; var dy = srvTouchY - e.changedTouches[0].clientY; if (Math.abs(dy) < 40) return; var next = srvPhase + (dy > 0 ? 1 : -1); if (next < 0 || next >= srvN) return; srvLocked = true; srvGoTo(next); }); document.addEventListener('keydown', function (e) { if (!srvActive) return; if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; var dir = e.key === 'ArrowDown' ? 1 : -1; var next = srvPhase + dir; if (next < 0 || next >= srvN) return; e.preventDefault(); if (srvLocked) return; srvLocked = true; srvGoTo(next); unlockScrollAfterDelay(1500); }); } // battery time section var batterySection = document.querySelector('.battery-time-section'); var batteryH2 = batterySection && batterySection.querySelector('h2'); var batterySpan = batteryH2 && batteryH2.querySelector('.blue'); var batteryP = batterySection && batterySection.querySelector('.body-text'); if (batterySection && batteryH2 && batteryP) { var splitBattery = new SplitText(batteryP, { type: 'words', wordsClass: 'word' }); const batteryCountNo = parseInt($("#batteryCount").text(), 10); var batteryCount = { val: 0 }; if (batterySpan) batterySpan.textContent = '0'; var batteryTl = gsap.timeline({ scrollTrigger: { trigger: batterySection, start: 'top top', end: 'bottom top', pin: true, anticipatePin: 1, scrub: 0.5, } }); batteryTl.fromTo(batteryH2, { opacity: 0, y: 400 }, { opacity: 1, y: 0, duration: 2, ease: 'power2.out', } ); batteryTl.fromTo(batteryCount, { val: 0 }, { val: batteryCountNo, duration: 6, delay: 0.5, ease: 'none', onUpdate: function () { if (batterySpan) batterySpan.textContent = Math.round(batteryCount.val); } } ); batteryTl.fromTo(batteryP, { opacity: 0, y: 400 }, { opacity: 1, y: 0, duration: 2, ease: 'power2.out', } ); batteryTl.fromTo(splitBattery.words, { color: '#818183' }, { color: '#ffffff', ease: 'power2.out', delay: 0.2, stagger: { each: 0.4, from: 'start' }, }, '+=0.3'); } // ─── comfort-section-new: 4-step slide-up animation ──────────────── var csnSection = document.querySelector('.comfort-section-new'); if (csnSection) { var csnLine1 = csnSection.querySelector('.csn-line-1'); var csnLine2 = csnSection.querySelector('.csn-line-2'); var csnLine3 = csnSection.querySelector('.csn-line-3'); var csnLine4 = csnSection.querySelector('.csn-line-4'); var cN = 5; var cPhase = 0; var cLocked = false; var cActive = false; var cSectionTop = 0; var cVH = window.innerHeight; var csnLines = [csnLine1, csnLine2, csnLine3, csnLine4]; gsap.set(csnLines, { y: 80, opacity: 0 }); function csnGoTo(idx) { var prev = cPhase; cPhase = Math.max(0, Math.min(cN - 1, idx)); function syncScroll() { var sc = cSectionTop + cPhase * window.innerHeight; if (cPhase >= cN - 1) sc -= 1; window.scrollTo({ top: sc, left: 0, behavior: 'auto' }); } var goingForward = cPhase > prev; var outLine = prev > 0 ? csnLines[prev - 1] : null; var inLine = cPhase > 0 ? csnLines[cPhase - 1] : null; function animateIn() { if (inLine) { gsap.fromTo(inLine, { y: goingForward ? 60 : -60, opacity: 0 }, { y: 0, opacity: 1, duration: 0.5, ease: 'power3.out', overwrite: true, onComplete: function () { syncScroll(); cLocked = false; } } ); } else { syncScroll(); cLocked = false; } } if (outLine) { gsap.to(outLine, { y: goingForward ? -60 : 60, opacity: 0, duration: 0.5, ease: 'power2.in', overwrite: true, onComplete: animateIn }); } else { animateIn(); } } var cLockTimer = null; ScrollTrigger.create({ trigger: csnSection, start: 'top top', end: '+=' + (cN - 1) * 100 + '%', pin: true, anticipatePin: 1, onEnter: function (self) { cActive = true; cPhase = 0; cSectionTop = self.start; cLocked = false; // reset all lines below the viewport, ready to slide up gsap.set(csnLines, { y: 60, opacity: 0 }); }, onLeave: function () { cActive = false; if (cLockTimer) { clearTimeout(cLockTimer); cLockTimer = null; } cLocked = false; }, onEnterBack: function (self) { cActive = true; cSectionTop = self.start; cPhase = cN - 1; cLocked = false; // hide all lines above, then show only the last one gsap.set(csnLines, { y: -60, opacity: 0 }); gsap.set(csnLines[cN - 2], { y: 0, opacity: 1 }); }, onLeaveBack: function () { cActive = false; if (cLockTimer) { clearTimeout(cLockTimer); cLockTimer = null; } cLocked = false; // reset all lines for a clean forward re-entry gsap.set(csnLines, { y: 60, opacity: 0 }); } }); csnSection.addEventListener('wheel', function (e) { if (!cActive) return; var dir = e.deltaY > 0 ? 1 : -1; var next = cPhase + dir; if (next < 0 || next >= cN) { if (cLocked) e.preventDefault(); return; } e.preventDefault(); e.stopPropagation(); if (cLocked) return; cLocked = true; csnGoTo(next); if (cLockTimer) clearTimeout(cLockTimer); cLockTimer = setTimeout(function () { cLocked = false; cLockTimer = null; }, 1500); }, { passive: false }); var cTouchY = 0; csnSection.addEventListener('touchstart', function (e) { cTouchY = e.touches[0].clientY; }, { passive: true }); csnSection.addEventListener('touchend', function (e) { if (!cActive || cLocked) return; var dy = cTouchY - e.changedTouches[0].clientY; if (Math.abs(dy) < 40) return; var next = cPhase + (dy > 0 ? 1 : -1); if (next < 0 || next >= cN) return; cLocked = true; csnGoTo(next); if (cLockTimer) clearTimeout(cLockTimer); cLockTimer = setTimeout(function () { cLocked = false; cLockTimer = null; }, 1500); }); document.addEventListener('keydown', function (e) { if (!cActive) return; if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; var dir = e.key === 'ArrowDown' ? 1 : -1; var next = cPhase + dir; if (next < 0 || next >= cN) return; e.preventDefault(); if (cLocked) return; cLocked = true; csnGoTo(next); if (cLockTimer) clearTimeout(cLockTimer); cLockTimer = setTimeout(function () { cLocked = false; cLockTimer = null; }, 1500); }); } // ─── crystal-clear-section (same animation as product-expanded-section) ─── var crystalSection = document.querySelector('.crystal-clear-section'); var crystalTitle = crystalSection && crystalSection.querySelector('h2'); var crystalP = crystalSection && crystalSection.querySelector('.caption-wrap p'); if (crystalSection && crystalTitle && crystalP) { var splitCrystal = new SplitText(crystalP, { type: 'words', wordsClass: 'word' }); gsap.set(splitCrystal.words, { color: '#818183' }); var crystalTl = gsap.timeline({ scrollTrigger: { trigger: crystalSection, start: 'top top', end: '+=200%', pin: true, anticipatePin: 1, scrub: 0.5, } }); // title slides up from below crystalTl.fromTo( crystalTitle, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' } ); // paragraph slides in from below crystalTl.fromTo( crystalP, { opacity: 0, y: '100%' }, { opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }, "<0.2" ); // word by word gray → white crystalTl.to(splitCrystal.words, { color: '#ffffff', duration: 0.3, ease: 'power2.out', stagger: { each: 0.05, from: 'start' }, }); } } else { // ─── Mobile / tablet (≤ 1280): viewport-entry fade-in (no scroll pinning) ─ function mobileFadeIn(elements, staggerMs) { var els = (Array.isArray(elements) ? elements : [elements]).filter(Boolean); if (!els.length) return; var step = staggerMs !== undefined ? staggerMs : 120; els.forEach(function (el) { el.style.opacity = '0'; el.style.transform = 'translateY(20px)'; el.style.transition = 'none'; }); var io = new IntersectionObserver(function (entries, obs) { entries.forEach(function (entry) { if (!entry.isIntersecting) return; var idx = els.indexOf(entry.target); var el = entry.target; setTimeout(function () { el.style.transition = 'opacity 0.7s ease, transform 0.7s ease'; el.style.opacity = '1'; el.style.transform = 'translateY(0)'; }, idx * step); obs.unobserve(el); }); }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }); els.forEach(function (el) { io.observe(el); }); } // into-section mobileFadeIn([ document.querySelector('.intro-content'), document.querySelector('.intro-para-1'), document.querySelector('.intro-para-2') ], 150); // spatial slides mobileFadeIn(Array.from(document.querySelectorAll('.spatial-slide-content'))); // adaptive noise mobileFadeIn([document.querySelector('#adaptive-noise-section .main-title')]); // discover text mobileFadeIn([document.querySelector('.discover-text-section p')]); // product expanded mobileFadeIn([ document.querySelector('.product-expanded-section h2'), document.querySelector('.product-expanded-section .caption-wrap') ], 150); // smart control app mobileFadeIn([ document.querySelector('.sca-eyebrow'), document.querySelector('.sca-heading'), document.querySelector('.sca-body') ], 120); // lossless mobileFadeIn([document.querySelector('.lossless-section .content-wrap')]); // sound revelation mobileFadeIn([ document.querySelector('#sound-revelation-section .srv-headline'), document.querySelector('#sound-revelation-section .srv-para'), document.querySelector('#sound-revelation-section .srv-btn') ], 150); // battery mobileFadeIn([ document.querySelector('.battery-time-section h2'), document.querySelector('.battery-time-section .body-text') ], 150); // comfort section mobileFadeIn([document.querySelector('.comfort-section-new .csn-content')]); // crystal clear mobileFadeIn([ document.querySelector('.crystal-clear-section h2'), document.querySelector('.crystal-clear-section .caption-wrap p') ], 150); } (function () { var bar = document.getElementById('page-progress-bar'); function updateBar() { var scrollTop = window.scrollY || document.documentElement.scrollTop; var docHeight = document.documentElement.scrollHeight - window.innerHeight; var progress = docHeight > 0 ? scrollTop / docHeight : 0; bar.style.width = (progress * 100) + '%'; } window.addEventListener('scroll', updateBar, { passive: true }); updateBar(); })(); });