/* Stumble CRO Bundle — Built 2026-04-11T06:40:23.215593 */ window.__STUMBLE_CRO_CONFIG={"global":{"frequency_cap_days":5,"mobile_enabled":true,"app_store_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794","ab_testing":{"enabled":true,"cookie_days":30,"min_sample_size":100}},"banners":[{"id":"exit-popup-homepage","type":"exit-intent","pages":["/"],"enabled":true,"delay_seconds":10,"frequency_cap_days":14,"privacy_text":"Free \u00b7 Anonymous \u00b7 iOS","variants":[{"variant_id":"A-company","weight":25,"headline":"You don't have to do this alone.","body":"Stumble is a free, anonymous app for the hardest days after a breakup, loss, or life change. Download it and the next hard moment has company.","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"B-first-place","weight":25,"headline":"The first place to go after a breakup.","body":"No sign-up. No judgment. Just tools and people who get it \u2014 whenever you need them.","cta_text":"Get The App","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"C-rating","weight":25,"headline":"4.86 stars from people exactly where you are.","body":"Stumble is free, anonymous, and built with mental health professionals. Take it with you.","cta_text":"Download Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"D-pocket","weight":25,"headline":"Keep Stumble in your pocket for 3 AM.","body":"The hardest moments don't happen on a schedule. Stumble is always there \u2014 free and anonymous.","cta_text":"Install Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"}]},{"id":"exit-popup-breakup-topics","type":"exit-intent","pages":["/breakup-recovery","/breakup-recovery-2","/heartbreak-peer-support","/anxiety-after-breakup","/toxic-relationship-recovery"],"enabled":true,"delay_seconds":8,"frequency_cap_days":10,"privacy_text":"Free \u00b7 Anonymous \u00b7 Built with mental health professionals","variants":[{"variant_id":"A-take-with-you","weight":50,"headline":"Take this support with you.","body":"Everything you just read is inside the Stumble app \u2014 plus a private journal, guided exercises, and anonymous peer support. Free to download.","cta_text":"Download Stumble Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"B-3am","weight":50,"headline":"Breakup spirals don't keep office hours.","body":"Stumble is awake at 3 AM with you. Free, anonymous, and built for exactly this.","cta_text":"Get Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"}]},{"id":"exit-popup-divorce","type":"exit-intent","pages":["/divorce-support","/divorce-mental-health-app","/life-transitions"],"enabled":true,"delay_seconds":8,"frequency_cap_days":10,"privacy_text":"Free \u00b7 Anonymous \u00b7 iOS","headline":"Divorce is a beginning, not just an ending.","body":"Stumble is a free, anonymous app for the long middle \u2014 with tools, check-ins, and people who've been through it.","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"id":"exit-popup-loneliness","type":"exit-intent","pages":["/loneliness-support","/loneliness-support-2","/ai-companion-loneliness","/ai-companion","/anonymous-community"],"enabled":true,"delay_seconds":8,"frequency_cap_days":10,"privacy_text":"Free \u00b7 Anonymous \u00b7 No sign-up required","headline":"Loneliness lies. Stumble reminds you you're not the only one.","body":"Free, anonymous peer support and guided exercises \u2014 in your pocket, whenever you need them.","cta_text":"Download Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"id":"exit-popup-alternatives","type":"exit-intent","pages":["/cerebral-alternative","/calm-alternative","/7-cups-alternative","/replika-alternative","/woebot-alternative","/talkspace-alternative","/wysa-alternative","/betterhelp","/headspace","/mend"],"enabled":true,"delay_seconds":6,"frequency_cap_days":10,"privacy_text":"Free \u00b7 Anonymous \u00b7 No waitlist","variants":[{"variant_id":"A-no-price-tag","weight":50,"headline":"Can't afford therapy right now? Stumble is free.","body":"Real peer support and guided tools \u2014 no waitlist, no $200/hour sessions, no credit card.","cta_text":"Download Stumble Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"B-built-for-this","weight":50,"headline":"Built specifically for heartbreak \u2014 not everything.","body":"General mental health apps are great, but Stumble was built from a breakup, for breakups. Free and anonymous.","cta_text":"Get The App","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"}]},{"id":"exit-popup-journaling","type":"exit-intent","pages":["/journaling","/anonymous-journaling-app","/mood-tracking"],"enabled":true,"delay_seconds":8,"frequency_cap_days":10,"privacy_text":"Free \u00b7 Anonymous \u00b7 No account required","headline":"Writing it out helps. Doing it anonymously helps more.","body":"Stumble's anonymous journal and mood tracking live in your pocket \u2014 no account, no pressure.","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"id":"sticky-bar-global","type":"sticky-bar","pages":["/*"],"exclude_pages":["/contactus","/support","/privacy","/terms"],"enabled":true,"delay_seconds":5,"frequency_cap_days":5,"variants":[{"variant_id":"A-first-place","weight":25,"headline":"The first place to go after a breakup \u2014 free, anonymous, always with you.","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794","bg_color":"#1a1a1a","cta_bg_color":"#fff","cta_text_color":"#1a1a1a","position":"bottom"},{"variant_id":"B-3am","weight":25,"headline":"Heartbreak doesn't keep office hours. Stumble is free and always there.","cta_text":"Get The App","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794","bg_color":"#4F46E5","cta_bg_color":"#fff","cta_text_color":"#4F46E5","position":"bottom"},{"variant_id":"C-community","weight":25,"headline":"You're not the only one. Stumble connects you anonymously.","cta_text":"Download Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794","bg_color":"#059669","cta_bg_color":"#fff","cta_text_color":"#059669","position":"bottom"},{"variant_id":"D-pocket","weight":25,"headline":"Keep peer support in your pocket. Free \u00b7 Anonymous \u00b7 iOS.","cta_text":"Install Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794","bg_color":"#0f172a","cta_bg_color":"#fcd34d","cta_text_color":"#0f172a","position":"bottom"}]},{"id":"inline-cta-blog","type":"inline-cta","pages":["/2024/*","/2025/*","/2026/*","/blog/*"],"enabled":true,"placement":"after-h2-2","variants":[{"variant_id":"A-take-this-with-you","weight":25,"headline":"Take this with you in your pocket","body":"Stumble is a free, anonymous iOS app that turns what you're reading into tools you can actually use \u2014 journaling, grounding exercises, and peer support.","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"B-not-alone","weight":25,"headline":"You're not the only one feeling this","body":"Stumble connects you anonymously with people going through the same thing. Free, no sign-up, always in your pocket.","cta_text":"Get Stumble Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"C-3am","weight":25,"headline":"For the 3 AM version of this moment","body":"Articles help during the day. Stumble helps at 3 AM \u2014 anonymous, free, and always awake.","cta_text":"Download The App","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"variant_id":"D-build-for-this","weight":25,"headline":"Stumble was built for exactly this","body":"Founded after a breakup in 2023, built with mental health professionals. Free, anonymous, iOS. Take the next hard day with company.","cta_text":"Install Stumble Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"}]},{"id":"inline-cta-topic-pages","type":"inline-cta","pages":["/breakup-recovery","/breakup-recovery-2","/heartbreak-peer-support","/anxiety-after-breakup","/toxic-relationship-recovery","/divorce-support","/divorce-mental-health-app","/life-transitions","/loneliness-support","/loneliness-support-2","/ai-companion","/ai-companion-loneliness","/anonymous-community","/anonymous-journaling-app","/journaling","/mood-tracking"],"enabled":true,"placement":"after-h2-2","headline":"Stumble turns all of this into something you can hold","body":"A free, anonymous iOS app for breakups, loneliness, and life transitions. No sign-up, no judgment, always there.","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"id":"inline-cta-alternatives","type":"inline-cta","pages":["/cerebral-alternative","/calm-alternative","/7-cups-alternative","/replika-alternative","/woebot-alternative","/talkspace-alternative","/wysa-alternative","/betterhelp","/headspace","/mend"],"enabled":true,"placement":"after-h2-2","headline":"Ready to try Stumble? It's free.","body":"No waitlists. No monthly subscription. No $200/hour sessions. Just an anonymous app built specifically for heartbreak, in your pocket when you need it.","cta_text":"Download Stumble Free","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794"},{"id":"scroll-popup-blog","type":"scroll-popup","pages":["/2024/*","/2025/*","/2026/*","/blog/*"],"enabled":true,"scroll_percent":55,"delay_seconds":2,"frequency_cap_days":7,"privacy_text":"Free \u00b7 Anonymous \u00b7 No sign-up required","cta_text":"Download Stumble","cta_url":"https://apps.apple.com/us/app/stumble-llc/id6758137794","headline_template":"Struggling with {feature}? Stumble is in your pocket.","body_template":"{angle}. Free, anonymous, and built for exactly this.","fallback_headline":"Healing is easier with company.","fallback_body":"Stumble is a free, anonymous app for heartbreak, loneliness, and life transitions. Take it with you for the next hard day.","variants":[{"variant_id":"A-contextual-empathetic","weight":50},{"variant_id":"B-contextual-direct","weight":50,"headline_template":"{feature}, in your pocket \u2014 free.","body_template":"{angle}. Download Stumble and take it with you.","cta_text":"Get Stumble Free"}]},{"id":"form-optimizer-contact","type":"form-optimizer","pages":["/contactus","/contact*","/support"],"form_config":{"social_proof_text":"Stumble is free and anonymous \u2014 no account needed to get started","cta_text":"Send Message","inline_validation":true,"privacy_text":"We reply from a real human at Stumble, usually within a day."},"enabled":true},{"id":"form-optimizer-global","type":"form-optimizer","pages":["/*"],"form_config":{"social_proof_text":"Join thousands healing with Stumble \u2014 free and anonymous","inline_validation":true},"enabled":true}]}; /* ── cro-loader.js ── */ /** * CRO Loader — Main entry point for Stumble CRO system * Loads banner config, runs A/B variant selection, and activates modules per page. * Deploy this single script to WordPress; it handles everything else. */ (function () { "use strict"; const CRO_VERSION = "2.0.0"; const COOKIE_PREFIX = "stumble_cro_"; const CONFIG_ATTR = "data-cro-config"; // ── Kill Switch ── function isKilled() { if (window.__STUMBLE_CRO_ENABLED === false) return true; var params = new URLSearchParams(window.location.search); var croParam = params.get("cro"); if (croParam === "off") { document.cookie = COOKIE_PREFIX + "disabled=1;path=/;SameSite=Lax"; return true; } if (croParam === "on") { document.cookie = COOKIE_PREFIX + "disabled=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/"; return false; } if (document.cookie.indexOf(COOKIE_PREFIX + "disabled=1") !== -1) return true; return false; } // ── Utility Functions ── function getCookie(name) { var match = document.cookie.match( new RegExp("(^| )" + COOKIE_PREFIX + name + "=([^;]+)") ); return match ? match[2] : null; } function setCookie(name, value, days) { var d = new Date(); d.setTime(d.getTime() + days * 86400000); document.cookie = COOKIE_PREFIX + name + "=" + value + ";expires=" + d.toUTCString() + ";path=/;SameSite=Lax"; } function matchesPage(patterns) { var path = window.location.pathname; return patterns.some(function (pattern) { if (pattern.endsWith("*")) { return path.startsWith(pattern.slice(0, -1)); } return path === pattern || path === pattern + "/"; }); } function isMobile() { return window.innerWidth < 768; } function trackEvent(action, label, variantId) { var params = { event_category: "CRO", event_label: label, }; if (variantId) params.cro_variant = variantId; if (window.gtag) { window.gtag("event", action, params); } if (window.dataLayer) { window.dataLayer.push({ event: "cro_event", cro_action: action, cro_label: label, cro_variant: variantId || null, }); } } // ── A/B Testing Infrastructure ── function hashString(str) { // djb2 hash — deterministic, fast, good distribution var hash = 5381; for (var i = 0; i < str.length; i++) { hash = ((hash << 5) + hash) + str.charCodeAt(i); hash = hash & hash; // Convert to 32-bit integer } return Math.abs(hash); } function getVisitorId() { var vid = getCookie("vid"); if (vid) return vid; vid = Date.now().toString(36) + Math.random().toString(36).substr(2, 9); setCookie("vid", vid, 365); return vid; } function selectVariant(banner, visitorId) { var variants = banner.variants; if (!variants || variants.length === 0) return null; if (variants.length === 1) return variants[0]; // Calculate total weight var totalWeight = 0; for (var i = 0; i < variants.length; i++) { totalWeight += (variants[i].weight || 1); } // Deterministic bucket based on visitor + banner ID var bucket = hashString(visitorId + "|" + banner.id) % totalWeight; // Walk cumulative weights to find the selected variant var cumulative = 0; for (var j = 0; j < variants.length; j++) { cumulative += (variants[j].weight || 1); if (bucket < cumulative) return variants[j]; } return variants[variants.length - 1]; } function resolveVariant(banner, variant) { if (!variant) return banner; // Copy all banner fields except variants array var resolved = {}; for (var key in banner) { if (key !== "variants") resolved[key] = banner[key]; } // Overlay variant fields (non-null/undefined values only) var variantFields = [ "headline", "body", "cta_text", "cta_url", "image_url", "bg_color", "cta_bg_color", "cta_text_color", "position", "success_headline", "success_body", "privacy_text", "headline_template", "body_template", "fallback_headline", "fallback_body", "form_config" ]; for (var i = 0; i < variantFields.length; i++) { var f = variantFields[i]; if (variant[f] !== undefined && variant[f] !== null) { // Deep merge for form_config if (f === "form_config" && resolved.form_config && typeof variant[f] === "object") { var merged = {}; for (var k in resolved.form_config) merged[k] = resolved.form_config[k]; for (var k2 in variant[f]) merged[k2] = variant[f][k2]; resolved.form_config = merged; } else { resolved[f] = variant[f]; } } } resolved._variant_id = variant.variant_id || null; return resolved; } // ── CSS Injection ── function injectStyles() { if (document.getElementById("stumble-cro-styles")) return; var style = document.createElement("style"); style.id = "stumble-cro-styles"; style.textContent = [ // Overlay ".zcro-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.55);z-index:99998;opacity:0;transition:opacity .3s ease}", ".zcro-overlay.active{opacity:1}", // Popup ".zcro-popup{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) scale(.9);background:#fff;border-radius:12px;padding:40px;max-width:480px;width:90%;z-index:99999;opacity:0;transition:all .3s ease;box-shadow:0 20px 60px rgba(0,0,0,.3)}", ".zcro-popup.active{opacity:1;transform:translate(-50%,-50%) scale(1)}", ".zcro-popup-close{position:absolute;top:12px;right:16px;background:none;border:none;font-size:24px;cursor:pointer;color:#666;line-height:1}", ".zcro-popup h2{margin:0 0 12px;font-size:24px;color:#1a1a1a;line-height:1.3}", ".zcro-popup p{margin:0 0 20px;color:#555;font-size:16px;line-height:1.5}", ".zcro-popup form{display:flex;flex-direction:column;gap:12px}", ".zcro-popup input{padding:12px 16px;border:1px solid #ddd;border-radius:8px;font-size:15px;outline:none;transition:border-color .2s}", ".zcro-popup input:focus{border-color:#4F46E5}", ".zcro-popup button[type=submit]{padding:14px;background:#4F46E5;color:#fff;border:none;border-radius:8px;font-size:16px;font-weight:600;cursor:pointer;transition:background .2s}", ".zcro-popup button[type=submit]:hover{background:#4338CA}", ".zcro-popup .zcro-privacy{font-size:12px;color:#999;text-align:center;margin-top:8px}", ".zcro-popup img.zcro-hero{width:100%;max-height:200px;object-fit:cover;border-radius:8px;margin-bottom:16px}", // Sticky Bar ".zcro-sticky{position:fixed;left:0;width:100%;z-index:99997;padding:12px 20px;display:flex;align-items:center;justify-content:center;gap:16px;font-size:15px;transition:transform .3s ease}", ".zcro-sticky-top{top:0;transform:translateY(-100%)}", ".zcro-sticky-bottom{bottom:0;transform:translateY(100%)}", ".zcro-sticky.active.zcro-sticky-top{transform:translateY(0)}", ".zcro-sticky.active.zcro-sticky-bottom{transform:translateY(0)}", ".zcro-sticky-text{color:#fff;font-weight:500}", ".zcro-sticky-cta{padding:8px 20px;border-radius:6px;text-decoration:none;font-weight:600;font-size:14px;white-space:nowrap;transition:opacity .2s}", ".zcro-sticky-cta:hover{opacity:.9}", ".zcro-sticky-close{background:none;border:none;color:rgba(255,255,255,.7);font-size:20px;cursor:pointer;padding:0 4px;line-height:1}", ".zcro-sticky-close:hover{color:#fff}", // Inline CTA ".zcro-inline{margin:32px 0;padding:28px 32px;border-radius:12px;border:2px solid #E0E7FF;background:linear-gradient(135deg,#EEF2FF,#F5F3FF);text-align:center}", ".zcro-inline h3{margin:0 0 8px;font-size:20px;color:#1a1a1a}", ".zcro-inline p{margin:0 0 16px;color:#555;font-size:15px}", ".zcro-inline a{display:inline-block;padding:12px 28px;background:#4F46E5;color:#fff;border-radius:8px;text-decoration:none;font-weight:600;font-size:15px;transition:background .2s}", ".zcro-inline a:hover{background:#4338CA}", ".zcro-inline img.zcro-hero{max-width:100%;border-radius:8px;margin-bottom:12px}", // Mobile adjustments "@media(max-width:767px){", ".zcro-popup{padding:28px 20px;max-width:95%}", ".zcro-popup h2{font-size:20px}", ".zcro-sticky{flex-wrap:wrap;gap:8px;padding:10px 16px;font-size:13px}", ".zcro-inline{padding:20px 16px}", "}", ].join("\n"); document.head.appendChild(style); } // ── Module Registry ── var modules = {}; function registerModule(name, initFn) { modules[name] = initFn; } // ── Config Loading ── function loadConfig() { var scriptTag = document.querySelector("script[" + CONFIG_ATTR + "]"); if (scriptTag) { try { return JSON.parse(scriptTag.getAttribute(CONFIG_ATTR)); } catch (e) { console.warn("[CRO] Invalid inline config:", e); } } if (window.__STUMBLE_CRO_CONFIG) { return window.__STUMBLE_CRO_CONFIG; } return null; } // ── Init ── function init() { if (isKilled()) { console.log("[CRO] Disabled via admin toggle or ?cro=off"); return; } var config = loadConfig(); if (!config) { console.warn("[CRO] No config found."); return; } injectStyles(); var globalConfig = config.global || {}; var banners = config.banners || []; var visitorId = getVisitorId(); banners.forEach(function (banner) { if (!banner.enabled) return; if (!matchesPage(banner.pages || ["*"])) return; if (globalConfig.mobile_enabled === false && isMobile()) return; // Check frequency cap var capKey = "dismissed_" + banner.id; var dismissed = getCookie(capKey); if (dismissed) return; var capDays = banner.frequency_cap_days || globalConfig.frequency_cap_days || 3; // ── A/B Variant Selection ── var selectedVariant = selectVariant(banner, visitorId); var resolvedBanner = resolveVariant(banner, selectedVariant); var moduleName = resolvedBanner.type; if (modules[moduleName]) { modules[moduleName](resolvedBanner, capDays); } else { console.warn("[CRO] Unknown module:", moduleName); } }); console.log("[CRO] Initialized v" + CRO_VERSION + " | visitor: " + visitorId.substr(0, 8)); } // Expose for modules window.__STUMBLE_CRO = { registerModule: registerModule, getCookie: getCookie, setCookie: setCookie, trackEvent: trackEvent, isMobile: isMobile, getVisitorId: getVisitorId, init: init, }; // Auto-init on DOM ready — defer via setTimeout(0) so all module IIFEs // in the concatenated bundle have a chance to register themselves before // init() iterates the banner list. function scheduleInit() { setTimeout(init, 0); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", scheduleInit); } else { scheduleInit(); } })(); /* ── exit-intent.js ── */ /** * Exit-Intent Popup Module * Detects when a visitor is about to leave and shows a lead capture popup. * Desktop: mouse leaves viewport. Mobile: scroll up + pause pattern. */ (function () { "use strict"; var CRO = window.__STUMBLE_CRO; if (!CRO) return; CRO.registerModule("exit-intent", function (banner, capDays) { var triggered = false; var overlay = null; var popup = null; function createPopup() { // Overlay overlay = document.createElement("div"); overlay.className = "zcro-overlay"; overlay.addEventListener("click", dismiss); // Popup container popup = document.createElement("div"); popup.className = "zcro-popup"; popup.setAttribute("role", "dialog"); popup.setAttribute("aria-label", banner.headline || "Special offer"); // Close button var closeBtn = document.createElement("button"); closeBtn.className = "zcro-popup-close"; closeBtn.innerHTML = "×"; closeBtn.setAttribute("aria-label", "Close"); closeBtn.addEventListener("click", dismiss); // Headline var h2 = document.createElement("h2"); h2.textContent = banner.headline || "Wait! Before you go..."; // Body text var p = document.createElement("p"); p.textContent = banner.body || ""; popup.appendChild(closeBtn); // Hero image (optional) if (banner.image_url) { var img = document.createElement("img"); img.className = "zcro-hero"; img.src = banner.image_url; img.alt = banner.headline || "Offer"; popup.appendChild(img); } popup.appendChild(h2); if (banner.body) popup.appendChild(p); // Form or CTA link if (banner.form_fields && banner.form_fields.length > 0) { var form = createForm(banner); popup.appendChild(form); } else if (banner.cta_url) { var ctaLink = document.createElement("a"); ctaLink.href = banner.cta_url; ctaLink.textContent = banner.cta_text || "Learn More"; ctaLink.style.cssText = "display:block;padding:14px;background:#4F46E5;color:#fff;border:none;border-radius:8px;font-size:16px;font-weight:600;text-align:center;text-decoration:none;cursor:pointer;transition:background .2s"; if (/apps\.apple\.com|play\.google\.com/.test(ctaLink.href)) { ctaLink.target = "_blank"; ctaLink.rel = "noopener"; } ctaLink.addEventListener("click", function () { CRO.trackEvent("cro_popup_cta_click", banner.id, banner._variant_id); CRO.trackEvent("cro_app_install_click", banner.id, banner._variant_id); CRO.setCookie("dismissed_" + banner.id, "installed", capDays * 10); }); popup.appendChild(ctaLink); } // Privacy note var privacy = document.createElement("div"); privacy.className = "zcro-privacy"; privacy.textContent = banner.privacy_text || "We respect your privacy. Unsubscribe anytime."; popup.appendChild(privacy); document.body.appendChild(overlay); document.body.appendChild(popup); // Animate in requestAnimationFrame(function () { overlay.classList.add("active"); popup.classList.add("active"); }); CRO.trackEvent("cro_popup_shown", banner.id, banner._variant_id); } function createForm(banner) { var form = document.createElement("form"); form.addEventListener("submit", function (e) { e.preventDefault(); handleSubmit(form, banner); }); var fieldMap = { email: { type: "email", placeholder: "you@company.com", required: true }, name: { type: "text", placeholder: "Your name", required: false }, company: { type: "text", placeholder: "Company name", required: false }, phone: { type: "tel", placeholder: "Phone number", required: false }, }; banner.form_fields.forEach(function (fieldName) { var config = fieldMap[fieldName] || { type: "text", placeholder: fieldName, required: false, }; var input = document.createElement("input"); input.type = config.type; input.name = fieldName; input.placeholder = config.placeholder; if (config.required) input.required = true; form.appendChild(input); }); var submitBtn = document.createElement("button"); submitBtn.type = "submit"; submitBtn.textContent = banner.cta_text || "Get Access"; form.appendChild(submitBtn); return form; } function handleSubmit(form, banner) { var data = {}; var inputs = form.querySelectorAll("input"); inputs.forEach(function (inp) { data[inp.name] = inp.value; }); CRO.trackEvent("cro_popup_submit", banner.id, banner._variant_id); // Send to configured endpoint or fallback var endpoint = banner.submit_url || "/wp-json/cro/v1/lead"; fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ banner_id: banner.id, variant_id: banner._variant_id || null, page: window.location.pathname, fields: data, timestamp: new Date().toISOString(), }), }) .then(function () { showSuccess(banner); }) .catch(function () { // Still show success to user; log error showSuccess(banner); console.error("[CRO] Lead submission failed for", banner.id); }); } function showSuccess(banner) { if (!popup) return; popup.innerHTML = '
" + (banner.success_body || "Check your inbox for your free resource.") + "
" + banner.body + "
" : "") + '' + (banner.cta_text || "Get Started Free") + "