Big Questions Accordion
Original · freeA large-type editorial FAQ accordion.
Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.
npx shadcn@latest add https://webinnoventix.com/r/accordion-big-questions.json"use client";
import { useId, useRef, useState, type KeyboardEvent } from "react";
type QA = {
q: string;
a: string;
tag: string;
};
const FAQS: QA[] = [
{
tag: "Timeline",
q: "How long before we see real results?",
a: "Most sites feel faster and cleaner within the first two weeks. Meaningful search movement — new rankings, more qualified traffic — typically lands between month three and month six. We work in shippable increments, so you never wait months to see the first proof it is working.",
},
{
tag: "Pricing",
q: "What does a project actually cost?",
a: "We scope every engagement to the outcome you need, not an hourly meter. A focused landing page rebuild starts around a fixed project fee; ongoing growth work runs on a flat monthly retainer. You get the full number, in writing, before we begin — no surprise line items and no lock-in.",
},
{
tag: "Process",
q: "Do I have to hand over my whole website?",
a: "No. We work inside your existing stack and access only what the task requires. You keep ownership of every account, domain, and repository. If we build something new, it ships to you documented and portable — the work is yours the day we finish.",
},
{
tag: "Scope",
q: "Can you take over a project someone else started?",
a: "Often, yes. We begin with a short audit of what exists, tell you honestly what is worth keeping, and give you a plan to finish or replace the rest. Inherited codebases are one of the most common ways clients reach us — you are not the first, and we will not judge the last team's shortcuts.",
},
{
tag: "Support",
q: "What happens after the site goes live?",
a: "Launch is a milestone, not the finish line. Every build ships with a thirty-day fix window at no charge, and you can move onto a maintenance plan for monitoring, updates, and monthly improvements. If you would rather run it in-house, we hand off clean documentation so your team is never stuck.",
},
];
export default function AccordionBigQuestions() {
const [open, setOpen] = useState<number | null>(0);
const baseId = useId();
const btnRefs = useRef<(HTMLButtonElement | null)[]>([]);
const toggle = (i: number) => setOpen((cur) => (cur === i ? null : i));
const onKeyDown = (e: KeyboardEvent, i: number) => {
const last = FAQS.length - 1;
let next: number | null = null;
if (e.key === "ArrowDown") next = i === last ? 0 : i + 1;
else if (e.key === "ArrowUp") next = i === 0 ? last : i - 1;
else if (e.key === "Home") next = 0;
else if (e.key === "End") next = last;
if (next !== null) {
e.preventDefault();
btnRefs.current[next]?.focus();
}
};
return (
<section className="relative w-full overflow-hidden bg-white px-6 py-24 text-slate-900 sm:py-32 dark:bg-slate-950 dark:text-slate-100">
<style>{`
@keyframes bq-reveal-abq {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
.bq-panel-abq[data-open="true"] .bq-inner-abq {
animation: bq-reveal-abq 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@media (prefers-reduced-motion: reduce) {
.bq-panel-abq[data-open="true"] .bq-inner-abq { animation: none; }
.bq-chev-abq { transition: none !important; }
.bq-grid-abq { transition: none !important; }
}
`}</style>
{/* soft ambient accents */}
<div
aria-hidden
className="pointer-events-none absolute -left-32 top-0 h-96 w-96 rounded-full bg-indigo-200/40 blur-3xl dark:bg-indigo-500/10"
/>
<div
aria-hidden
className="pointer-events-none absolute -right-24 bottom-0 h-80 w-80 rounded-full bg-violet-200/40 blur-3xl dark:bg-violet-500/10"
/>
<div className="relative mx-auto max-w-4xl">
<div className="mb-14 max-w-2xl sm:mb-20">
<span className="inline-flex items-center gap-2 rounded-full border border-slate-200 bg-slate-50 px-3 py-1 text-xs font-medium uppercase tracking-widest text-slate-500 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-400">
<span className="h-1.5 w-1.5 rounded-full bg-indigo-500" />
Frequently asked
</span>
<h2 className="mt-6 text-4xl font-semibold tracking-tight text-slate-900 sm:text-6xl dark:text-white">
The big questions,{" "}
<span className="text-indigo-600 dark:text-indigo-400">
answered plainly.
</span>
</h2>
<p className="mt-5 text-lg leading-relaxed text-slate-600 dark:text-slate-400">
No fine print, no runaround. Here is exactly how we work, what it
costs, and what you own when it is done.
</p>
</div>
<div className="divide-y divide-slate-200 border-y border-slate-200 dark:divide-slate-800 dark:border-slate-800">
{FAQS.map((item, i) => {
const isOpen = open === i;
const panelId = `${baseId}-panel-${i}`;
const headerId = `${baseId}-header-${i}`;
return (
<div key={item.q} className="group">
<h3>
<button
ref={(el) => {
btnRefs.current[i] = el;
}}
id={headerId}
type="button"
aria-expanded={isOpen}
aria-controls={panelId}
onClick={() => toggle(i)}
onKeyDown={(e) => onKeyDown(e, i)}
className="flex w-full items-start gap-5 py-7 text-left outline-none transition-colors sm:py-9 focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-4 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-950"
>
<span className="mt-2 hidden w-10 shrink-0 font-mono text-sm text-slate-400 tabular-nums sm:block dark:text-slate-600">
{String(i + 1).padStart(2, "0")}
</span>
<span className="flex-1">
<span className="mb-2 block text-xs font-semibold uppercase tracking-widest text-indigo-600 dark:text-indigo-400">
{item.tag}
</span>
<span
className={`block text-2xl font-medium leading-snug tracking-tight transition-colors sm:text-3xl ${
isOpen
? "text-slate-900 dark:text-white"
: "text-slate-700 group-hover:text-slate-900 dark:text-slate-300 dark:group-hover:text-white"
}`}
>
{item.q}
</span>
</span>
<span
aria-hidden
className={`bq-chev-abq mt-2 flex h-9 w-9 shrink-0 items-center justify-center rounded-full border transition-all duration-300 ${
isOpen
? "rotate-45 border-indigo-500 bg-indigo-500 text-white dark:border-indigo-400 dark:bg-indigo-500"
: "border-slate-300 text-slate-500 group-hover:border-slate-400 group-hover:text-slate-700 dark:border-slate-700 dark:text-slate-400 dark:group-hover:border-slate-500 dark:group-hover:text-slate-200"
}`}
>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
className="h-4 w-4"
>
<path d="M12 5v14M5 12h14" />
</svg>
</span>
</button>
</h3>
<div
id={panelId}
role="region"
aria-labelledby={headerId}
hidden={!isOpen}
data-open={isOpen}
className="bq-panel-abq bq-grid-abq grid transition-[grid-template-rows] duration-300 ease-out"
style={{ gridTemplateRows: isOpen ? "1fr" : "0fr" }}
>
<div className="overflow-hidden">
<div className="bq-inner-abq pb-9 pl-0 pr-4 sm:pl-[3.75rem]">
<p className="max-w-2xl text-lg leading-relaxed text-slate-600 dark:text-slate-400">
{item.a}
</p>
</div>
</div>
</div>
</div>
);
})}
</div>
<div className="mt-14 flex flex-col items-start gap-4 rounded-2xl bg-slate-50 p-8 sm:flex-row sm:items-center sm:justify-between dark:bg-slate-900">
<div>
<p className="text-lg font-medium text-slate-900 dark:text-white">
Still have a question?
</p>
<p className="mt-1 text-slate-600 dark:text-slate-400">
Ask us directly — we reply to every message within one business
day.
</p>
</div>
<a
href="#contact"
className="inline-flex shrink-0 items-center gap-2 rounded-full bg-indigo-600 px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-indigo-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-50 dark:focus-visible:ring-offset-slate-900"
>
Talk to us
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4"
aria-hidden
>
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</a>
</div>
</div>
</section>
);
}Dependencies
Licence
Built by Web Innoventix. Free for personal and commercial use, no attribution required.
Built by Web Innoventix
Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.
Get a free quoteSimilar components
Browse all →
Simple Accordion
OriginalA clean single-column accordion, one panel open at a time, chevron rotates.

Multi Accordion
OriginalAn accordion where multiple panels can be open at once.

Plus Minus Accordion
OriginalAccordion with a plus/minus icon that toggles per item.

Bordered Accordion
OriginalBordered card-style accordion panels with rounded corners.

Filled Accordion
OriginalFilled, tinted accordion panels; the active one is highlighted.

FAQ Two Col Accordion
OriginalA two-column FAQ accordion layout.

Numbered Accordion
OriginalA numbered-step accordion (01, 02, 03...).
Icon Left Accordion
OriginalAccordion with a leading icon per item and a right chevron.

Gradient Active Accordion
OriginalAccordion where the open panel gets a soft gradient background.

Nested Accordion
OriginalAn accordion with nested sub-accordions.

Flush Accordion
OriginalA borderless, flush accordion separated by hairlines.

Pill Accordion
OriginalAccordion with rounded pill-shaped headers.

