/* ============================================================ Shunya Announce v1.0 Rule-filtered messaging: announcement bar + geo-targeted popup - No async/await (wp_kses-safe), no inline handlers - All styles injected by JS — nothing for WordPress to strip - Edit CONFIG below, host this file as .txt in WP Media Library ============================================================ */ (function () { 'use strict'; var CONFIG = { // Your Apps Script /exec URL: apiUrl: 'https://script.google.com/macros/s/AKfycbwZAHis73uNYONS6YqWFQY_2WM4T0CK3oA8huVoVqTAJFxytnl9tNSn8Zun64q2mWiNng/exec', homeCountry: 'IN', // visitors NOT from here = "international" popupDelayMs: 4000, // wait before showing popup barRotateMs: 6000, // rotation interval if multiple bar messages announcementsCacheMin: 10, // client cache for sheet data brand: { green: '#1B4332', // deep forest greenLight: '#2D6A4F', accent: '#95D5B2', text: '#FFFFFF', font: "'Montserrat', sans-serif" } }; /* ---------- tiny utils ---------- */ function ss(key, val) { // sessionStorage get/set with JSON try { if (arguments.length === 2) { sessionStorage.setItem(key, JSON.stringify(val)); return val; } var raw = sessionStorage.getItem(key); return raw ? JSON.parse(raw) : null; } catch (e) { return null; } } function dismissedIds() { return ss('shunya_dismissed') || []; } function dismiss(id) { var d = dismissedIds(); if (d.indexOf(id) === -1) d.push(id); ss('shunya_dismissed', d); } /* ---------- geo detection (cached per session) ---------- */ function getCountry() { if (window.SHUNYA_TEST && window.SHUNYA_TEST.country) { return Promise.resolve(window.SHUNYA_TEST.country); } var cached = ss('shunya_cc'); if (cached) return Promise.resolve(cached); return fetch('https://ipapi.co/json/') .then(function (r) { if (!r.ok) throw new Error('ipapi failed'); return r.json(); }) .then(function (d) { return d.country_code; }) .catch(function () { return fetch('https://ipwho.is/') .then(function (r) { return r.json(); }) .then(function (d) { return d.country_code; }); }) .then(function (cc) { cc = (cc || CONFIG.homeCountry).toUpperCase(); ss('shunya_cc', cc); return cc; }) .catch(function () { return CONFIG.homeCountry; }); // fail safe: treat as home } /* ---------- announcements fetch (cached) ---------- */ function getAnnouncements() { if (window.SHUNYA_TEST && window.SHUNYA_TEST.items) { return Promise.resolve(window.SHUNYA_TEST.items); } var cached = ss('shunya_ann'); if (cached && (Date.now() - cached.t) < CONFIG.announcementsCacheMin * 60000) { return Promise.resolve(cached.items); } return fetch(CONFIG.apiUrl) .then(function (r) { return r.json(); }) .then(function (d) { var items = (d && d.items) || []; ss('shunya_ann', { t: Date.now(), items: items }); return items; }) .catch(function () { return (cached && cached.items) || []; }); } /* ---------- filter engine ---------- */ function isLive(item, now) { if (item.start && now < new Date(item.start)) return false; if (item.end && now > new Date(item.end)) return false; return true; } function audienceMatch(item, countryCode) { if (item.audience === 'all' || !item.audience) return true; var isHome = countryCode === CONFIG.homeCountry; if (item.audience === 'india') return isHome; if (item.audience === 'international') return !isHome; return false; } function selectMessages(items, countryCode) { var now = new Date(); var d = dismissedIds(); var eligible = items.filter(function (it) { return isLive(it, now) && audienceMatch(it, countryCode) && d.indexOf(it.id) === -1; }).sort(function (a, b) { return a.priority - b.priority; }); return { bars: eligible.filter(function (it) { return it.type === 'bar'; }), popup: eligible.filter(function (it) { return it.type === 'popup'; })[0] || null }; } /* ---------- styles ---------- */ function injectStyles() { var b = CONFIG.brand; var css = '' + '#shunya-bar{position:relative;z-index:99998;background:' + b.green + ';color:' + b.text + ';font-family:' + b.font + ';font-size:14px;line-height:1.4;}' + '#shunya-bar .sb-inner{max-width:1200px;margin:0 auto;padding:10px 44px 10px 16px;display:flex;align-items:center;justify-content:center;gap:12px;flex-wrap:wrap;text-align:center;}' + '#shunya-bar .sb-dot{width:8px;height:8px;border-radius:50%;background:' + b.accent + ';flex:none;animation:sbPulse 1.6s ease-in-out infinite;}' + '@keyframes sbPulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.5;transform:scale(.7)}}' + '@media (prefers-reduced-motion: reduce){#shunya-bar .sb-dot{animation:none}}' + '#shunya-bar .sb-msg{transition:opacity .35s ease;}' + '#shunya-bar .sb-cta{color:' + b.green + ';background:' + b.accent + ';text-decoration:none;font-weight:600;padding:4px 14px;border-radius:999px;white-space:nowrap;flex:none;}' + '#shunya-bar .sb-cta:hover{background:#b7e4c7;color:' + b.green + ';}' + '#shunya-bar .sb-close{position:absolute;right:10px;top:50%;transform:translateY(-50%);background:none;border:none;color:' + b.text + ';opacity:.7;font-size:18px;cursor:pointer;padding:6px;line-height:1;}' + '#shunya-bar .sb-close:hover,#shunya-bar .sb-close:focus{opacity:1;outline:2px solid ' + b.accent + ';border-radius:4px;}' + '#shunya-popup{position:fixed;right:20px;bottom:20px;z-index:99999;max-width:340px;width:calc(100vw - 40px);background:#fff;border-radius:14px;border-left:5px solid ' + b.greenLight + ';box-shadow:0 12px 36px rgba(27,67,50,.25);font-family:' + b.font + ';padding:20px 20px 18px;transform:translateY(24px);opacity:0;transition:transform .4s ease,opacity .4s ease;}' + '#shunya-popup.sp-show{transform:translateY(0);opacity:1;}' + '@media (prefers-reduced-motion: reduce){#shunya-popup{transition:none;transform:none}}' + '#shunya-popup .sp-eyebrow{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:' + b.greenLight + ';font-weight:700;margin:0 0 8px;}' + '#shunya-popup .sp-msg{font-size:15px;color:#1c2b24;line-height:1.55;margin:0 0 14px;}' + '#shunya-popup .sp-cta{display:inline-block;background:' + b.green + ';color:#fff;text-decoration:none;font-weight:600;font-size:14px;padding:10px 20px;border-radius:8px;}' + '#shunya-popup .sp-cta:hover{background:' + b.greenLight + ';color:#fff;}' + '#shunya-popup .sp-close{position:absolute;right:10px;top:8px;background:none;border:none;color:#7a8a82;font-size:18px;cursor:pointer;padding:6px;line-height:1;}' + '#shunya-popup .sp-close:hover,#shunya-popup .sp-close:focus{color:' + b.green + ';outline:2px solid ' + b.accent + ';border-radius:4px;}'; var style = document.createElement('style'); style.textContent = css; document.head.appendChild(style); } /* ---------- announcement bar ---------- */ function renderBar(bars) { if (!bars.length) return; var bar = document.createElement('div'); bar.id = 'shunya-bar'; bar.setAttribute('role', 'region'); bar.setAttribute('aria-label', 'Announcement'); var inner = document.createElement('div'); inner.className = 'sb-inner'; var dot = document.createElement('span'); dot.className = 'sb-dot'; var msg = document.createElement('span'); msg.className = 'sb-msg'; var cta = document.createElement('a'); cta.className = 'sb-cta'; var close = document.createElement('button'); close.className = 'sb-close'; close.setAttribute('aria-label', 'Dismiss announcement'); close.textContent = '\u2715'; inner.appendChild(dot); inner.appendChild(msg); inner.appendChild(cta); bar.appendChild(inner); bar.appendChild(close); var i = 0; function show(idx) { var item = bars[idx]; msg.textContent = item.message; if (item.ctaLabel && item.ctaLink) { cta.textContent = item.ctaLabel; cta.href = item.ctaLink; cta.style.display = ''; } else { cta.style.display = 'none'; } bar.dataset.currentId = item.id; } show(0); if (bars.length > 1) { setInterval(function () { msg.style.opacity = '0'; setTimeout(function () { i = (i + 1) % bars.length; show(i); msg.style.opacity = '1'; }, 350); }, CONFIG.barRotateMs); } close.addEventListener('click', function () { // dismissing hides the whole bar for this session bars.forEach(function (b) { dismiss(b.id); }); bar.parentNode.removeChild(bar); }); document.body.insertBefore(bar, document.body.firstChild); } /* ---------- popup ---------- */ function renderPopup(item) { if (!item) return; setTimeout(function () { var card = document.createElement('div'); card.id = 'shunya-popup'; card.setAttribute('role', 'dialog'); card.setAttribute('aria-label', 'Message from Shunya'); var eyebrow = document.createElement('p'); eyebrow.className = 'sp-eyebrow'; eyebrow.textContent = 'Shunya Agritech'; var msg = document.createElement('p'); msg.className = 'sp-msg'; msg.textContent = item.message; card.appendChild(eyebrow); card.appendChild(msg); if (item.ctaLabel && item.ctaLink) { var cta = document.createElement('a'); cta.className = 'sp-cta'; cta.textContent = item.ctaLabel; cta.href = item.ctaLink; card.appendChild(cta); } var close = document.createElement('button'); close.className = 'sp-close'; close.setAttribute('aria-label', 'Close message'); close.textContent = '\u2715'; close.addEventListener('click', function () { dismiss(item.id); card.parentNode.removeChild(card); }); card.appendChild(close); document.body.appendChild(card); requestAnimationFrame(function () { requestAnimationFrame(function () { card.classList.add('sp-show'); }); }); }, (window.SHUNYA_TEST && window.SHUNYA_TEST.popupDelayMs) || CONFIG.popupDelayMs); } /* ---------- boot ---------- */ function init() { injectStyles(); Promise.all([getAnnouncements(), getCountry()]) .then(function (res) { var selected = selectMessages(res[0], res[1]); renderBar(selected.bars); renderPopup(selected.popup); }) .catch(function () { /* fail silently — never break the site */ }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();