16 / 36
All 36 in 36 Tailwind Stacked Cards
- 01Tailwind Scroll-Driven Scaling Card Stack
- 02Tailwind Swipe Card Deck Drag to Dismiss
- 03Tailwind Glassmorphism Testimonial Card Stack
- 04Tailwind Stacked Cards Expand Accordion on Click
- 05Tailwind Fan Out Photo Stack on Hover
- 06Tailwind 3D Perspective Tilt Card Stack
- 07Tailwind Multi Step Form Card Stack
- 08Tailwind Tabbed Card Stack Bring to Front
- 09Tailwind Click to Front Stacked Cards Cycle
- 10Tailwind Classic Card Deck Stack Shadow
- 11Tailwind Fan Spread Hand of Cards
- 12Tailwind Polaroid Photo Stack Scattered Rotate
- 13Tailwind Staircase Offset Stacked Cards Cascade
- 14Tailwind Cards Spread Out Horizontally on Hover
- 15Tailwind Stacked Cards Lift on Hover Sibling Push
- 16Tailwind Accordion Stacked Cards Slide Out Menu
- 17Tailwind Shuffle Cards Animation Loop Deck
- 18Tailwind File Folder Tab Stacked Cards
- 19Tailwind Scattered Photos Pinch to Centre on Hover
- 20Tailwind Mobile Swipe Card Stack Translate3d
- 21Tailwind Single Accordion Card Nested Layers
- 22Tailwind Isometric Tower Stacked Cards 3D Column
- 23Tailwind 3D Flip Card Stack Reveal Back
- 24Tailwind Card Stack Tilt on Hover Quadrant
- 25Tailwind Notification Stack Pile Dismiss
- 26Tailwind Receipt Roll Unroll Stacked Items
- 27Tailwind Scratch Card Reveal Canvas Mask
- 28Tailwind Stacked Cards Hover Reveal Spread
- 29Tailwind Scroll Activated Sticky Stacking Cards
- 30Tailwind Stacked Testimonial Slider Radio
- 31Tailwind Isometric Overlapping Stacked Cards
- 32Tailwind Bento Grid Stacked Cards Hover Fan
- 33Tailwind Perspective Card Deck Depth Tunnel
- 34Tailwind Peel Back Corner Card Reveal
- 35Tailwind Timeline Stacked Milestone Cards
- 36Tailwind Spiral Tower Rotating Stacked Cards
Tailwind Accordion Stacked Cards Slide Out Menu
One checkbox unfurls a packed pile into a spaced menu. The reveal is the grid-rows-[0fr] → 1fr pattern again, but the interesting part is reaching the items: peer-* stops at siblings, so the links are addressed with peer-checked:[&_a]:opacity-100 — the child-selector bolt-on that is the single most common Tailwind port bug.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="stk-16 w-full min-h-svh flex items-start justify-center px-5 py-[12vh] font-stk16-sans bg-stk16-bg" aria-label="Accordion-spread menu">
<div class="w-[min(300px,100%)]">
<input class="peer sr-only" type="checkbox" id="stk-16-t">
<label class="relative z-10 flex items-center justify-between rounded-[14px] bg-stk16-accent px-5 py-4 text-base font-extrabold text-white cursor-pointer shadow-[0_14px_30px_-16px_rgba(0,0,0,0.7)] peer-focus-visible:outline-3 peer-focus-visible:outline-white peer-focus-visible:outline-offset-3 peer-checked:[&_i]:rotate-180" for="stk-16-t">
<span>Menu</span>
<i class="text-xl not-italic leading-none transition-transform duration-350 motion-reduce:transition-none" aria-hidden="true">⌄</i>
</label>
<div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-stk16 peer-checked:grid-rows-[1fr] peer-checked:[&_a]:opacity-100 peer-checked:[&_a]:translate-y-0 motion-reduce:transition-none">
<nav class="flex flex-col gap-2 overflow-hidden pt-2" aria-label="Main">
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:0">Dashboard</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:1">Projects</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:2">Team</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:3">Billing</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:4">Settings</a>
</nav>
</div>
</div>
</section><section class="stk-16 w-full min-h-svh flex items-start justify-center px-5 py-[12vh] font-stk16-sans bg-stk16-bg" aria-label="Accordion-spread menu">
<div class="w-[min(300px,100%)]">
<input class="peer sr-only" type="checkbox" id="stk-16-t">
<label class="relative z-10 flex items-center justify-between rounded-[14px] bg-stk16-accent px-5 py-4 text-base font-extrabold text-white cursor-pointer shadow-[0_14px_30px_-16px_rgba(0,0,0,0.7)] peer-focus-visible:outline-3 peer-focus-visible:outline-white peer-focus-visible:outline-offset-3 peer-checked:[&_i]:rotate-180" for="stk-16-t">
<span>Menu</span>
<i class="text-xl not-italic leading-none transition-transform duration-350 motion-reduce:transition-none" aria-hidden="true">⌄</i>
</label>
<div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-stk16 peer-checked:grid-rows-[1fr] peer-checked:[&_a]:opacity-100 peer-checked:[&_a]:translate-y-0 motion-reduce:transition-none">
<nav class="flex flex-col gap-2 overflow-hidden pt-2" aria-label="Main">
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:0">Dashboard</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:1">Projects</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:2">Team</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:3">Billing</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:4">Settings</a>
</nav>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-stk16-bg: #101018;
--color-stk16-bg: oklch(0.18 0.012 285);
--color-stk16-item: #1c1e2a;
--color-stk16-item: oklch(0.25 0.016 285);
--color-stk16-itemh: #262a3a;
--color-stk16-itemh: oklch(0.31 0.018 285);
--color-stk16-ink: #c9cde0;
--color-stk16-ink: oklch(0.85 0.018 285);
--color-stk16-accent: #7b5fe0;
--color-stk16-accent: oklch(0.64 0.17 285);
--font-stk16-sans: 'Archivo', system-ui, sans-serif;
--ease-stk16: cubic-bezier(0.3, 0.9, 0.3, 1);
}@import "tailwindcss";
@theme {
--color-stk16-bg: #101018;
--color-stk16-bg: oklch(0.18 0.012 285);
--color-stk16-item: #1c1e2a;
--color-stk16-item: oklch(0.25 0.016 285);
--color-stk16-itemh: #262a3a;
--color-stk16-itemh: oklch(0.31 0.018 285);
--color-stk16-ink: #c9cde0;
--color-stk16-ink: oklch(0.85 0.018 285);
--color-stk16-accent: #7b5fe0;
--color-stk16-accent: oklch(0.64 0.17 285);
--font-stk16-sans: 'Archivo', system-ui, sans-serif;
--ease-stk16: cubic-bezier(0.3, 0.9, 0.3, 1);
}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-stk16-bg: #101018;
--color-stk16-bg: oklch(0.18 0.012 285);
--color-stk16-item: #1c1e2a;
--color-stk16-item: oklch(0.25 0.016 285);
--color-stk16-itemh: #262a3a;
--color-stk16-itemh: oklch(0.31 0.018 285);
--color-stk16-ink: #c9cde0;
--color-stk16-ink: oklch(0.85 0.018 285);
--color-stk16-accent: #7b5fe0;
--color-stk16-accent: oklch(0.64 0.17 285);
--font-stk16-sans: 'Archivo', system-ui, sans-serif;
--ease-stk16: cubic-bezier(0.3, 0.9, 0.3, 1);
}@import "tailwindcss";
@theme {
--color-stk16-bg: #101018;
--color-stk16-bg: oklch(0.18 0.012 285);
--color-stk16-item: #1c1e2a;
--color-stk16-item: oklch(0.25 0.016 285);
--color-stk16-itemh: #262a3a;
--color-stk16-itemh: oklch(0.31 0.018 285);
--color-stk16-ink: #c9cde0;
--color-stk16-ink: oklch(0.85 0.018 285);
--color-stk16-accent: #7b5fe0;
--color-stk16-accent: oklch(0.64 0.17 285);
--font-stk16-sans: 'Archivo', system-ui, sans-serif;
--ease-stk16: cubic-bezier(0.3, 0.9, 0.3, 1);
}<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=Archivo:wdth,wght@75..125,400;75..125,600;75..125,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=Archivo:wdth,wght@75..125,400;75..125,600;75..125,800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The webfonts load as
<link>tags insetup, not as an@importinside the stylesheet. Tailwind emits user@importrules after its own@layerblocks, and a late@importis invalid CSS — the browser drops it and the demo silently falls back to system fonts. peer-checked:[&_a]:opacity-100is the port's key lesson:peer-*only matches previous siblings, so reaching a descendant needs a selector bolted onto the variant.- The chevron is reached the same way (
peer-checked:[&_i]:rotate-180) from a checkbox that is a sibling of the label, not of the icon. - The
0fr → 1frgrid reveal is a real utility pair here, same as demo 04 — the modern way to expand toheight:auto. - Five delay rules collapse to
delay-[calc(var(--n)*40ms)], and the reduced-motion override needs the!modifier to beat it. - The whole component is one
sr-onlycheckbox, one label and five anchors — no script, noaria-expandedbookkeeping, and the native control carries the state. - The stylesheet is
@themeonly: five colours, a font and an easing curve.
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 Accordion Stacked Cards Slide Out Menu
Source: https://codefronts.com/components/tailwind-stacked-cards/tailwind-accordion-stacked-cards-slide-out-menu/
One checkbox unfurls a packed pile into a spaced menu. The reveal is the grid-rows-[0fr] → 1fr pattern again, but the interesting part is reaching the items: peer-* stops at siblings, so the links are addressed with peer-checked:[&_a]:opacity-100 — the child-selector bolt-on that is the single most common Tailwind port bug.
## HTML
```html
<section class="stk-16 w-full min-h-svh flex items-start justify-center px-5 py-[12vh] font-stk16-sans bg-stk16-bg" aria-label="Accordion-spread menu">
<div class="w-[min(300px,100%)]">
<input class="peer sr-only" type="checkbox" id="stk-16-t">
<label class="relative z-10 flex items-center justify-between rounded-[14px] bg-stk16-accent px-5 py-4 text-base font-extrabold text-white cursor-pointer shadow-[0_14px_30px_-16px_rgba(0,0,0,0.7)] peer-focus-visible:outline-3 peer-focus-visible:outline-white peer-focus-visible:outline-offset-3 peer-checked:[&_i]:rotate-180" for="stk-16-t">
<span>Menu</span>
<i class="text-xl not-italic leading-none transition-transform duration-350 motion-reduce:transition-none" aria-hidden="true">⌄</i>
</label>
<div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-stk16 peer-checked:grid-rows-[1fr] peer-checked:[&_a]:opacity-100 peer-checked:[&_a]:translate-y-0 motion-reduce:transition-none">
<nav class="flex flex-col gap-2 overflow-hidden pt-2" aria-label="Main">
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:0">Dashboard</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:1">Projects</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:2">Team</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:3">Billing</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:4">Settings</a>
</nav>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-stk16-bg: #101018;
--color-stk16-bg: oklch(0.18 0.012 285);
--color-stk16-item: #1c1e2a;
--color-stk16-item: oklch(0.25 0.016 285);
--color-stk16-itemh: #262a3a;
--color-stk16-itemh: oklch(0.31 0.018 285);
--color-stk16-ink: #c9cde0;
--color-stk16-ink: oklch(0.85 0.018 285);
--color-stk16-accent: #7b5fe0;
--color-stk16-accent: oklch(0.64 0.17 285);
--font-stk16-sans: 'Archivo', system-ui, sans-serif;
--ease-stk16: cubic-bezier(0.3, 0.9, 0.3, 1);
}
```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 Accordion Stacked Cards Slide Out Menu
Source: https://codefronts.com/components/tailwind-stacked-cards/tailwind-accordion-stacked-cards-slide-out-menu/
One checkbox unfurls a packed pile into a spaced menu. The reveal is the grid-rows-[0fr] → 1fr pattern again, but the interesting part is reaching the items: peer-* stops at siblings, so the links are addressed with peer-checked:[&_a]:opacity-100 — the child-selector bolt-on that is the single most common Tailwind port bug.
## HTML
```html
<section class="stk-16 w-full min-h-svh flex items-start justify-center px-5 py-[12vh] font-stk16-sans bg-stk16-bg" aria-label="Accordion-spread menu">
<div class="w-[min(300px,100%)]">
<input class="peer sr-only" type="checkbox" id="stk-16-t">
<label class="relative z-10 flex items-center justify-between rounded-[14px] bg-stk16-accent px-5 py-4 text-base font-extrabold text-white cursor-pointer shadow-[0_14px_30px_-16px_rgba(0,0,0,0.7)] peer-focus-visible:outline-3 peer-focus-visible:outline-white peer-focus-visible:outline-offset-3 peer-checked:[&_i]:rotate-180" for="stk-16-t">
<span>Menu</span>
<i class="text-xl not-italic leading-none transition-transform duration-350 motion-reduce:transition-none" aria-hidden="true">⌄</i>
</label>
<div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-stk16 peer-checked:grid-rows-[1fr] peer-checked:[&_a]:opacity-100 peer-checked:[&_a]:translate-y-0 motion-reduce:transition-none">
<nav class="flex flex-col gap-2 overflow-hidden pt-2" aria-label="Main">
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:0">Dashboard</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:1">Projects</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:2">Team</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:3">Billing</a>
<a class="rounded-xl bg-stk16-item px-5 py-3.75 text-[15px] font-semibold text-stk16-ink no-underline opacity-0 -translate-y-2 shadow-[0_10px_22px_-14px_rgba(0,0,0,0.8)] transition-[opacity,transform] duration-300 delay-[calc(var(--n)*40ms)] hover:bg-stk16-itemh hover:text-white focus-visible:opacity-100 focus-visible:outline-3 focus-visible:outline-stk16-accent focus-visible:outline-offset-2 motion-reduce:delay-0!" href="#" style="--n:4">Settings</a>
</nav>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-stk16-bg: #101018;
--color-stk16-bg: oklch(0.18 0.012 285);
--color-stk16-item: #1c1e2a;
--color-stk16-item: oklch(0.25 0.016 285);
--color-stk16-itemh: #262a3a;
--color-stk16-itemh: oklch(0.31 0.018 285);
--color-stk16-ink: #c9cde0;
--color-stk16-ink: oklch(0.85 0.018 285);
--color-stk16-accent: #7b5fe0;
--color-stk16-accent: oklch(0.64 0.17 285);
--font-stk16-sans: 'Archivo', system-ui, sans-serif;
--ease-stk16: cubic-bezier(0.3, 0.9, 0.3, 1);
}
```How this works
The peer gap, and the fix. The checkbox is a sibling of the bar and of the grid wrapper, so peer-checked: reaches both directly. It is not a sibling of the links inside — and no amount of variant stacking changes that. The answer is to bolt a descendant selector onto the variant:
peer-checked:[&_a]:opacity-100
peer-checked:[&_a]:translate-y-0
peer-checked:[&_i]:rotate-180Read it as ‘when my peer is checked, my descendant a gets this’. Reaching for a bare peer-checked:opacity-100 on the wrapper and expecting the children to inherit is the mistake, and it fails silently.
The stagger is a calc, and reduced motion needs a shout. Each link carries --n and delay-[calc(var(--n)*40ms)]. Because that is a real declaration on the element, motion-reduce:delay-0 at equal specificity is not guaranteed to win against source order — hence motion-reduce:delay-0!, which is the utility equivalent of the CSS version's transition-delay:0s!important.
State is reflected, not just drawn. The checkbox is a real focusable control with a label, so the disclosure opens by keyboard and announces itself; the items stay in flow and reachable rather than being hidden behind visibility tricks that would strand focus.
Make it yours
- Change the packed-to-open spacing through the list's
gap-2and the item padding. - Set the unfurl speed via the
40msin the delay calc. - Swap the items for real nav links — they already are anchors, so only the copy changes.
- Recolour the bar through
--color-stk16-accent; the focus ring on each item reads the same token. - Start open by adding
checkedto the input.
Gotchas — read before shipping
peer-checked:opacity-100on a wrapper does not reach its children. You need the[&_a]descendant bolt-on, and this is the most common port bug in the whole collection.motion-reduce:delay-0needs the!modifier to beat a per-element delay calc reliably.- Keep the checkbox
sr-onlyand labelled, or the menu cannot be opened from the keyboard at all. overflow-hiddenon the inner list is required for the0frrow to actually clip.- Collapsed items stay in flow and focusable here; if you hide them with
opacity-0alone, addinertor a tab user will focus invisible links. - The chevron is a decorative
<i>— mark itaria-hiddenso it is not announced as a character.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Checkbox :checked sibling styling is universal; animating grid-template-rows to 0fr/1fr needs Chrome 107+, Safari 16+, Firefox 66+ and snaps open where unsupported.