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

  • --nl-focus: Signal has no focus color. The package uses var(--nl-ink).
  • --nl-section-y: Signal has no section spacing. The package uses 96px.
  • dark mode: Signal has no dark mode. The package uses Light values in every mode.
  • Arial Black isn't loaded by this package. It shows only where the font is installed; elsewhere the stack falls back to "Helvetica Neue", Arial, sans-serif.
  • Helvetica Neue isn't loaded by this package. It shows only where the font is installed; elsewhere the stack falls back to Arial, sans-serif.
Desktop, 1280px, lightOpen alone
Phone, 390px, lightOpen alone

Signal has no dark mode, so only light is shown.

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-signal.css with your styles.
  2. Import styles/neat-signal.css once, after @import "tailwindcss" in your global stylesheet.
  3. Make sure Tailwind scans the folder that holds the component.
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-signal.css
/* Neat Labs theme "signal" (revision 5aa0ba0b4008) for faq-disclosure (revision 00e6e8d41633), catalogue 0.1.0. */
:root {
  --nl-canvas: #FFFFFF;
  --nl-ink: #0A0A0A;
  --nl-muted: #3F3F3F;
  --nl-line: #0A0A0A;
  --nl-focus: var(--nl-ink); /* fallback: not part of the style */
  --nl-font-display: "Arial Black", "Helvetica Neue", Arial, sans-serif;
  --nl-font-sans: "Helvetica Neue", Arial, sans-serif;
  --nl-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --nl-radius: 0px;
  --nl-section-y: 96px; /* fallback: not part of the style */
}
MCP tool call
{
  "name": "get_component",
  "arguments": {
    "id": "faq-disclosure",
    "style": "signal"
  }
}

In every style