31 / 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 Isometric Overlapping Stacked Cards
Three pricing planes floated on a true isometric grid, sliding apart on hover so every price stays readable. The port keeps the geometry in arbitrary properties where it belongs, and the accessibility work is the substantive part: prices are legible at rest, and under reduced motion the whole plane flattens to rotate-none rather than merely animating slower.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="stk-31 grid w-full min-h-svh place-items-center px-5 py-15 font-stk31-mono bg-stk31-bg [background-image:radial-gradient(circle_at_50%_30%,var(--color-stk31-glow),transparent_70%)]" aria-label="Pricing plans, isometric view">
<div class="group relative h-105 w-85 [perspective:1400px]">
<div class="relative size-full [transform-style:preserve-3d] [transform:rotateX(52deg)_rotateZ(-34deg)] transition-transform duration-700 ease-stk31 group-hover:[transform:rotateX(46deg)_rotateZ(-28deg)] motion-reduce:transition-none motion-reduce:rotate-none!">
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-stk31-dark [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t3a),var(--color-stk31-t3b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(12px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(12px)_translate(150px,150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">SCALE</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">Unlimited seats · SSO · SLA</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$79<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t2a),var(--color-stk31-t2b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(24px)] transition-transform duration-650 ease-stk31 motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">GROWTH</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">10 seats · analytics · API</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$29<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t1a),var(--color-stk31-t1b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(36px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(36px)_translate(-150px,-150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">STARTER</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">1 seat · core features</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$9<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
</div>
<span class="absolute bottom-2.5 left-1/2 -translate-x-1/2 text-[0.72rem] tracking-[0.18em] text-stk31-hint transition-opacity duration-400 group-hover:opacity-0">HOVER TO COMPARE PLANS</span>
</div>
</section><section class="stk-31 grid w-full min-h-svh place-items-center px-5 py-15 font-stk31-mono bg-stk31-bg [background-image:radial-gradient(circle_at_50%_30%,var(--color-stk31-glow),transparent_70%)]" aria-label="Pricing plans, isometric view">
<div class="group relative h-105 w-85 [perspective:1400px]">
<div class="relative size-full [transform-style:preserve-3d] [transform:rotateX(52deg)_rotateZ(-34deg)] transition-transform duration-700 ease-stk31 group-hover:[transform:rotateX(46deg)_rotateZ(-28deg)] motion-reduce:transition-none motion-reduce:rotate-none!">
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-stk31-dark [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t3a),var(--color-stk31-t3b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(12px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(12px)_translate(150px,150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">SCALE</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">Unlimited seats · SSO · SLA</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$79<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t2a),var(--color-stk31-t2b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(24px)] transition-transform duration-650 ease-stk31 motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">GROWTH</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">10 seats · analytics · API</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$29<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t1a),var(--color-stk31-t1b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(36px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(36px)_translate(-150px,-150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">STARTER</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">1 seat · core features</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$9<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
</div>
<span class="absolute bottom-2.5 left-1/2 -translate-x-1/2 text-[0.72rem] tracking-[0.18em] text-stk31-hint transition-opacity duration-400 group-hover:opacity-0">HOVER TO COMPARE PLANS</span>
</div>
</section>@import "tailwindcss";
@theme {
--color-stk31-bg: #0a0c14;
--color-stk31-bg: oklch(0.13 0.016 275);
--color-stk31-glow: #191d2e;
--color-stk31-glow: oklch(0.23 0.028 275);
--color-stk31-hint: #5b6480;
--color-stk31-hint: oklch(0.52 0.030 275);
--color-stk31-dark: #03241c;
--color-stk31-dark: oklch(0.24 0.050 165);
--color-stk31-t1a: #3a4cf0;
--color-stk31-t1b: #6d7cff;
--color-stk31-t2a: #f0466b;
--color-stk31-t2b: #ff7aa0;
--color-stk31-t3a: #11b894;
--color-stk31-t3b: #46f0c4;
--font-stk31-mono: 'DM Mono', ui-monospace, monospace;
--font-stk31-display: 'Space Grotesk', system-ui, sans-serif;
--ease-stk31: cubic-bezier(0.3, 0.9, 0.3, 1);
}@import "tailwindcss";
@theme {
--color-stk31-bg: #0a0c14;
--color-stk31-bg: oklch(0.13 0.016 275);
--color-stk31-glow: #191d2e;
--color-stk31-glow: oklch(0.23 0.028 275);
--color-stk31-hint: #5b6480;
--color-stk31-hint: oklch(0.52 0.030 275);
--color-stk31-dark: #03241c;
--color-stk31-dark: oklch(0.24 0.050 165);
--color-stk31-t1a: #3a4cf0;
--color-stk31-t1b: #6d7cff;
--color-stk31-t2a: #f0466b;
--color-stk31-t2b: #ff7aa0;
--color-stk31-t3a: #11b894;
--color-stk31-t3b: #46f0c4;
--font-stk31-mono: 'DM Mono', ui-monospace, monospace;
--font-stk31-display: 'Space Grotesk', system-ui, sans-serif;
--ease-stk31: 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-stk31-bg: #0a0c14;
--color-stk31-bg: oklch(0.13 0.016 275);
--color-stk31-glow: #191d2e;
--color-stk31-glow: oklch(0.23 0.028 275);
--color-stk31-hint: #5b6480;
--color-stk31-hint: oklch(0.52 0.030 275);
--color-stk31-dark: #03241c;
--color-stk31-dark: oklch(0.24 0.050 165);
--color-stk31-t1a: #3a4cf0;
--color-stk31-t1b: #6d7cff;
--color-stk31-t2a: #f0466b;
--color-stk31-t2b: #ff7aa0;
--color-stk31-t3a: #11b894;
--color-stk31-t3b: #46f0c4;
--font-stk31-mono: 'DM Mono', ui-monospace, monospace;
--font-stk31-display: 'Space Grotesk', system-ui, sans-serif;
--ease-stk31: cubic-bezier(0.3, 0.9, 0.3, 1);
}@import "tailwindcss";
@theme {
--color-stk31-bg: #0a0c14;
--color-stk31-bg: oklch(0.13 0.016 275);
--color-stk31-glow: #191d2e;
--color-stk31-glow: oklch(0.23 0.028 275);
--color-stk31-hint: #5b6480;
--color-stk31-hint: oklch(0.52 0.030 275);
--color-stk31-dark: #03241c;
--color-stk31-dark: oklch(0.24 0.050 165);
--color-stk31-t1a: #3a4cf0;
--color-stk31-t1b: #6d7cff;
--color-stk31-t2a: #f0466b;
--color-stk31-t2b: #ff7aa0;
--color-stk31-t3a: #11b894;
--color-stk31-t3b: #46f0c4;
--font-stk31-mono: 'DM Mono', ui-monospace, monospace;
--font-stk31-display: 'Space Grotesk', system-ui, sans-serif;
--ease-stk31: 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=Space+Grotesk:wght@500;700&family=DM+Mono:wght@400&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@500;700&family=DM+Mono:wght@400&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. - Both isometric rotations stay in one arbitrary transform on the plane, and the stage above it owns
[perspective:1400px]— the division that every 3D demo in this collection repeats. - The hover spread moves each tier equally on both axes, which is what keeps it sliding along the projected grid instead of off it.
motion-reduce:rotate-none!flattens the projection outright: for a rotation-driven effect the right accommodation is removing the rotation, not slowing it.- Every price is legible at rest, because on touch there is no hover and hover-gated pricing is simply missing information.
- The light mint tier switches to
text-stk31-dark; contrast has to be checked per plane, not once for the palette. - Hover is scoped to the stage rather than to each tier, which avoids the fan-versus-lift fight documented in demo 28.
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 Isometric Overlapping Stacked Cards
Source: https://codefronts.com/components/tailwind-stacked-cards/tailwind-isometric-overlapping-stacked-cards/
Three pricing planes floated on a true isometric grid, sliding apart on hover so every price stays readable. The port keeps the geometry in arbitrary properties where it belongs, and the accessibility work is the substantive part: prices are legible at rest, and under reduced motion the whole plane flattens to rotate-none rather than merely animating slower.
## HTML
```html
<section class="stk-31 grid w-full min-h-svh place-items-center px-5 py-15 font-stk31-mono bg-stk31-bg [background-image:radial-gradient(circle_at_50%_30%,var(--color-stk31-glow),transparent_70%)]" aria-label="Pricing plans, isometric view">
<div class="group relative h-105 w-85 [perspective:1400px]">
<div class="relative size-full [transform-style:preserve-3d] [transform:rotateX(52deg)_rotateZ(-34deg)] transition-transform duration-700 ease-stk31 group-hover:[transform:rotateX(46deg)_rotateZ(-28deg)] motion-reduce:transition-none motion-reduce:rotate-none!">
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-stk31-dark [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t3a),var(--color-stk31-t3b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(12px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(12px)_translate(150px,150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">SCALE</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">Unlimited seats · SSO · SLA</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$79<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t2a),var(--color-stk31-t2b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(24px)] transition-transform duration-650 ease-stk31 motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">GROWTH</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">10 seats · analytics · API</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$29<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t1a),var(--color-stk31-t1b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(36px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(36px)_translate(-150px,-150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">STARTER</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">1 seat · core features</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$9<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
</div>
<span class="absolute bottom-2.5 left-1/2 -translate-x-1/2 text-[0.72rem] tracking-[0.18em] text-stk31-hint transition-opacity duration-400 group-hover:opacity-0">HOVER TO COMPARE PLANS</span>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-stk31-bg: #0a0c14;
--color-stk31-bg: oklch(0.13 0.016 275);
--color-stk31-glow: #191d2e;
--color-stk31-glow: oklch(0.23 0.028 275);
--color-stk31-hint: #5b6480;
--color-stk31-hint: oklch(0.52 0.030 275);
--color-stk31-dark: #03241c;
--color-stk31-dark: oklch(0.24 0.050 165);
--color-stk31-t1a: #3a4cf0;
--color-stk31-t1b: #6d7cff;
--color-stk31-t2a: #f0466b;
--color-stk31-t2b: #ff7aa0;
--color-stk31-t3a: #11b894;
--color-stk31-t3b: #46f0c4;
--font-stk31-mono: 'DM Mono', ui-monospace, monospace;
--font-stk31-display: 'Space Grotesk', system-ui, sans-serif;
--ease-stk31: 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 Isometric Overlapping Stacked Cards
Source: https://codefronts.com/components/tailwind-stacked-cards/tailwind-isometric-overlapping-stacked-cards/
Three pricing planes floated on a true isometric grid, sliding apart on hover so every price stays readable. The port keeps the geometry in arbitrary properties where it belongs, and the accessibility work is the substantive part: prices are legible at rest, and under reduced motion the whole plane flattens to rotate-none rather than merely animating slower.
## HTML
```html
<section class="stk-31 grid w-full min-h-svh place-items-center px-5 py-15 font-stk31-mono bg-stk31-bg [background-image:radial-gradient(circle_at_50%_30%,var(--color-stk31-glow),transparent_70%)]" aria-label="Pricing plans, isometric view">
<div class="group relative h-105 w-85 [perspective:1400px]">
<div class="relative size-full [transform-style:preserve-3d] [transform:rotateX(52deg)_rotateZ(-34deg)] transition-transform duration-700 ease-stk31 group-hover:[transform:rotateX(46deg)_rotateZ(-28deg)] motion-reduce:transition-none motion-reduce:rotate-none!">
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-stk31-dark [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t3a),var(--color-stk31-t3b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(12px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(12px)_translate(150px,150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">SCALE</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">Unlimited seats · SSO · SLA</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$79<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t2a),var(--color-stk31-t2b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(24px)] transition-transform duration-650 ease-stk31 motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">GROWTH</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">10 seats · analytics · API</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$29<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
<div class="absolute left-12.5 top-30 flex h-37.5 w-60 flex-col justify-between rounded-[18px] p-5.5 text-white [transform-style:preserve-3d] bg-linear-[135deg,var(--color-stk31-t1a),var(--color-stk31-t1b)] shadow-[0_36px_60px_rgba(0,0,0,0.55)] [transform:translateZ(36px)] transition-transform duration-650 ease-stk31 group-hover:[transform:translateZ(36px)_translate(-150px,-150px)] motion-reduce:transition-none motion-reduce:rotate-none!">
<span class="font-stk31-display text-[1.15rem] font-bold tracking-[0.04em]">STARTER</span>
<span class="text-[0.72rem] leading-relaxed opacity-90">1 seat · core features</span>
<span class="font-stk31-display text-[2.1rem] font-bold leading-none">$9<small class="text-[0.85rem] opacity-75">/mo</small></span>
</div>
</div>
<span class="absolute bottom-2.5 left-1/2 -translate-x-1/2 text-[0.72rem] tracking-[0.18em] text-stk31-hint transition-opacity duration-400 group-hover:opacity-0">HOVER TO COMPARE PLANS</span>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-stk31-bg: #0a0c14;
--color-stk31-bg: oklch(0.13 0.016 275);
--color-stk31-glow: #191d2e;
--color-stk31-glow: oklch(0.23 0.028 275);
--color-stk31-hint: #5b6480;
--color-stk31-hint: oklch(0.52 0.030 275);
--color-stk31-dark: #03241c;
--color-stk31-dark: oklch(0.24 0.050 165);
--color-stk31-t1a: #3a4cf0;
--color-stk31-t1b: #6d7cff;
--color-stk31-t2a: #f0466b;
--color-stk31-t2b: #ff7aa0;
--color-stk31-t3a: #11b894;
--color-stk31-t3b: #46f0c4;
--font-stk31-mono: 'DM Mono', ui-monospace, monospace;
--font-stk31-display: 'Space Grotesk', system-ui, sans-serif;
--ease-stk31: cubic-bezier(0.3, 0.9, 0.3, 1);
}
```How this works
Two rotations make the grid. rotateX(52deg) tips the plane away and rotateZ(-34deg) turns it, which together read as isometric. Both live on the plane; [perspective:1400px] lives on the stage above it. Swap those two and the 3D collapses into a flat skew — the same failure as demos 06, 22 and 23, and worth internalising once.
Depth and spread are one property each. Each tier sits at its own translateZ and slides along the isometric axis on hover:
[transform:translateZ(36px)]
group-hover:[transform:translateZ(36px)_translate(-150px,-150px)]Moving on both axes equally is what makes the tier appear to slide along the projected grid rather than off it.
Prices must be readable without hovering. An isometric projection foreshortens text, and a pricing table whose numbers only resolve on hover is unusable on touch — where there is no hover at all. Each plane is sized and angled so its tier, features and price are legible at rest; the hover spread is an enhancement that separates them further.
Reduced motion flattens the geometry. motion-reduce:rotate-none! on the plane and on each tier removes the projection, leaving three plainly stacked cards. That is a better accommodation than a slow tilt, because the discomfort comes from the rotation itself.
Make it yours
- Change the isometric angle via
rotateX(52deg)_rotateZ(-34deg); 60/−45 is textbook isometric, softer angles feel friendlier. - Adjust the hover spread with the
±150pxtranslate; keep the two axes equal to stay on the projected grid. - Tune the depth stack with the three
translateZvalues. - Rebrand each tier through its own
bg-linear-[...]pair of tokens. - Add a ‘most popular’ marker to the middle tier as an absolutely-positioned ribbon inside that plane.
Gotchas — read before shipping
perspectiveon the stage,preserve-3don the plane. Perspective on the rotating element flattens everything.- Show the prices at rest. On touch there is no hover, so hover-gated pricing information is simply missing.
- Check contrast on the projected card, not the swatch — the light mint tier needs dark ink to clear 4.5:1.
- The reduced-motion override needs
!to beat the arbitrary transforms at equal specificity. - Keep the hover spread inside the stage's box, or tiers slide out of view on smaller screens.
- Hover on the stage, not on each tier: per-tier hover here would cause the same fight-and-flicker as demo 28.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
3D transforms, preserve-3d and perspective are universally supported (Chrome 36+, Safari 9+, Firefox 16+) with no prefixes. The floor is Tailwind v4's own generated sheet.