23 Tailwind CSS Flip Cards
02 / 23

All 23 in 23 Tailwind CSS Flip Cards

  1. 01Tailwind Product Comparison Flip Card with Hover, Tap & Keyboard Reveal
  2. 02Tailwind Pricing Plan Flip Card with Gradient Price & Feature Reveal
  3. 03Tailwind Gift Card Flip with Copy-to-Clipboard Coupon Code Reveal
  4. 04Tailwind Meet the Team Flip Card with Bio, Socials & Contact Reveal
  5. 05Tailwind Portfolio Flip Card with Animated Skill Bar Proficiency Meters
  6. 06Tailwind Language Flashcard Flip with Phonetics, Example & Memory Tip
  7. 07Tailwind Trivia Quiz Flip Card with Answer Reveal & Score Readout
  8. 08Tailwind Gaming Trading Card Flip with Character Stats & Rarity Glow
  9. 09Tailwind Photo Gallery Flip Card with EXIF Metadata & Download CTA
  10. 10Tailwind Video Thumbnail Flip Card with Playlist, Stats & Watch CTA
  11. 11Tailwind Testimonial Flip Card with Star Rating & Reviewer Profile
  12. 12Tailwind Digital Business Card Flip with vCard Contacts & QR Panel
  13. 13Tailwind Restaurant Menu Card with Sliding Ingredient & Nutrition Reveal
  14. 14Tailwind Process Steps Flip Card Grid with Task Lists & Timelines
  15. 15Tailwind Vertical Axis Flip Card with rotateX Top-to-Bottom Reveal
  16. 16Tailwind Click-to-Flip Card with Persisted State & Keyboard Control
  17. 17Tailwind Auto-Height Flip Card with CSS Grid Stacking & Cross-Fade
  18. 18Tailwind Responsive Flip Card Grid with Per-Card 3D Perspective
  19. 19Tailwind Luxury Product Card with Hinged Book-Open 3D Unfold
  20. 20Tailwind Travel Postcard Flip Card with Diagonal rotate3d Twist
  21. 21Tailwind Album Card with clip-path Iris Aperture Reveal (No 3D)
  22. 22Tailwind Event Ticket Card with Bi-Fold Stub Reveal & QR Panel
  23. 23Tailwind Scratch Card with Diagonal clip-path Peel & Prize Reveal
Pure TailwindMIT licensed

Tailwind Pricing Plan Flip Card with Gradient Price & Feature Reveal

