portfolio video cards case-study hover overlay agency portfolio video cards case-study overlay hover portfolio grid with video preview on hover dark card case study grid agency work showcase with play button
Portfolio Video Cards
Fetch pattern JSON:
curl https://webspire.de/patterns/portfolio/video-cards.json video-cards.html
<section class="ws-portfolio bg-[var(--ws-portfolio-bg)] py-20">
<div class="mx-auto max-w-7xl px-6">
<!-- Header -->
<div class="mb-12 flex flex-wrap items-end justify-between gap-6">
<div>
<p class="mb-2 font-mono text-xs tracking-widest text-[var(--ws-portfolio-text-muted)] uppercase">Selected work</p>
<h2 class="text-3xl font-bold tracking-tight text-[var(--ws-portfolio-text)] sm:text-4xl">Case studies</h2>
</div>
<a href="#" class="text-sm font-medium text-[var(--ws-portfolio-link)] transition hover:text-[var(--ws-portfolio-text)]">
All projects →
</a>
</div>
<!-- Video card grid -->
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
<!-- Card 1 -->
<article class="group relative overflow-hidden rounded-2xl bg-[oklch(14%_0.02_280)]">
<!-- Video placeholder (replace with <video> or <img>) -->
<div class="aspect-[4/3] overflow-hidden bg-gradient-to-br from-violet-900 to-indigo-950">
<!-- Play overlay — visible on hover -->
<div class="absolute inset-0 flex items-center justify-center opacity-0 transition-opacity duration-300 group-hover:opacity-100" aria-hidden="true">
<div class="flex h-14 w-14 items-center justify-center rounded-full bg-white/15 backdrop-blur-sm">
<svg class="ml-1 h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M8 5.14v14l11-7-11-7z"/>
</svg>
</div>
</div>
<!-- Gradient overlay on hover for text legibility -->
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-60 transition-opacity duration-300 group-hover:opacity-80"></div>
</div>
<!-- Card content -->
<div class="absolute bottom-0 left-0 right-0 p-5">
<span class="mb-2 inline-block rounded-full bg-white/10 px-2.5 py-0.5 text-xs font-medium text-white/70">Branding</span>
<h3 class="text-base font-semibold text-white leading-snug">Nova Financial Rebrand</h3>
<p class="mt-1 text-xs text-white/55">Identity design • Motion • 2024</p>
</div>
</article>
<!-- Card 2 -->
<article class="group relative overflow-hidden rounded-2xl bg-[oklch(14%_0.02_160)]">
<div class="aspect-[4/3] overflow-hidden bg-gradient-to-br from-emerald-900 to-teal-950">
<div class="absolute inset-0 flex items-center justify-center opacity-0 transition-opacity duration-300 group-hover:opacity-100" aria-hidden="true">
<div class="flex h-14 w-14 items-center justify-center rounded-full bg-white/15 backdrop-blur-sm">
<svg class="ml-1 h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M8 5.14v14l11-7-11-7z"/>
</svg>
</div>
</div>
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-60 transition-opacity duration-300 group-hover:opacity-80"></div>
</div>
<div class="absolute bottom-0 left-0 right-0 p-5">
<span class="mb-2 inline-block rounded-full bg-white/10 px-2.5 py-0.5 text-xs font-medium text-white/70">Web</span>
<h3 class="text-base font-semibold text-white leading-snug">Verdant E-Commerce Platform</h3>
<p class="mt-1 text-xs text-white/55">UI design • Frontend dev • 2024</p>
</div>
</article>
<!-- Card 3 -->
<article class="group relative overflow-hidden rounded-2xl bg-[oklch(14%_0.02_30)]">
<div class="aspect-[4/3] overflow-hidden bg-gradient-to-br from-amber-900 to-orange-950">
<div class="absolute inset-0 flex items-center justify-center opacity-0 transition-opacity duration-300 group-hover:opacity-100" aria-hidden="true">
<div class="flex h-14 w-14 items-center justify-center rounded-full bg-white/15 backdrop-blur-sm">
<svg class="ml-1 h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M8 5.14v14l11-7-11-7z"/>
</svg>
</div>
</div>
<div class="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent opacity-60 transition-opacity duration-300 group-hover:opacity-80"></div>
</div>
<div class="absolute bottom-0 left-0 right-0 p-5">
<span class="mb-2 inline-block rounded-full bg-white/10 px-2.5 py-0.5 text-xs font-medium text-white/70">Motion</span>
<h3 class="text-base font-semibold text-white leading-snug">Pulse App Launch Campaign</h3>
<p class="mt-1 text-xs text-white/55">Animation • Social • 2023</p>
</div>
</article>
</div>
</div>
</section>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste
Stable Published
portfoliovideocardscase-studyhoveroverlayagency
Slots
| Name | Required | Description |
|---|---|---|
| heading | Yes | Section heading and subtext. |
| cards | Yes | Portfolio cards — each needs a media area, category badge, title, and meta line. |
Dark gradient cards where the project content (title, category, meta) is always visible at the bottom, and a frosted-glass play button appears on hover using only group-hover:opacity-100. Replace the gradient placeholder with a real <video> element — the overlay works identically.
With real video
<article class="group relative overflow-hidden rounded-2xl">
<video
class="aspect-[4/3] w-full object-cover"
src="/work/nova-rebrand.mp4"
autoplay muted loop playsinline
preload="none"
></video>
<!-- same overlay and bottom content -->
</article>