09 / 20
All 20 in 20 Tailwind CSS Cards
- 01Tailwind E-Commerce Product Grid Card with Hover Quick-Add
- 02Tailwind SaaS Pricing Tier Card Row with Popular Plan
- 03Tailwind Recipe Card with Cook-Time Meta Grid
- 04Tailwind Real Estate Listing Card with Walk Score Rings
- 05Tailwind Hotel Booking Card with Photo Mosaic & Price Breakdown
- 06Tailwind Blog Index Card Stack with Split Hero
- 07Tailwind Horizontal Article Card Feed with Ranked Covers
- 08Tailwind Testimonial Card with Sentiment Strip
- 09Tailwind Video Preview Card with Glass Play Button
- 10Tailwind Leaderboard Card with Gradient Medal Ranks
- 11Tailwind Team Profile Card with Masked Grid Cover
- 12Tailwind SaaS Feature Card with Arrow-Slide Link
- 13Tailwind Dark vCard with Iridescent Sheen
- 14Tailwind Portfolio Card with CSS-Drawn Dashboard Mock
- 15Tailwind Dark KPI Stat Card with SVG Sparkline
- 16Tailwind 3D Flip Business Card with Keyboard Reveal
- 17Tailwind Glassmorphism Card on Animated Aurora Stage
- 18Tailwind Rotating Conic-Border Card with Terminal Panel
- 19Tailwind 3D Pop-Out Product Card with translateZ Lift
- 20Tailwind Stacked Card Cascade with Focus-Within Fan-Out
Tailwind Video Preview Card with Glass Play Button
A video shelf card: 16:9 thumbnail, glass play button with a breathing ring, LIVE and 4K pills, a watch-progress bar, and a creator row with subscriber delta. The port's win is that three infinite animations become three animate-* utilities minted from @theme, each carrying its own motion-reduce:animate-none beside it.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="twc-09 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc09-bg [background-image:radial-gradient(ellipse_at_20%_20%,oklch(0.68_0.2_350/0.06),transparent_50%),radial-gradient(ellipse_at_80%_80%,oklch(0.6_0.2_295/0.06),transparent_50%)] font-twc09-sans">
<article class="group/card relative isolate w-full max-w-[380px] overflow-hidden rounded-[22px] bg-white border border-black/5 shadow-[0_30px_60px_-30px_oklch(0.35_0.15_320/0.24),inset_0_0_0_1px_oklch(1_0_0/0.5)] transition-[transform,box-shadow] duration-300 hover:-translate-y-[3px] hover:shadow-[0_40px_80px_-30px_oklch(0.35_0.15_320/0.34)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div aria-hidden="true" class="absolute -top-20 -right-20 size-65 -z-10 pointer-events-none blur-[30px] [background:radial-gradient(circle,oklch(0.68_0.2_350/0.18)_0%,transparent_55%),radial-gradient(circle_at_30%_30%,oklch(0.6_0.2_295/0.16)_0%,transparent_55%)]"></div>
<a href="#play" aria-label="Play video: Building Container Queries in 8 Minutes" class="relative block w-full aspect-video overflow-hidden no-underline rounded-t-[22px] focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-[-2px]">
<img src="https://images.unsplash.com/photo-1517180102446-f3ece451e9d8?w=800&q=80&auto=format&fit=crop" alt="CSS Container Queries tutorial" loading="lazy" decoding="async" class="absolute inset-0 size-full object-cover block transition-[transform,filter] duration-600 ease-out group-hover/card:scale-105 group-hover/card:brightness-110 group-hover/card:saturate-110 motion-reduce:transition-none motion-reduce:group-hover/card:scale-100">
<div aria-hidden="true" class="absolute inset-0 pointer-events-none [background:linear-gradient(180deg,oklch(0_0_0/0.15)_0%,oklch(0_0_0/0.4)_100%)]"></div>
<div aria-hidden="true" class="absolute top-[40%] left-1/2 -translate-x-1/2 -translate-y-1/2 w-3/5 h-3/5 pointer-events-none transition-opacity duration-350 group-hover/card:opacity-70 [background:radial-gradient(ellipse,oklch(1_0_0/0.2),transparent_70%)]"></div>
<span class="absolute top-3 left-3 inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-twc09-red/95 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.14em] shadow-[0_4px_12px_oklch(0.58_0.22_25/0.35)]">
<span aria-hidden="true" class="size-[5px] rounded-full bg-white animate-twc09-blink motion-reduce:animate-none"></span>
LIVE
</span>
<span class="absolute top-3 right-3 px-[7px] py-[3px] rounded-[5px] bg-black/72 backdrop-blur-[6px] border border-white/15 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.06em]">4K</span>
<span aria-hidden="true" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex items-center justify-center size-14 rounded-full bg-black/60 backdrop-blur-[8px] border-[1.5px] border-white/28 shadow-[0_8px_24px_oklch(0_0_0/0.35)] transition-[transform,background,box-shadow] duration-250 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover/card:scale-108 group-hover/card:bg-twc09-acc/80 group-hover/card:shadow-[0_12px_32px_oklch(0.68_0.2_350/0.45)] motion-reduce:transition-[background] motion-reduce:group-hover/card:scale-100">
<span class="absolute -inset-1.5 rounded-full border-[1.5px] border-white/20 animate-twc09-ring motion-reduce:animate-none"></span>
<svg width="22" height="22" viewBox="0 0 24 24" fill="#fff" class="ml-[3px]" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg>
</span>
<div aria-hidden="true" class="absolute bottom-0 inset-x-0 px-3 pb-2 pointer-events-none [background:linear-gradient(180deg,transparent_0%,oklch(0_0_0/0.6)_100%)]">
<div class="h-[3px] mb-1.5 rounded-sm overflow-hidden bg-white/16">
<span class="block w-[42%] h-full rounded-sm [background:linear-gradient(90deg,#ec4899,#f472b6)]"></span>
</div>
<div class="flex items-center justify-between text-white">
<span class="inline-flex items-center gap-1 text-[10px] font-bold tracking-[0.02em]">
<span class="size-[5px] rounded-full bg-twc09-green shadow-[0_0_6px_oklch(0.78_0.14_165)] animate-twc09-pulse motion-reduce:animate-none"></span>
2.4k watching
</span>
<span class="font-twc09-mono text-[10.5px] font-bold tracking-[0.02em]">12:47</span>
</div>
</div>
</a>
<div class="relative z-1 px-4 py-3.5">
<span class="inline-block mb-2 px-2 py-0.5 rounded-full font-twc09-mono text-[9.5px] font-bold tracking-[0.14em] uppercase text-twc09-indigoink bg-twc09-indigo/8 border border-twc09-indigo/16">CSS · Tutorial</span>
<h3 class="m-0 mb-3 text-[15px]/[1.3] font-bold tracking-[-0.015em] [background-image:linear-gradient(180deg,#1a1a1a_0%,#4b4b57_130%)] bg-clip-text text-transparent">Building Container Queries in 8 Minutes</h3>
<div class="grid grid-cols-[36px_1fr_auto] items-center gap-2.5 mb-3">
<span aria-hidden="true" class="relative flex items-center justify-center size-9 rounded-full border-2 border-white [background:linear-gradient(135deg,#ec4899,#f97316)] text-white text-xs font-extrabold shadow-[0_2px_6px_oklch(0_0_0/0.1)]">
JC
<span class="absolute -bottom-[3px] -right-[3px] flex items-center justify-center size-3.5 rounded-full bg-twc09-blue border-[1.5px] border-white">
<svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
</span>
</span>
<div class="flex flex-col gap-px min-w-0">
<span class="inline-flex items-center gap-1">
<span class="text-[13px] font-bold tracking-[-0.01em] text-twc09-ink">Josh Comeau</span>
<svg role="img" aria-label="Verified creator" width="12" height="12" viewBox="0 0 24 24" fill="none" class="flex-none"><path d="M12 2 L14 4 L17 3 L18 6 L21 7 L20 10 L22 12 L20 14 L21 17 L18 18 L17 21 L14 20 L12 22 L10 20 L7 21 L6 18 L3 17 L4 14 L2 12 L4 10 L3 7 L6 6 L7 3 L10 4 Z" fill="#3b82f6"/><path d="M9 12 L11 14 L15 10" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<span class="text-[11px] text-twc09-muted truncate">128k subscribers · <span class="font-twc09-mono text-[10.5px] font-bold text-twc09-greenink">+2.1k this week</span></span>
</div>
<button type="button" aria-label="Save video" class="inline-flex items-center justify-center size-11 rounded-[10px] bg-transparent border border-black/6 text-twc09-muted cursor-pointer transition-[color,background,border-color,transform] duration-200 hover:text-twc09-acc hover:bg-twc09-acc/6 hover:border-twc09-acc/25 hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-2 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
</button>
</div>
<div class="flex items-center justify-between gap-3 pt-2.5 border-t border-black/5">
<div class="flex gap-2.5">
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><polygon points="12 2 15 9 22 9 17 14 19 21 12 17 5 21 7 14 2 9 9 9"/></svg>
8.2k
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
342
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/><line x1="15.4" y1="6.5" x2="8.6" y2="10.5"/></svg>
892
</span>
</div>
<div class="flex items-center gap-1 text-[11px] text-twc09-dim">
<time datetime="2026-07-05">Jul 5</time>
<span aria-hidden="true" class="text-twc09-hair">·</span>
<span>24.7k views</span>
</div>
</div>
</div>
</article>
</section><section class="twc-09 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc09-bg [background-image:radial-gradient(ellipse_at_20%_20%,oklch(0.68_0.2_350/0.06),transparent_50%),radial-gradient(ellipse_at_80%_80%,oklch(0.6_0.2_295/0.06),transparent_50%)] font-twc09-sans">
<article class="group/card relative isolate w-full max-w-[380px] overflow-hidden rounded-[22px] bg-white border border-black/5 shadow-[0_30px_60px_-30px_oklch(0.35_0.15_320/0.24),inset_0_0_0_1px_oklch(1_0_0/0.5)] transition-[transform,box-shadow] duration-300 hover:-translate-y-[3px] hover:shadow-[0_40px_80px_-30px_oklch(0.35_0.15_320/0.34)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div aria-hidden="true" class="absolute -top-20 -right-20 size-65 -z-10 pointer-events-none blur-[30px] [background:radial-gradient(circle,oklch(0.68_0.2_350/0.18)_0%,transparent_55%),radial-gradient(circle_at_30%_30%,oklch(0.6_0.2_295/0.16)_0%,transparent_55%)]"></div>
<a href="#play" aria-label="Play video: Building Container Queries in 8 Minutes" class="relative block w-full aspect-video overflow-hidden no-underline rounded-t-[22px] focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-[-2px]">
<img src="https://images.unsplash.com/photo-1517180102446-f3ece451e9d8?w=800&q=80&auto=format&fit=crop" alt="CSS Container Queries tutorial" loading="lazy" decoding="async" class="absolute inset-0 size-full object-cover block transition-[transform,filter] duration-600 ease-out group-hover/card:scale-105 group-hover/card:brightness-110 group-hover/card:saturate-110 motion-reduce:transition-none motion-reduce:group-hover/card:scale-100">
<div aria-hidden="true" class="absolute inset-0 pointer-events-none [background:linear-gradient(180deg,oklch(0_0_0/0.15)_0%,oklch(0_0_0/0.4)_100%)]"></div>
<div aria-hidden="true" class="absolute top-[40%] left-1/2 -translate-x-1/2 -translate-y-1/2 w-3/5 h-3/5 pointer-events-none transition-opacity duration-350 group-hover/card:opacity-70 [background:radial-gradient(ellipse,oklch(1_0_0/0.2),transparent_70%)]"></div>
<span class="absolute top-3 left-3 inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-twc09-red/95 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.14em] shadow-[0_4px_12px_oklch(0.58_0.22_25/0.35)]">
<span aria-hidden="true" class="size-[5px] rounded-full bg-white animate-twc09-blink motion-reduce:animate-none"></span>
LIVE
</span>
<span class="absolute top-3 right-3 px-[7px] py-[3px] rounded-[5px] bg-black/72 backdrop-blur-[6px] border border-white/15 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.06em]">4K</span>
<span aria-hidden="true" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex items-center justify-center size-14 rounded-full bg-black/60 backdrop-blur-[8px] border-[1.5px] border-white/28 shadow-[0_8px_24px_oklch(0_0_0/0.35)] transition-[transform,background,box-shadow] duration-250 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover/card:scale-108 group-hover/card:bg-twc09-acc/80 group-hover/card:shadow-[0_12px_32px_oklch(0.68_0.2_350/0.45)] motion-reduce:transition-[background] motion-reduce:group-hover/card:scale-100">
<span class="absolute -inset-1.5 rounded-full border-[1.5px] border-white/20 animate-twc09-ring motion-reduce:animate-none"></span>
<svg width="22" height="22" viewBox="0 0 24 24" fill="#fff" class="ml-[3px]" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg>
</span>
<div aria-hidden="true" class="absolute bottom-0 inset-x-0 px-3 pb-2 pointer-events-none [background:linear-gradient(180deg,transparent_0%,oklch(0_0_0/0.6)_100%)]">
<div class="h-[3px] mb-1.5 rounded-sm overflow-hidden bg-white/16">
<span class="block w-[42%] h-full rounded-sm [background:linear-gradient(90deg,#ec4899,#f472b6)]"></span>
</div>
<div class="flex items-center justify-between text-white">
<span class="inline-flex items-center gap-1 text-[10px] font-bold tracking-[0.02em]">
<span class="size-[5px] rounded-full bg-twc09-green shadow-[0_0_6px_oklch(0.78_0.14_165)] animate-twc09-pulse motion-reduce:animate-none"></span>
2.4k watching
</span>
<span class="font-twc09-mono text-[10.5px] font-bold tracking-[0.02em]">12:47</span>
</div>
</div>
</a>
<div class="relative z-1 px-4 py-3.5">
<span class="inline-block mb-2 px-2 py-0.5 rounded-full font-twc09-mono text-[9.5px] font-bold tracking-[0.14em] uppercase text-twc09-indigoink bg-twc09-indigo/8 border border-twc09-indigo/16">CSS · Tutorial</span>
<h3 class="m-0 mb-3 text-[15px]/[1.3] font-bold tracking-[-0.015em] [background-image:linear-gradient(180deg,#1a1a1a_0%,#4b4b57_130%)] bg-clip-text text-transparent">Building Container Queries in 8 Minutes</h3>
<div class="grid grid-cols-[36px_1fr_auto] items-center gap-2.5 mb-3">
<span aria-hidden="true" class="relative flex items-center justify-center size-9 rounded-full border-2 border-white [background:linear-gradient(135deg,#ec4899,#f97316)] text-white text-xs font-extrabold shadow-[0_2px_6px_oklch(0_0_0/0.1)]">
JC
<span class="absolute -bottom-[3px] -right-[3px] flex items-center justify-center size-3.5 rounded-full bg-twc09-blue border-[1.5px] border-white">
<svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
</span>
</span>
<div class="flex flex-col gap-px min-w-0">
<span class="inline-flex items-center gap-1">
<span class="text-[13px] font-bold tracking-[-0.01em] text-twc09-ink">Josh Comeau</span>
<svg role="img" aria-label="Verified creator" width="12" height="12" viewBox="0 0 24 24" fill="none" class="flex-none"><path d="M12 2 L14 4 L17 3 L18 6 L21 7 L20 10 L22 12 L20 14 L21 17 L18 18 L17 21 L14 20 L12 22 L10 20 L7 21 L6 18 L3 17 L4 14 L2 12 L4 10 L3 7 L6 6 L7 3 L10 4 Z" fill="#3b82f6"/><path d="M9 12 L11 14 L15 10" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<span class="text-[11px] text-twc09-muted truncate">128k subscribers · <span class="font-twc09-mono text-[10.5px] font-bold text-twc09-greenink">+2.1k this week</span></span>
</div>
<button type="button" aria-label="Save video" class="inline-flex items-center justify-center size-11 rounded-[10px] bg-transparent border border-black/6 text-twc09-muted cursor-pointer transition-[color,background,border-color,transform] duration-200 hover:text-twc09-acc hover:bg-twc09-acc/6 hover:border-twc09-acc/25 hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-2 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
</button>
</div>
<div class="flex items-center justify-between gap-3 pt-2.5 border-t border-black/5">
<div class="flex gap-2.5">
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><polygon points="12 2 15 9 22 9 17 14 19 21 12 17 5 21 7 14 2 9 9 9"/></svg>
8.2k
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
342
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/><line x1="15.4" y1="6.5" x2="8.6" y2="10.5"/></svg>
892
</span>
</div>
<div class="flex items-center gap-1 text-[11px] text-twc09-dim">
<time datetime="2026-07-05">Jul 5</time>
<span aria-hidden="true" class="text-twc09-hair">·</span>
<span>24.7k views</span>
</div>
</div>
</div>
</article>
</section>@import "tailwindcss";
@theme {
--color-twc09-bg: #f8f7f4;
--color-twc09-bg: oklch(0.97 0.005 90);
--color-twc09-ink: #1a1a1a;
--color-twc09-ink: oklch(0.21 0.005 270);
--color-twc09-ink2: #4b4b57;
--color-twc09-ink2: oklch(0.4 0.015 280);
--color-twc09-muted: #6b6b7c;
--color-twc09-muted: oklch(0.51 0.02 285);
--color-twc09-dim: #9ca3af;
--color-twc09-dim: oklch(0.71 0.02 265);
--color-twc09-hair: #cbd5e1;
--color-twc09-hair: oklch(0.85 0.02 250);
--color-twc09-acc: #ec4899;
--color-twc09-acc: oklch(0.68 0.2 350);
--color-twc09-red: #dc2626;
--color-twc09-red: oklch(0.58 0.22 25);
--color-twc09-green: #34d399;
--color-twc09-green: oklch(0.78 0.14 165);
--color-twc09-greenink: #059669;
--color-twc09-greenink: oklch(0.56 0.13 163);
--color-twc09-blue: #3b82f6;
--color-twc09-blue: oklch(0.62 0.17 255);
--color-twc09-indigo: #6366f1;
--color-twc09-indigo: oklch(0.55 0.2 275);
--color-twc09-indigoink: #4338ca;
--color-twc09-indigoink: oklch(0.42 0.21 275);
--font-twc09-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc09-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--animate-twc09-blink: twc09-blink 1.4s ease-in-out infinite;
--animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite;
--animate-twc09-pulse: twc09-pulse 2s ease-in-out infinite;
}
/* Three keyframe blocks, three @theme entries: the blocks stay CSS because
keyframes are not utilities, the entries mint animate-twc09-* so each
element can pair its animation with motion-reduce:animate-none inline. */
@keyframes twc09-blink {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.85);
}
}
@keyframes twc09-ring {
0%,
100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.15);
opacity: 0.1;
}
}
@keyframes twc09-pulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 6px #34d399;
}
50% {
transform: scale(1.3);
box-shadow: 0 0 10px #34d399;
}
}
.twc-09 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-twc09-bg: #f8f7f4;
--color-twc09-bg: oklch(0.97 0.005 90);
--color-twc09-ink: #1a1a1a;
--color-twc09-ink: oklch(0.21 0.005 270);
--color-twc09-ink2: #4b4b57;
--color-twc09-ink2: oklch(0.4 0.015 280);
--color-twc09-muted: #6b6b7c;
--color-twc09-muted: oklch(0.51 0.02 285);
--color-twc09-dim: #9ca3af;
--color-twc09-dim: oklch(0.71 0.02 265);
--color-twc09-hair: #cbd5e1;
--color-twc09-hair: oklch(0.85 0.02 250);
--color-twc09-acc: #ec4899;
--color-twc09-acc: oklch(0.68 0.2 350);
--color-twc09-red: #dc2626;
--color-twc09-red: oklch(0.58 0.22 25);
--color-twc09-green: #34d399;
--color-twc09-green: oklch(0.78 0.14 165);
--color-twc09-greenink: #059669;
--color-twc09-greenink: oklch(0.56 0.13 163);
--color-twc09-blue: #3b82f6;
--color-twc09-blue: oklch(0.62 0.17 255);
--color-twc09-indigo: #6366f1;
--color-twc09-indigo: oklch(0.55 0.2 275);
--color-twc09-indigoink: #4338ca;
--color-twc09-indigoink: oklch(0.42 0.21 275);
--font-twc09-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc09-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--animate-twc09-blink: twc09-blink 1.4s ease-in-out infinite;
--animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite;
--animate-twc09-pulse: twc09-pulse 2s ease-in-out infinite;
}
/* Three keyframe blocks, three @theme entries: the blocks stay CSS because
keyframes are not utilities, the entries mint animate-twc09-* so each
element can pair its animation with motion-reduce:animate-none inline. */
@keyframes twc09-blink {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.85);
}
}
@keyframes twc09-ring {
0%,
100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.15);
opacity: 0.1;
}
}
@keyframes twc09-pulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 6px #34d399;
}
50% {
transform: scale(1.3);
box-shadow: 0 0 10px #34d399;
}
}
.twc-09 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-twc09-bg: #f8f7f4;
--color-twc09-bg: oklch(0.97 0.005 90);
--color-twc09-ink: #1a1a1a;
--color-twc09-ink: oklch(0.21 0.005 270);
--color-twc09-ink2: #4b4b57;
--color-twc09-ink2: oklch(0.4 0.015 280);
--color-twc09-muted: #6b6b7c;
--color-twc09-muted: oklch(0.51 0.02 285);
--color-twc09-dim: #9ca3af;
--color-twc09-dim: oklch(0.71 0.02 265);
--color-twc09-hair: #cbd5e1;
--color-twc09-hair: oklch(0.85 0.02 250);
--color-twc09-acc: #ec4899;
--color-twc09-acc: oklch(0.68 0.2 350);
--color-twc09-red: #dc2626;
--color-twc09-red: oklch(0.58 0.22 25);
--color-twc09-green: #34d399;
--color-twc09-green: oklch(0.78 0.14 165);
--color-twc09-greenink: #059669;
--color-twc09-greenink: oklch(0.56 0.13 163);
--color-twc09-blue: #3b82f6;
--color-twc09-blue: oklch(0.62 0.17 255);
--color-twc09-indigo: #6366f1;
--color-twc09-indigo: oklch(0.55 0.2 275);
--color-twc09-indigoink: #4338ca;
--color-twc09-indigoink: oklch(0.42 0.21 275);
--font-twc09-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc09-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--animate-twc09-blink: twc09-blink 1.4s ease-in-out infinite;
--animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite;
--animate-twc09-pulse: twc09-pulse 2s ease-in-out infinite;
}
/* Three keyframe blocks, three @theme entries: the blocks stay CSS because
keyframes are not utilities, the entries mint animate-twc09-* so each
element can pair its animation with motion-reduce:animate-none inline. */
@keyframes twc09-blink {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.85);
}
}
@keyframes twc09-ring {
0%,
100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.15);
opacity: 0.1;
}
}
@keyframes twc09-pulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 6px #34d399;
}
50% {
transform: scale(1.3);
box-shadow: 0 0 10px #34d399;
}
}
.twc-09 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-twc09-bg: #f8f7f4;
--color-twc09-bg: oklch(0.97 0.005 90);
--color-twc09-ink: #1a1a1a;
--color-twc09-ink: oklch(0.21 0.005 270);
--color-twc09-ink2: #4b4b57;
--color-twc09-ink2: oklch(0.4 0.015 280);
--color-twc09-muted: #6b6b7c;
--color-twc09-muted: oklch(0.51 0.02 285);
--color-twc09-dim: #9ca3af;
--color-twc09-dim: oklch(0.71 0.02 265);
--color-twc09-hair: #cbd5e1;
--color-twc09-hair: oklch(0.85 0.02 250);
--color-twc09-acc: #ec4899;
--color-twc09-acc: oklch(0.68 0.2 350);
--color-twc09-red: #dc2626;
--color-twc09-red: oklch(0.58 0.22 25);
--color-twc09-green: #34d399;
--color-twc09-green: oklch(0.78 0.14 165);
--color-twc09-greenink: #059669;
--color-twc09-greenink: oklch(0.56 0.13 163);
--color-twc09-blue: #3b82f6;
--color-twc09-blue: oklch(0.62 0.17 255);
--color-twc09-indigo: #6366f1;
--color-twc09-indigo: oklch(0.55 0.2 275);
--color-twc09-indigoink: #4338ca;
--color-twc09-indigoink: oklch(0.42 0.21 275);
--font-twc09-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc09-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--animate-twc09-blink: twc09-blink 1.4s ease-in-out infinite;
--animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite;
--animate-twc09-pulse: twc09-pulse 2s ease-in-out infinite;
}
/* Three keyframe blocks, three @theme entries: the blocks stay CSS because
keyframes are not utilities, the entries mint animate-twc09-* so each
element can pair its animation with motion-reduce:animate-none inline. */
@keyframes twc09-blink {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.85);
}
}
@keyframes twc09-ring {
0%,
100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.15);
opacity: 0.1;
}
}
@keyframes twc09-pulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 6px #34d399;
}
50% {
transform: scale(1.3);
box-shadow: 0 0 10px #34d399;
}
}
.twc-09 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;800&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Three
animation:noneresets that lived in a reduced-motion block at the bottom of the stylesheet are now threemotion-reduce:animate-noneutilities sitting beside the animations they cancel. - The play button's reduced-motion fallback is a colour change rather than nothing:
motion-reduce:transition-[background]keeps the hover signal while dropping the scale. That distinction is expressible inline and was not in the original. aspect-videoandsize-14replace a ratio declaration and a width/height pair; the rest of the thumbnail's four overlays are plainabsoluteoffsets.- UI change from the CSS original: the save button went from 34px to
size-11(44px) — the original's notes proposed an::beforehit-area hack; making the button actually 44px is the simpler fix.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Video Preview Card with Glass Play Button
Source: https://codefronts.com/components/tailwind-css-cards/tailwind-video-preview-card-glass-play-button/
A video shelf card: 16:9 thumbnail, glass play button with a breathing ring, LIVE and 4K pills, a watch-progress bar, and a creator row with subscriber delta. The port's win is that three infinite animations become three animate-* utilities minted from @theme, each carrying its own motion-reduce:animate-none beside it.
## HTML
```html
<section class="twc-09 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc09-bg [background-image:radial-gradient(ellipse_at_20%_20%,oklch(0.68_0.2_350/0.06),transparent_50%),radial-gradient(ellipse_at_80%_80%,oklch(0.6_0.2_295/0.06),transparent_50%)] font-twc09-sans">
<article class="group/card relative isolate w-full max-w-[380px] overflow-hidden rounded-[22px] bg-white border border-black/5 shadow-[0_30px_60px_-30px_oklch(0.35_0.15_320/0.24),inset_0_0_0_1px_oklch(1_0_0/0.5)] transition-[transform,box-shadow] duration-300 hover:-translate-y-[3px] hover:shadow-[0_40px_80px_-30px_oklch(0.35_0.15_320/0.34)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div aria-hidden="true" class="absolute -top-20 -right-20 size-65 -z-10 pointer-events-none blur-[30px] [background:radial-gradient(circle,oklch(0.68_0.2_350/0.18)_0%,transparent_55%),radial-gradient(circle_at_30%_30%,oklch(0.6_0.2_295/0.16)_0%,transparent_55%)]"></div>
<a href="#play" aria-label="Play video: Building Container Queries in 8 Minutes" class="relative block w-full aspect-video overflow-hidden no-underline rounded-t-[22px] focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-[-2px]">
<img src="https://images.unsplash.com/photo-1517180102446-f3ece451e9d8?w=800&q=80&auto=format&fit=crop" alt="CSS Container Queries tutorial" loading="lazy" decoding="async" class="absolute inset-0 size-full object-cover block transition-[transform,filter] duration-600 ease-out group-hover/card:scale-105 group-hover/card:brightness-110 group-hover/card:saturate-110 motion-reduce:transition-none motion-reduce:group-hover/card:scale-100">
<div aria-hidden="true" class="absolute inset-0 pointer-events-none [background:linear-gradient(180deg,oklch(0_0_0/0.15)_0%,oklch(0_0_0/0.4)_100%)]"></div>
<div aria-hidden="true" class="absolute top-[40%] left-1/2 -translate-x-1/2 -translate-y-1/2 w-3/5 h-3/5 pointer-events-none transition-opacity duration-350 group-hover/card:opacity-70 [background:radial-gradient(ellipse,oklch(1_0_0/0.2),transparent_70%)]"></div>
<span class="absolute top-3 left-3 inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-twc09-red/95 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.14em] shadow-[0_4px_12px_oklch(0.58_0.22_25/0.35)]">
<span aria-hidden="true" class="size-[5px] rounded-full bg-white animate-twc09-blink motion-reduce:animate-none"></span>
LIVE
</span>
<span class="absolute top-3 right-3 px-[7px] py-[3px] rounded-[5px] bg-black/72 backdrop-blur-[6px] border border-white/15 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.06em]">4K</span>
<span aria-hidden="true" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex items-center justify-center size-14 rounded-full bg-black/60 backdrop-blur-[8px] border-[1.5px] border-white/28 shadow-[0_8px_24px_oklch(0_0_0/0.35)] transition-[transform,background,box-shadow] duration-250 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover/card:scale-108 group-hover/card:bg-twc09-acc/80 group-hover/card:shadow-[0_12px_32px_oklch(0.68_0.2_350/0.45)] motion-reduce:transition-[background] motion-reduce:group-hover/card:scale-100">
<span class="absolute -inset-1.5 rounded-full border-[1.5px] border-white/20 animate-twc09-ring motion-reduce:animate-none"></span>
<svg width="22" height="22" viewBox="0 0 24 24" fill="#fff" class="ml-[3px]" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg>
</span>
<div aria-hidden="true" class="absolute bottom-0 inset-x-0 px-3 pb-2 pointer-events-none [background:linear-gradient(180deg,transparent_0%,oklch(0_0_0/0.6)_100%)]">
<div class="h-[3px] mb-1.5 rounded-sm overflow-hidden bg-white/16">
<span class="block w-[42%] h-full rounded-sm [background:linear-gradient(90deg,#ec4899,#f472b6)]"></span>
</div>
<div class="flex items-center justify-between text-white">
<span class="inline-flex items-center gap-1 text-[10px] font-bold tracking-[0.02em]">
<span class="size-[5px] rounded-full bg-twc09-green shadow-[0_0_6px_oklch(0.78_0.14_165)] animate-twc09-pulse motion-reduce:animate-none"></span>
2.4k watching
</span>
<span class="font-twc09-mono text-[10.5px] font-bold tracking-[0.02em]">12:47</span>
</div>
</div>
</a>
<div class="relative z-1 px-4 py-3.5">
<span class="inline-block mb-2 px-2 py-0.5 rounded-full font-twc09-mono text-[9.5px] font-bold tracking-[0.14em] uppercase text-twc09-indigoink bg-twc09-indigo/8 border border-twc09-indigo/16">CSS · Tutorial</span>
<h3 class="m-0 mb-3 text-[15px]/[1.3] font-bold tracking-[-0.015em] [background-image:linear-gradient(180deg,#1a1a1a_0%,#4b4b57_130%)] bg-clip-text text-transparent">Building Container Queries in 8 Minutes</h3>
<div class="grid grid-cols-[36px_1fr_auto] items-center gap-2.5 mb-3">
<span aria-hidden="true" class="relative flex items-center justify-center size-9 rounded-full border-2 border-white [background:linear-gradient(135deg,#ec4899,#f97316)] text-white text-xs font-extrabold shadow-[0_2px_6px_oklch(0_0_0/0.1)]">
JC
<span class="absolute -bottom-[3px] -right-[3px] flex items-center justify-center size-3.5 rounded-full bg-twc09-blue border-[1.5px] border-white">
<svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
</span>
</span>
<div class="flex flex-col gap-px min-w-0">
<span class="inline-flex items-center gap-1">
<span class="text-[13px] font-bold tracking-[-0.01em] text-twc09-ink">Josh Comeau</span>
<svg role="img" aria-label="Verified creator" width="12" height="12" viewBox="0 0 24 24" fill="none" class="flex-none"><path d="M12 2 L14 4 L17 3 L18 6 L21 7 L20 10 L22 12 L20 14 L21 17 L18 18 L17 21 L14 20 L12 22 L10 20 L7 21 L6 18 L3 17 L4 14 L2 12 L4 10 L3 7 L6 6 L7 3 L10 4 Z" fill="#3b82f6"/><path d="M9 12 L11 14 L15 10" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<span class="text-[11px] text-twc09-muted truncate">128k subscribers · <span class="font-twc09-mono text-[10.5px] font-bold text-twc09-greenink">+2.1k this week</span></span>
</div>
<button type="button" aria-label="Save video" class="inline-flex items-center justify-center size-11 rounded-[10px] bg-transparent border border-black/6 text-twc09-muted cursor-pointer transition-[color,background,border-color,transform] duration-200 hover:text-twc09-acc hover:bg-twc09-acc/6 hover:border-twc09-acc/25 hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-2 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
</button>
</div>
<div class="flex items-center justify-between gap-3 pt-2.5 border-t border-black/5">
<div class="flex gap-2.5">
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><polygon points="12 2 15 9 22 9 17 14 19 21 12 17 5 21 7 14 2 9 9 9"/></svg>
8.2k
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
342
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/><line x1="15.4" y1="6.5" x2="8.6" y2="10.5"/></svg>
892
</span>
</div>
<div class="flex items-center gap-1 text-[11px] text-twc09-dim">
<time datetime="2026-07-05">Jul 5</time>
<span aria-hidden="true" class="text-twc09-hair">·</span>
<span>24.7k views</span>
</div>
</div>
</div>
</article>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-twc09-bg: #f8f7f4;
--color-twc09-bg: oklch(0.97 0.005 90);
--color-twc09-ink: #1a1a1a;
--color-twc09-ink: oklch(0.21 0.005 270);
--color-twc09-ink2: #4b4b57;
--color-twc09-ink2: oklch(0.4 0.015 280);
--color-twc09-muted: #6b6b7c;
--color-twc09-muted: oklch(0.51 0.02 285);
--color-twc09-dim: #9ca3af;
--color-twc09-dim: oklch(0.71 0.02 265);
--color-twc09-hair: #cbd5e1;
--color-twc09-hair: oklch(0.85 0.02 250);
--color-twc09-acc: #ec4899;
--color-twc09-acc: oklch(0.68 0.2 350);
--color-twc09-red: #dc2626;
--color-twc09-red: oklch(0.58 0.22 25);
--color-twc09-green: #34d399;
--color-twc09-green: oklch(0.78 0.14 165);
--color-twc09-greenink: #059669;
--color-twc09-greenink: oklch(0.56 0.13 163);
--color-twc09-blue: #3b82f6;
--color-twc09-blue: oklch(0.62 0.17 255);
--color-twc09-indigo: #6366f1;
--color-twc09-indigo: oklch(0.55 0.2 275);
--color-twc09-indigoink: #4338ca;
--color-twc09-indigoink: oklch(0.42 0.21 275);
--font-twc09-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc09-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--animate-twc09-blink: twc09-blink 1.4s ease-in-out infinite;
--animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite;
--animate-twc09-pulse: twc09-pulse 2s ease-in-out infinite;
}
/* Three keyframe blocks, three @theme entries: the blocks stay CSS because
keyframes are not utilities, the entries mint animate-twc09-* so each
element can pair its animation with motion-reduce:animate-none inline. */
@keyframes twc09-blink {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.85);
}
}
@keyframes twc09-ring {
0%,
100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.15);
opacity: 0.1;
}
}
@keyframes twc09-pulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 6px #34d399;
}
50% {
transform: scale(1.3);
box-shadow: 0 0 10px #34d399;
}
}
.twc-09 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Video Preview Card with Glass Play Button
Source: https://codefronts.com/components/tailwind-css-cards/tailwind-video-preview-card-glass-play-button/
A video shelf card: 16:9 thumbnail, glass play button with a breathing ring, LIVE and 4K pills, a watch-progress bar, and a creator row with subscriber delta. The port's win is that three infinite animations become three animate-* utilities minted from @theme, each carrying its own motion-reduce:animate-none beside it.
## HTML
```html
<section class="twc-09 w-full min-h-svh flex items-center justify-center px-5 py-9 bg-twc09-bg [background-image:radial-gradient(ellipse_at_20%_20%,oklch(0.68_0.2_350/0.06),transparent_50%),radial-gradient(ellipse_at_80%_80%,oklch(0.6_0.2_295/0.06),transparent_50%)] font-twc09-sans">
<article class="group/card relative isolate w-full max-w-[380px] overflow-hidden rounded-[22px] bg-white border border-black/5 shadow-[0_30px_60px_-30px_oklch(0.35_0.15_320/0.24),inset_0_0_0_1px_oklch(1_0_0/0.5)] transition-[transform,box-shadow] duration-300 hover:-translate-y-[3px] hover:shadow-[0_40px_80px_-30px_oklch(0.35_0.15_320/0.34)] motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<div aria-hidden="true" class="absolute -top-20 -right-20 size-65 -z-10 pointer-events-none blur-[30px] [background:radial-gradient(circle,oklch(0.68_0.2_350/0.18)_0%,transparent_55%),radial-gradient(circle_at_30%_30%,oklch(0.6_0.2_295/0.16)_0%,transparent_55%)]"></div>
<a href="#play" aria-label="Play video: Building Container Queries in 8 Minutes" class="relative block w-full aspect-video overflow-hidden no-underline rounded-t-[22px] focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-[-2px]">
<img src="https://images.unsplash.com/photo-1517180102446-f3ece451e9d8?w=800&q=80&auto=format&fit=crop" alt="CSS Container Queries tutorial" loading="lazy" decoding="async" class="absolute inset-0 size-full object-cover block transition-[transform,filter] duration-600 ease-out group-hover/card:scale-105 group-hover/card:brightness-110 group-hover/card:saturate-110 motion-reduce:transition-none motion-reduce:group-hover/card:scale-100">
<div aria-hidden="true" class="absolute inset-0 pointer-events-none [background:linear-gradient(180deg,oklch(0_0_0/0.15)_0%,oklch(0_0_0/0.4)_100%)]"></div>
<div aria-hidden="true" class="absolute top-[40%] left-1/2 -translate-x-1/2 -translate-y-1/2 w-3/5 h-3/5 pointer-events-none transition-opacity duration-350 group-hover/card:opacity-70 [background:radial-gradient(ellipse,oklch(1_0_0/0.2),transparent_70%)]"></div>
<span class="absolute top-3 left-3 inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-twc09-red/95 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.14em] shadow-[0_4px_12px_oklch(0.58_0.22_25/0.35)]">
<span aria-hidden="true" class="size-[5px] rounded-full bg-white animate-twc09-blink motion-reduce:animate-none"></span>
LIVE
</span>
<span class="absolute top-3 right-3 px-[7px] py-[3px] rounded-[5px] bg-black/72 backdrop-blur-[6px] border border-white/15 text-white font-twc09-mono text-[9.5px] font-extrabold tracking-[0.06em]">4K</span>
<span aria-hidden="true" class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex items-center justify-center size-14 rounded-full bg-black/60 backdrop-blur-[8px] border-[1.5px] border-white/28 shadow-[0_8px_24px_oklch(0_0_0/0.35)] transition-[transform,background,box-shadow] duration-250 ease-[cubic-bezier(0.34,1.2,0.64,1)] group-hover/card:scale-108 group-hover/card:bg-twc09-acc/80 group-hover/card:shadow-[0_12px_32px_oklch(0.68_0.2_350/0.45)] motion-reduce:transition-[background] motion-reduce:group-hover/card:scale-100">
<span class="absolute -inset-1.5 rounded-full border-[1.5px] border-white/20 animate-twc09-ring motion-reduce:animate-none"></span>
<svg width="22" height="22" viewBox="0 0 24 24" fill="#fff" class="ml-[3px]" aria-hidden="true"><path d="M8 5v14l11-7z"/></svg>
</span>
<div aria-hidden="true" class="absolute bottom-0 inset-x-0 px-3 pb-2 pointer-events-none [background:linear-gradient(180deg,transparent_0%,oklch(0_0_0/0.6)_100%)]">
<div class="h-[3px] mb-1.5 rounded-sm overflow-hidden bg-white/16">
<span class="block w-[42%] h-full rounded-sm [background:linear-gradient(90deg,#ec4899,#f472b6)]"></span>
</div>
<div class="flex items-center justify-between text-white">
<span class="inline-flex items-center gap-1 text-[10px] font-bold tracking-[0.02em]">
<span class="size-[5px] rounded-full bg-twc09-green shadow-[0_0_6px_oklch(0.78_0.14_165)] animate-twc09-pulse motion-reduce:animate-none"></span>
2.4k watching
</span>
<span class="font-twc09-mono text-[10.5px] font-bold tracking-[0.02em]">12:47</span>
</div>
</div>
</a>
<div class="relative z-1 px-4 py-3.5">
<span class="inline-block mb-2 px-2 py-0.5 rounded-full font-twc09-mono text-[9.5px] font-bold tracking-[0.14em] uppercase text-twc09-indigoink bg-twc09-indigo/8 border border-twc09-indigo/16">CSS · Tutorial</span>
<h3 class="m-0 mb-3 text-[15px]/[1.3] font-bold tracking-[-0.015em] [background-image:linear-gradient(180deg,#1a1a1a_0%,#4b4b57_130%)] bg-clip-text text-transparent">Building Container Queries in 8 Minutes</h3>
<div class="grid grid-cols-[36px_1fr_auto] items-center gap-2.5 mb-3">
<span aria-hidden="true" class="relative flex items-center justify-center size-9 rounded-full border-2 border-white [background:linear-gradient(135deg,#ec4899,#f97316)] text-white text-xs font-extrabold shadow-[0_2px_6px_oklch(0_0_0/0.1)]">
JC
<span class="absolute -bottom-[3px] -right-[3px] flex items-center justify-center size-3.5 rounded-full bg-twc09-blue border-[1.5px] border-white">
<svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
</span>
</span>
<div class="flex flex-col gap-px min-w-0">
<span class="inline-flex items-center gap-1">
<span class="text-[13px] font-bold tracking-[-0.01em] text-twc09-ink">Josh Comeau</span>
<svg role="img" aria-label="Verified creator" width="12" height="12" viewBox="0 0 24 24" fill="none" class="flex-none"><path d="M12 2 L14 4 L17 3 L18 6 L21 7 L20 10 L22 12 L20 14 L21 17 L18 18 L17 21 L14 20 L12 22 L10 20 L7 21 L6 18 L3 17 L4 14 L2 12 L4 10 L3 7 L6 6 L7 3 L10 4 Z" fill="#3b82f6"/><path d="M9 12 L11 14 L15 10" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<span class="text-[11px] text-twc09-muted truncate">128k subscribers · <span class="font-twc09-mono text-[10.5px] font-bold text-twc09-greenink">+2.1k this week</span></span>
</div>
<button type="button" aria-label="Save video" class="inline-flex items-center justify-center size-11 rounded-[10px] bg-transparent border border-black/6 text-twc09-muted cursor-pointer transition-[color,background,border-color,transform] duration-200 hover:text-twc09-acc hover:bg-twc09-acc/6 hover:border-twc09-acc/25 hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-twc09-acc focus-visible:outline-offset-2 motion-reduce:transition-none motion-reduce:hover:translate-y-0">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
</button>
</div>
<div class="flex items-center justify-between gap-3 pt-2.5 border-t border-black/5">
<div class="flex gap-2.5">
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><polygon points="12 2 15 9 22 9 17 14 19 21 12 17 5 21 7 14 2 9 9 9"/></svg>
8.2k
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
342
</span>
<span class="inline-flex items-center gap-1 text-[11.5px] font-bold text-twc09-ink2 [font-variant-numeric:tabular-nums]">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="flex-none text-twc09-dim"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.6" y1="13.5" x2="15.4" y2="17.5"/><line x1="15.4" y1="6.5" x2="8.6" y2="10.5"/></svg>
892
</span>
</div>
<div class="flex items-center gap-1 text-[11px] text-twc09-dim">
<time datetime="2026-07-05">Jul 5</time>
<span aria-hidden="true" class="text-twc09-hair">·</span>
<span>24.7k views</span>
</div>
</div>
</div>
</article>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-twc09-bg: #f8f7f4;
--color-twc09-bg: oklch(0.97 0.005 90);
--color-twc09-ink: #1a1a1a;
--color-twc09-ink: oklch(0.21 0.005 270);
--color-twc09-ink2: #4b4b57;
--color-twc09-ink2: oklch(0.4 0.015 280);
--color-twc09-muted: #6b6b7c;
--color-twc09-muted: oklch(0.51 0.02 285);
--color-twc09-dim: #9ca3af;
--color-twc09-dim: oklch(0.71 0.02 265);
--color-twc09-hair: #cbd5e1;
--color-twc09-hair: oklch(0.85 0.02 250);
--color-twc09-acc: #ec4899;
--color-twc09-acc: oklch(0.68 0.2 350);
--color-twc09-red: #dc2626;
--color-twc09-red: oklch(0.58 0.22 25);
--color-twc09-green: #34d399;
--color-twc09-green: oklch(0.78 0.14 165);
--color-twc09-greenink: #059669;
--color-twc09-greenink: oklch(0.56 0.13 163);
--color-twc09-blue: #3b82f6;
--color-twc09-blue: oklch(0.62 0.17 255);
--color-twc09-indigo: #6366f1;
--color-twc09-indigo: oklch(0.55 0.2 275);
--color-twc09-indigoink: #4338ca;
--color-twc09-indigoink: oklch(0.42 0.21 275);
--font-twc09-sans: 'Space Grotesk', system-ui, sans-serif;
--font-twc09-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--animate-twc09-blink: twc09-blink 1.4s ease-in-out infinite;
--animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite;
--animate-twc09-pulse: twc09-pulse 2s ease-in-out infinite;
}
/* Three keyframe blocks, three @theme entries: the blocks stay CSS because
keyframes are not utilities, the entries mint animate-twc09-* so each
element can pair its animation with motion-reduce:animate-none inline. */
@keyframes twc09-blink {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.85);
}
}
@keyframes twc09-ring {
0%,
100% {
transform: scale(1);
opacity: 0.5;
}
50% {
transform: scale(1.15);
opacity: 0.1;
}
}
@keyframes twc09-pulse {
0%,
100% {
transform: scale(1);
box-shadow: 0 0 6px #34d399;
}
50% {
transform: scale(1.3);
box-shadow: 0 0 10px #34d399;
}
}
.twc-09 {
width: 100%;
min-height: 100svh;
}
```How this works
The animation and its opt-out travel together. A @keyframes block cannot be a utility, but --animate-twc09-ring: twc09-ring 2.4s ease-in-out infinite in @theme mints one:
<span class="absolute -inset-1.5 rounded-full border-[1.5px]
border-white/20 animate-twc09-ring
motion-reduce:animate-none">In the CSS version the three animation:none resets live in a reduced-motion block at the bottom of the file, three screens from the elements they cancel. Here they cannot drift apart.
The play button is one element with two states. Resting bg-black/60, hovered group-hover/card:bg-twc09-acc/80 and scale-108 — and under motion-reduce the scale is dropped while the colour change stays, which is the correct fallback: signal preserved, motion removed.
The progress bar is a width. w-[42%] on the fill, so a live player writes one style property and never touches layout.
Make it yours
--color-twc09-accdrives the play-button hover, the progress gradient, the aura and every focus ring.- Bind progress to the player: replace
w-[42%]withstyle="width:…"written fromcurrentTime / duration. - Swap the LIVE badge for PREMIERE or NEW by changing its fill utility and label; the pulsing dot is worth keeping either way for scannability.
- Pause the ring off-screen with an IntersectionObserver toggling a class — cheaper than running three infinite animations on a long shelf.
Gotchas — read before shipping
- Do not nest buttons inside the thumbnail anchor. Mute or caption controls belong outside it, or the nested interactive elements fail WCAG 4.1.2 and confuse screen readers.
loading="lazy"is right for a shelf card and wrong for a hero. If this card is ever the LCP element, drop the attribute or the metric suffers.- Without
backdrop-blursupport the play icon can fall under 3:1 against a bright thumbnail. Theborder-white/28ring plus the drop shadow is the fallback that keeps it visible. - Three infinite animations per card multiply across a shelf.
motion-reduce:animate-nonehandles the preference; viewport-gating handles the battery. outline-offset-[-2px]is deliberate: a positive offset on the thumbnail link draws the focus ring outside the card's rounded corner, where it looks like a rendering bug.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
aspect-ratio is Chrome 88+ / Safari 15+ / Firefox 89+ and backdrop-filter Firefox 103+; the floor is Tailwind v4's generated sheet (cascade layers, @property, color-mix()).