export const FONT_DEBUG_ASSET_PATH = "/assets/font-debug.js"; export const FONT_DEBUG_SCRIPT = `(() => { const storageKey = "stream-body-font-preview"; const defaultStack = "Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif"; const familyPattern = /^[A-Za-z0-9][A-Za-z0-9 -]{0,79}$/; let requestVersion = 0; let pendingLink = null; const style = document.createElement("style"); style.textContent = ".font-debug-panel{position:fixed;right:max(16px,env(safe-area-inset-right));bottom:max(16px,env(safe-area-inset-bottom));z-index:10000;width:min(340px,calc(100vw - 32px));border:1px solid var(--border,var(--line,#444));border-radius:16px;background:var(--panel,var(--bg,#111));color:var(--text,#eee);box-shadow:0 18px 56px rgba(0,0,0,.28);padding:16px;font:14px/1.45 var(--font-body)}.font-debug-panel[hidden]{display:none}.font-debug-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}.font-debug-head strong{font-size:14px}.font-debug-close{border:0;background:transparent;color:var(--muted,#888);padding:4px;cursor:pointer}.font-debug-panel label{display:grid;gap:6px;color:var(--muted,#888);font-size:12px}.font-debug-panel input{width:100%;min-height:40px;border:1px solid var(--border,var(--line,#444));border-radius:10px;background:var(--surface-control,var(--surface,#171717));color:var(--text,#eee);padding:8px 10px}.font-debug-actions{display:flex;gap:8px;margin-top:10px}.font-debug-actions button{min-height:36px;border:1px solid var(--border,var(--line,#444));border-radius:999px;background:transparent;color:var(--text,#eee);padding:7px 12px;cursor:pointer}.font-debug-actions button:first-child{border-color:var(--accent,#b497bf);background:var(--accent-soft,rgba(180,151,191,.11))}.font-debug-status{min-height:20px;margin:10px 0 0;color:var(--muted,#888);font-size:12px}"; document.head.append(style); const panel = document.createElement("section"); panel.className = "font-debug-panel"; panel.hidden = true; panel.setAttribute("role", "dialog"); panel.setAttribute("aria-label", "Body font preview"); panel.innerHTML = '
Around display type stays unchanged.
'; document.body.append(panel); const input = panel.querySelector("#font-debug-family"); const status = panel.querySelector(".font-debug-status"); const closeButton = panel.querySelector(".font-debug-close"); const applyButton = panel.querySelector("[data-font-apply]"); const resetButton = panel.querySelector("[data-font-reset]"); function storedFamily() { try { return localStorage.getItem(storageKey) || ""; } catch { return ""; } } function storeFamily(family) { try { if (family) localStorage.setItem(storageKey, family); else localStorage.removeItem(storageKey); } catch {} } function setPanelOpen(open) { panel.hidden = !open; if (open) { input.value = storedFamily(); input.focus(); input.select(); } } function resetFont() { requestVersion += 1; pendingLink = null; document.querySelectorAll("link[data-stream-font-debug]").forEach(link => link.remove()); document.documentElement.style.removeProperty("--font-body"); storeFamily(""); input.value = ""; status.textContent = "Using the default body font. Around display type stays unchanged."; } function applyFont(rawFamily, persist = true) { const family = rawFamily.trim().replace(/\\s+/g, " "); if (!familyPattern.test(family)) { status.textContent = "Use the exact Google Fonts family name with letters, numbers, spaces, or hyphens."; return; } const version = ++requestVersion; pendingLink?.remove(); const previous = document.querySelector("#font-debug-google-font"); const link = document.createElement("link"); link.dataset.streamFontDebug = "true"; link.rel = "stylesheet"; link.href = "https://fonts.googleapis.com/css2?family=" + encodeURIComponent(family).replace(/%20/g, "+") + "&display=swap"; link.addEventListener("load", () => { if (version !== requestVersion) { link.remove(); return; } pendingLink = null; previous?.remove(); link.id = "font-debug-google-font"; document.documentElement.style.setProperty("--font-body", '"' + family + '",' + defaultStack); if (persist) storeFamily(family); input.value = family; status.textContent = "Using " + family + " for body text. Around is unchanged."; }); link.addEventListener("error", () => { if (pendingLink === link) pendingLink = null; link.remove(); if (version !== requestVersion) return; status.textContent = "Google Fonts did not return that family."; }); pendingLink = link; document.head.append(link); status.textContent = "Loading " + family + "…"; } applyButton.addEventListener("click", () => applyFont(input.value)); resetButton.addEventListener("click", resetFont); closeButton.addEventListener("click", () => setPanelOpen(false)); input.addEventListener("keydown", event => { if (event.key === "Enter") { event.preventDefault(); applyFont(input.value); } }); document.addEventListener("keydown", event => { if (event.key === "Escape" && !panel.hidden) setPanelOpen(false); if (event.altKey && event.shiftKey && event.key.toLowerCase() === "f") { event.preventDefault(); setPanelOpen(panel.hidden); } }); const trigger = document.querySelector("h1"); let clickCount = 0; let lastClickAt = 0; trigger?.addEventListener("click", () => { const now = Date.now(); clickCount = now - lastClickAt < 650 ? clickCount + 1 : 1; lastClickAt = now; if (clickCount === 3) { clickCount = 0; setPanelOpen(panel.hidden); } }); const saved = storedFamily(); if (saved && familyPattern.test(saved)) applyFont(saved, false); })(); `;