15 / 25
All 25 in 25 Tailwind CSS FAQ Accordion
- 01Tailwind Peer-Checked FAQ Accordion with No JavaScript
- 02Tailwind Native Details/Summary FAQ with Custom Styled Icons
- 03Tailwind Exclusive Accordion — Only One FAQ Open at a Time
- 04Tailwind Multi-Open FAQ Accordion with a Live CSS Counter
- 05Tailwind CSS FAQ Accordion Template (Free, Copy-Paste)
- 06Tailwind Dark Mode FAQ Accordion with light-dark() and No .dark Class
- 07Tailwind Glassmorphism FAQ Accordion with Frosted Backdrop Blur
- 08Tailwind Minimalist E-Commerce FAQ Accordion for Product Pages
- 09Tailwind Neumorphic Soft-UI FAQ Accordion Cards
- 10Tailwind Animate Height Auto FAQ with grid-rows 0fr to 1fr
- 11Tailwind FAQ Chevron Rotate 180 Degrees on Toggle
- 12Tailwind Animated Plus to Minus Icon Morph FAQ Accordion
- 13Tailwind Spring Bounce FAQ Accordion with linear() Easing
- 14Tailwind Two-Column FAQ Accordion Grid with Independent Columns
- 15Tailwind Horizontal FAQ Accordion with Sideways Expanding Panels
- 16Tailwind Categorised FAQ Help Centre with a Sticky Sidebar Menu
- 17Tailwind Card-Style FAQ Panels with a Layered Shadow Elevation System
- 18Tailwind FAQ Accordion with a Live Search Bar Filter
- 19Tailwind Expand All and Collapse All FAQ Accordion Buttons
- 20Tailwind FAQ with a Still Have Questions Contact CTA Card
- 21Tailwind Accessible ARIA FAQ Accordion with Keyboard Navigation
- 22Tailwind FAQ with FAQPage JSON-LD Schema for Rich Snippets and AI Search
- 23Bootstrap 5 Accordion Rebuilt in Tailwind (and the JavaScript You Delete)
- 24Tailwind FAQ Component in React, Vue, Svelte and Astro (One Port Recipe)
- 25Tailwind FAQ with Voice Search Using the Speech Recognition API
Tailwind Horizontal FAQ Accordion with Sideways Expanding Panels
The showpiece: five photo panels standing shoulder to shoulder, the active one unfolding sideways to reveal its answer while the others compress into spines with vertically-written titles. Demo 10's fr-unit trick rotated 90° — grid-cols-[64px_0fr] to [64px_1fr] — plus a grow-[3.2] transition, [writing-mode:vertical-rl] spines, and radio state, so it stays pure Tailwind.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<section class="tfa-15 w-full min-h-svh font-tfa15-sans text-white">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa15-bg px-5 py-12">
<div class="w-[min(1020px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.4vw,40px)] font-extrabold tracking-[-0.025em]">Plan your expedition</h1>
<p class="mt-3 max-w-[54ch] text-[14.5px] leading-relaxed text-white/85">Five questions standing sideways — the open one unfolds. Arrow keys move between panels.</p>
</header>
<div class="mt-7 flex min-h-[420px] gap-2.5 @max-tfa15fold:min-h-0 @max-tfa15fold:flex-col">
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p1" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none" checked>
<label for="tfa15-p1" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">When to go?</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">When is the best season?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">June through September for the high passes — long days, stable weather, open refuges. Shoulder months halve the crowds but add real weather risk above 2,500m.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1551632811-561732d1e306?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p2" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p2" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Fitness level</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How fit do I need to be?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Comfortable hiking 6–7 hours with a daypack, two days in a row. Our grade-2 routes need no technical skills; if you can do a hilly half-day hike smiling, twelve training weeks gets you there.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1501554728187-ce583db33af7?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p3" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p3" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">What is included</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What does the price include?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Guides, refuge nights, breakfasts and dinners, luggage transfer between stages and safety kit. Flights, lunches and insurance are yours — full packing list on booking.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1522163182402-834f871fd851?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p4" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p4" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Group size</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How big are the groups?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Max 10, average 7, two certified guides per group. Solo travellers are half of every departure — the refuge table does the introductions by night two.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p5" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p5" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Cancellation</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What if I need to cancel?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Free date changes until 30 days out, full refund minus deposit until 14, and the deposit converts to credit after that. Weather cancellations on our side refund everything.</p>
</div>
</div>
</div>
</div>
<p class="mt-5 text-[12.5px] text-white/80">grid-cols-[0fr] → [1fr] plus a grow transition — demo 10's trick, rotated. Folds vertical in narrow containers.</p>
</div>
</div>
</section><section class="tfa-15 w-full min-h-svh font-tfa15-sans text-white">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa15-bg px-5 py-12">
<div class="w-[min(1020px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.4vw,40px)] font-extrabold tracking-[-0.025em]">Plan your expedition</h1>
<p class="mt-3 max-w-[54ch] text-[14.5px] leading-relaxed text-white/85">Five questions standing sideways — the open one unfolds. Arrow keys move between panels.</p>
</header>
<div class="mt-7 flex min-h-[420px] gap-2.5 @max-tfa15fold:min-h-0 @max-tfa15fold:flex-col">
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p1" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none" checked>
<label for="tfa15-p1" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">When to go?</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">When is the best season?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">June through September for the high passes — long days, stable weather, open refuges. Shoulder months halve the crowds but add real weather risk above 2,500m.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1551632811-561732d1e306?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p2" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p2" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Fitness level</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How fit do I need to be?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Comfortable hiking 6–7 hours with a daypack, two days in a row. Our grade-2 routes need no technical skills; if you can do a hilly half-day hike smiling, twelve training weeks gets you there.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1501554728187-ce583db33af7?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p3" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p3" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">What is included</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What does the price include?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Guides, refuge nights, breakfasts and dinners, luggage transfer between stages and safety kit. Flights, lunches and insurance are yours — full packing list on booking.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1522163182402-834f871fd851?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p4" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p4" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Group size</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How big are the groups?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Max 10, average 7, two certified guides per group. Solo travellers are half of every departure — the refuge table does the introductions by night two.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p5" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p5" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Cancellation</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What if I need to cancel?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Free date changes until 30 days out, full refund minus deposit until 14, and the deposit converts to credit after that. Weather cancellations on our side refund everything.</p>
</div>
</div>
</div>
</div>
<p class="mt-5 text-[12.5px] text-white/80">grid-cols-[0fr] → [1fr] plus a grow transition — demo 10's trick, rotated. Folds vertical in narrow containers.</p>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tfa15-bg: #1b1d2a;
--color-tfa15-bg: oklch(0.2 0.02 260);
--color-tfa15-acc: #ffc94d;
--color-tfa15-acc: oklch(0.85 0.15 80);
--font-tfa15-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Matches the CSS twin's @container (width < 720px) fold. The
built-in 3xl is 768px, which stacked the panels while there was
still room for the sideways layout. */
--container-tfa15fold: 45rem;
}
.tfa-15 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tfa15-bg: #1b1d2a;
--color-tfa15-bg: oklch(0.2 0.02 260);
--color-tfa15-acc: #ffc94d;
--color-tfa15-acc: oklch(0.85 0.15 80);
--font-tfa15-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Matches the CSS twin's @container (width < 720px) fold. The
built-in 3xl is 768px, which stacked the panels while there was
still room for the sideways layout. */
--container-tfa15fold: 45rem;
}
.tfa-15 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tfa15-bg: #1b1d2a;
--color-tfa15-bg: oklch(0.2 0.02 260);
--color-tfa15-acc: #ffc94d;
--color-tfa15-acc: oklch(0.85 0.15 80);
--font-tfa15-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Matches the CSS twin's @container (width < 720px) fold. The
built-in 3xl is 768px, which stacked the panels while there was
still room for the sideways layout. */
--container-tfa15fold: 45rem;
}
.tfa-15 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tfa15-bg: #1b1d2a;
--color-tfa15-bg: oklch(0.2 0.02 260);
--color-tfa15-acc: #ffc94d;
--color-tfa15-acc: oklch(0.85 0.15 80);
--font-tfa15-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Matches the CSS twin's @container (width < 720px) fold. The
built-in 3xl is 768px, which stacked the panels while there was
still room for the sideways layout. */
--container-tfa15fold: 45rem;
}
.tfa-15 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;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=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Three
:has()rules became three variants on the element they style:has-checked:,[&:not(:has(:checked)):hover]:andhas-focus-visible:. This is the demo where the utility version is genuinely easier to read than the CSS — the panel now lists its own state machine. - The entire vertical fold is a
@max-tfa15fold:variant layer instead of a second CSS block, which means the two layouts sit in the same class list and can be diffed by eye. It is long, and it is still the better trade. [writing-mode:vertical-rl]is an arbitrary property because writing mode is not a design-scale value;sideways-lrwould be semantically nicer but only reached Safari in 2024, andvertical-rlplusrotate-180reads identically much further back.- UI upgrade from the CSS original: body copy moved from a muted
oklch(0.88)token to full-opacity white at 90% with a per-element text-shadow, which holds 4.5:1 over the brightest part of every photo — the original's spine labels in particular washed out on the snow images. - UI upgrade: the focus ring is now driven by
has-focus-visible:on the panel rather than a:has(:focus-visible)rule that only tinted the outline colour, so keyboard users get the same 2px accent ring the rest of the collection uses.
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 Horizontal FAQ Accordion with Sideways Expanding Panels
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-horizontal-faq-accordion-sideways-panels/
The showpiece: five photo panels standing shoulder to shoulder, the active one unfolding sideways to reveal its answer while the others compress into spines with vertically-written titles. Demo 10's fr-unit trick rotated 90° — grid-cols-[64px_0fr] to [64px_1fr] — plus a grow-[3.2] transition, [writing-mode:vertical-rl] spines, and radio state, so it stays pure Tailwind.
## HTML
```html
<section class="tfa-15 w-full min-h-svh font-tfa15-sans text-white">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa15-bg px-5 py-12">
<div class="w-[min(1020px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.4vw,40px)] font-extrabold tracking-[-0.025em]">Plan your expedition</h1>
<p class="mt-3 max-w-[54ch] text-[14.5px] leading-relaxed text-white/85">Five questions standing sideways — the open one unfolds. Arrow keys move between panels.</p>
</header>
<div class="mt-7 flex min-h-[420px] gap-2.5 @max-tfa15fold:min-h-0 @max-tfa15fold:flex-col">
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p1" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none" checked>
<label for="tfa15-p1" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">When to go?</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">When is the best season?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">June through September for the high passes — long days, stable weather, open refuges. Shoulder months halve the crowds but add real weather risk above 2,500m.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1551632811-561732d1e306?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p2" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p2" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Fitness level</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How fit do I need to be?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Comfortable hiking 6–7 hours with a daypack, two days in a row. Our grade-2 routes need no technical skills; if you can do a hilly half-day hike smiling, twelve training weeks gets you there.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1501554728187-ce583db33af7?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p3" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p3" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">What is included</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What does the price include?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Guides, refuge nights, breakfasts and dinners, luggage transfer between stages and safety kit. Flights, lunches and insurance are yours — full packing list on booking.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1522163182402-834f871fd851?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p4" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p4" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Group size</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How big are the groups?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Max 10, average 7, two certified guides per group. Solo travellers are half of every departure — the refuge table does the introductions by night two.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p5" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p5" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Cancellation</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What if I need to cancel?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Free date changes until 30 days out, full refund minus deposit until 14, and the deposit converts to credit after that. Weather cancellations on our side refund everything.</p>
</div>
</div>
</div>
</div>
<p class="mt-5 text-[12.5px] text-white/80">grid-cols-[0fr] → [1fr] plus a grow transition — demo 10's trick, rotated. Folds vertical in narrow containers.</p>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tfa15-bg: #1b1d2a;
--color-tfa15-bg: oklch(0.2 0.02 260);
--color-tfa15-acc: #ffc94d;
--color-tfa15-acc: oklch(0.85 0.15 80);
--font-tfa15-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Matches the CSS twin's @container (width < 720px) fold. The
built-in 3xl is 768px, which stacked the panels while there was
still room for the sideways layout. */
--container-tfa15fold: 45rem;
}
.tfa-15 {
width: 100%;
min-height: 100svh;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Horizontal FAQ Accordion with Sideways Expanding Panels
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-horizontal-faq-accordion-sideways-panels/
The showpiece: five photo panels standing shoulder to shoulder, the active one unfolding sideways to reveal its answer while the others compress into spines with vertically-written titles. Demo 10's fr-unit trick rotated 90° — grid-cols-[64px_0fr] to [64px_1fr] — plus a grow-[3.2] transition, [writing-mode:vertical-rl] spines, and radio state, so it stays pure Tailwind.
## HTML
```html
<section class="tfa-15 w-full min-h-svh font-tfa15-sans text-white">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa15-bg px-5 py-12">
<div class="w-[min(1020px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.4vw,40px)] font-extrabold tracking-[-0.025em]">Plan your expedition</h1>
<p class="mt-3 max-w-[54ch] text-[14.5px] leading-relaxed text-white/85">Five questions standing sideways — the open one unfolds. Arrow keys move between panels.</p>
</header>
<div class="mt-7 flex min-h-[420px] gap-2.5 @max-tfa15fold:min-h-0 @max-tfa15fold:flex-col">
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p1" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none" checked>
<label for="tfa15-p1" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">When to go?</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">When is the best season?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">June through September for the high passes — long days, stable weather, open refuges. Shoulder months halve the crowds but add real weather risk above 2,500m.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1551632811-561732d1e306?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p2" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p2" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Fitness level</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How fit do I need to be?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Comfortable hiking 6–7 hours with a daypack, two days in a row. Our grade-2 routes need no technical skills; if you can do a hilly half-day hike smiling, twelve training weeks gets you there.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1501554728187-ce583db33af7?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p3" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p3" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">What is included</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What does the price include?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Guides, refuge nights, breakfasts and dinners, luggage transfer between stages and safety kit. Flights, lunches and insurance are yours — full packing list on booking.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1522163182402-834f871fd851?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p4" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p4" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Group size</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">How big are the groups?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Max 10, average 7, two certified guides per group. Solo travellers are half of every departure — the refuge table does the introductions by night two.</p>
</div>
</div>
</div>
<div class="group relative grid flex-1 overflow-hidden rounded-[18px] bg-[linear-gradient(oklch(0.2_0.03_260/0.25),oklch(0.15_0.03_260/0.7)),url('https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center outline-2 outline-offset-[3px] outline-transparent transition-[grid-template-columns,grid-template-rows,flex-grow,outline-color] duration-600 ease-[cubic-bezier(0.3,0.8,0.25,1)] grid-cols-[64px_0fr] has-checked:grid-cols-[64px_1fr] has-checked:grow-[3.2] [&:not(:has(:checked)):hover]:grow-[1.15] has-focus-visible:outline-tfa15-acc @max-tfa15fold:grid-cols-[1fr] @max-tfa15fold:grid-rows-[56px_0fr] @max-tfa15fold:has-checked:grid-cols-[1fr] @max-tfa15fold:has-checked:grid-rows-[56px_1fr] @max-tfa15fold:has-checked:grow-[1] motion-reduce:transition-none">
<input id="tfa15-p5" type="radio" name="tfa15" class="absolute opacity-0 pointer-events-none">
<label for="tfa15-p5" class="grid min-w-11 cursor-pointer items-end justify-items-center py-[18px] @max-tfa15fold:min-h-11 @max-tfa15fold:place-items-center @max-tfa15fold:justify-items-start @max-tfa15fold:px-5 @max-tfa15fold:py-0">
<h3 class="[writing-mode:vertical-rl] rotate-180 text-[13.5px] font-bold uppercase tracking-[0.06em] text-white [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.85)] transition-colors duration-300 group-hover:text-tfa15-acc group-has-checked:text-tfa15-acc @max-tfa15fold:[writing-mode:horizontal-tb] @max-tfa15fold:rotate-0">Cancellation</h3>
</label>
<div class="grid min-w-0 items-end overflow-hidden @max-tfa15fold:min-h-0">
<div class="w-[max(260px,26cqi)] translate-x-3.5 py-[22px] pl-2 pr-6 opacity-0 transition-[translate,opacity] delay-150 duration-500 ease-[cubic-bezier(0.3,0.8,0.25,1)] group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none @max-tfa15fold:w-full @max-tfa15fold:px-5 @max-tfa15fold:pb-5 @max-tfa15fold:pt-0">
<h2 class="text-[clamp(17px,2.2vw,22px)] font-extrabold tracking-[-0.02em] text-white [text-shadow:0_1px_14px_oklch(0.15_0.03_260/0.8)]">What if I need to cancel?</h2>
<p class="mt-2.5 text-[13.5px] leading-[1.65] text-white/90 [text-shadow:0_1px_12px_oklch(0.15_0.03_260/0.75)]">Free date changes until 30 days out, full refund minus deposit until 14, and the deposit converts to credit after that. Weather cancellations on our side refund everything.</p>
</div>
</div>
</div>
</div>
<p class="mt-5 text-[12.5px] text-white/80">grid-cols-[0fr] → [1fr] plus a grow transition — demo 10's trick, rotated. Folds vertical in narrow containers.</p>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tfa15-bg: #1b1d2a;
--color-tfa15-bg: oklch(0.2 0.02 260);
--color-tfa15-acc: #ffc94d;
--color-tfa15-acc: oklch(0.85 0.15 80);
--font-tfa15-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
/* Matches the CSS twin's @container (width < 720px) fold. The
built-in 3xl is 768px, which stacked the panels while there was
still room for the sideways layout. */
--container-tfa15fold: 45rem;
}
.tfa-15 {
width: 100%;
min-height: 100svh;
}
```How this works
Two animations, one curve. Every panel is a grid of a fixed 64px spine plus a fraction-unit body; the checked panel's fraction opens from 0fr to 1fr while its flex-grow travels 1→3.2. flex-grow is a plain number, so it transitions too, letting the active panel claim more of the strip while siblings share the rest.
The state relationships are all has-*. The radio lives inside the panel, so the panel styles itself with has-checked:, invites with [&:not(:has(:checked)):hover]:, and shows its focus ring with has-focus-visible:. In CSS these were three :has() rules a long way from the markup; here they read as a list of conditions on the element they affect.
The fold is the honest part. Horizontal disclosure is a display pattern for three to six visual items on wide canvases, not an information pattern. Rather than pretending spines work on phones, @max-tfa15fold: variants rebuild the whole thing as a normal vertical accordion: rows instead of columns, horizontal writing mode, full-width bodies.
Make it yours
- Panel count: three to six. Beyond that spines go sliver-thin.
- Greed:
has-checked:grow-[3.2]is how much of the strip the open panel claims. - Images: one background-image utility per panel; the gradient overlay keeps spine text readable over any photo.
- Vertical fold: the
@max-tfa15fold:layer is a complete second layout — customise it like an ordinary accordion.
Gotchas — read before shipping
min-w-0on the expanding body is the horizontal twin of demo 10'smin-h-0. Without it the fr column refuses to close fully.- Animating
widthinstead of the grid track plusgrowreflows text every frame; the fr version lets the browser crop a clipped body instead of rewrapping. [writing-mode:vertical-rl]without the 180° rotation reads bottom-to-top for Latin labels. Always pair them.- Radios in one group give arrow-key navigation for free — but make the label fill the whole spine so the hit target is not just the text.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
grid-template-columns interpolation matches demo 10's floors and flex-grow transitions are ancient; the real floor is :has() (Chrome 105 / Safari 15.4 / Firefox 121), which drives every state here.