- Shared header/footer/chrome (src/header.html, src/footer.html, src/chrome.js) now on every page: editor (header above its app toolbar), player, teacher, stage, micro, showcase, embed. chrome.js defers to DOMContentLoaded so the footer version stamps regardless of placement. Player's fullscreen toggle relocated out of the header to a floating control. - Open = Info: each form-factor page is self-contained — a more-detailed description (.about) + an expandable "Spec & BOM" (<details class="spec">, hidden in embed). info-*.html retired; build/deploy/README updated. Next: teacher-style dimensioned front + top/side views + loading panels for Stage, Micro and Showcase. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
22 lines
1.6 KiB
JavaScript
22 lines
1.6 KiB
JavaScript
/* Shared site chrome — assembled into every page by build.sh.
|
|
Wires the header theme toggle (system - light - dark, shared "metronome.theme")
|
|
and stamps the footer version. Expects a global APP_VERSION declared earlier in
|
|
the page (deploy.sh rewrites that line) and the header/footer markup present. */
|
|
(function () {
|
|
var byId = function (id) { return document.getElementById(id); };
|
|
var THEMES = ["system", "light", "dark"];
|
|
function eff(p) { return p === "system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p; }
|
|
function pref() { try { var p = localStorage.getItem("metronome.theme"); return (p === "light" || p === "dark" || p === "system") ? p : "system"; } catch (e) { return "system"; } }
|
|
function apply(p) {
|
|
try { localStorage.setItem("metronome.theme", p); } catch (e) {}
|
|
document.documentElement.dataset.theme = eff(p);
|
|
var b = byId("themeBtn"); if (b) { b.textContent = p === "system" ? "◐" : p === "light" ? "☀" : "☾"; b.title = "Theme: " + p + " (system → light → dark)"; }
|
|
}
|
|
function init() {
|
|
try { var v = byId("appVersion"); if (v && typeof APP_VERSION !== "undefined") v.textContent = "v" + APP_VERSION.replace(/^v/, ""); } catch (e) {}
|
|
var btn = byId("themeBtn"); if (btn) btn.onclick = function () { apply(THEMES[(THEMES.indexOf(pref()) + 1) % THEMES.length]); };
|
|
apply(pref());
|
|
}
|
|
try { matchMedia("(prefers-color-scheme: light)").addEventListener("change", function () { if (pref() === "system") apply("system"); }); } catch (e) {}
|
|
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", init); else init();
|
|
})();
|