17 / 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 Card-Style FAQ Panels with a Layered Shadow Elevation System
Separated FAQ cards with a real elevation system: three levels (resting, hover, open) built from layered shadows that mimic how light actually falls — a tight dark contact layer plus a wide soft ambient one — instead of the single fuzzy grey blob of tutorial CSS. Cards lift 2px on hover and rise to full elevation when open, with the shadow tinted in the page's own hue rather than black.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<section class="tfa-17 w-full min-h-svh grid place-items-center bg-tfa17-bg font-tfa17-sans text-tfa17-ink px-5 py-12">
<div class="w-[min(640px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.6vw,38px)] font-extrabold tracking-[-0.025em]">Warranty & repairs</h1>
<p class="mt-3 max-w-[52ch] text-[14.5px] leading-relaxed text-tfa17-mut">Three elevations: resting, hover-lift, open. Every shadow is two layers — contact plus ambient — in the page's own hue.</p>
</header>
<div data-panel class="mt-7 flex flex-col gap-4">
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">What does the warranty cover?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Two years, parts and labour, covering manufacturing defects and battery health below 80%. Accidental damage is a separate care plan — but out-of-warranty repairs are flat-rate and published, never “send it in for a quote”.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">How do I start a repair?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Run the diagnostic in the app, which pre-fills the repair ticket with logs. A prepaid label arrives by email; most repairs turn around in five business days door to door, with a loaner option on the care plan.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Can I repair it myself?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Yes — self-repair kits with genuine parts, tools and guides cover the battery, screen and buttons. DIY repairs with our parts do not void the warranty; third-party parts void only the affected subsystem.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Is water damage covered?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">IP67 failures within rating are warranty repairs — a pressure test tells us quickly. Beyond-rating exposure (diving, jacuzzi chemistry) falls to the care plan accidental tier at the flat rate.</p>
</details>
</div>
<p class="mt-6 text-[12.5px] text-tfa17-mut">Shadow recipe: tight contact layer plus wide ambient layer, tinted in the page hue. Never plain black.</p>
</div>
</section><section class="tfa-17 w-full min-h-svh grid place-items-center bg-tfa17-bg font-tfa17-sans text-tfa17-ink px-5 py-12">
<div class="w-[min(640px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.6vw,38px)] font-extrabold tracking-[-0.025em]">Warranty & repairs</h1>
<p class="mt-3 max-w-[52ch] text-[14.5px] leading-relaxed text-tfa17-mut">Three elevations: resting, hover-lift, open. Every shadow is two layers — contact plus ambient — in the page's own hue.</p>
</header>
<div data-panel class="mt-7 flex flex-col gap-4">
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">What does the warranty cover?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Two years, parts and labour, covering manufacturing defects and battery health below 80%. Accidental damage is a separate care plan — but out-of-warranty repairs are flat-rate and published, never “send it in for a quote”.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">How do I start a repair?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Run the diagnostic in the app, which pre-fills the repair ticket with logs. A prepaid label arrives by email; most repairs turn around in five business days door to door, with a loaner option on the care plan.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Can I repair it myself?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Yes — self-repair kits with genuine parts, tools and guides cover the battery, screen and buttons. DIY repairs with our parts do not void the warranty; third-party parts void only the affected subsystem.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Is water damage covered?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">IP67 failures within rating are warranty repairs — a pressure test tells us quickly. Beyond-rating exposure (diving, jacuzzi chemistry) falls to the care plan accidental tier at the flat rate.</p>
</details>
</div>
<p class="mt-6 text-[12.5px] text-tfa17-mut">Shadow recipe: tight contact layer plus wide ambient layer, tinted in the page hue. Never plain black.</p>
</div>
</section>@import "tailwindcss";
@theme {
--color-tfa17-bg: #f0f0f7;
--color-tfa17-bg: oklch(0.95 0.012 265);
--color-tfa17-ink: #2a2733;
--color-tfa17-ink: oklch(0.24 0.03 268);
--color-tfa17-mut: #5d596b;
--color-tfa17-mut: oklch(0.47 0.022 265);
--color-tfa17-edge: #e3e1ec;
--color-tfa17-edge: oklch(0.91 0.012 265);
--color-tfa17-tint: #ebe8fa;
--color-tfa17-tint: oklch(0.93 0.03 268);
--color-tfa17-tinthover: #ded8f7;
--color-tfa17-tinthover: oklch(0.89 0.05 268);
--color-tfa17-acc: #5238c8;
--color-tfa17-acc: oklch(0.45 0.2 268);
--font-tfa17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-17 {
width: 100%;
min-height: 100svh;
}
.tfa-17 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-17 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .38s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .38s allow-discrete;
}
.tfa-17 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-17 details::details-content {
transition-duration: 1ms;
}
}@import "tailwindcss";
@theme {
--color-tfa17-bg: #f0f0f7;
--color-tfa17-bg: oklch(0.95 0.012 265);
--color-tfa17-ink: #2a2733;
--color-tfa17-ink: oklch(0.24 0.03 268);
--color-tfa17-mut: #5d596b;
--color-tfa17-mut: oklch(0.47 0.022 265);
--color-tfa17-edge: #e3e1ec;
--color-tfa17-edge: oklch(0.91 0.012 265);
--color-tfa17-tint: #ebe8fa;
--color-tfa17-tint: oklch(0.93 0.03 268);
--color-tfa17-tinthover: #ded8f7;
--color-tfa17-tinthover: oklch(0.89 0.05 268);
--color-tfa17-acc: #5238c8;
--color-tfa17-acc: oklch(0.45 0.2 268);
--font-tfa17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-17 {
width: 100%;
min-height: 100svh;
}
.tfa-17 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-17 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .38s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .38s allow-discrete;
}
.tfa-17 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-17 details::details-content {
transition-duration: 1ms;
}
}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-tfa17-bg: #f0f0f7;
--color-tfa17-bg: oklch(0.95 0.012 265);
--color-tfa17-ink: #2a2733;
--color-tfa17-ink: oklch(0.24 0.03 268);
--color-tfa17-mut: #5d596b;
--color-tfa17-mut: oklch(0.47 0.022 265);
--color-tfa17-edge: #e3e1ec;
--color-tfa17-edge: oklch(0.91 0.012 265);
--color-tfa17-tint: #ebe8fa;
--color-tfa17-tint: oklch(0.93 0.03 268);
--color-tfa17-tinthover: #ded8f7;
--color-tfa17-tinthover: oklch(0.89 0.05 268);
--color-tfa17-acc: #5238c8;
--color-tfa17-acc: oklch(0.45 0.2 268);
--font-tfa17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-17 {
width: 100%;
min-height: 100svh;
}
.tfa-17 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-17 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .38s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .38s allow-discrete;
}
.tfa-17 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-17 details::details-content {
transition-duration: 1ms;
}
}@import "tailwindcss";
@theme {
--color-tfa17-bg: #f0f0f7;
--color-tfa17-bg: oklch(0.95 0.012 265);
--color-tfa17-ink: #2a2733;
--color-tfa17-ink: oklch(0.24 0.03 268);
--color-tfa17-mut: #5d596b;
--color-tfa17-mut: oklch(0.47 0.022 265);
--color-tfa17-edge: #e3e1ec;
--color-tfa17-edge: oklch(0.91 0.012 265);
--color-tfa17-tint: #ebe8fa;
--color-tfa17-tint: oklch(0.93 0.03 268);
--color-tfa17-tinthover: #ded8f7;
--color-tfa17-tinthover: oklch(0.89 0.05 268);
--color-tfa17-acc: #5238c8;
--color-tfa17-acc: oklch(0.45 0.2 268);
--font-tfa17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-17 {
width: 100%;
min-height: 100svh;
}
.tfa-17 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-17 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .38s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .38s allow-discrete;
}
.tfa-17 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-17 details::details-content {
transition-duration: 1ms;
}
}<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-layer shadows survive the port intact inside
shadow-[...], which is worth stating plainly: comma-separated layers,oklch()colours with alpha, and negative offsets all pass through as long as spaces are underscores. - The CSS version kept the stack in three
--shadow-*custom properties, which was genuinely tidier to reuse. The v4 equivalent is@theme--shadow-rest/--shadow-openentries mintingshadow-rest/shadow-openutilities — do that the moment a second component needs the same elevation set. [&:not([open]):hover]:replaces.item:not([open]):hoverfor both the shadow and the lift, so the two halves of the hover state cannot drift apart.- UI upgrade from the CSS original: muted copy
oklch(0.5)→0.47, accent0.52→0.45, and the icon chip gained a darker hover tint — the original's 10% mix was under 3:1 against the card and effectively invisible. - UI upgrade: the page ground dropped from
oklch(0.96)to0.95. Elevation systems need a mid-tone surface; the original was close enough to white that the resting shadow barely registered.
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 Card-Style FAQ Panels with a Layered Shadow Elevation System
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-card-style-faq-panels-elevation-shadow/
Separated FAQ cards with a real elevation system: three levels (resting, hover, open) built from layered shadows that mimic how light actually falls — a tight dark contact layer plus a wide soft ambient one — instead of the single fuzzy grey blob of tutorial CSS. Cards lift 2px on hover and rise to full elevation when open, with the shadow tinted in the page's own hue rather than black.
## HTML
```html
<section class="tfa-17 w-full min-h-svh grid place-items-center bg-tfa17-bg font-tfa17-sans text-tfa17-ink px-5 py-12">
<div class="w-[min(640px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.6vw,38px)] font-extrabold tracking-[-0.025em]">Warranty & repairs</h1>
<p class="mt-3 max-w-[52ch] text-[14.5px] leading-relaxed text-tfa17-mut">Three elevations: resting, hover-lift, open. Every shadow is two layers — contact plus ambient — in the page's own hue.</p>
</header>
<div data-panel class="mt-7 flex flex-col gap-4">
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">What does the warranty cover?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Two years, parts and labour, covering manufacturing defects and battery health below 80%. Accidental damage is a separate care plan — but out-of-warranty repairs are flat-rate and published, never “send it in for a quote”.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">How do I start a repair?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Run the diagnostic in the app, which pre-fills the repair ticket with logs. A prepaid label arrives by email; most repairs turn around in five business days door to door, with a loaner option on the care plan.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Can I repair it myself?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Yes — self-repair kits with genuine parts, tools and guides cover the battery, screen and buttons. DIY repairs with our parts do not void the warranty; third-party parts void only the affected subsystem.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Is water damage covered?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">IP67 failures within rating are warranty repairs — a pressure test tells us quickly. Beyond-rating exposure (diving, jacuzzi chemistry) falls to the care plan accidental tier at the flat rate.</p>
</details>
</div>
<p class="mt-6 text-[12.5px] text-tfa17-mut">Shadow recipe: tight contact layer plus wide ambient layer, tinted in the page hue. Never plain black.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tfa17-bg: #f0f0f7;
--color-tfa17-bg: oklch(0.95 0.012 265);
--color-tfa17-ink: #2a2733;
--color-tfa17-ink: oklch(0.24 0.03 268);
--color-tfa17-mut: #5d596b;
--color-tfa17-mut: oklch(0.47 0.022 265);
--color-tfa17-edge: #e3e1ec;
--color-tfa17-edge: oklch(0.91 0.012 265);
--color-tfa17-tint: #ebe8fa;
--color-tfa17-tint: oklch(0.93 0.03 268);
--color-tfa17-tinthover: #ded8f7;
--color-tfa17-tinthover: oklch(0.89 0.05 268);
--color-tfa17-acc: #5238c8;
--color-tfa17-acc: oklch(0.45 0.2 268);
--font-tfa17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-17 {
width: 100%;
min-height: 100svh;
}
.tfa-17 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-17 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .38s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .38s allow-discrete;
}
.tfa-17 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-17 details::details-content {
transition-duration: 1ms;
}
}
```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 Card-Style FAQ Panels with a Layered Shadow Elevation System
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-card-style-faq-panels-elevation-shadow/
Separated FAQ cards with a real elevation system: three levels (resting, hover, open) built from layered shadows that mimic how light actually falls — a tight dark contact layer plus a wide soft ambient one — instead of the single fuzzy grey blob of tutorial CSS. Cards lift 2px on hover and rise to full elevation when open, with the shadow tinted in the page's own hue rather than black.
## HTML
```html
<section class="tfa-17 w-full min-h-svh grid place-items-center bg-tfa17-bg font-tfa17-sans text-tfa17-ink px-5 py-12">
<div class="w-[min(640px,100%)]">
<header>
<h1 class="text-[clamp(26px,4.6vw,38px)] font-extrabold tracking-[-0.025em]">Warranty & repairs</h1>
<p class="mt-3 max-w-[52ch] text-[14.5px] leading-relaxed text-tfa17-mut">Three elevations: resting, hover-lift, open. Every shadow is two layers — contact plus ambient — in the page's own hue.</p>
</header>
<div data-panel class="mt-7 flex flex-col gap-4">
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">What does the warranty cover?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Two years, parts and labour, covering manufacturing defects and battery health below 80%. Accidental damage is a separate care plan — but out-of-warranty repairs are flat-rate and published, never “send it in for a quote”.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">How do I start a repair?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Run the diagnostic in the app, which pre-fills the repair ticket with logs. A prepaid label arrives by email; most repairs turn around in five business days door to door, with a loaner option on the care plan.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Can I repair it myself?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">Yes — self-repair kits with genuine parts, tools and guides cover the battery, screen and buttons. DIY repairs with our parts do not void the warranty; third-party parts void only the affected subsystem.</p>
</details>
<details class="group rounded-[18px] border border-tfa17-edge bg-white shadow-[0_1px_2px_oklch(0.35_0.04_265/0.1),0_4px_12px_oklch(0.35_0.04_265/0.07)] [&:not([open]):hover]:shadow-[0_2px_3px_oklch(0.35_0.04_265/0.12),0_8px_20px_oklch(0.35_0.04_265/0.1)] [&:not([open]):hover]:-translate-y-0.5 open:shadow-[0_2px_4px_oklch(0.35_0.04_265/0.12),0_12px_32px_oklch(0.35_0.04_265/0.14),0_24px_60px_oklch(0.35_0.04_265/0.1)] open:-translate-y-0.5 open:border-transparent transition-[box-shadow,translate,border-color] duration-350 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-5 py-[18px] text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa17-acc focus-visible:rounded-[18px] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-tfa17-acc [&::-webkit-details-marker]:hidden">Is water damage covered?
<span aria-hidden="true" class="grid size-7 shrink-0 place-items-center rounded-[10px] bg-tfa17-tint text-tfa17-acc transition-[rotate,background-color] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] group-hover:bg-tfa17-tinthover group-open:rotate-180 motion-reduce:transition-colors"><svg viewBox="0 0 16 16" width="13" height="13"><path d="M3 6l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span>
</summary>
<p class="max-w-[58ch] px-5 pb-[19px] text-[14px] leading-[1.7] text-tfa17-mut">IP67 failures within rating are warranty repairs — a pressure test tells us quickly. Beyond-rating exposure (diving, jacuzzi chemistry) falls to the care plan accidental tier at the flat rate.</p>
</details>
</div>
<p class="mt-6 text-[12.5px] text-tfa17-mut">Shadow recipe: tight contact layer plus wide ambient layer, tinted in the page hue. Never plain black.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tfa17-bg: #f0f0f7;
--color-tfa17-bg: oklch(0.95 0.012 265);
--color-tfa17-ink: #2a2733;
--color-tfa17-ink: oklch(0.24 0.03 268);
--color-tfa17-mut: #5d596b;
--color-tfa17-mut: oklch(0.47 0.022 265);
--color-tfa17-edge: #e3e1ec;
--color-tfa17-edge: oklch(0.91 0.012 265);
--color-tfa17-tint: #ebe8fa;
--color-tfa17-tint: oklch(0.93 0.03 268);
--color-tfa17-tinthover: #ded8f7;
--color-tfa17-tinthover: oklch(0.89 0.05 268);
--color-tfa17-acc: #5238c8;
--color-tfa17-acc: oklch(0.45 0.2 268);
--font-tfa17-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-17 {
width: 100%;
min-height: 100svh;
}
.tfa-17 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-17 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .38s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .38s allow-discrete;
}
.tfa-17 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-17 details::details-content {
transition-duration: 1ms;
}
}
```How this works
Real shadows have two parts, because real light does. A tight, darker contact layer sells that the card touches the surface; a wide, soft ambient layer sells the room's light. One-layer shadows always look painted on because they can only be one of the two. The open state adds a third atmosphere layer at low alpha.
Colour matters more than blur. Every layer is a desaturated version of the page's own blue-violet, not black: black shadows grey out coloured backgrounds, while same-hue shadows read as shade. In Tailwind that means writing oklch(0.35_0.04_265/0.1) inside the arbitrary value — underscores for spaces, and the alpha stays in the colour function.
Elevation is state. Resting cards sit nearly flat; hover lifts 2px with a slightly deeper stack (you can pick me up); open cards rise to the full three-layer stack while the border fades out. [&:not([open]):hover]: is what keeps those two from fighting — in CSS it was .item:not([open]):hover.
Performance honesty: animating box-shadow repaints. For a handful of cards on state change it is imperceptible; for 60fps scroll-linked effects you would animate a pseudo-element's opacity instead. Knowing when not to optimise is the skill.
Make it yours
- Elevation set: the three shadow utilities are your system — reuse them on modals and dropdowns so depth stays consistent app-wide. Promote them to
@theme--shadow-*entries to getshadow-rest/shadow-opennames. - Shadow hue: change the oklch hue to match your background's undertone; keep chroma near 0.04 or shadows go neon.
- Flat-until-touched: drop the resting shadow for cards that only elevate on interaction — a quieter variant.
- Radius pairing: big shadows want big radii (18px here); tight radii with huge shadows reads uncanny.
Gotchas — read before shipping
- Never
transition-allwith shadows — you will animate layout properties by accident. Name the three properties. - Layered shadows multiply alpha where they overlap: keep individual layers under about 0.15 or the stack muddies.
- Shadows are invisible on pure black and harsh on pure white. Mid-tone tinted backgrounds are where elevation systems live.
- Do not lift on hover for touch-primary UIs — there is no hover, and the open elevation already carries the state.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 129+ | not yet | not yet | 129+ |
Floor set by oklch(), interpolate-size as this demo is written. The core technique itself goes back further — Chrome 111+.
Layered box-shadows and translate transitions are universal; the oklch() shadow colours and Tailwind v4's sheet set the floor. The animated panel enhances progressively.