components/we-inc/card-accordion-with-icons.tsx
import { useState } from "react";
const services = [
{ title: "Check-up and clean", price: "From $95", tone: "bg-teal-100 text-teal-800", icon: "M12 3c-3 0-5 1.5-5 4.5 0 2 .8 3 1 5.5.3 3 .7 7 2 7s1.2-4 2-4 .7 4 2 4 1.7-4 2-7c.2-2.5 1-3.5 1-5.5C17 4.5 15 3 12 3z", body: "A full examination, scale and polish with our hygienist, plus X-rays once every two years. Plan for forty minutes in the chair." },
{ title: "Whitening", price: "From $340", tone: "bg-amber-100 text-amber-800", icon: "M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1M12 8a4 4 0 100 8 4 4 0 000-8z", body: "Custom trays made from a scan of your teeth and two weeks of gel to use at home. Most people see four to six shades lighter." },
{ title: "Emergency appointments", price: "Same day", tone: "bg-rose-100 text-rose-800", icon: "M12 3a9 9 0 100 18 9 9 0 000-18zM12 7v5l3 2", body: "Call before 10am and we will see you the same day for pain, swelling or a broken tooth. Evening slots are kept free on weekdays." },
{ title: "Children's dentistry", price: "Free under 12", tone: "bg-sky-100 text-sky-800", icon: "M8 10a2 2 0 100-4 2 2 0 000 4zM16 10a2 2 0 100-4 2 2 0 000 4zM7 15c1.3 1.6 3 2.5 5 2.5s3.7-.9 5-2.5", body: "Short, gentle visits with a dentist who sees children every day. Fissure sealants and fluoride varnish are included." },
];
export default function CardAccordionWithIcons() {
const [open, setOpen] = useState(0);
return (
<section className="cia bg-[#f6f1ea] px-5 py-16 sm:py-20">
<style>{`
.cia-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .3s cubic-bezier(.2,.7,.2,1); }
.cia-panel[data-open] { grid-template-rows: 1fr; }
@media (prefers-reduced-motion: reduce) { .cia-panel { transition: none; } }
`}</style>
<div className="mx-auto max-w-2xl">
<h2 className="text-center text-2xl font-semibold tracking-tight text-stone-900 sm:text-3xl">Treatments at Brightwater Dental</h2>
<p className="mt-2 text-center text-[15px] text-stone-600">Tap a treatment to see what is included.</p>
<ul className="mt-10 space-y-3">
{services.map((s, i) => {
const isOpen = open === i;
return (
<li key={s.title} className={`rounded-2xl bg-white transition-shadow ${isOpen ? "shadow-md shadow-stone-300/50" : "shadow-sm shadow-stone-200"}`}>
<h3>
<button
type="button"
id={`cia-b${i}`}
aria-expanded={isOpen}
aria-controls={`cia-p${i}`}
onClick={() => setOpen(isOpen ? -1 : i)}
className="flex min-h-[72px] w-full items-center gap-4 rounded-2xl p-4 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stone-800"
>
<span className={`grid h-11 w-11 shrink-0 place-items-center rounded-xl ${s.tone}`}>
<svg viewBox="0 0 24 24" className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d={s.icon} /></svg>
</span>
<span className="flex-1 text-base font-semibold text-stone-900">{s.title}</span>
<span className="hidden text-sm text-stone-600 sm:inline">{s.price}</span>
<svg viewBox="0 0 20 20" className={`h-5 w-5 shrink-0 text-stone-500 transition-transform duration-300 motion-reduce:transition-none ${isOpen ? "rotate-180" : ""}`} fill="none" stroke="currentColor" strokeWidth="1.8" aria-hidden="true"><path d="M5 7.5l5 5 5-5" strokeLinecap="round" strokeLinejoin="round" /></svg>
</button>
</h3>
<div id={`cia-p${i}`} role="region" aria-labelledby={`cia-b${i}`} data-open={isOpen ? "" : undefined} className="cia-panel">
<div className="overflow-hidden" {...(isOpen ? {} : { inert: "" })}>
<div className="px-4 pb-5 sm:pl-[76px]">
<p className="text-[15px] leading-relaxed text-stone-700">{s.body}</p>
<p className="mt-3 text-sm font-medium text-stone-900 sm:hidden">{s.price}</p>
<a href="#" className="mt-4 inline-flex h-10 items-center rounded-full bg-stone-900 px-4 text-sm font-medium text-white hover:bg-stone-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stone-900 focus-visible:ring-offset-2">Book this</a>
</div>
</div>
</div>
</li>
);
})}
</ul>
</div>
</section>
);
}