(function(){ /* ====== SETTINGS ====== */ const tz = "America/Los_Angeles"; const startHHMM = "17:30"; // league window start const endHHMM = "21:00"; // league window end const days = [1,2,3,4,5]; // Mon–Fri (0=Sun) const reserveHref = "/LANE-RESERVATIONS"; const bg = "#5b21b6"; // banner purple const cta = "#fbbf24"; // gold button const storageKey = "bmbAlertDismissedUntil"; const params = new URLSearchParams(location.search); const force = params.get("showAlert") === "1"; // force visible for testing const clear = params.get("clearBMB") === "1"; if (clear) localStorage.removeItem(storageKey); // Build and inject styles const css = ` .bmb-sticky-alert{position:sticky;top:0;z-index:9999;width:100%; font:600 16px/1.35 system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif; background:${bg};color:#fff;padding:12px 16px;border-bottom:3px solid rgba(255,255,255,.15)} .bmb-sticky-alert[hidden]{display:none !important} .bmb-sticky-alert .bmb-wrap{max-width:1100px;margin:0 auto;display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap} .bmb-sticky-alert .bmb-text{display:inline-flex;gap:10px;align-items:center} .bmb-sticky-alert .bmb-dot{display:inline-block;width:10px;height:10px;border-radius:50%;background:${cta}; box-shadow:0 0 0 6px rgba(251,191,36,.25);animation:bmbPulse 2s infinite} @keyframes bmbPulse{0%{box-shadow:0 0 0 6px rgba(251,191,36,.25)}50%{box-shadow:0 0 0 10px rgba(251,191,36,.05)}100%{box-shadow:0 0 0 6px rgba(251,191,36,.25)}} .bmb-sticky-alert a.bmb-cta,.bmb-sticky-alert a.bmb-cta:visited{ display:inline-block;padding:10px 14px;border-radius:999px;background:${cta};color:#111 !important; text-decoration:none;font-weight:800;white-space:nowrap;box-shadow:0 6px 20px rgba(0,0,0,.15);transition:transform .08s,box-shadow .2s} .bmb-sticky-alert a.bmb-cta:hover{transform:translateY(-1px);box-shadow:0 8px 22px rgba(0,0,0,.2)} .bmb-sticky-alert button.bmb-dismiss{appearance:none;border:0;background:transparent;color:#fff;opacity:.85; font-weight:700;cursor:pointer;padding:6px 8px;border-radius:6px} .bmb-sticky-alert button.bmb-dismiss:hover{background:rgba(255,255,255,.12);opacity:1} @media (max-width:520px){.bmb-sticky-alert a.bmb-cta{width:100%;text-align:center}} `; const style = document.createElement("style"); style.textContent = css; document.head.appendChild(style); // Build banner const bar = document.createElement("div"); bar.id = "bmbAlert"; bar.className = "bmb-sticky-alert"; bar.setAttribute("role","region"); bar.setAttribute("aria-label","Lane availability notice"); bar.hidden = true; // Copy (no lanes during league window) const textHTML = ` `; // Decide CTA behavior: if we're already on the reservations page, don't link (just show Dismiss) const onReservations = location.pathname.toUpperCase().indexOf("/LANE-RESERVATIONS") === 0; const actions = document.createElement("div"); actions.className = "bmb-actions"; actions.style.display = "flex"; actions.style.gap = "8px"; actions.style.alignItems = "center"; if (!onReservations) { const link = document.createElement("a"); link.className = "bmb-cta"; link.href = reserveHref; link.textContent = "Reserve a Lane"; actions.appendChild(link); } const dismissBtn = document.createElement("button"); dismissBtn.type = "button"; dismissBtn.className = "bmb-dismiss"; dismissBtn.setAttribute("aria-label","Hide this notice"); dismissBtn.textContent = "Dismiss"; actions.appendChild(dismissBtn); const wrap = document.createElement("div"); wrap.className = "bmb-wrap"; wrap.innerHTML = textHTML; wrap.appendChild(actions); bar.appendChild(wrap); // Insert at top of body function prependWhenReady(){ if (!document.body) return setTimeout(prependWhenReady, 30); document.body.prepend(bar); } prependWhenReady(); /* ===== Logic ===== */ function nowPT(){ const now = new Date(); return new Date(now.toLocaleString("en-US",{ timeZone: tz })); } function inWindow(){ if (force) return true; const loc = nowPT(); const dow = loc.getDay(); if (!days.includes(dow)) return false; const [sH,sM] = startHHMM.split(":").map(Number); const [eH,eM] = endHHMM.split(":").map(Number); const start = new Date(loc); start.setHours(sH,sM,0,0); const end = new Date(loc); end.setHours(eH,eM,0,0); return loc >= start && loc <= end; } function dismissed(){ if (force) return false; const until = Number(localStorage.getItem(storageKey) || 0); return Date.now() < until; } function setDismiss(){ const loc = nowPT(); const [eH,eM] = endHHMM.split(":").map(Number); const end = new Date(loc); end.setHours(eH,eM,0,0); let expire = end.getTime() + 60*60*1000; if (Date.now() > expire) expire = Date.now() + 24*60*60*1000; localStorage.setItem(storageKey, String(expire)); } function update(){ bar.hidden = !(inWindow() && !dismissed()); } dismissBtn.addEventListener("click", function(){ setDismiss(); bar.hidden = true; }); update(); setInterval(update, 60*1000); })();