FAQ Accordion
Two-column FAQ: sticky title + support CTA on the left, numbered accordion cards on the right with a yellow plus that rotates into an ink cross when open. Built on Radix Accordion.
brutalist/section/faq-accordionSource
"use client";
import { Accordion } from "radix-ui";
import { Plus } from "lucide-react";
import { cn } from "@/lib/utils";
export interface FaqAccordionItem {
question: string;
answer: string;
}
export interface FaqAccordionProps {
kicker?: string;
title?: string;
description?: string;
contact?: { label: string; href: string };
items?: FaqAccordionItem[];
/** Allow several answers open at once. */
multiple?: boolean;
className?: string;
}
const DEFAULT_ITEMS: FaqAccordionItem[] = [
{
question: "Do I need to change how my team writes pull requests?",
answer: "No. Shipyard reads the labels you already use (feature, fix, improvement…) and the PR title. You can optionally add a “## Release note” block in the PR description to override the generated text.",
},
{
question: "Which Git providers are supported?",
answer: "GitHub (cloud and Enterprise Server 3.8+), GitLab (cloud and self-managed 16+) and Bitbucket Cloud. Monorepos are supported with path-based project routing.",
},
{
question: "Is the AI summary sent to users without review?",
answer: "Never by default. Summaries land as drafts. You can enable auto-publish per project once you trust the output, with a minimum-confidence threshold.",
},
{
question: "Can I host the changelog on my own domain?",
answer: "Yes, on Team and Scale. Point a CNAME (e.g. changelog.yourapp.com) to us and we provision TLS automatically within a few minutes.",
},
{
question: "What happens to my data if I cancel?",
answer: "You can export every release as Markdown or JSON at any time. After cancellation your public page stays read-only for 30 days, then everything is deleted.",
},
];
export function FaqAccordion({
kicker = "[ 06 ] FAQ",
title = "Questions, answered bluntly.",
description = "Still stuck? Our engineers answer support tickets — usually in under two hours.",
contact = { label: "Contact support", href: "#support" },
items = DEFAULT_ITEMS,
multiple = false,
className,
}: FaqAccordionProps) {
const list = items.map((item, i) => (
<Accordion.Item key={item.question} value={`item-${i}`} className="da-stroke bg-da-surface text-da-surface-fg shadow-da-sm has-[[data-state=open]]:shadow-da-md">
<Accordion.Header asChild>
<h3>
<Accordion.Trigger className="da-focus group flex w-full items-center gap-4 p-5 text-left text-lg font-bold">
<span aria-hidden className="font-da-mono text-xs text-da-muted-fg">
{String(i + 1).padStart(2, "0")}
</span>
<span className="flex-1">{item.question}</span>
<span
aria-hidden
className="da-stroke da-transition grid size-8 shrink-0 place-items-center bg-da-primary text-da-primary-fg group-data-[state=open]:bg-da-fg group-data-[state=open]:text-da-bg"
>
<Plus className="da-transition size-4 group-data-[state=open]:rotate-45" strokeWidth={3} />
</span>
</Accordion.Trigger>
</h3>
</Accordion.Header>
<Accordion.Content className="da-stroke-t overflow-hidden px-5 pt-4 pb-5 text-da-muted-fg">
<p className="max-w-2xl leading-relaxed">{item.answer}</p>
</Accordion.Content>
</Accordion.Item>
));
return (
<section className={cn("da-section da-stroke-b bg-da-bg text-da-fg", className)} aria-labelledby="faq-accordion-title">
<div className="da-container grid gap-10 lg:grid-cols-[1fr_1.6fr]">
<div className="lg:sticky lg:top-24 lg:self-start">
<p className="font-da-mono text-xs font-bold tracking-da-label text-da-muted-fg uppercase">{kicker}</p>
<h2 id="faq-accordion-title" className="mt-3 font-da-display text-[clamp(2rem,5vw,3.5rem)] leading-[0.95] tracking-da-display uppercase">
{title}
</h2>
<p className="mt-4 text-lg text-da-muted-fg">{description}</p>
<a
href={contact.href}
className="da-focus da-transition da-stroke mt-6 inline-block bg-da-surface px-5 py-3 font-bold text-da-surface-fg shadow-da-sm hover:translate-x-[3px] hover:translate-y-[3px] hover:shadow-none"
>
{contact.label} →
</a>
</div>
{multiple ? (
<Accordion.Root type="multiple" className="flex flex-col gap-4">
{list}
</Accordion.Root>
) : (
<Accordion.Root type="single" collapsible defaultValue="item-0" className="flex flex-col gap-4">
{list}
</Accordion.Root>
)}
</div>
</section>
);
}
export default FaqAccordion;
modules/brutalist/section/faq-accordion/index.tsx
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| kicker | string | "[ 06 ] FAQ" | Mono label above the title. |
| title | string | "Questions, answered bluntly." | Section title (h2). |
| description | string | — | Paragraph under the title. |
| contact | { label: string; href: string } | Contact support | Support link under the description. |
| items | FaqAccordionItem[] | 5 Shipyard questions | { question, answer }. |
| multiple | boolean | false | Allow several answers open at once (otherwise the first is open by default). |
| className | string | — | Extra classes on the <section>. |
Other faq variants in Brutalist
FAQ Categories
Help-center style FAQ: topic buttons with counts on the left (stacked on desktop, wrapped on mobile), and a ruled accordion on the right whose open question floods yellow.
FAQ Grid
Always-open FAQ grid: ruled cells (1/2/3 columns) with a yellow question-mark square, uppercase question and answer, closed by a full-width ink contact row. No interaction needed.
FAQ Search
Searchable FAQ: a huge ruled search field that presses in on focus, live result count, and native <details> cards with tags; a pink empty state points to support.
FAQ in other art directions
Faq Cards
All-open FAQ: a 3-column grid of glass cards, each with a gradient number badge, question and answer, followed by a glass contact pill with an ink button.
Faq Chat
FAQ as a chat: suggested question chips on the left; picking one adds a gradient user bubble and, after a typing indicator, a glass answer bubble in the conversation panel.
FAQ Glass
Centered FAQ with stacked frosted accordion cards; the plus button spins into a gradient cross with a slight overshoot and answers expand smoothly. Built on Radix Accordion.
Faq Search
Help-center FAQ: large glass search pill filtering a frosted Radix accordion live, with category tags, result count and highlighted matches; empty state.
Faq Grid
All answers visible at once: a three-column grid of short questions and answers under a header, followed by two support link cards (documentation, talk to us).
Faq List
Centered single-column FAQ built on native details/summary (zero JS): hairline dividers, a plus icon that rotates into a cross when open, and a contact line underneath.
FAQ Split
Two-column FAQ: title, description and support link on the left, hairline-divided Radix accordion on the right with a rotating chevron and a smooth height + fade expand.
Faq Tabs
FAQ grouped by category behind an underline tab bar (Radix Tabs, with counts); the active category shows every question and answer in a two-column definition list.
Faq Inline
Ultra-compact FAQ: short questions and one-line answers flowing as a 3-column grid of mono question labels over large answers — scannable in seconds.
Faq List
Numbered accordion FAQ in a ruled list: mono index + question, a +/− glyph that swaps, answer indented under the question; left column holds the label and title.
Faq Split
Always-open FAQ as a two-column definition list (question left in medium weight, answer right in muted text) on hairline rows, followed by a mono contact line.
Faq Tabs
FAQ grouped by topic with text tabs (Radix Tabs) underlined in ink when active, and each topic’s answers as a ruled definition list.
Faq Accordion
Two-column FAQ: heading + description + contact link on the left, bordered Radix accordion with plus icons rotating to × on the right.
Faq Security
Security & compliance FAQ: dark-tinted certification cards (SOC 2, ISO 27001, GDPR, PCI) with shield icons, then security questions as native <details> disclosure rows.
Faq Sidebar
Help-center style FAQ: a vertical category nav (left, becomes horizontal scroll chips on mobile) and the selected category’s questions as an open definition list.
Faq Support
Compact 2×3 grid of short Q&As followed by three bordered support channel cards (docs, chat, dedicated support).
Faq Columns
Editorial FAQ: serif title and intro in a narrow left column, questions as a two-column definition list on the right separated by warm hairlines.
Faq Contact
FAQ beside a contact card: native disclosure list on the left, and a clay-tinted card with a sprouting-leaf illustration, email and chat buttons on the right.
Faq Search
Searchable FAQ: rounded search field plus topic pills filter a list of questions (native details), with a friendly empty state and live result count.
Faq Soft
Soft accordion: each question is its own rounded paper pill-card that turns sage when open, with a round plus that rotates into a cross; generous spacing.
Faq Columns
All-visible FAQ: sticky intro with a peach “Chat with us” pill on the left, six Q&As in a 2-column grid with round lavender number badges on the right.
Faq Help
Help-center FAQ: lavender panel with a friendly greeting, big white search pill and popular-search chips; matching answers show as white cards with a peach empty state.
Faq Pills
Single-column FAQ of rounded white blocks on native details/summary; the open item turns lavender and its round chevron button flips and fills periwinkle.
Faq Tinted
FAQ by topic: three big pastel topic buttons (emoji + label) switch the list of white Q&A cards below, which fades in on change.