/* MoonBite site shell: header scroll state, phone menu, live network pill.
External file (CSP: script-src 'self'), no inline handlers. */
(function () {
"use strict";
var h = document.querySelector("[data-mbs-header]");
if (!h) return;
/* header gains its blurred background once the page scrolls */
function onScroll() { h.classList.toggle("is-scrolled", window.scrollY > 8); }
onScroll(); window.addEventListener("scroll", onScroll, { passive: true });
/* phone menu */
var btn = h.querySelector("[data-mbs-menu]"), sheet = document.getElementById("mbs-sheet");
function setOpen(open) {
if (!btn || !sheet) return;
sheet.hidden = !open; btn.setAttribute("aria-expanded", String(open));
btn.textContent = open ? "Close" : "Menu";
h.classList.toggle("is-open", open); document.body.classList.toggle("mbs-locked", open);
}
if (btn) btn.addEventListener("click", function () { setOpen(sheet.hidden); });
document.addEventListener("keydown", function (e) { if (e.key === "Escape") setOpen(false); });
window.addEventListener("resize", function () { if (window.innerWidth > 900) setOpen(false); });
/* live network pill: before launch, when mining opens (genesis is stamped
2 h after launch); afterwards, the current block height */
var pills = document.querySelectorAll("[data-mbs-status]");
if (!pills.length) return;
var CET = { timeZone: "Europe/Paris" };
function opensText(ms) {
var d = new Date(ms);
return d.toLocaleString("en-GB", Object.assign({ weekday: "short", hour: "2-digit", minute: "2-digit", timeZoneName: "short" }, CET));
}
function left(ms) {
var s = Math.max(0, Math.round((ms - Date.now()) / 1000)), d = Math.floor(s / 86400), hh = Math.floor(s % 86400 / 3600), m = Math.floor(s % 3600 / 60);
return d ? d + "d " + hh + "h" : hh ? hh + "h " + m + "m" : m + "m";
}
var state = null;
function paint() {
if (!state) return;
pills.forEach(function (p) {
var dot = p.querySelector(".mbs-dot"), txt = p.querySelector("[data-mbs-status-text]");
if (state.launchAt && Date.now() < state.launchAt) {
dot.className = "mbs-dot is-soon";
txt.innerHTML = "Mining opens " + opensText(state.launchAt) + " · " + left(state.launchAt);
p.title = "Nobody can mine before launch; the rule is in the genesis block.";
} else if (state.height === 0) {
dot.className = "mbs-dot is-soon"; txt.innerHTML = "Mining open · block 1 unclaimed";
} else {
dot.className = "mbs-dot is-live"; txt.innerHTML = "Block #" + state.height + ""; // heights never separated (d11)
p.title = "Live height of the MoonBite network";
}
});
}
function poll() {
fetch("/api/blockchain/info", { cache: "no-store" }).then(function (r) { return r.json(); }).then(function (d) {
if (!d || d.height === undefined) return;
var hgt = Number(d.height);
state = { height: hgt, launchAt: (hgt === 0 && d.tip_time) ? (Number(d.tip_time) - 7200) * 1000 : null };
paint();
}).catch(function () {});
}
poll(); setInterval(poll, 30000); setInterval(paint, 15000);
})();