diff --git a/public/announce.js b/public/announce.js
index 8d87c71..012038a 100644
--- a/public/announce.js
+++ b/public/announce.js
@@ -9,10 +9,10 @@
}
function start(EV) {
- if (!EV || !EV.enabled || !EV.id || !EV.img) return;
- if (EV.expiresUTC) { var exp = Date.parse(EV.expiresUTC); if (exp && Date.now() > exp) return; }
+ if (!EV || !EV.enabled || !EV.id || !EV.img) return false;
+ if (EV.expiresUTC) { var exp = Date.parse(EV.expiresUTC); if (exp && Date.now() > exp) return false; }
var KEY = 'rmc-announce-' + EV.id;
- try { if (localStorage.getItem(KEY) === 'done') return; } catch (e) {}
+ try { if (localStorage.getItem(KEY) === 'done') return false; } catch (e) {}
EV.timesArr = parseTimes(EV.times);
var back, card;
@@ -131,12 +131,62 @@
}
setTimeout(build, 1100);
+ return true;
+ }
+
+ /* Promo overlay: one flyer, one button, once per browser SESSION (sessionStorage), only on the
+ pages listed in promo.pages (path segment after the first slash: 'my', 'app', or 'all'). */
+ function startPromo(P) {
+ if (!P || !P.enabled || !P.id || !P.img) return;
+ if (P.expiresUTC) { var exp = Date.parse(P.expiresUTC); if (exp && Date.now() > exp) return; }
+ var seg = (location.pathname.split('/')[1] || 'home').toLowerCase();
+ var pages = String(P.pages || 'all').split(',').map(function (x) { return x.trim().toLowerCase(); }).filter(Boolean);
+ if (pages.indexOf('all') < 0 && pages.indexOf(seg) < 0) return;
+ var KEY = 'rmc-promo-' + P.id;
+ try { if (sessionStorage.getItem(KEY) === 'seen') return; } catch (e) {}
+ var back;
+ function mark() { try { sessionStorage.setItem(KEY, 'seen'); } catch (e) {} }
+ function close() { if (!back) return; mark(); back.style.opacity = '0'; setTimeout(function () { if (back && back.parentNode) back.parentNode.removeChild(back); back = null; }, 260); document.removeEventListener('keydown', onKey); }
+ function onKey(e) { if (e.key === 'Escape') close(); }
+ function build() {
+ back = document.createElement('div');
+ back.setAttribute('role', 'dialog'); back.setAttribute('aria-label', P.eyebrow || 'Upgrade');
+ back.style.cssText = 'position:fixed;inset:0;z-index:2147483000;display:flex;align-items:center;justify-content:center;padding:16px;background:rgba(3,7,14,.84);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);opacity:0;transition:opacity .28s ease;overflow:auto;';
+ back.addEventListener('click', function (e) { if (e.target === back) close(); });
+ var card = document.createElement('div');
+ card.style.cssText = 'position:relative;width:100%;max-width:420px;max-height:96vh;overflow:auto;border-radius:20px;background:#0a1119;border:1px solid rgba(212,175,55,.55);box-shadow:0 24px 70px rgba(0,0,0,.7);font-family:system-ui,Segoe UI,Arial,sans-serif;';
+ var x = document.createElement('button');
+ x.setAttribute('aria-label', 'Close'); x.innerHTML = '×';
+ x.style.cssText = 'position:absolute;top:10px;right:12px;z-index:2;width:38px;height:38px;border-radius:50%;border:none;cursor:pointer;background:rgba(6,10,16,.72);color:#fff;font-size:24px;line-height:1;font-weight:700;display:grid;place-items:center;box-shadow:0 2px 10px rgba(0,0,0,.5);';
+ x.addEventListener('click', close);
+ var img = document.createElement('img');
+ img.src = P.img; img.alt = P.eyebrow || 'Upgrade'; img.style.cssText = 'display:block;width:100%;height:auto;border-radius:20px 20px 0 0;';
+ var foot = document.createElement('div'); foot.style.cssText = 'padding:14px 18px 18px;';
+ var cta = document.createElement('a');
+ cta.href = P.ctaUrl || '/my'; cta.textContent = P.ctaText || 'See my next step \u2192';
+ cta.style.cssText = 'display:block;text-align:center;text-decoration:none;background:linear-gradient(180deg,#e9c249,#d4af37);color:#0a1119;font-size:18px;font-weight:800;padding:15px;border-radius:12px;box-shadow:0 8px 22px rgba(212,175,55,.35);';
+ cta.addEventListener('click', function (e) {
+ // already on the target page: close and scroll to the plan card instead of reloading
+ var here = (P.ctaUrl || '/my').split('#')[0].replace(/\/$/, '') === location.pathname.replace(/\/$/, '');
+ if (here) { e.preventDefault(); close(); var t = document.querySelector('.ns-card, #nextStep, #plan'); if (t) setTimeout(function () { t.scrollIntoView({ behavior: 'smooth', block: 'center' }); }, 300); }
+ else mark();
+ });
+ var later = document.createElement('button');
+ later.textContent = 'Not now'; later.style.cssText = 'display:block;margin:10px auto 0;background:none;border:none;color:#7d8ea0;font-size:13px;cursor:pointer;text-decoration:underline;';
+ later.addEventListener('click', close);
+ foot.appendChild(cta); foot.appendChild(later);
+ card.appendChild(x); card.appendChild(img); card.appendChild(foot);
+ back.appendChild(card); document.body.appendChild(back);
+ document.addEventListener('keydown', onKey);
+ requestAnimationFrame(function () { back.style.opacity = '1'; });
+ }
+ setTimeout(build, 900);
}
function fetchAndGo() {
fetch('/api/announce', { headers: { 'Accept': 'application/json' } })
.then(function (r) { return r.ok ? r.json() : null; })
- .then(function (EV) { if (EV) start(EV); })
+ .then(function (EV) { if (!EV) return; var shown = start(EV); if (!shown) startPromo(EV.promo); })
.catch(function () {});
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fetchAndGo);
diff --git a/public/app.html b/public/app.html
index 17fe6ea..61baf4f 100644
--- a/public/app.html
+++ b/public/app.html
@@ -28,5 +28,5 @@
Open the dashboard
-
+