A SaaS pricing tier that lifts from its base rather than spinning around its centre: the top edge swings toward the camera on rotateX while the bottom stays anchored, revealing the full feature ledger. The gradient price survives the port as bg-linear-135 bg-clip-text text-transparent, three utilities where the CSS needed four prefixed declarations.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tfc-02 w-full min-h-svh grid place-items-center bg-tfc02-bg font-tfc02-sans px-5 py-10 text-tfc02-ink">
  <div class="group relative w-[320px] h-[470px] [perspective:1200px] rounded-3xl has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-tfc02-acc has-[:focus-visible]:outline-offset-4">
    <input id="tfc-02-flip" type="checkbox" class="peer sr-only">
    <label for="tfc-02-flip" class="absolute inset-0 z-20 cursor-pointer rounded-3xl"><span class="sr-only">Show the full Pro plan feature list</span></label>

    <div class="relative w-full h-full origin-bottom transition-transform duration-[850ms] ease-[cubic-bezier(.34,1.2,.4,1)] [transform-style:preserve-3d] group-hover:[transform:translateY(-100%)_rotateX(180deg)] group-has-checked:[transform:translateY(-100%)_rotateX(180deg)] group-has-[:focus-visible]:[transform:translateY(-100%)_rotateX(180deg)] motion-reduce:transition-none">

      <div class="absolute inset-0 flex flex-col rounded-3xl overflow-hidden bg-linear-160 from-tfc02-panel to-tfc02-panel2 border border-tfc02-edge shadow-[0_1px_2px_oklch(0_0_0/0.45),0_24px_50px_-16px_oklch(0.55_0.15_165/0.25)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden]">
        <div aria-hidden="true" class="pointer-events-none absolute -top-16 left-1/2 size-52 -translate-x-1/2 bg-[radial-gradient(circle,oklch(0.7_0.15_165/0.25),transparent_70%)]"></div>
        <div class="relative px-7 pt-8 pb-6 text-center">
          <div class="mx-auto mb-4 grid size-14 place-items-center rounded-2xl border border-tfc02-edge bg-linear-135 from-tfc02-acc/20 to-tfc02-acc/5">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" class="text-tfc02-acc" aria-hidden="true"><path d="M5 19l3-8 8-3-3 8-8 3z"/><path d="M12 12l6-6"/></svg>
          </div>
          <p class="mb-2 text-[11px] font-bold uppercase tracking-[0.2em] text-tfc02-acc">Pro Plan</p>
          <p class="flex items-baseline justify-center gap-1">
            <span class="mt-1.5 text-xl font-bold text-tfc02-muted">$</span>
            <span class="bg-linear-135 from-tfc02-acc to-tfc02-acc3 bg-clip-text text-[52px] font-black leading-none tracking-[-0.03em] text-transparent">49</span>
          </p>
          <p class="mt-1.5 text-[13px] text-tfc02-muted">per month, billed annually</p>
        </div>
        <div class="mx-7 h-px bg-linear-to-r from-transparent via-tfc02-acc/25 to-transparent"></div>
        <div class="flex-1 px-7 py-6">
          <p class="mb-3.5 text-[10px] uppercase tracking-[0.12em] text-tfc02-dim">Includes</p>
          <ul class="flex flex-col gap-2.5 text-[13px] text-tfc02-muted">
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Unlimited projects</li>
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Advanced analytics</li>
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Priority support</li>
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Custom domains</li>
          </ul>
        </div>
        <p class="px-7 pb-6 text-center text-[11px] tracking-[0.08em] text-tfc02-dim">Hover, tap or press Space for all features</p>
      </div>

      <div class="absolute inset-0 flex flex-col rounded-3xl overflow-hidden p-7 bg-linear-160 from-tfc02-back to-tfc02-back2 border border-tfc02-edge2 shadow-[0_1px_2px_oklch(0_0_0/0.45),0_24px_50px_-16px_oklch(0.5_0.2_295/0.3)] [transform:rotateX(180deg)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden]">
        <h3 class="mb-5 text-[13px] font-bold uppercase tracking-[0.12em] text-tfc02-purple">Everything in Pro</h3>
        <ul class="flex flex-1 flex-col gap-2.5 text-[13px] text-tfc02-ink/80">
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Unlimited projects &amp; workspaces</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Advanced real-time analytics</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Custom domain mapping</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>API access (10k req/day)</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Priority 4h support SLA</li>
          <li class="flex items-center gap-3 rounded-xl border border-tfc02-gold/20 bg-tfc02-gold/6 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-gold/30 bg-tfc02-gold/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-gold stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>AI content generation (50/mo)</li>
          <li class="flex items-center gap-3 rounded-xl border border-tfc02-gold/20 bg-tfc02-gold/6 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-gold/30 bg-tfc02-gold/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-gold stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>White-label exports</li>
        </ul>
        <button type="button" class="relative z-30 mt-5 min-h-11 w-full rounded-xl bg-linear-135 from-tfc02-acc to-tfc02-acc2 text-sm font-extrabold tracking-[0.04em] text-black transition-transform duration-150 hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 motion-reduce:hover:translate-y-0">Get Started &mdash; $49/mo</button>
      </div>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tfc02-bg: #050d0a;
  --color-tfc02-bg: oklch(0.14 0.02 165);
  --color-tfc02-panel: #071a12;
  --color-tfc02-panel: oklch(0.19 0.04 165);
  --color-tfc02-panel2: #0a2e1e;
  --color-tfc02-panel2: oklch(0.26 0.06 165);
  --color-tfc02-back: #0a0a1e;
  --color-tfc02-back: oklch(0.17 0.04 285);
  --color-tfc02-back2: #0d1533;
  --color-tfc02-back2: oklch(0.21 0.07 275);
  --color-tfc02-acc: #10b981;
  --color-tfc02-acc: oklch(0.72 0.16 165);
  --color-tfc02-acc2: #059669;
  --color-tfc02-acc2: oklch(0.61 0.14 165);
  --color-tfc02-acc3: #34d399;
  --color-tfc02-acc3: oklch(0.8 0.14 165);
  --color-tfc02-gold: #f59e0b;
  --color-tfc02-gold: oklch(0.77 0.16 70);
  --color-tfc02-purple: #8b5cf6;
  --color-tfc02-purple: oklch(0.63 0.2 295);
  --color-tfc02-ink: #f0fdf4;
  --color-tfc02-ink: oklch(0.98 0.02 160);
  --color-tfc02-muted: #9fd9bd;
  --color-tfc02-muted: oklch(0.82 0.06 165);
  --color-tfc02-dim: #77a691;
  --color-tfc02-dim: oklch(0.68 0.04 165);
  --color-tfc02-edge: #17553c;
  --color-tfc02-edge: oklch(0.4 0.09 165);
  --color-tfc02-edge2: #453089;
  --color-tfc02-edge2: oklch(0.4 0.14 292);
  --font-tfc02-sans: 'Sora', system-ui, sans-serif;
}

