diff --git a/website/assets/js/global-header.js b/website/assets/js/global-header.js index 587e7aac..7cb0e97f 100644 --- a/website/assets/js/global-header.js +++ b/website/assets/js/global-header.js @@ -1,4 +1,16 @@ (function () { + // Immediately restore theme on script load + const savedTheme = localStorage.getItem('theme') || localStorage.getItem('exchangeTheme'); + if (savedTheme) { + if (savedTheme === 'dark') { + document.documentElement.setAttribute('data-theme', 'dark'); + document.documentElement.classList.add('dark'); + } else { + document.documentElement.removeAttribute('data-theme'); + document.documentElement.classList.remove('dark'); + } + } + const NAV_ITEMS = [ { key: 'home', label: 'Home', href: '/' }, { key: 'explorer', label: 'Explorer', href: '/explorer/' }, @@ -69,22 +81,39 @@ } } + function setGlobalTheme(theme) { + if (theme === 'dark') { + document.documentElement.setAttribute('data-theme', 'dark'); + document.documentElement.classList.add('dark'); + document.body.classList.remove('light'); + } else { + document.documentElement.removeAttribute('data-theme'); + document.documentElement.classList.remove('dark'); + document.body.classList.add('light'); + } + localStorage.setItem('theme', theme); + localStorage.setItem('exchangeTheme', theme); // for backwards compat + } + + function getGlobalTheme() { + return localStorage.getItem('theme') || localStorage.getItem('exchangeTheme') || 'dark'; + } + function bindThemeToggle() { const toggle = document.querySelector('[data-role="global-theme-toggle"]'); if (!toggle) return; toggle.addEventListener('click', () => { - if (typeof window.toggleDarkMode === 'function') { - window.toggleDarkMode(); - } else if (typeof window.toggleTheme === 'function') { - window.toggleTheme(); - } else { - const isDark = document.documentElement.classList.toggle('dark'); - if (isDark) { - document.documentElement.setAttribute('data-theme', 'dark'); - } else { - document.documentElement.removeAttribute('data-theme'); - } + // Don't call window.toggleDarkMode anymore because it causes state desync. + // We take full control of the global theme here. + const current = getCurrentTheme(); + const next = current === 'dark' ? 'light' : 'dark'; + + setGlobalTheme(next); + + // If the page has a specific app-level override, trigger it + if (typeof window.setTheme === 'function' && window.location.pathname === '/') { + window.setTheme(next); } setTimeout(() => updateToggleLabel(getCurrentTheme()), 0); @@ -93,6 +122,7 @@ updateToggleLabel(getCurrentTheme()); } + function initHeader() { const activeKey = determineActiveKey(window.location.pathname); const headerHTML = buildHeader(activeKey); diff --git a/website/assets/js/main.js b/website/assets/js/main.js index c89e3a62..0904d229 100644 --- a/website/assets/js/main.js +++ b/website/assets/js/main.js @@ -38,49 +38,12 @@ document.querySelectorAll('.feature-card, .arch-component').forEach(el => { }); // Dark mode functionality with enhanced persistence and system preference detection -function toggleDarkMode() { - const currentTheme = document.documentElement.getAttribute('data-theme'); - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - setTheme(newTheme); + } -function setTheme(theme) { - // Apply theme immediately - document.documentElement.setAttribute('data-theme', theme); - - // Save to localStorage for persistence - localStorage.setItem('theme', theme); - - // Update button display if it exists - updateThemeButton(theme); - - // Send analytics event - if (window.analytics) { - window.analytics.track('theme_changed', { theme }); } } -function updateThemeButton(theme) { - const emoji = document.getElementById('darkModeEmoji'); - const text = document.getElementById('darkModeText'); - - if (emoji && text) { - if (theme === 'dark') { - emoji.textContent = '🌙'; - text.textContent = 'Dark'; - } else { - emoji.textContent = '☀️'; - text.textContent = 'Light'; - } - } -} - -function getPreferredTheme() { - // 1. Check localStorage first (user preference) - const saved = localStorage.getItem('theme'); - if (saved) { - return saved; - } // 2. Check system preference if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { @@ -107,7 +70,6 @@ function initializeTheme() { } // Initialize theme immediately (before DOM loads) -initializeTheme(); // Touch gesture support for mobile navigation class TouchNavigation {