23 Tailwind CSS Flip Cards
13 / 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 Restaurant Menu Card with Sliding Ingredient & Nutrition Reveal

The one card in the set with no 3D at all: the front slides out left while the back slides in from the right, like pulling a card from a file. It proves the pattern is about the reveal, not the rotation — and because there is no preserve-3d, the frosted price tag's backdrop-blur actually works, which it would not inside a 3D context in Firefox.

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-13 w-full min-h-svh grid place-items-center bg-tfc13-bg font-tfc13-sans px-5 py-10 text-tfc13-cream">
  <div class="group relative w-[340px] max-w-full h-[470px] overflow-hidden rounded-2xl shadow-[0_1px_2px_oklch(0_0_0/0.5),0_22px_48px_-18px_oklch(0.3_0.08_50/0.7)] has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-tfc13-amber has-[:focus-visible]:outline-offset-4">
    <input id="tfc-13-flip" type="checkbox" class="peer sr-only">
    <label for="tfc-13-flip" class="absolute inset-0 z-20 cursor-pointer rounded-2xl"><span class="sr-only">Show ingredients, allergens and nutrition for Spaghetti al Ragu</span></label>

    <div class="absolute inset-0 flex flex-col rounded-2xl overflow-hidden bg-tfc13-panel border border-tfc13-amber/20 transition-transform duration-[550ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:-translate-x-full group-has-checked:-translate-x-full group-has-[:focus-visible]:-translate-x-full motion-reduce:transition-none">
      <div class="relative grid h-55 shrink-0 place-items-center overflow-hidden bg-linear-160 from-tfc13-stage via-tfc13-stage2 to-tfc13-stage3 before:absolute before:inset-0 before:bg-[radial-gradient(circle_at_50%_60%,oklch(0.6_0.13_60/0.3),transparent_65%)]">
        <svg class="relative z-1" width="180" height="160" viewBox="0 0 180 160" fill="none" role="img" aria-label="Illustration of a plate of spaghetti with meatballs, sauce and basil">
          <ellipse cx="90" cy="110" rx="78" ry="30" fill="oklch(0.25 0.03 60 / 0.6)"/>
          <ellipse cx="90" cy="105" rx="76" ry="28" fill="#2a1a08"/>
          <ellipse cx="90" cy="103" rx="68" ry="24" fill="#1a0e04"/>
          <path d="M55 95 Q70 80 85 95 Q100 110 115 95 Q130 80 125 95" stroke="oklch(0.65 0.14 65 / 0.8)" stroke-width="5" fill="none" stroke-linecap="round"/>
          <path d="M60 100 Q75 85 90 100 Q105 115 120 100" stroke="oklch(0.58 0.12 55 / 0.7)" stroke-width="4" fill="none" stroke-linecap="round"/>
          <path d="M65 90 Q80 75 95 90 Q110 105 125 90" stroke="oklch(0.75 0.15 70 / 0.6)" stroke-width="3" fill="none" stroke-linecap="round"/>
          <circle cx="72" cy="88" r="14" fill="oklch(0.45 0.1 50 / 0.85)"/>
          <circle cx="72" cy="88" r="10" fill="oklch(0.52 0.1 50 / 0.8)"/>
          <circle cx="108" cy="93" r="13" fill="oklch(0.45 0.1 50 / 0.85)"/>
          <circle cx="108" cy="93" r="9" fill="oklch(0.52 0.1 50 / 0.8)"/>
          <ellipse cx="90" cy="95" rx="35" ry="12" fill="oklch(0.45 0.18 30 / 0.35)"/>
          <circle cx="78" cy="76" r="3" fill="oklch(0.73 0.18 150 / 0.7)"/>
          <circle cx="85" cy="74" r="2" fill="oklch(0.73 0.18 150 / 0.6)"/>
          <circle cx="95" cy="78" r="2.5" fill="oklch(0.73 0.18 150 / 0.7)"/>
          <ellipse cx="90" cy="85" rx="20" ry="6" fill="oklch(0.95 0.06 85 / 0.3)"/>
        </svg>
        <p class="absolute top-3.5 right-3.5 z-2 rounded-full border border-tfc13-amber/40 bg-black/70 px-3 py-1.5 text-base font-extrabold text-tfc13-amber backdrop-blur-md">$24</p>
      </div>
      <div class="flex flex-1 flex-col gap-2 p-5">
        <p class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Italian &middot; Pasta</p>
        <h3 class="text-[22px] font-extrabold tracking-[-0.02em] text-tfc13-cream">Spaghetti al Ragu</h3>
        <p class="text-[13px] leading-[1.6] text-tfc13-muted text-pretty">House-made spaghetti with slow-cooked Bolognese, fresh parmesan, and wild basil.</p>
        <ul class="mt-1 flex flex-wrap gap-1.5">
          <li class="rounded-full border border-tfc13-red/20 bg-tfc13-red/10 px-2.5 py-0.5 text-[10px] text-tfc13-cream/75">Medium spice</li>
          <li class="rounded-full border border-tfc13-red/20 bg-tfc13-red/10 px-2.5 py-0.5 text-[10px] text-tfc13-cream/75">Chef's pick</li>
        </ul>
        <p class="mt-auto text-[10px] tracking-[0.08em] text-tfc13-dim">Hover, tap or press Space for ingredients &amp; nutrition &rarr;</p>
      </div>
    </div>

    <div class="absolute inset-0 flex translate-x-full flex-col gap-3 rounded-2xl overflow-hidden p-6 bg-linear-160 from-tfc13-back to-tfc13-back2 border border-tfc13-red/20 transition-transform duration-[550ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:translate-x-0 group-has-checked:translate-x-0 group-has-[:focus-visible]:translate-x-0 motion-reduce:transition-none">
      <h3 class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Key ingredients</h3>
      <ul class="grid grid-cols-2 gap-1.5 text-xs text-tfc13-cream/75">
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Spaghetti pasta</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Beef mince (15%)</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">San Marzano tomato</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Parmigiano 24mo</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Soffritto base</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Fresh basil</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Dry white wine</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Extra virgin olive oil</li>
      </ul>
      <h3 class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Allergens</h3>
      <ul class="flex flex-wrap gap-1.5">
        <li class="flex items-center gap-1 rounded-md border border-tfc13-red/35 bg-tfc13-red/10 px-2 py-1 text-[10px] font-semibold text-tfc13-cream/80"><span aria-hidden="true">&#9888;</span>Gluten</li>
        <li class="flex items-center gap-1 rounded-md border border-tfc13-red/35 bg-tfc13-red/10 px-2 py-1 text-[10px] font-semibold text-tfc13-cream/80"><span aria-hidden="true">&#9888;</span>Dairy</li>
        <li class="flex items-center gap-1 rounded-md border border-tfc13-red/35 bg-tfc13-red/10 px-2 py-1 text-[10px] font-semibold text-tfc13-cream/80"><span aria-hidden="true">&#9888;</span>Sulphites</li>
      </ul>
      <h3 class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Nutrition per serving</h3>
      <dl class="grid grid-cols-4 gap-1.5">
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">620</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">kcal</dt></div>
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">42g</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">Carbs</dt></div>
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">38g</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">Protein</dt></div>
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">22g</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">Fat</dt></div>
      </dl>
      <button type="button" class="relative z-30 mt-auto min-h-11 w-full rounded-xl bg-linear-135 from-tfc13-red to-tfc13-amber text-[13px] font-extrabold tracking-[0.04em] text-white transition-opacity duration-150 hover:opacity-90 focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2">Add to order &mdash; $24</button>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tfc13-bg: #0c0400;
  --color-tfc13-bg: oklch(0.13 0.02 45);
  --color-tfc13-panel: #111008;
  --color-tfc13-panel: oklch(0.17 0.015 80);
  --color-tfc13-stage: #1a0800;
  --color-tfc13-stage: oklch(0.18 0.05 45);
  --color-tfc13-stage2: #2d1200;
  --color-tfc13-stage2: oklch(0.24 0.07 50);
  --color-tfc13-stage3: #0d0800;
  --color-tfc13-stage3: oklch(0.14 0.02 60);
  --color-tfc13-back: #0e0800;
  --color-tfc13-back: oklch(0.15 0.02 60);
  --color-tfc13-back2: #12090a;
  --color-tfc13-back2: oklch(0.16 0.02 25);
  --color-tfc13-red: #dc2626;
  --color-tfc13-red: oklch(0.58 0.21 27);
  --color-tfc13-amber: #d97706;
  --color-tfc13-amber: oklch(0.68 0.16 60);
  --color-tfc13-cream: #fef3c7;
  --color-tfc13-cream: oklch(0.96 0.06 92);
  --color-tfc13-muted: #c5b48d;
  --color-tfc13-muted: oklch(0.79 0.05 90);
  --color-tfc13-dim: #8e8265;
  --color-tfc13-dim: oklch(0.63 0.03 90);
  --font-tfc13-sans: 'Sora', system-ui, sans-serif;
}

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

