/* ==========================================================================
Ertunç Özbay — Workshop & Portfolio Script (Plain JS, No Dependencies)
Handles:
1. Prominent Multi-Theme Switcher (🎨 Colorful Studio [Default] | 🌈 Neon | 📐 Blueprint)
2. Accessible mobile navigation menu toggle (with Escape key support)
3. Static blog category filtering on the Blog page
4. One-click copy buttons for Email addresses and Code/Command blocks
5. Image lightbox for hardware prototype photos and schematics
========================================================================== */
(function () {
"use strict";
// 1. Multi-Theme Switcher (Colorful Default, Cyber Neon, Blueprint Lab)
var rootEl = document.documentElement;
var validThemes = ["colorful", "neon", "blueprint"];
var savedTheme = "colorful";
try {
var stored = localStorage.getItem("eo-studio-theme");
if (stored && validThemes.indexOf(stored) !== -1) {
savedTheme = stored;
}
} catch (e) {}
function applyTheme(themeName) {
if (validThemes.indexOf(themeName) === -1) {
themeName = "colorful";
}
rootEl.setAttribute("data-theme", themeName);
try {
localStorage.setItem("eo-studio-theme", themeName);
} catch (e) {}
var buttons = document.querySelectorAll("[data-set-theme]");
buttons.forEach(function (btn) {
var isTarget = btn.getAttribute("data-set-theme") === themeName;
btn.setAttribute("aria-pressed", isTarget ? "true" : "false");
});
}
applyTheme(savedTheme);
document.addEventListener("click", function (event) {
var themeBtn = event.target.closest("[data-set-theme]");
if (themeBtn) {
applyTheme(themeBtn.getAttribute("data-set-theme"));
}
});
// 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 copyEmailButtons = document.querySelectorAll("[data-copy-email]");
copyEmailButtons.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. Copy Code / Terminal Commands Buttons
var copyCodeButtons = document.querySelectorAll("[data-copy-code]");
copyCodeButtons.forEach(function (btn) {
btn.addEventListener("click", function () {
var windowEl = btn.closest(".code-window");
if (!windowEl || !navigator.clipboard) return;
var preEl = windowEl.querySelector("pre");
if (!preEl) return;
var originalText = btn.textContent;
navigator.clipboard.writeText(preEl.innerText).then(function () {
btn.textContent = "✓ Copied!";
setTimeout(function () {
btn.textContent = originalText;
}, 2000);
});
});
});
// 6. 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 =
'' +
'' +
'