/* Novizun — Interactive Script */ // Initialize Lucide icons lucide.createIcons(); // Dark mode toggle (function () { const toggle = document.querySelector('[data-theme-toggle]'); const root = document.documentElement; let dark = matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; root.setAttribute('data-theme', dark); if (toggle) { toggle.addEventListener('click', function () { dark = dark === 'dark' ? 'light' : 'dark'; root.setAttribute('data-theme', dark); toggle.setAttribute('aria-label', 'Switch to ' + (dark === 'dark' ? 'light' : 'dark') + ' mode'); toggle.innerHTML = dark === 'dark' ? '' : ''; }); } })(); // Mobile menu toggle (function () { const btn = document.getElementById('mobile-menu-btn'); const nav = document.getElementById('nav'); if (btn && nav) { btn.addEventListener('click', function () { const expanded = btn.getAttribute('aria-expanded') === 'true'; btn.setAttribute('aria-expanded', String(!expanded)); nav.classList.toggle('open'); }); // Close on link click nav.querySelectorAll('.nav-link').forEach(function (link) { link.addEventListener('click', function () { btn.setAttribute('aria-expanded', 'false'); nav.classList.remove('open'); }); }); } })(); // Header scroll behavior (function () { const header = document.getElementById('header'); let lastScroll = 0; window.addEventListener('scroll', function () { const scrollY = window.scrollY; if (scrollY > 10) { header.classList.add('header--scrolled'); } else { header.classList.remove('header--scrolled'); } lastScroll = scrollY; }, { passive: true }); })(); // Product category filtering (function () { const tabs = document.querySelectorAll('.product-tab'); const cards = document.querySelectorAll('.product-card'); tabs.forEach(function (tab) { tab.addEventListener('click', function () { // Update active tab tabs.forEach(function (t) { t.classList.remove('active'); t.setAttribute('aria-selected', 'false'); }); tab.classList.add('active'); tab.setAttribute('aria-selected', 'true'); const filter = tab.getAttribute('data-filter'); cards.forEach(function (card) { if (filter === 'all') { card.classList.remove('hidden'); } else { const category = card.getAttribute('data-category') || ''; if (category.includes(filter)) { card.classList.remove('hidden'); } else { card.classList.add('hidden'); } } }); }); }); })(); // Smooth scroll for anchor links document.querySelectorAll('a[href^="#"]').forEach(function (anchor) { anchor.addEventListener('click', function (e) { const target = document.querySelector(this.getAttribute('href')); if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // Intersection Observer for scroll reveal (function () { const sections = document.querySelectorAll('.section'); if (!('IntersectionObserver' in window)) return; const observer = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { entry.target.style.opacity = '1'; entry.target.style.transform = 'translateY(0)'; observer.unobserve(entry.target); } }); }, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }); sections.forEach(function (section) { section.style.opacity = '0'; section.style.transform = 'translateY(20px)'; section.style.transition = 'opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1)'; observer.observe(section); }); })(); // Floating CTA — show after scrolling past hero (function () { var floatingCta = document.getElementById('floating-cta'); if (!floatingCta) return; var hero = document.querySelector('.hero'); if (!hero) return; // Check if mobile (floating CTA hidden on desktop via CSS, but let's be safe) function checkMobile() { return window.innerWidth < 768; } function toggleFloatingCta() { if (!checkMobile()) { floatingCta.classList.remove('visible'); return; } var heroBottom = hero.getBoundingClientRect().bottom; if (heroBottom < 0) { floatingCta.classList.add('visible'); } else { floatingCta.classList.remove('visible'); } } window.addEventListener('scroll', toggleFloatingCta, { passive: true }); window.addEventListener('resize', toggleFloatingCta, { passive: true }); // Initial check toggleFloatingCta(); })();