agency-web/app/components/Faq.tsx

62 lines
1.9 KiB
TypeScript

"use client";
/**
* Faq — accessible accordion built on real <button> controls with
* aria-expanded / aria-controls and a CSS grid-rows reveal (no JS height math,
* animates cleanly, collapsible content stays in the DOM for SEO/AEO). The
* answer copy matches the FAQPage JSON-LD in layout.tsx verbatim.
*/
import { useState } from "react";
import Reveal from "./Reveal";
import { faqs } from "../content";
export default function Faq() {
const [open, setOpen] = useState<number | null>(0);
return (
<section id="faq" className="faq" aria-label="Frequently asked questions">
<div className="wrap faq__inner">
<div className="faq__head">
<p className="kicker">FAQ</p>
<h2 className="section__title">
Questions about working with a digital marketing agency
</h2>
</div>
<div className="faq__list">
{faqs.map((f, i) => {
const isOpen = open === i;
return (
<div className="faq__item" key={f.q} data-open={isOpen}>
<h3>
<button
type="button"
className="faq__q hoverable"
aria-expanded={isOpen}
aria-controls={`faq-a-${i}`}
id={`faq-q-${i}`}
onClick={() => setOpen(isOpen ? null : i)}
>
{f.q}
<span className="faq__icon" aria-hidden="true" />
</button>
</h3>
<div
className="faq__a"
id={`faq-a-${i}`}
role="region"
aria-labelledby={`faq-q-${i}`}
>
<div className="faq__a-inner">
<p>{f.a}</p>
</div>
</div>
</div>
);
})}
</div>
</div>
</section>
);
}