/** 中控主题:暗色(默认)/ 亮色,localStorage hub-theme */ (function (global) { const KEY = "hub-theme"; const META = { dark: "#0b0e18", light: "#d4dde8" }; function normalize(theme) { return theme === "light" ? "light" : "dark"; } function get() { try { return normalize(localStorage.getItem(KEY)); } catch (_) { return "dark"; } } function broadcastThemeToInstances() { const msg = { type: "hub-theme-sync", theme: get() }; document.querySelectorAll("iframe#instance-frame, iframe.instance-frame").forEach((frame) => { try { if (frame.contentWindow) frame.contentWindow.postMessage(msg, "*"); } catch (_) {} }); } function apply(theme) { const t = normalize(theme); const root = document.documentElement; root.setAttribute("data-theme", t); try { localStorage.setItem(KEY, t); } catch (_) {} const meta = document.querySelector('meta[name="theme-color"]'); if (meta) meta.setAttribute("content", META[t]); root.style.colorScheme = t; document.dispatchEvent(new CustomEvent("hub-theme-change", { detail: { theme: t } })); broadcastThemeToInstances(); return t; } function toggle() { return apply(get() === "dark" ? "light" : "dark"); } function syncToggleUI(root) { const scope = root || document; scope.querySelectorAll(".theme-toggle-btn[data-theme-value]").forEach((btn) => { const on = btn.getAttribute("data-theme-value") === get(); btn.classList.toggle("is-active", on); btn.setAttribute("aria-pressed", on ? "true" : "false"); }); } function initToggleUI(root) { const scope = root || document; syncToggleUI(scope); scope.querySelectorAll(".theme-toggle-btn[data-theme-value]").forEach((btn) => { if (btn.dataset.themeBound === "1") return; btn.dataset.themeBound = "1"; btn.addEventListener("click", () => { apply(btn.getAttribute("data-theme-value")); syncToggleUI(scope); }); }); document.addEventListener("hub-theme-change", () => syncToggleUI(scope)); } apply(get()); global.HubTheme = { KEY, get, apply, toggle, syncToggleUI, initToggleUI }; })(typeof window !== "undefined" ? window : globalThis);