Swaps navbar layout (theme toggle left, nav links right), replaces the mobile dropdown with a fullscreen overlay whose items fly in top-to-bottom, and renames the site-wide "slate" gray to "neutral" to remove a blue undertone that clashed with the brand green. Also converts the flat saturated-green YouTube and stats sections into dark backgrounds with green used only as an accent, matching typical premium car-audio branding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
50 lines
1.9 KiB
JavaScript
50 lines
1.9 KiB
JavaScript
import { useState } from 'react';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
|
|
export default function Accordion({ items }) {
|
|
const [openIndex, setOpenIndex] = useState(null);
|
|
|
|
return (
|
|
<div className="divide-y divide-neutral-200 rounded-xl border border-neutral-200 bg-white dark:divide-neutral-800 dark:border-neutral-800 dark:bg-neutral-900">
|
|
{items.map((item, i) => {
|
|
const isOpen = openIndex === i;
|
|
return (
|
|
<div key={item.question}>
|
|
<button
|
|
onClick={() => setOpenIndex(isOpen ? null : i)}
|
|
className="flex w-full items-center justify-between gap-4 px-5 py-4 text-left"
|
|
aria-expanded={isOpen}
|
|
>
|
|
<span className="font-medium text-neutral-900 dark:text-white">{item.question}</span>
|
|
<motion.svg
|
|
animate={{ rotate: isOpen ? 180 : 0 }}
|
|
transition={{ duration: 0.2 }}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
className="h-5 w-5 shrink-0 text-neutral-500"
|
|
>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="m6 9 6 6 6-6" />
|
|
</motion.svg>
|
|
</button>
|
|
<AnimatePresence initial={false}>
|
|
{isOpen && (
|
|
<motion.div
|
|
initial={{ height: 0, opacity: 0 }}
|
|
animate={{ height: 'auto', opacity: 1 }}
|
|
exit={{ height: 0, opacity: 0 }}
|
|
transition={{ duration: 0.25, ease: 'easeInOut' }}
|
|
className="overflow-hidden"
|
|
>
|
|
<p className="px-5 pb-4 text-sm text-neutral-600 dark:text-neutral-300">{item.answer}</p>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|