diff --git a/static/svrnty_nav.js b/static/svrnty_nav.js index fd6d1ee..5729cf5 100644 --- a/static/svrnty_nav.js +++ b/static/svrnty_nav.js @@ -15,55 +15,84 @@ const ERR = (...a) => console.error("[svrnty-nav]", ...a); LOG("loaded", { readyState: document.readyState }); + // SVG paths only — sizes/strokes templated per container (rail uses 20×20 + // stroke 1.5; sidebar-nav uses 18×18 stroke 2). Matches existing buttons. + const ICONS = { + adwright: + '', + bte: + '', + }; const TABS = [ + { id: "adwright", label: "Adwright", tooltip: "Adwright — marketing intelligence" }, + { id: "bte", label: "BTE", tooltip: "BTE — brand creative studio" }, + ]; + + function _svg(iconPath, size, stroke) { + return ( + '" + ); + } + + // Two containers: .rail (desktop, .rail-btn nav-tab 20×20 stroke-1.5) + + // .sidebar-nav (mobile, .nav-tab 18×18 stroke-2). Inject into BOTH if present. + const CONTAINERS = [ { - id: "adwright", - label: "Adwright", - tooltip: "Adwright — marketing intelligence", - // Bullseye / target icon — marketing focus - svg: '', + selector: ".rail", + btnClass: "rail-btn nav-tab has-tooltip svrnty-nav-tab", + size: 20, + stroke: 1.5, + tooltipMod: "", }, { - id: "bte", - label: "BTE", - tooltip: "BTE — brand creative studio", - // Palette/sparkle icon — creative - svg: '', + selector: ".sidebar-nav", + btnClass: "nav-tab has-tooltip has-tooltip--bottom svrnty-nav-tab", + size: 18, + stroke: 2, + tooltipMod: "--bottom", }, ]; function _injectButtons() { - const nav = document.querySelector(".sidebar-nav"); - if (!nav) { - LOG("_injectButtons: .sidebar-nav not found yet"); + let anyContainerFound = false; + let totalAdded = 0; + CONTAINERS.forEach((c) => { + const container = document.querySelector(c.selector); + if (!container) return; + anyContainerFound = true; + TABS.forEach((t) => { + if (container.querySelector('[data-panel="' + t.id + '"]')) return; + try { + const btn = document.createElement("button"); + btn.className = c.btnClass; + btn.setAttribute("data-panel", t.id); + btn.setAttribute("data-label", t.label); + btn.setAttribute("data-tooltip", t.tooltip); + btn.setAttribute("aria-label", t.label); + btn.innerHTML = _svg(ICONS[t.id], c.size, c.stroke); + btn.addEventListener("click", () => { + LOG("clicked:", t.id); + if (typeof window.switchPanel === "function") { + window.switchPanel(t.id, { fromRailClick: true }); + } else { + ERR("switchPanel undefined — cannot route click"); + } + }); + container.appendChild(btn); + totalAdded++; + } catch (e) { + ERR("inject failed", c.selector, t.id, e); + } + }); + }); + if (!anyContainerFound) { + LOG("_injectButtons: neither .rail nor .sidebar-nav present yet"); return false; } - let added = 0; - TABS.forEach((t) => { - if (nav.querySelector('[data-panel="' + t.id + '"]')) return; - try { - const btn = document.createElement("button"); - btn.className = "nav-tab has-tooltip has-tooltip--bottom svrnty-nav-tab"; - btn.setAttribute("data-panel", t.id); - btn.setAttribute("data-label", t.label); - btn.setAttribute("data-tooltip", t.tooltip); - btn.setAttribute("aria-label", t.label); - btn.innerHTML = t.svg; - btn.addEventListener("click", () => { - LOG("button clicked:", t.id); - if (typeof window.switchPanel === "function") { - window.switchPanel(t.id, { fromRailClick: true }); - } else { - ERR("switchPanel is not a function — cannot route click"); - } - }); - nav.appendChild(btn); - added++; - } catch (e) { - ERR("failed to inject button", t.id, e); - } - }); - LOG("_injectButtons: added", added, "of", TABS.length, "(nav children:", nav.children.length, ")"); + LOG("_injectButtons: added", totalAdded, "buttons across containers"); return true; } @@ -119,12 +148,14 @@ _init(); } - // Re-inject buttons if something re-renders the sidebar (defensive). + // Re-inject buttons if something re-renders rail or sidebar-nav (defensive). const obs = new MutationObserver(() => { - const nav = document.querySelector(".sidebar-nav"); - if (!nav) return; - const missing = TABS.some((t) => !nav.querySelector('[data-panel="' + t.id + '"]')); - if (missing) _injectButtons(); + CONTAINERS.forEach((c) => { + const container = document.querySelector(c.selector); + if (!container) return; + const missing = TABS.some((t) => !container.querySelector('[data-panel="' + t.id + '"]')); + if (missing) _injectButtons(); + }); }); if (document.body) { obs.observe(document.body, { childList: true, subtree: true });