Skip to content
Neat LabsJoin the waitlist

FAQ disclosure

Questions in native <details> elements with a plus that turns into a cross when open.

id faq-disclosure · revision 00e6e8d41633 · catalogue 0.1.0

Preview

What this style doesn't cover

  • Inter isn't loaded by this package. It shows only where the font is installed; elsewhere the stack falls back to ui-sans-serif, system-ui, sans-serif.
Desktop, 1280px, lightOpen alone
Phone, 390px, lightOpen alone
Desktop, 1280px, darkOpen alone
Phone, 390px, darkOpen alone

Hover and keyboard focus

The component's own hover and focus styles, switched on for every link and button at once so you can see them without a mouse. In the previews above they work as usual.

Hover, desktop, lightOpen alone
Keyboard focus, desktop, lightOpen alone

Copy it

These two files are exactly what the previews above render. The MCP tool get_component returns the same files.

  1. Save FaqDisclosure.tsx with your components and styles/neat-harbor.css with your styles.
  2. Import styles/neat-harbor.css once, after @import "tailwindcss" in your global stylesheet.
  3. Make sure Tailwind scans the folder that holds the component.
  4. For dark mode, set data-theme="dark" on the <html> element.
components/FaqDisclosure.tsx
export interface Question {
  question: string;
  answer: string;
}

export interface FaqDisclosureProps {
  heading?: string;
  questions?: Question[];
  /** Index of the question that starts open. Omit to start with all closed. */
  openIndex?: number;
}

const focusRing =
  "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--nl-focus)]";

/**
 * Questions as native disclosure widgets. Keyboard and screen reader support
 * come from <details> and <summary>, and it needs no client JavaScript.
 */
export function FaqDisclosure({
  heading = "Questions",
  questions = [
    { question: "Does anything publish without approval?", answer: "No. Every draft waits for someone on your team to approve it." },
    { question: "Which repositories can I connect?", answer: "Any GitHub repository you can install an app on, public or private." },
    { question: "Can I export my notes?", answer: "Yes. Download every note as Markdown from the settings page." },
    { question: "What happens when my trial ends?", answer: "Your drafts stay. Publishing pauses until you choose a plan." },
  ],
  openIndex,
}: FaqDisclosureProps) {
  return (
    <section className="bg-[color:var(--nl-canvas)] px-6 py-[var(--nl-section-y)] font-[family-name:var(--nl-font-sans)] text-[color:var(--nl-ink)]">
      <div className="mx-auto max-w-3xl">
        <h2 className="font-[family-name:var(--nl-font-display)] text-3xl font-semibold sm:text-4xl">{heading}</h2>
        <div className="mt-10 divide-y divide-[color:var(--nl-line)] border-y border-[color:var(--nl-line)]">
          {questions.map((item, index) => (
            <details key={item.question} open={index === openIndex} className="group">
              <summary
                className={`flex cursor-pointer list-none items-center justify-between gap-6 rounded-[var(--nl-radius)] py-5 font-medium [&::-webkit-details-marker]:hidden ${focusRing}`}
              >
                {item.question}
                <span aria-hidden="true" className="font-[family-name:var(--nl-font-mono)] text-[color:var(--nl-muted)] group-open:rotate-45 motion-safe:transition-transform">
                  +
                </span>
              </summary>
              <p className="pb-6 leading-relaxed text-[color:var(--nl-muted)]">{item.answer}</p>
            </details>
          ))}
        </div>
      </div>
    </section>
  );
}
styles/neat-harbor.css
/* Neat Labs theme "harbor" (revision 99a4282efae6) for faq-disclosure (revision 00e6e8d41633), catalogue 0.1.0. */
:root {
  --nl-canvas: #F7F9FC;
  --nl-ink: #0E1726;
  --nl-muted: #4A5568;
  --nl-line: #D8DEE8;
  --nl-focus: #0369A1;
  --nl-font-display: "Inter", ui-sans-serif, system-ui, sans-serif;
  --nl-font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  --nl-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --nl-radius: 12px;
  --nl-section-y: 112px;
}

[data-theme="dark"] {
  --nl-canvas: #0B1220;
  --nl-ink: #E6EDF7;
  --nl-muted: #9AA8BD;
  --nl-line: #24324A;
  --nl-focus: #7DD3FC;
}
MCP tool call
{
  "name": "get_component",
  "arguments": {
    "id": "faq-disclosure",
    "style": "harbor"
  }
}

In every style