document.addEventListener('DOMContentLoaded', () => { const sidebar = document.getElementById('sidebar'); const closeBtn = document.getElementById('close-sidebar'); const trigger = document.getElementById('read-more-trigger'); const body = document.body; let manualClose = false; // --- Sidebar Logic --- function checkSidebarVisibility() { if (manualClose) return; const scrollTop = window.scrollY; const windowHeight = window.innerHeight; const docHeight = document.documentElement.scrollHeight; // "Sidebar fix": Check if page is short (content fits in window or close to it) // If content is short, sidebar should be visible immediately (if desktop) if (docHeight <= windowHeight * 1.2 && window.innerWidth > 900) { sidebar.classList.add('visible'); sidebar.style.opacity = 1; sidebar.style.pointerEvents = 'auto'; return; } // Scroll Logic for longer pages if (scrollTop + windowHeight > docHeight * 0.9) { sidebar.classList.add('visible'); trigger.classList.add('visible'); // Dynamic Opacity near bottom const remaining = docHeight - (scrollTop + windowHeight); const threshold = docHeight * 0.1; if (remaining < threshold) { const opacity = 1 - (remaining / threshold); sidebar.style.opacity = Math.min(Math.max(opacity, 0), 1); if (opacity > 0) { sidebar.style.pointerEvents = 'auto'; } else { sidebar.style.pointerEvents = 'none'; } } else { // Should be redundant with visibility check but safe } } else { // Hide if scrolled up? // "It just is gone then... manual close... refresh if want it back" // But scroll behavior implies transient visibility. // We'll hide it if we scroll back up, unless it's short content. sidebar.style.opacity = 0; sidebar.style.pointerEvents = 'none'; } } window.addEventListener('scroll', checkSidebarVisibility); window.addEventListener('resize', checkSidebarVisibility); // Initial check setTimeout(checkSidebarVisibility, 100); // Slight delay for rendering // Mobile Trigger trigger.addEventListener('click', () => { sidebar.classList.add('force-visible'); sidebar.style.opacity = 1; sidebar.style.pointerEvents = 'auto'; }); // Close Button closeBtn.addEventListener('click', () => { sidebar.classList.remove('visible'); sidebar.classList.remove('force-visible'); sidebar.style.opacity = 0; sidebar.style.pointerEvents = 'none'; manualClose = true; trigger.style.display = 'none'; }); // --- Dark Mode Logic --- // Create Toggle Button const sidebarContent = document.querySelector('.sidebar-content'); const themeBtn = document.createElement('button'); themeBtn.id = 'theme-toggle'; themeBtn.textContent = 'Toggle Theme'; sidebarContent.appendChild(themeBtn); function setDarkMode(enable) { if (enable) { body.classList.add('dark-mode'); themeBtn.textContent = 'Switch to Light Mode'; } else { body.classList.remove('dark-mode'); themeBtn.textContent = 'Switch to Dark Mode'; } } function getCookie(name) { const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); return v ? v[2] : null; } function setCookie(name, value, hours) { const d = new Date(); d.setTime(d.getTime() + (hours * 60 * 60 * 1000)); document.cookie = name + "=" + value + ";path=/;expires=" + d.toUTCString(); } // Init Dark Mode const cookieTheme = getCookie('theme'); if (cookieTheme === 'dark') { setDarkMode(true); } else if (cookieTheme === 'light') { setDarkMode(false); } else { // Time based auto-detect const hour = new Date().getHours(); if (hour < 6 || hour >= 18) { setDarkMode(true); } else { setDarkMode(false); } } themeBtn.addEventListener('click', () => { const isDark = body.classList.contains('dark-mode'); setDarkMode(!isDark); setCookie('theme', !isDark ? 'dark' : 'light', 24); }); });