@media (prefers-reduced-motion: reduce) {
  .tfc-13 * {
    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-tfc13-bg: #0c0400;
  --color-tfc13-bg: oklch(0.13 0.02 45);
  --color-tfc13-panel: #111008;
  --color-tfc13-panel: oklch(0.17 0.015 80);
  --color-tfc13-stage: #1a0800;
  --color-tfc13-stage: oklch(0.18 0.05 45);
  --color-tfc13-stage2: #2d1200;
  --color-tfc13-stage2: oklch(0.24 0.07 50);
  --color-tfc13-stage3: #0d0800;
  --color-tfc13-stage3: oklch(0.14 0.02 60);
  --color-tfc13-back: #0e0800;
  --color-tfc13-back: oklch(0.15 0.02 60);
  --color-tfc13-back2: #12090a;
  --color-tfc13-back2: oklch(0.16 0.02 25);
  --color-tfc13-red: #dc2626;
  --color-tfc13-red: oklch(0.58 0.21 27);
  --color-tfc13-amber: #d97706;
  --color-tfc13-amber: oklch(0.68 0.16 60);
  --color-tfc13-cream: #fef3c7;
  --color-tfc13-cream: oklch(0.96 0.06 92);
  --color-tfc13-muted: #c5b48d;
  --color-tfc13-muted: oklch(0.79 0.05 90);
  --color-tfc13-dim: #8e8265;
  --color-tfc13-dim: oklch(0.63 0.03 90);
  --font-tfc13-sans: 'Sora', system-ui, sans-serif;
}

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

@media (prefers-reduced-motion: reduce) {
  .tfc-13 * {
    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&display=swap">

What changed in the port

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

  • Two sibling rules (:hover .front, :hover .back) became two utility pairs on the faces themselves. The symmetry of the slide is now visible in the markup, which matters because a mismatched duration is the failure mode.
  • This is the demo that documents what preserve-3d costs you: with no 3D context, backdrop-blur-md just works.
  • UI change from the CSS original: allergens carry icon + text + border (not colour alone), ingredients and nutrition became <ul>/<dl>, the dish SVG has a real aria-label, and the emoji chilli was replaced with the words "Medium spice".
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 Restaurant Menu Card with Sliding Ingredient & Nutrition Reveal
Source: https://codefronts.com/components/tailwind-css-flip-cards/tailwind-restaurant-menu-card-sliding-ingredient-nutrition/

The one card in the set with no 3D at all: the front slides out left while the back slides in from the right, like pulling a card from a file. It proves the pattern is about the reveal, not the rotation &mdash; and because there is no preserve-3d, the frosted price tag's backdrop-blur actually works, which it would not inside a 3D context in Firefox.
## HTML
```html
<section class="tfc-13 w-full min-h-svh grid place-items-center bg-tfc13-bg font-tfc13-sans px-5 py-10 text-tfc13-cream">
  <div class="group relative w-[340px] max-w-full h-[470px] overflow-hidden rounded-2xl shadow-[0_1px_2px_oklch(0_0_0/0.5),0_22px_48px_-18px_oklch(0.3_0.08_50/0.7)] has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-tfc13-amber has-[:focus-visible]:outline-offset-4">
    <input id="tfc-13-flip" type="checkbox" class="peer sr-only">
    <label for="tfc-13-flip" class="absolute inset-0 z-20 cursor-pointer rounded-2xl"><span class="sr-only">Show ingredients, allergens and nutrition for Spaghetti al Ragu</span></label>

    <div class="absolute inset-0 flex flex-col rounded-2xl overflow-hidden bg-tfc13-panel border border-tfc13-amber/20 transition-transform duration-[550ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:-translate-x-full group-has-checked:-translate-x-full group-has-[:focus-visible]:-translate-x-full motion-reduce:transition-none">
      <div class="relative grid h-55 shrink-0 place-items-center overflow-hidden bg-linear-160 from-tfc13-stage via-tfc13-stage2 to-tfc13-stage3 before:absolute before:inset-0 before:bg-[radial-gradient(circle_at_50%_60%,oklch(0.6_0.13_60/0.3),transparent_65%)]">
        <svg class="relative z-1" width="180" height="160" viewBox="0 0 180 160" fill="none" role="img" aria-label="Illustration of a plate of spaghetti with meatballs, sauce and basil">
          <ellipse cx="90" cy="110" rx="78" ry="30" fill="oklch(0.25 0.03 60 / 0.6)"/>
          <ellipse cx="90" cy="105" rx="76" ry="28" fill="#2a1a08"/>
          <ellipse cx="90" cy="103" rx="68" ry="24" fill="#1a0e04"/>
          <path d="M55 95 Q70 80 85 95 Q100 110 115 95 Q130 80 125 95" stroke="oklch(0.65 0.14 65 / 0.8)" stroke-width="5" fill="none" stroke-linecap="round"/>
          <path d="M60 100 Q75 85 90 100 Q105 115 120 100" stroke="oklch(0.58 0.12 55 / 0.7)" stroke-width="4" fill="none" stroke-linecap="round"/>
          <path d="M65 90 Q80 75 95 90 Q110 105 125 90" stroke="oklch(0.75 0.15 70 / 0.6)" stroke-width="3" fill="none" stroke-linecap="round"/>
          <circle cx="72" cy="88" r="14" fill="oklch(0.45 0.1 50 / 0.85)"/>
          <circle cx="72" cy="88" r="10" fill="oklch(0.52 0.1 50 / 0.8)"/>
          <circle cx="108" cy="93" r="13" fill="oklch(0.45 0.1 50 / 0.85)"/>
          <circle cx="108" cy="93" r="9" fill="oklch(0.52 0.1 50 / 0.8)"/>
          <ellipse cx="90" cy="95" rx="35" ry="12" fill="oklch(0.45 0.18 30 / 0.35)"/>
          <circle cx="78" cy="76" r="3" fill="oklch(0.73 0.18 150 / 0.7)"/>
          <circle cx="85" cy="74" r="2" fill="oklch(0.73 0.18 150 / 0.6)"/>
          <circle cx="95" cy="78" r="2.5" fill="oklch(0.73 0.18 150 / 0.7)"/>
          <ellipse cx="90" cy="85" rx="20" ry="6" fill="oklch(0.95 0.06 85 / 0.3)"/>
        </svg>
        <p class="absolute top-3.5 right-3.5 z-2 rounded-full border border-tfc13-amber/40 bg-black/70 px-3 py-1.5 text-base font-extrabold text-tfc13-amber backdrop-blur-md">$24</p>
      </div>
      <div class="flex flex-1 flex-col gap-2 p-5">
        <p class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Italian &middot; Pasta</p>
        <h3 class="text-[22px] font-extrabold tracking-[-0.02em] text-tfc13-cream">Spaghetti al Ragu</h3>
        <p class="text-[13px] leading-[1.6] text-tfc13-muted text-pretty">House-made spaghetti with slow-cooked Bolognese, fresh parmesan, and wild basil.</p>
        <ul class="mt-1 flex flex-wrap gap-1.5">
          <li class="rounded-full border border-tfc13-red/20 bg-tfc13-red/10 px-2.5 py-0.5 text-[10px] text-tfc13-cream/75">Medium spice</li>
          <li class="rounded-full border border-tfc13-red/20 bg-tfc13-red/10 px-2.5 py-0.5 text-[10px] text-tfc13-cream/75">Chef's pick</li>
        </ul>
        <p class="mt-auto text-[10px] tracking-[0.08em] text-tfc13-dim">Hover, tap or press Space for ingredients &amp; nutrition &rarr;</p>
      </div>
    </div>

    <div class="absolute inset-0 flex translate-x-full flex-col gap-3 rounded-2xl overflow-hidden p-6 bg-linear-160 from-tfc13-back to-tfc13-back2 border border-tfc13-red/20 transition-transform duration-[550ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:translate-x-0 group-has-checked:translate-x-0 group-has-[:focus-visible]:translate-x-0 motion-reduce:transition-none">
      <h3 class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Key ingredients</h3>
      <ul class="grid grid-cols-2 gap-1.5 text-xs text-tfc13-cream/75">
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Spaghetti pasta</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Beef mince (15%)</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">San Marzano tomato</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Parmigiano 24mo</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Soffritto base</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Fresh basil</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Dry white wine</li>
        <li class="flex items-center gap-2 before:size-1.5 before:shrink-0 before:rounded-full before:bg-tfc13-amber">Extra virgin olive oil</li>
      </ul>
      <h3 class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Allergens</h3>
      <ul class="flex flex-wrap gap-1.5">
        <li class="flex items-center gap-1 rounded-md border border-tfc13-red/35 bg-tfc13-red/10 px-2 py-1 text-[10px] font-semibold text-tfc13-cream/80"><span aria-hidden="true">&#9888;</span>Gluten</li>
        <li class="flex items-center gap-1 rounded-md border border-tfc13-red/35 bg-tfc13-red/10 px-2 py-1 text-[10px] font-semibold text-tfc13-cream/80"><span aria-hidden="true">&#9888;</span>Dairy</li>
        <li class="flex items-center gap-1 rounded-md border border-tfc13-red/35 bg-tfc13-red/10 px-2 py-1 text-[10px] font-semibold text-tfc13-cream/80"><span aria-hidden="true">&#9888;</span>Sulphites</li>
      </ul>
      <h3 class="text-[10px] font-bold uppercase tracking-[0.15em] text-tfc13-amber">Nutrition per serving</h3>
      <dl class="grid grid-cols-4 gap-1.5">
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">620</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">kcal</dt></div>
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">42g</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">Carbs</dt></div>
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">38g</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">Protein</dt></div>
        <div class="rounded-lg border border-white/7 bg-white/4 px-1 py-2 text-center"><dd class="text-[15px] font-extrabold text-tfc13-cream">22g</dd><dt class="mt-0.5 text-[9px] uppercase tracking-[0.08em] text-tfc13-dim">Fat</dt></div>
      </dl>
      <button type="button" class="relative z-30 mt-auto min-h-11 w-full rounded-xl bg-linear-135 from-tfc13-red to-tfc13-amber text-[13px] font-extrabold tracking-[0.04em] text-white transition-opacity duration-150 hover:opacity-90 focus-visible:outline-2 focus-visible:outline-white focus-visible:outline-offset-2">Add to order &mdash; $24</button>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tfc13-bg: #0c0400;
  --color-tfc13-bg: oklch(0.13 0.02 45);
  --color-tfc13-panel: #111008;
  --color-tfc13-panel: oklch(0.17 0.015 80);
  --color-tfc13-stage: #1a0800;
  --color-tfc13-stage: oklch(0.18 0.05 45);
  --color-tfc13-stage2: #2d1200;
  --color-tfc13-stage2: oklch(0.24 0.07 50);
  --color-tfc13-stage3: #0d0800;
  --color-tfc13-stage3: oklch(0.14 0.02 60);
  --color-tfc13-back: #0e0800;
  --color-tfc13-back: oklch(0.15 0.02 60);
  --color-tfc13-back2: #12090a;
  --color-tfc13-back2: oklch(0.16 0.02 25);
  --color-tfc13-red: #dc2626;
  --color-tfc13-red: oklch(0.58 0.21 27);
  --color-tfc13-amber: #d97706;
  --color-tfc13-amber: oklch(0.68 0.16 60);
  --color-tfc13-cream: #fef3c7;
  --color-tfc13-cream: oklch(0.96 0.06 92);
  --color-tfc13-muted: #c5b48d;
  --color-tfc13-muted: oklch(0.79 0.05 90);
  --color-tfc13-dim: #8e8265;
  --color-tfc13-dim: oklch(0.63 0.03 90);
  --font-tfc13-sans: 'Sora', system-ui, sans-serif;
}

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

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

How this works

No rotation, no 3D context, no constraints. The two faces are absolutely positioned siblings translated on X. Everything that is illegal inside preserve-3d — filters, backdrop filters, heavy shadows — is fine here, which is exactly why this variant exists in the collection.

Allergens use three channels. A warning glyph, the word itself, and a red-tinted border. Colour alone fails for 8% of men; in a food-service context that is not an academic concern.

The slide is symmetric. Both faces share one duration and one curve, so the outgoing and incoming edges stay locked together — a 50ms mismatch reads as a glitch rather than a transition.

Make it yours

  • Direction: swap -translate-x-full / translate-x-full for the Y pair and the card becomes a vertical drawer.
  • Cuisine palette lives in --color-tfc13-amber and --color-tfc13-red; an indigo/white pair reads as sushi.
  • Portion toggle: add a second checkbox and drive price and nutrition values with has-checked: variants.
  • Dietary badges sit in the same flex row as the spice level; add V or GF pills there.

Gotchas — read before shipping

  • backdrop-blur inside a preserve-3d subtree is dropped by Firefox. It works here only because this demo has no 3D — do not copy the price tag into a rotating card without a solid fallback.
  • Both faces need overflow-hidden on the SCENE, not on themselves, or the outgoing face is visible beside the card mid-slide.
  • Allergen data is a legal matter in food service. This is a UI pattern, not a compliance solution.
  • Stroke-based SVG food art prints as hairlines. Bump stroke-width in a print block if the menu goes to paper.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

backdrop-filter needs Firefox 103+. Translation transitions are universal.

Techniques used in this demo

Theme tokensset in @theme, used by a utility

Search CodeFronts

Loading…