/* ========================================================================== Ertunç Özbay — Workshop & Portfolio Script (Plain JS, No Dependencies) Handles: 1. Accessible mobile navigation menu toggle (with Escape key support) 2. Luminous Aurora / Daylight Studio theme switcher (persisted in localStorage) 3. Static blog category filtering on the Blog page 4. One-click copy email button on Contact page 5. Image lightbox for hardware prototype photos and schematics ========================================================================== */ (function () { "use strict"; // 1. Theme Switcher (Vibrant Aurora Default + Daylight Studio Mode) var rootEl = document.documentElement; var savedTheme = null; try { savedTheme = localStorage.getItem("eo-theme"); } catch (e) {} if (savedTheme === "light" || savedTheme === "dark") { rootEl.setAttribute("data-theme", savedTheme); } var navList = document.querySelector(".nav-list"); if (navList && !document.querySelector("[data-theme-toggle]")) { var li = document.createElement("li"); var btn = document.createElement("button"); btn.type = "button"; btn.className = "theme-toggle"; btn.setAttribute("data-theme-toggle", ""); btn.setAttribute("aria-label", "Toggle color theme"); function updateThemeBtnLabel() { var isLight = rootEl.getAttribute("data-theme") === "light"; btn.textContent = isLight ? "🌙 Aurora" : "☀️ Daylight"; } updateThemeBtnLabel(); btn.addEventListener("click", function () { var isLight = rootEl.getAttribute("data-theme") === "light"; var nextTheme = isLight ? "dark" : "light"; rootEl.setAttribute("data-theme", nextTheme); try { localStorage.setItem("eo-theme", nextTheme); } catch (e) {} updateThemeBtnLabel(); }); li.appendChild(btn); navList.appendChild(li); } // 2. Mobile Navigation Toggle var navToggle = document.querySelector("[data-nav-toggle]"); var siteNav = document.querySelector("[data-site-nav]"); if (navToggle && siteNav) { navToggle.addEventListener("click", function () { var isExpanded = navToggle.getAttribute("aria-expanded") === "true"; var nextState = !isExpanded; navToggle.setAttribute("aria-expanded", String(nextState)); siteNav.classList.toggle("is-open", nextState); var labelSpan = navToggle.querySelector("[data-nav-label]"); if (labelSpan) { labelSpan.textContent = nextState ? "Close" : "Menu"; } }); document.addEventListener("keydown", function (event) { if (event.key === "Escape" && siteNav.classList.contains("is-open")) { navToggle.setAttribute("aria-expanded", "false"); siteNav.classList.remove("is-open"); var labelSpan = navToggle.querySelector("[data-nav-label]"); if (labelSpan) { labelSpan.textContent = "Menu"; } navToggle.focus(); } }); } // 3. Blog Category Filter var filterButtons = document.querySelectorAll("[data-blog-filter]"); var blogCards = document.querySelectorAll("[data-blog-category]"); var filterStatus = document.getElementById("blog-filter-status"); if (filterButtons.length > 0 && blogCards.length > 0) { filterButtons.forEach(function (button) { button.addEventListener("click", function () { var selectedCategory = button.getAttribute("data-blog-filter"); filterButtons.forEach(function (btn) { btn.setAttribute("aria-pressed", btn === button ? "true" : "false"); }); var visibleCount = 0; blogCards.forEach(function (card) { var categories = (card.getAttribute("data-blog-category") || "").split(","); var match = selectedCategory === "all" || categories.indexOf(selectedCategory) !== -1; card.hidden = !match; if (match) { visibleCount += 1; } }); if (filterStatus) { filterStatus.textContent = "Showing " + visibleCount + (visibleCount === 1 ? " entry" : " entries") + (selectedCategory === "all" ? "." : " in selected category."); } }); }); } // 4. Copy Email to Clipboard Buttons var copyButtons = document.querySelectorAll("[data-copy-email]"); copyButtons.forEach(function (btn) { btn.addEventListener("click", function () { var email = btn.getAttribute("data-copy-email"); if (!email || !navigator.clipboard) return; var originalText = btn.textContent; navigator.clipboard.writeText(email).then(function () { btn.textContent = "✓ Copied: " + email; setTimeout(function () { btn.textContent = originalText; }, 2200); }); }); }); // 5. Image Lightbox for Hardware Photos & Schematics var zoomImages = document.querySelectorAll(".zoomable-img"); if (zoomImages.length > 0) { var backdrop = document.createElement("div"); backdrop.className = "lightbox-backdrop"; backdrop.hidden = true; backdrop.innerHTML = '' + '' + ''; document.body.appendChild(backdrop); var lbImg = backdrop.querySelector(".lightbox-Backdrop-img"); var lbCap = backdrop.querySelector(".lightbox-caption"); var lbClose = backdrop.querySelector(".lightbox-close"); function closeLightbox() { backdrop.hidden = true; lbImg.src = ""; } zoomImages.forEach(function (img) { img.addEventListener("click", function () { lbImg.src = img.src; lbImg.alt = img.alt || ""; lbCap.textContent = img.alt || ""; backdrop.hidden = false; }); }); lbClose.addEventListener("click", closeLightbox); backdrop.addEventListener("click", function (e) { if (e.target === backdrop) closeLightbox(); }); document.addEventListener("keydown", function (e) { if (e.key === "Escape" && !backdrop.hidden) closeLightbox(); }); } })();