/** * XShop theme bootstrap – vanilla, no jQuery. * Feature modules are dynamically imported when DOM markers are present. */ (function () { 'use strict'; // Dark mode toggle via [data-theme] if enabled. function initThemeMode() { var data = window.xshopData; if (!data) return; // Theme mode is server-rendered via data-theme on ; this handles toggle clicks. document.addEventListener('click', function (e) { var btn = e.target.closest('[data-xshop-theme-toggle]'); if (!btn) return; var html = document.documentElement; var next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'; html.setAttribute('data-theme', next); try { localStorage.setItem('xshop_theme', next); } catch (_) {} // Cookie for server-side rendering on next request. document.cookie = 'xshop_theme=' + next + '; path=/; max-age=2592000; SameSite=Lax'; }); } // Minimal focus trap helper for drawers/modals (used by later modules). window.xshopTrapFocus = function (container) { var sel = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'; var nodes = container.querySelectorAll(sel); if (!nodes.length) return function () {}; var first = nodes[0], last = nodes[nodes.length - 1]; function onKey(e) { if (e.key !== 'Tab') return; if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); } else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); } } container.addEventListener('keydown', onKey); return function () { container.removeEventListener('keydown', onKey); }; }; function initMobileNav() { var toggle = document.querySelector('[data-xshop-mobile-toggle]'); var nav = document.getElementById('xshop-mobile-nav'); if (!toggle || !nav) return; var releaseTrap = null; function setOpen(open) { toggle.setAttribute('aria-expanded', open ? 'true' : 'false'); nav.classList.toggle('is-open', open); nav.hidden = !open; if (open) { // Move focus into nav. var firstLink = nav.querySelector('a, button'); if (firstLink) firstLink.focus(); if (window.xshopTrapFocus) releaseTrap = window.xshopTrapFocus(nav); document.addEventListener('keydown', onDocKey); } else { if (releaseTrap) { releaseTrap(); releaseTrap = null; } document.removeEventListener('keydown', onDocKey); toggle.focus(); } } function onDocKey(e) { if (e.key === 'Escape') setOpen(false); } toggle.addEventListener('click', function () { var open = toggle.getAttribute('aria-expanded') === 'true'; setOpen(!open); }); // Close when clicking outside. document.addEventListener('click', function (e) { if (nav.hidden) return; if (nav.contains(e.target) || toggle.contains(e.target)) return; setOpen(false); }); } initThemeMode(); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initMobileNav); } else { initMobileNav(); } })();