hero video play-button modal demo product landing-page saas hrworks intuit hero play button video modal demo thumbnail watch saas product launch hero section with video modal and play button product demo CTA above the fold
Hero Play Trigger
Fetch pattern JSON:
curl https://webspire.de/patterns/hero/play-trigger.json play-trigger.html
<section class="ws-hero relative isolate overflow-hidden bg-[var(--ws-hero-bg)]">
<!-- Content -->
<div class="mx-auto max-w-3xl px-6 pt-20 pb-16 text-center sm:pt-28 sm:pb-20">
<!-- Eyebrow badge -->
<p class="mb-5 inline-flex items-center gap-2 rounded-full border border-[var(--ws-hero-border)] bg-[var(--ws-color-primary-soft)] px-4 py-1.5 text-xs font-semibold uppercase tracking-widest text-[var(--ws-color-primary)]">
<span class="size-1.5 rounded-full bg-[var(--ws-color-primary)]"></span>
Now available — v3.0
</p>
<!-- Headline -->
<h1 class="text-balance text-4xl font-extrabold tracking-tight text-[var(--ws-hero-text)] sm:text-5xl lg:text-6xl">
See it in action.<br class="hidden sm:inline">
<span class="text-[var(--ws-color-primary)]">In two minutes.</span>
</h1>
<!-- Body -->
<p class="mx-auto mt-5 max-w-xl text-pretty text-lg leading-relaxed text-[var(--ws-hero-text-soft)]">
Watch how teams go from zero to production-ready in a single afternoon — no setup required.
</p>
<!-- CTAs -->
<div class="mt-9 flex flex-wrap items-center justify-center gap-3">
<a href="#" class="rounded-xl bg-[var(--ws-hero-action-bg)] px-6 py-3.5 text-sm font-semibold text-[var(--ws-hero-action-text)] shadow-sm transition hover:bg-[var(--ws-hero-action-bg-hover)]">
Get started free
</a>
<button
type="button"
onclick="document.getElementById('play-trigger-modal').removeAttribute('hidden')"
class="inline-flex items-center gap-2.5 rounded-xl border border-[var(--ws-hero-border)] bg-transparent px-6 py-3.5 text-sm font-semibold text-[var(--ws-hero-text)] transition hover:bg-[var(--ws-color-surface-alt)]"
aria-haspopup="dialog"
>
<!-- Play icon -->
<span class="inline-flex size-5 items-center justify-center rounded-full bg-[var(--ws-color-primary)]" aria-hidden="true">
<svg class="size-2.5 translate-x-px fill-white" viewBox="0 0 10 12"><path d="M1 1l8 5-8 5V1z"/></svg>
</span>
Watch the demo
</button>
</div>
</div>
<!-- Video thumbnail preview -->
<div class="mx-auto max-w-4xl px-6 pb-0">
<div class="relative overflow-hidden rounded-t-2xl bg-[var(--ws-hero-preview-bg)] ring-1 ring-[var(--ws-hero-preview-border)] shadow-2xl">
<!-- Aspect ratio container 16/9 -->
<div class="aspect-[16/9] flex items-center justify-center">
<!-- Fake dashboard UI -->
<div class="absolute inset-0 flex flex-col gap-0">
<div class="h-8 border-b border-slate-700/60 bg-slate-800/80 flex items-center gap-2 px-4">
<span class="size-2.5 rounded-full bg-red-500/70"></span>
<span class="size-2.5 rounded-full bg-yellow-500/70"></span>
<span class="size-2.5 rounded-full bg-green-500/70"></span>
<span class="ml-4 h-4 w-48 rounded bg-slate-700/60"></span>
</div>
<div class="flex flex-1 gap-0">
<div class="w-40 border-r border-slate-700/40 bg-slate-800/40 p-3 flex flex-col gap-2">
<div class="h-3 w-24 rounded bg-slate-700/60"></div>
<div class="h-2 w-20 rounded bg-slate-700/40"></div>
<div class="h-2 w-16 rounded bg-slate-700/40"></div>
<div class="h-2 w-22 rounded bg-slate-700/40"></div>
</div>
<div class="flex-1 p-4 flex flex-col gap-3">
<div class="h-4 w-1/3 rounded bg-slate-700/60"></div>
<div class="grid grid-cols-3 gap-3">
<div class="h-16 rounded-lg bg-slate-700/40 border border-slate-700/30"></div>
<div class="h-16 rounded-lg bg-slate-700/40 border border-slate-700/30"></div>
<div class="h-16 rounded-lg bg-blue-900/30 border border-blue-700/30"></div>
</div>
<div class="h-20 rounded-lg bg-slate-700/30 border border-slate-700/20"></div>
</div>
</div>
</div>
<!-- Centered play button overlay -->
<button
type="button"
onclick="document.getElementById('play-trigger-modal').removeAttribute('hidden')"
class="relative z-10 flex size-16 items-center justify-center rounded-full bg-white/90 shadow-lg shadow-black/30 transition hover:bg-white hover:scale-110 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
aria-label="Play demo video"
>
<svg class="size-6 translate-x-0.5 fill-slate-900" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 3l14 9-14 9V3z"/></svg>
</button>
</div>
</div>
</div>
<!-- Video modal -->
<div
id="play-trigger-modal"
hidden
role="dialog"
aria-modal="true"
aria-label="Product demo video"
class="fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4 backdrop-blur-sm"
onclick="if(event.target===this) this.setAttribute('hidden','')"
>
<div class="relative w-full max-w-3xl">
<!-- Close button -->
<button
type="button"
onclick="document.getElementById('play-trigger-modal').setAttribute('hidden','')"
class="absolute -top-10 right-0 inline-flex items-center gap-1.5 text-sm font-medium text-white/70 transition hover:text-white"
aria-label="Close video"
>
<svg class="size-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" d="M6 18L18 6M6 6l12 12"/></svg>
Close
</button>
<!-- Video placeholder (replace src with real iframe) -->
<div class="aspect-video overflow-hidden rounded-2xl bg-[var(--ws-hero-preview-bg)] flex items-center justify-center ring-1 ring-white/10">
<p class="text-sm text-[var(--ws-hero-text-muted)]">Replace this area with your <code class="text-[var(--ws-hero-text-soft)]"><iframe></code> or <code class="text-[var(--ws-hero-text-soft)]"><video></code> element.</p>
</div>
</div>
</div>
</section>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste Requires JS
Stable Published
herovideoplay-buttonmodaldemoproductlanding-pagesaashrworksintuit
Slots
| Name | Required | Description |
|---|---|---|
| badge | No | Eyebrow label above the headline. |
| headline | Yes | Primary value proposition with optional accent span. |
| body | Yes | Supporting copy explaining the video content. |
| cta-primary | Yes | Main conversion CTA button. |
| cta-video | Yes | Secondary play-trigger button that opens the modal. |
| thumbnail | Yes | Fake dashboard preview with centered play button — replace with real screenshot. |
| modal | Yes | Hidden video modal overlay — replace the placeholder with an iframe or video tag. |
Props
| Name | Type | Default | Description |
|---|---|---|---|
| modalId | string | play-trigger-modal | ID shared between the trigger buttons and the modal element. |
Enhanced Hero variant with an integrated video demo flow. Ideal for SaaS products where showing beats telling — the play button leads visitors directly into a product walkthrough without leaving the page.
The modal uses a native hidden attribute and plain onclick to stay framework-agnostic. Replace the placeholder content with your actual video embed.