.tfc-02 {
  width: 100%;
  min-height: 100svh;
}

@media (prefers-reduced-motion: reduce) {
  .tfc-02 * {
    transition-duration: 1ms !important;
  }
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tfc02-bg: #050d0a;
  --color-tfc02-bg: oklch(0.14 0.02 165);
  --color-tfc02-panel: #071a12;
  --color-tfc02-panel: oklch(0.19 0.04 165);
  --color-tfc02-panel2: #0a2e1e;
  --color-tfc02-panel2: oklch(0.26 0.06 165);
  --color-tfc02-back: #0a0a1e;
  --color-tfc02-back: oklch(0.17 0.04 285);
  --color-tfc02-back2: #0d1533;
  --color-tfc02-back2: oklch(0.21 0.07 275);
  --color-tfc02-acc: #10b981;
  --color-tfc02-acc: oklch(0.72 0.16 165);
  --color-tfc02-acc2: #059669;
  --color-tfc02-acc2: oklch(0.61 0.14 165);
  --color-tfc02-acc3: #34d399;
  --color-tfc02-acc3: oklch(0.8 0.14 165);
  --color-tfc02-gold: #f59e0b;
  --color-tfc02-gold: oklch(0.77 0.16 70);
  --color-tfc02-purple: #8b5cf6;
  --color-tfc02-purple: oklch(0.63 0.2 295);
  --color-tfc02-ink: #f0fdf4;
  --color-tfc02-ink: oklch(0.98 0.02 160);
  --color-tfc02-muted: #9fd9bd;
  --color-tfc02-muted: oklch(0.82 0.06 165);
  --color-tfc02-dim: #77a691;
  --color-tfc02-dim: oklch(0.68 0.04 165);
  --color-tfc02-edge: #17553c;
  --color-tfc02-edge: oklch(0.4 0.09 165);
  --color-tfc02-edge2: #453089;
  --color-tfc02-edge2: oklch(0.4 0.14 292);
  --font-tfc02-sans: 'Sora', system-ui, sans-serif;
}

.tfc-02 {
  width: 100%;
  min-height: 100svh;
}

