diff --git a/public/css/style.css b/public/css/style.css index 4f34a41..b73aefb 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -305,6 +305,98 @@ body { transform: rotate(30deg); } +/* ---- Theme Switch ---- */ +.theme-switch-wrapper { + display: flex; + align-items: center; +} + +.theme-switch { + display: inline-block; + height: 28px; + position: relative; + width: 54px; +} + +.theme-switch input { + display: none; +} + +.slider { + background-color: var(--bg-card); + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: .4s; + border: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 4px; +} + +.slider:before { + background-color: #fff; + bottom: 3px; + content: ""; + height: 20px; + left: 4px; + position: absolute; + transition: .4s; + width: 20px; + z-index: 2; + box-shadow: 0 2px 4px rgba(0,0,0,0.2); +} + +.slider.round { + border-radius: 34px; +} + +.slider.round:before { + border-radius: 50%; +} + +input:checked + .slider { + background-color: var(--accent-indigo); + border-color: var(--accent-indigo); +} + +input:checked + .slider:before { + transform: translateX(24px); +} + +.theme-icon { + width: 14px; + height: 14px; + z-index: 1; + transition: opacity 0.3s; +} + +.sun-icon { + color: #fbbf24; +} + +.moon-icon { + color: #cbd5e1; +} + +/* ---- Gauge Time ---- */ +.title-time { + font-family: var(--font-mono); + font-size: 0.85rem; + font-weight: 500; + color: var(--accent-indigo); + margin-right: 8px; + opacity: 0.9; +} + +:root.light-theme .title-time { + color: var(--accent-blue); +} + /* ---- Dashboard Layout ---- */ .dashboard { padding: 24px 28px 40px; diff --git a/public/index.html b/public/index.html index 267c7e7..9c4455c 100644 --- a/public/index.html +++ b/public/index.html @@ -67,10 +67,15 @@
- +
+ +
@@ -198,6 +203,7 @@

+ diff --git a/public/js/app.js b/public/js/app.js index 051a508..017e099 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -63,7 +63,8 @@ loginModal: document.getElementById('loginModalOverlay'), closeLoginModal: document.getElementById('closeLoginModal'), loginForm: document.getElementById('loginForm'), - loginError: document.getElementById('loginError') + loginError: document.getElementById('loginError'), + gaugesTime: document.getElementById('gaugesTime') }; // ---- State ---- @@ -79,6 +80,10 @@ // Clock updateClock(); setInterval(updateClock, 1000); + + // Resource Gauges Time + updateGaugesTime(); + setInterval(updateGaugesTime, 1000); // Initial theme check (localStorage handled after site settings load to ensure priority) @@ -95,7 +100,7 @@ dom.btnAdd.addEventListener('click', addSource); // Auth & Theme listeners - dom.themeToggle.addEventListener('click', toggleTheme); + dom.themeToggle.addEventListener('change', toggleTheme); dom.btnLogin.addEventListener('click', openLoginModal); dom.closeLoginModal.addEventListener('click', closeLoginModal); dom.loginForm.addEventListener('submit', handleLogin); @@ -152,25 +157,30 @@ // ---- Theme Switching ---- function toggleTheme() { - const isLight = document.documentElement.classList.toggle('light-theme'); - const theme = isLight ? 'light' : 'dark'; + const theme = dom.themeToggle.checked ? 'light' : 'dark'; + document.documentElement.classList.toggle('light-theme', theme === 'light'); localStorage.setItem('theme', theme); updateThemeIcons(theme); } function applyTheme(theme) { const isLight = theme === 'light'; + dom.themeToggle.checked = isLight; document.documentElement.classList.toggle('light-theme', isLight); updateThemeIcons(theme); } function updateThemeIcons(theme) { if (theme === 'light') { - dom.sunIcon.style.display = 'none'; + dom.sunIcon.style.display = 'block'; // Always show both in slider, but might adjust opacity dom.moonIcon.style.display = 'block'; + dom.sunIcon.style.opacity = '0.3'; + dom.moonIcon.style.opacity = '1'; } else { dom.sunIcon.style.display = 'block'; - dom.moonIcon.style.display = 'none'; + dom.moonIcon.style.display = 'block'; + dom.sunIcon.style.opacity = '1'; + dom.moonIcon.style.opacity = '0.3'; } } @@ -287,6 +297,12 @@ dom.clock.textContent = formatClock(); } + function updateGaugesTime() { + if (dom.gaugesTime) { + dom.gaugesTime.textContent = formatClock(); + } + } + // ---- Fetch Metrics ---- async function fetchMetrics() { try {