PopupFrame
Variables: id, class, hidden, dialog, modal, labelledBy, describedBy, ariaLabel, overlay
Slots: default
Design reference
src/components/popups/. The examples below are rendered through those
components, so the reference page shows the same API that can be used across the Lead
Caravan site.
PopupFrame + PopupDialog variant=fullscreen PopupFrame + PopupDialog formAction PopupPanel PopupToastStack + PopupToast PopupDialog class=popup-consent PopupBanner placement=top PopupBanner placement=bottom Component API
Variables: id, class, hidden, dialog, modal, labelledBy, describedBy, ariaLabel, overlay
Slots: default
Variables: id, variant, as, class, title, titleClass, kicker, description, closeLabel, dismissible, hidden, formAction, formMethod, inert
Slots: default, fields, actions, consent, support
Variables: id, class, title, kicker, description, closeLabel, hidden, inert
Slots: default, actions
Variables: id, class, hidden, live, atomic, role, title, message, tone, closeLabel, ariaLabel, alert, inert
Slots: toast default content
Variables: id, class, placement, hidden, closeLabel, role, ariaLabel, inert
Slots: default, actions
Live demo
Try it. Tab moves through the email box, the website box, the close button, and the two buttons below, and never leaves the box. Esc and a click outside close it too.
A full-screen offer with one clear path. Ask for a free look, or keep reading. It sells the work, not a vague mailing list.
Show it only after real interest, like a 60% scroll or a second visit. Never the moment the page loads. Once per person, per push.
Static specimen — controls inert; see the live demo above.
We look at your page, your follow-up, your calendar, and your CRM hand-off. Those turn interest into booked calls. You leave with the first fixes, in order of what helps most.
A small box that asks for details. The words make clear that we look at lead paths and booking.
Only when they go to leave, or after a slow scroll. Esc, a click outside, and the close button all shut it and remember that — see the live demo above for that trap, Esc, and backdrop behavior working for real; this static specimen's controls are inert.
The close button does nothing here. The send button is real and needs no JavaScript. See the live demo above for how it really behaves.
A panel on the right with nothing dimmed behind it. It points at the next step and lets you keep using the page.
Slide it in after something useful happens, like finishing a quiz, getting a number, or reading half a guide. Then leave it shut for that visit.
Static specimen — controls inert; see the live demo above.
Short notes that say what just happened. They should never carry the main pitch or ask you to fill in a form.
Announce good news gently and only shout for errors. Fade them out after enough time to read, and always keep a close button.
Static specimen — controls inert; see the live demo above.
We have your website and will reply with next steps.
Answer a few questions to lock in your time.
Send it in and we will come back with times.
A bottom banner that matches the real cookie note. The parts the site needs keep working. Ad tags wait until you say yes.
It blocks nothing. Both choices are saved on your device through window.__setConsent.
Static specimen — controls inert; see the live demo above.
A one-line banner at the top. It shows right away without hiding the header or pushing the page around.
It does not move. Once you close it, it stays closed across pages while that push is running.
Static specimen — controls inert; see the live demo above.
A reminder at the bottom edge with one next step. It only helps when that same button is not already on screen.
Show it once the top button scrolls away, and hide it near the footer so it never fights the rest of the page.
Static specimen — controls inert; see the live demo above.
Already shipped
ChatWidget.astro is env-gated by LEADCARAVAN_CHAT_WIDGET_ENABLED
and opens a bottom-right dialog panel when enabled. The wired cookie consent banner above
the fold is the real version of the cookie specimen further up this page: ConsentBanner.astro
renders through the same PopupDialog component and appears only when
BaseLayout detects a configured ad-pixel ID, staying hidden once a choice is
stored via window.__setConsent. The side panel and toast patterns above reserve
the same corner spacing so chat can coexist with the rest of the system instead of stacking over it.