@media (prefers-reduced-motion: reduce) {
  .tfc-02 * {
    transition-duration: 1ms !important;
  }
}
3Fonts used by this demooptional — skip if you have your own type stack
<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=Sora:wght@400;600;700;800;900&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • The base hinge is the one place where the port is LONGER than the CSS: the counter-translate has to be restated in all three trigger variants. A @theme-level custom property would dedupe it, at the cost of hiding the gesture from the markup — not worth it for a value read three times in one element.
  • -webkit-background-clip and -webkit-text-fill-color disappear entirely: bg-clip-text text-transparent emits both, which removes the demo's most-reported iOS bug by construction.
  • UI change from the CSS original: the emoji tier icon became a stroked SVG (emoji render differently per platform and break the card's type), the feature list became a real <ul>, shadows are now tinted with the tier colour, and the gold rows carry a tinted border so the highlight survives greyscale printing.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 Pricing Plan Flip Card with Gradient Price & Feature Reveal
Source: https://codefronts.com/components/tailwind-css-flip-cards/tailwind-pricing-plan-flip-card-gradient-price-feature-reveal/

A SaaS pricing tier that lifts from its base rather than spinning around its centre: the top edge swings toward the camera on rotateX while the bottom stays anchored, revealing the full feature ledger. The gradient price survives the port as bg-linear-135 bg-clip-text text-transparent, three utilities where the CSS needed four prefixed declarations.
## HTML
```html
<section class="tfc-02 w-full min-h-svh grid place-items-center bg-tfc02-bg font-tfc02-sans px-5 py-10 text-tfc02-ink">
  <div class="group relative w-[320px] h-[470px] [perspective:1200px] rounded-3xl has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-tfc02-acc has-[:focus-visible]:outline-offset-4">
    <input id="tfc-02-flip" type="checkbox" class="peer sr-only">
    <label for="tfc-02-flip" class="absolute inset-0 z-20 cursor-pointer rounded-3xl"><span class="sr-only">Show the full Pro plan feature list</span></label>

    <div class="relative w-full h-full origin-bottom transition-transform duration-[850ms] ease-[cubic-bezier(.34,1.2,.4,1)] [transform-style:preserve-3d] group-hover:[transform:translateY(-100%)_rotateX(180deg)] group-has-checked:[transform:translateY(-100%)_rotateX(180deg)] group-has-[:focus-visible]:[transform:translateY(-100%)_rotateX(180deg)] motion-reduce:transition-none">

      <div class="absolute inset-0 flex flex-col rounded-3xl overflow-hidden bg-linear-160 from-tfc02-panel to-tfc02-panel2 border border-tfc02-edge shadow-[0_1px_2px_oklch(0_0_0/0.45),0_24px_50px_-16px_oklch(0.55_0.15_165/0.25)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden]">
        <div aria-hidden="true" class="pointer-events-none absolute -top-16 left-1/2 size-52 -translate-x-1/2 bg-[radial-gradient(circle,oklch(0.7_0.15_165/0.25),transparent_70%)]"></div>
        <div class="relative px-7 pt-8 pb-6 text-center">
          <div class="mx-auto mb-4 grid size-14 place-items-center rounded-2xl border border-tfc02-edge bg-linear-135 from-tfc02-acc/20 to-tfc02-acc/5">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" class="text-tfc02-acc" aria-hidden="true"><path d="M5 19l3-8 8-3-3 8-8 3z"/><path d="M12 12l6-6"/></svg>
          </div>
          <p class="mb-2 text-[11px] font-bold uppercase tracking-[0.2em] text-tfc02-acc">Pro Plan</p>
          <p class="flex items-baseline justify-center gap-1">
            <span class="mt-1.5 text-xl font-bold text-tfc02-muted">$</span>
            <span class="bg-linear-135 from-tfc02-acc to-tfc02-acc3 bg-clip-text text-[52px] font-black leading-none tracking-[-0.03em] text-transparent">49</span>
          </p>
          <p class="mt-1.5 text-[13px] text-tfc02-muted">per month, billed annually</p>
        </div>
        <div class="mx-7 h-px bg-linear-to-r from-transparent via-tfc02-acc/25 to-transparent"></div>
        <div class="flex-1 px-7 py-6">
          <p class="mb-3.5 text-[10px] uppercase tracking-[0.12em] text-tfc02-dim">Includes</p>
          <ul class="flex flex-col gap-2.5 text-[13px] text-tfc02-muted">
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Unlimited projects</li>
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Advanced analytics</li>
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Priority support</li>
            <li class="flex items-center gap-2.5 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc02-acc">Custom domains</li>
          </ul>
        </div>
        <p class="px-7 pb-6 text-center text-[11px] tracking-[0.08em] text-tfc02-dim">Hover, tap or press Space for all features</p>
      </div>

      <div class="absolute inset-0 flex flex-col rounded-3xl overflow-hidden p-7 bg-linear-160 from-tfc02-back to-tfc02-back2 border border-tfc02-edge2 shadow-[0_1px_2px_oklch(0_0_0/0.45),0_24px_50px_-16px_oklch(0.5_0.2_295/0.3)] [transform:rotateX(180deg)] [backface-visibility:hidden] [-webkit-backface-visibility:hidden]">
        <h3 class="mb-5 text-[13px] font-bold uppercase tracking-[0.12em] text-tfc02-purple">Everything in Pro</h3>
        <ul class="flex flex-1 flex-col gap-2.5 text-[13px] text-tfc02-ink/80">
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Unlimited projects &amp; workspaces</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Advanced real-time analytics</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Custom domain mapping</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>API access (10k req/day)</li>
          <li class="flex items-center gap-3 rounded-xl border border-white/6 bg-white/3 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-acc/30 bg-tfc02-acc/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-acc stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>Priority 4h support SLA</li>
          <li class="flex items-center gap-3 rounded-xl border border-tfc02-gold/20 bg-tfc02-gold/6 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-gold/30 bg-tfc02-gold/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-gold stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>AI content generation (50/mo)</li>
          <li class="flex items-center gap-3 rounded-xl border border-tfc02-gold/20 bg-tfc02-gold/6 px-3.5 py-2.5"><span class="grid size-5 shrink-0 place-items-center rounded-md border border-tfc02-gold/30 bg-tfc02-gold/15"><svg viewBox="0 0 12 12" class="size-3 fill-none stroke-tfc02-gold stroke-[2.5]" aria-hidden="true"><polyline points="2,6 5,9 10,3"/></svg></span>White-label exports</li>
        </ul>
        <button type="button" class="relative z-30 mt-5 min-h-11 w-full rounded-xl bg-linear-135 from-tfc02-acc to-tfc02-acc2 text-sm font-extrabold tracking-[0.04em] text-black transition-transform duration-150 hover:-translate-y-px focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2 motion-reduce:hover:translate-y-0">Get Started &mdash; $49/mo</button>
      </div>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tfc02-bg: #050d0a;
  --color-tfc02-bg: oklch(0.14 0.02 165);
  --color-tfc02-panel: #071a12;
  --color-tfc02-panel: oklch(0.19 0.04 165);
  --color-tfc02-panel2: #0a2e1e;
  --color-tfc02-panel2: oklch(0.26 0.06 165);
  --color-tfc02-back: #0a0a1e;
  --color-tfc02-back: oklch(0.17 0.04 285);
  --color-tfc02-back2: #0d1533;
  --color-tfc02-back2: oklch(0.21 0.07 275);
  --color-tfc02-acc: #10b981;
  --color-tfc02-acc: oklch(0.72 0.16 165);
  --color-tfc02-acc2: #059669;
  --color-tfc02-acc2: oklch(0.61 0.14 165);
  --color-tfc02-acc3: #34d399;
  --color-tfc02-acc3: oklch(0.8 0.14 165);
  --color-tfc02-gold: #f59e0b;
  --color-tfc02-gold: oklch(0.77 0.16 70);
  --color-tfc02-purple: #8b5cf6;
  --color-tfc02-purple: oklch(0.63 0.2 295);
  --color-tfc02-ink: #f0fdf4;
  --color-tfc02-ink: oklch(0.98 0.02 160);
  --color-tfc02-muted: #9fd9bd;
  --color-tfc02-muted: oklch(0.82 0.06 165);
  --color-tfc02-dim: #77a691;
  --color-tfc02-dim: oklch(0.68 0.04 165);
  --color-tfc02-edge: #17553c;
  --color-tfc02-edge: oklch(0.4 0.09 165);
  --color-tfc02-edge2: #453089;
  --color-tfc02-edge2: oklch(0.4 0.14 292);
  --font-tfc02-sans: 'Sora', system-ui, sans-serif;
}

.tfc-02 {
  width: 100%;
  min-height: 100svh;
}

@media (prefers-reduced-motion: reduce) {
  .tfc-02 * {
    transition-duration: 1ms !important;
  }
}
```

How this works

Rotating around the base needs a counter-translate. With origin-bottom, a 180° rotateX swings the top edge down through the space below the card — the card renders one full height lower than it started. translateY(-100%) applied first in the transform list cancels exactly that, so the card appears to lift and turn in place. Both values live in one arbitrary property, which is the honest way to write it: they are a single gesture, not two.

The back is pre-rotated on X, not Y. [transform:rotateX(180deg)] at rest, cancelled when the card completes its turn. Swapping axis without swapping the pre-rotation is what produces upside-down feature lists.

Gradient text is now three utilities. bg-clip-text plus text-transparent over a bg-linear-* emits the -webkit- pair automatically, so the Safari-invisible-text failure mode of the hand-written version cannot happen here.

Make it yours

  • Tier colour is one token: --color-tfc02-acc drives the price gradient, the bullet dots, the check tiles and the CTA.
  • Make it a standard spin: replace [transform:translateY(-100%)_rotateX(180deg)] with [transform:rotateY(180deg)] and the back's pre-rotation to match — the counter-translate is only needed for the base hinge.
  • Highlight any feature by moving the tfc02-gold check tile classes onto its row; nothing else changes.
  • Soften the overshoot by dropping ease-[cubic-bezier(.34,1.2,.4,1)] to ease-out.

Gotchas — read before shipping

  • Transform order is not commutative: translateY(-100%) rotateX(180deg) lifts then turns; reverse them and the card swings off-screen. Keep the underscore-joined order exactly as written.
  • bg-clip-text needs text-transparent on the SAME element as the gradient background, not on a parent — a wrapper gradient clips to the wrapper's box and the text stays invisible.
  • backdrop-blur anywhere inside a preserve-3d subtree is ignored in Firefox; this demo uses flat translucent fills instead, which render identically everywhere.
  • The overshoot curve means the card briefly passes 180°. Both faces need [backface-visibility:hidden] or the overshoot frame shows a flash of the reversed face.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

background-clip:text is Baseline; v4 emits the -webkit- prefix pair for it. Without :has() the card still flips on hover.

Techniques used in this demo

Theme tokensset in @theme, used by a utility

Search CodeFronts

Loading…