Create an exit-intent offer modal with Tailwind CSS. Markup: a fixed inset-0 overlay with a black/40 backdrop, hidden by default, centring a max-w-md white card with rounded-3xl corners and a shadow. The card holds a small close ✕ in the corner, a rounded discount badge, a headline offering 20% off the first three months, a short supporting line, an email field with a full-width dark claim button, a row of two reassurance items with check glyphs, and a muted "No thanks, I'll pay full price" text button underneath. Then add JavaScript that shows it at most once per session: arm the trigger after a few seconds on the page, open when the pointer leaves through the top of the window or when the visitor scrolls past 60% of the document, remember the shown state in sessionStorage so a reload does not nag, close on the ✕, the decline link, a backdrop click, or Escape, and move focus into the email field when it opens.
Paste it into Claude, Cursor, v0 or any AI coding tool. Prefer the
finished markup? .
Create an exit-intent offer modal with Tailwind CSS. Markup: a fixed inset-0 overlay with a black/40 backdrop, hidden by default, centring a max-w-md white card with rounded-3xl corners and a shadow. The card holds a small close ✕ in the corner, a rounded discount badge, a headline offering 20% off the first three months, a short supporting line, an email field with a full-width dark claim button, a row of two reassurance items with check glyphs, and a muted "No thanks, I'll pay full price" text button underneath. Then add JavaScript that shows it at most once per session: arm the trigger after a few seconds on the page, open when the pointer leaves through the top of the window or when the visitor scrolls past 60% of the document, remember the shown state in sessionStorage so a reload does not nag, close on the ✕, the decline link, a backdrop click, or Escape, and move focus into the email field when it opens.
var STORAGE_KEY = "exit-offer-seen";
var ARM_DELAY = 4000;
var SCROLL_TRIGGER = 0.6;
var offer = document.getElementById("offer");
var card = document.getElementById("offerCard");
var email = document.getElementById("offerEmail");
var armed = false;
function alreadySeen() {
try { return sessionStorage.getItem(STORAGE_KEY) === "1"; } catch (e) { return false; }
}
function open() {
if (!armed || alreadySeen()) return;
armed = false;
try { sessionStorage.setItem(STORAGE_KEY, "1"); } catch (e) {}
offer.classList.remove("hidden");
offer.classList.add("flex");
email.focus();
}
function close() {
offer.classList.add("hidden");
offer.classList.remove("flex");
}
// Give people a moment to actually read the page before offering anything.
if (!alreadySeen()) setTimeout(function () { armed = true; }, ARM_DELAY);
document.addEventListener("mouseout", function (e) {
// Leaving through the top edge, not just crossing into an iframe or child node.
if (!e.relatedTarget && e.clientY <= 0) open();
});
window.addEventListener("scroll", function () {
var depth = (window.scrollY + window.innerHeight) / document.body.scrollHeight;
if (depth > SCROLL_TRIGGER) open();
});
document.getElementById("offerClose").addEventListener("click", close);
document.getElementById("offerDecline").addEventListener("click", close);
offer.addEventListener("click", function (e) { if (!card.contains(e.target)) close(); });
document.addEventListener("keydown", function (e) { if (e.key === "Escape") close(); });