(function () { 'use strict'; document.documentElement.classList.remove('no-js'); document.documentElement.classList.add('js'); function initStickyHeader() { var header = document.querySelector('#header'); if (!header) return; function updateHeader() { header.classList.toggle('sticky', window.scrollY > 1); } updateHeader(); window.addEventListener('scroll', updateHeader, { passive: true }); } function initNavigation() { var panel = document.querySelector('#fragrance-navigation'); if (!panel || !window.bootstrap || !window.bootstrap.Offcanvas) return; panel.querySelectorAll('a[href*="#"]').forEach(function (link) { link.addEventListener('click', function () { var instance = window.bootstrap.Offcanvas.getInstance(panel); if (instance) instance.hide(); }); }); } function initCarousels() { var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; document.querySelectorAll('[data-carousel]').forEach(function (carousel) { var viewport = carousel.querySelector('.b2b-carousel-viewport'); var track = carousel.querySelector('.b2b-carousel-track'); var slides = Array.prototype.slice.call(carousel.querySelectorAll('.b2b-carousel-slide')); var previousButton = carousel.querySelector('.b2b-carousel-prev'); var nextButton = carousel.querySelector('.b2b-carousel-next'); var dotsContainer = carousel.querySelector('.b2b-carousel-dots'); var autoplayDelay = parseInt(carousel.getAttribute('data-autoplay'), 10) || 9000; var pageLabel = carousel.getAttribute('data-page-label') || 'Page %d'; var currentPage = 0; var pageCount = 1; var autoplayTimer = null; var scrollTimer = null; var resizeTimer = null; var hoverPaused = false; var focusPaused = false; var pointerPaused = false; if (!viewport || !track || !slides.length || !previousButton || !nextButton || !dotsContainer) { return; } function getItemsPerPage() { var value = parseInt(window.getComputedStyle(carousel).getPropertyValue('--carousel-items'), 10); return Math.max(1, value || 1); } function updateDots() { dotsContainer.querySelectorAll('.b2b-carousel-dot').forEach(function (dot, index) { var active = index === currentPage; dot.classList.toggle('is-active', active); dot.setAttribute('aria-current', active ? 'true' : 'false'); }); } function stopAutoplay() { if (!autoplayTimer) return; window.clearInterval(autoplayTimer); autoplayTimer = null; } function goToPage(page, smooth) { if (!pageCount) return; currentPage = (page + pageCount) % pageCount; var targetIndex = Math.min(currentPage * getItemsPerPage(), slides.length - 1); var maximumScroll = Math.max(0, viewport.scrollWidth - viewport.clientWidth); viewport.scrollTo({ left: Math.min(slides[targetIndex].offsetLeft, maximumScroll), behavior: smooth && !reducedMotion ? 'smooth' : 'auto' }); updateDots(); } function startAutoplay() { stopAutoplay(); if ( reducedMotion || hoverPaused || focusPaused || pointerPaused || pageCount < 2 || document.hidden ) { return; } autoplayTimer = window.setInterval(function () { goToPage(currentPage + 1, true); }, Math.max(autoplayDelay, 7000)); } function buildDots() { var itemsPerPage = getItemsPerPage(); var nextPageCount = Math.ceil(slides.length / itemsPerPage); var fragment = document.createDocumentFragment(); pageCount = Math.max(1, nextPageCount); currentPage = Math.min(currentPage, pageCount - 1); dotsContainer.textContent = ''; for (var index = 0; index < pageCount; index += 1) { var dot = document.createElement('button'); dot.type = 'button'; dot.className = 'b2b-carousel-dot'; dot.setAttribute('aria-label', pageLabel.replace('%d', index + 1)); dot.dataset.page = index; dot.addEventListener('click', function () { goToPage(parseInt(this.dataset.page, 10), true); startAutoplay(); }); fragment.appendChild(dot); } dotsContainer.appendChild(fragment); carousel.classList.toggle('has-single-page', pageCount < 2); updateDots(); goToPage(currentPage, false); startAutoplay(); } previousButton.addEventListener('click', function () { goToPage(currentPage - 1, true); startAutoplay(); }); nextButton.addEventListener('click', function () { goToPage(currentPage + 1, true); startAutoplay(); }); viewport.addEventListener( 'scroll', function () { window.clearTimeout(scrollTimer); scrollTimer = window.setTimeout(function () { var itemsPerPage = getItemsPerPage(); var maximumScroll = Math.max(0, viewport.scrollWidth - viewport.clientWidth); var closestPage = 0; var closestDistance = Number.POSITIVE_INFINITY; for (var page = 0; page < pageCount; page += 1) { var targetIndex = Math.min(page * itemsPerPage, slides.length - 1); var targetPosition = Math.min(slides[targetIndex].offsetLeft, maximumScroll); var distance = Math.abs(viewport.scrollLeft - targetPosition); if (distance < closestDistance) { closestDistance = distance; closestPage = page; } } currentPage = closestPage; updateDots(); }, 100); }, { passive: true } ); carousel.addEventListener('mouseenter', function () { hoverPaused = true; stopAutoplay(); }); carousel.addEventListener('mouseleave', function () { hoverPaused = false; startAutoplay(); }); carousel.addEventListener('focusin', function () { focusPaused = true; stopAutoplay(); }); carousel.addEventListener('focusout', function () { window.setTimeout(function () { if (carousel.contains(document.activeElement)) return; focusPaused = false; startAutoplay(); }, 0); }); viewport.addEventListener( 'pointerdown', function () { pointerPaused = true; stopAutoplay(); }, { passive: true } ); viewport.addEventListener( 'pointerup', function () { pointerPaused = false; startAutoplay(); }, { passive: true } ); viewport.addEventListener( 'pointercancel', function () { pointerPaused = false; startAutoplay(); }, { passive: true } ); window.addEventListener( 'resize', function () { window.clearTimeout(resizeTimer); resizeTimer = window.setTimeout(buildDots, 160); }, { passive: true } ); document.addEventListener('visibilitychange', function () { if (document.hidden) { stopAutoplay(); } else { startAutoplay(); } }); carousel.classList.add('is-ready'); buildDots(); }); } function initRevealMotion() { var reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; var compactMotion = window.matchMedia('(max-width: 768px)').matches; if (reducedMotion || !('IntersectionObserver' in window)) return; var revealItems = []; function prepareGroup(containerSelector, itemSelector, delayStep) { document.querySelectorAll(containerSelector).forEach(function (container) { container.querySelectorAll(itemSelector).forEach(function (item, index) { var effectiveStep = compactMotion ? 40 : delayStep; var maximumDelay = compactMotion ? 200 : 300; var delay = Math.min(index * effectiveStep, maximumDelay); item.classList.add('reveal-item'); item.style.setProperty('--reveal-delay', delay + 'ms'); revealItems.push(item); }); }); } prepareGroup( '.b2b-hero', '.section-eyebrow, h1, .b2b-hero-lead, .d-flex.flex-wrap, .hero-proof-list', 80 ); prepareGroup('.trust-strip .row', '.trust-metric', 60); prepareGroup('.capability-grid', '.capability-card', 60); prepareGroup('.case-grid', '.case-card', 60); prepareGroup('.news-grid', '.news-card', 60); prepareGroup('.factory-gallery', 'figure', 60); prepareGroup('.credentials-grid', '.credential-card', 60); prepareGroup('.document-grid', 'article', 60); prepareGroup('.contact-detail-grid', '.contact-detail-card', 60); prepareGroup('.service-content, .case-content, .news-single-content', ':scope > *', 40); document.querySelectorAll( [ '.section-heading', '.factory-proof .col-lg-5', '.factory-video-card', '.faq-section .col-lg-4', '.faq-section .accordion', '.contact-hero-copy', '.contact-store-media', '.contact-map-heading', '.contact-map-panel', '.news-page-header', '.news-single-header', '.news-single-image', '.news-post-navigation', '.news-single-cta', '.cta-section .container', '.about-cta .container', '.page-header' ].join(', ') ).forEach(function (item) { if (item.classList.contains('reveal-item')) return; item.classList.add('reveal-item'); item.style.setProperty('--reveal-delay', '0ms'); revealItems.push(item); }); if (!revealItems.length) return; document.documentElement.classList.add('motion-ready'); var observer = new IntersectionObserver( function (entries) { entries.forEach(function (entry) { if (!entry.isIntersecting) return; entry.target.classList.add('is-visible'); observer.unobserve(entry.target); }); }, { threshold: 0.12, rootMargin: '0px' } ); window.requestAnimationFrame(function () { window.requestAnimationFrame(function () { revealItems.forEach(function (item) { observer.observe(item); }); }); }); } function initTheme() { initStickyHeader(); initNavigation(); initCarousels(); initRevealMotion(); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initTheme); } else { initTheme(); } })();