Call-to-action that remains visible while scrolling.
Scroll this frame — the call to action stays pinned.
Page content keeps flowing underneath it.
More content here to make the frame scrollable.
<div class="sticky-demo">
<div class="sticky-demo__scroll">
<p>Scroll this frame — the call to action stays pinned.</p>
<p>Page content keeps flowing underneath it.</p>
<p>More content here to make the frame scrollable.</p>
</div>
<div class="sticky-bar sticky-bar--bottom-bar" style="background:#241430;">
<span>Start your free trial</span>
<button type="button" class="sticky-bar__close" aria-label="Dismiss">×</button>
</div>
</div>
<style>
.sticky-demo { position: relative; height: 200px; overflow: auto; border: 1px solid #24143022; border-radius: 12px; font: 14px system-ui, sans-serif; color: #241430; }
.sticky-demo__scroll { padding: 16px; }
.sticky-demo__scroll p { margin: 0 0 60px; color: #241430aa; }
.sticky-bar { position: sticky; bottom: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; color: #FAF7F2; font-weight: 700; }
.sticky-bar--bottom-bar { width: 100%; padding: 14px 18px; }
.sticky-bar--bottom-right { margin: 0 12px 12px auto; width: fit-content; padding: 12px 18px; border-radius: 999px; }
.sticky-bar__close { background: none; border: none; color: inherit; font-size: 16px; cursor: pointer; }
.sticky-bar__close:hover, .sticky-bar__close:focus-visible { opacity: .7; }
</style><div class="relative h-[200px] overflow-auto border border-[#24143022] rounded-xl font-sans text-sm text-[#241430]">
<div class="p-4">
<p class="m-0 mb-15 text-[#241430]/65">Scroll this frame — the call to action stays pinned.</p>
<p class="m-0 mb-15 text-[#241430]/65">Page content keeps flowing underneath it.</p>
<p class="m-0 mb-15 text-[#241430]/65">More content here to make the frame scrollable.</p>
</div>
<div class="sticky-tw sticky-tw--bottom-bar sticky bottom-0 flex items-center justify-between gap-3 text-[#FAF7F2] font-bold" style="background:#241430;">
<span>Start your free trial</span>
<button type="button" class="bg-transparent border-0 text-inherit text-base cursor-pointer hover:opacity-70" aria-label="Dismiss">×</button>
</div>
</div>
<style>
.sticky-tw--bottom-bar { width: 100%; padding: 14px 18px; }
.sticky-tw--bottom-right { margin: 0 12px 12px auto; width: fit-content; padding: 12px 18px; border-radius: 999px; }
</style>export function StickyCta({
ctaText = "Start your free trial",
position = "bottom-bar",
accent = "#241430",
showDismiss = true,
}) {
const corner = position === "bottom-right";
return (
<div style={{ position: "relative", height: 200, overflow: "auto", border: "1px solid #24143022",
borderRadius: 12, font: "14px system-ui, sans-serif", color: "#241430" }}>
<div style={{ padding: 16 }}>
<p style={{ margin: "0 0 60px", color: "#241430aa" }}>Scroll this frame — the call to action stays pinned.</p>
<p style={{ margin: "0 0 60px", color: "#241430aa" }}>Page content keeps flowing underneath it.</p>
<p style={{ margin: "0 0 60px", color: "#241430aa" }}>More content here to make the frame scrollable.</p>
</div>
<div style={{ position: "sticky", bottom: 0, display: "flex", alignItems: "center", justifyContent: "space-between",
gap: 12, color: "#FAF7F2", fontWeight: 700, background: accent,
width: corner ? "fit-content" : "100%", padding: corner ? "12px 18px" : "14px 18px",
borderRadius: corner ? 999 : 0, margin: corner ? "0 12px 12px auto" : 0 }}>
<span>{ctaText}</span>
{showDismiss && <button type="button" aria-label="Dismiss" style={{ background: "none", border: "none", color: "inherit", fontSize: 16, cursor: "pointer" }}>×</button>}
</div>
</div>
);
}