c834919a3c
First-time visitors now always see light theme (paper aesthetic) regardless of their system dark mode preference. Users can still switch to dark or auto mode, and their preference is saved to localStorage for future visits. This maintains the professional CV paper appearance as the default experience while giving users full control over their preference.
108 lines
3.2 KiB
JavaScript
108 lines
3.2 KiB
JavaScript
/**
|
|
* COLOR THEME SYSTEM
|
|
* Pure JavaScript implementation (replacing hyperscript due to parsing issues)
|
|
* Handles light/dark/auto theme switching
|
|
*/
|
|
|
|
// Set color theme
|
|
function setColorTheme(mode) {
|
|
// Save preference to localStorage
|
|
localStorage.setItem('color-theme-mode', mode);
|
|
|
|
// Apply theme to document
|
|
document.documentElement.setAttribute('data-color-theme', mode);
|
|
|
|
// Update button icon and color based on mode
|
|
const themeButton = document.querySelector('#color-theme-switcher');
|
|
const themeIcon = document.querySelector('#themeIcon');
|
|
|
|
if (themeButton) {
|
|
// Set data attribute for CSS styling
|
|
themeButton.setAttribute('data-theme-mode', mode);
|
|
}
|
|
|
|
if (themeIcon) {
|
|
if (mode === 'light') {
|
|
themeIcon.setAttribute('icon', 'mdi:white-balance-sunny');
|
|
} else if (mode === 'dark') {
|
|
themeIcon.setAttribute('icon', 'mdi:moon-waning-crescent');
|
|
} else {
|
|
themeIcon.setAttribute('icon', 'mdi:theme-light-dark');
|
|
}
|
|
}
|
|
|
|
// Update button active states (for hidden compatibility buttons)
|
|
const buttons = document.querySelectorAll('.theme-option-btn');
|
|
buttons.forEach(btn => {
|
|
if (btn.getAttribute('data-theme-mode') === mode) {
|
|
btn.classList.add('active');
|
|
} else {
|
|
btn.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialize color theme
|
|
function initColorTheme() {
|
|
// Check if theme was already set by FOUC prevention script
|
|
const existingTheme = document.documentElement.getAttribute('data-color-theme');
|
|
|
|
// If theme is already set (by FOUC script), save it to localStorage
|
|
if (existingTheme) {
|
|
// Save the FOUC-detected theme to localStorage
|
|
localStorage.setItem('color-theme-mode', existingTheme);
|
|
setColorTheme(existingTheme);
|
|
} else {
|
|
// Fallback: Get saved preference or default to 'light' (paper aesthetic)
|
|
const savedTheme = localStorage.getItem('color-theme-mode') || 'light';
|
|
setColorTheme(savedTheme);
|
|
}
|
|
}
|
|
|
|
// Setup button click handler
|
|
function setupColorThemeButton() {
|
|
const button = document.querySelector('#color-theme-switcher');
|
|
if (button) {
|
|
button.addEventListener('click', () => {
|
|
// Get current theme
|
|
const currentTheme = localStorage.getItem('color-theme-mode') || 'light';
|
|
|
|
// Cycle: auto → light → dark → auto
|
|
if (currentTheme === 'auto') {
|
|
setColorTheme('light');
|
|
} else if (currentTheme === 'light') {
|
|
setColorTheme('dark');
|
|
} else {
|
|
setColorTheme('auto');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
// Watch system theme changes (optional enhancement)
|
|
function watchSystemTheme() {
|
|
const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
darkModeQuery.addEventListener('change', () => {
|
|
const currentMode = localStorage.getItem('color-theme-mode');
|
|
if (currentMode === 'auto' || currentMode === null) {
|
|
// Theme will automatically update via CSS
|
|
// Just ensure the UI reflects the current state
|
|
setColorTheme('auto');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialize on DOM ready
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
initColorTheme();
|
|
setupColorThemeButton();
|
|
watchSystemTheme();
|
|
});
|
|
} else {
|
|
initColorTheme();
|
|
setupColorThemeButton();
|
|
watchSystemTheme();
|
|
}
|