{
  "schemaVersion": 1,
  "name": "accordion",
  "useFor": "Use for FAQs or details that can stay collapsed, in a reading column (800px at most). Pull the list out by its row padding (-mx-4) so the questions line up with the heading. The WithTopics example adds topic tabs.",
  "constraints": [
    "Chevrons or typed plus signs",
    "Bold questions",
    "Borders or shadows around each question",
    "More than one answer open by default"
  ],
  "documentation": "",
  "source": "opencommerce-agentcard-web src/components/faq.tsx; src/app/globals.css (details[open] > .faq-answer)",
  "exports": [
    "Accordion",
    "AccordionContent",
    "AccordionItem",
    "AccordionMark",
    "AccordionTrigger"
  ],
  "client": true,
  "docsUrl": "https://opencommerce-ds.vercel.app/components/accordion",
  "markdownUrl": "https://opencommerce-ds.vercel.app/r/accordion.md",
  "examples": [
    {
      "path": "examples/accordion.tsx",
      "content": "import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from \"@/components/ui/accordion\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\n\nconst GENERAL = [\n  { q: \"What is opencommerce?\", a: \"An open router for commerce: one endpoint your agent calls to search, buy and track orders across any online store, built by Agentcard.\" },\n  { q: \"Which stores can my agent buy from?\", a: \"Any online store. The Free plan covers five merchants of your choice; Standard opens every merchant we route to.\" },\n  { q: \"How are payments handled?\", a: \"Cards are tokenized through your payment provider and attached to a customer. Your agent never sees or stores raw card numbers.\" },\n  { q: \"Which agent frameworks does it work with?\", a: \"Anything that can call a tool. The SDK exports a ready-made tool definition, and the same API is available over plain HTTP.\" },\n];\n\nfunction Faq({ items }: { items: { q: string; a: string }[] }) {\n  return (\n    <Accordion type=\"single\" collapsible defaultValue=\"item-0\" className=\"-mx-4 w-[calc(100%+var(--ds-space-8))] max-w-208\">\n      {items.map((item, i) => (\n        <AccordionItem key={item.q} value={`item-${i}`}>\n          <AccordionTrigger>{item.q}</AccordionTrigger>\n          <AccordionContent>{item.a}</AccordionContent>\n        </AccordionItem>\n      ))}\n    </Accordion>\n  );\n}\n\nexport function Site() {\n  return (\n    <div className=\"mx-auto w-full max-w-200 px-4\">\n      <Faq items={GENERAL} />\n    </div>\n  );\n}\n\nexport function WithTopics() {\n  return (\n    <div className=\"mx-auto flex w-full max-w-200 flex-col items-center gap-10 px-4\">\n      <h2 className=\"text-center text-h2 leading-display tracking-tighter\">Questions</h2>\n      <Tabs defaultValue=\"general\" className=\"w-full items-center gap-8\">\n        <TabsList>\n          <TabsTrigger value=\"general\">General</TabsTrigger>\n          <TabsTrigger value=\"payments\">Payments</TabsTrigger>\n          <TabsTrigger value=\"merchants\">Merchants</TabsTrigger>\n        </TabsList>\n        <TabsContent value=\"general\" className=\"w-full\">\n          <Faq items={GENERAL} />\n        </TabsContent>\n        <TabsContent value=\"payments\" className=\"w-full\">\n          <Faq items={GENERAL.slice(2)} />\n        </TabsContent>\n        <TabsContent value=\"merchants\" className=\"w-full\">\n          <Faq items={GENERAL.slice(1, 3)} />\n        </TabsContent>\n      </Tabs>\n    </div>\n  );\n}\n",
      "exports": [
        "Site",
        "WithTopics"
      ],
      "requires": [
        "accordion",
        "tabs"
      ],
      "packages": [],
      "previews": [
        {
          "name": "Site",
          "url": "https://opencommerce-ds.vercel.app/preview/accordion/Site"
        },
        {
          "name": "WithTopics",
          "url": "https://opencommerce-ds.vercel.app/preview/accordion/WithTopics"
        }
      ]
    }
  ],
  "type": "ui",
  "title": "Accordion",
  "description": "Expandable questions or sections with keyboard navigation.",
  "surface": "site",
  "kinds": [
    "faq"
  ],
  "requires": [
    "theme",
    "utils"
  ],
  "packages": [
    "@radix-ui/react-accordion"
  ],
  "files": [
    {
      "path": "components/ui/accordion.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\";\n\nimport { cn } from \"@/lib/utils\";\n\n// The brand's questions (faq.tsx, globals.css details[open] > .faq-answer; computed): rows on 9 percent ink rules, each\n// question in 16px Inter at 20px by 16px, a drawn + at the right (two 1px bars in a 14px box, 64 percent ink). Under the\n// pointer, and while open, a row takes the pale blue on a card drawn 3px inside its edges (6px corners), and the rules on\n// both its edges step aside so the card never sits between lines; the color eases in 200ms. Open, the + turns an eighth\n// into an x and goes blue (200ms ease-out), and the answer (15px Inter at 64 percent ink, 576px wide) slides open and\n// fades up 4px into place. Reduced motion opens it at once. Pull the list out by its padding (-mx-4) so the text lines\n// up with the column.\nfunction Accordion(props: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n  return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\nfunction AccordionItem({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n  return <AccordionPrimitive.Item data-slot=\"accordion-item\" className={cn(\n        \"relative isolate border-b border-line px-4 before:absolute before:inset-x-0 before:inset-y-0.75 before:-z-10 before:rounded-card before:transition-[background-color] before:duration-200 before:ease-out last:border-b-0 hover:border-b-transparent hover:before:bg-blue-5 data-[state=open]:border-b-transparent data-[state=open]:before:bg-blue-5 motion-reduce:before:transition-none [&:has(+:hover)]:border-b-transparent [&:has(+[data-state=open])]:border-b-transparent\",\n        className,\n      )} {...props} />;\n}\n\n/** The question's mark: a 14px plus drawn in two 1px bars. */\nfunction AccordionMark({ className }: { className?: string }) {\n  return (\n    <span aria-hidden data-slot=\"accordion-mark\" className={cn(\"relative size-3.5 shrink-0 text-fg-muted transition-[rotate,color] duration-200 ease-out motion-reduce:transition-[color]\", className)}>\n      <span className=\"absolute top-1/2 left-0 h-px w-3.5 -translate-y-1/2 bg-current\" />\n      <span className=\"absolute top-0 left-1/2 h-3.5 w-px -translate-x-1/2 bg-current\" />\n    </span>\n  );\n}\n\nfunction AccordionTrigger({ className, children, icon, ...props }: React.ComponentProps<typeof AccordionPrimitive.Trigger> & { icon?: React.ReactNode | null }) {\n  return (\n    <AccordionPrimitive.Header className=\"flex\">\n      <AccordionPrimitive.Trigger\n        data-slot=\"accordion-trigger\"\n        className={cn(\n          \"group flex flex-1 cursor-pointer items-center justify-between gap-6 py-5 text-left font-sans text-body leading-body text-fg outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus-ring disabled:pointer-events-none disabled:opacity-50\",\n          className,\n        )}\n        {...props}\n      >\n        {children}\n        {icon === undefined ? <AccordionMark className=\"group-data-[state=open]:rotate-45 group-data-[state=open]:text-fg-brand\" /> : icon}\n      </AccordionPrimitive.Trigger>\n    </AccordionPrimitive.Header>\n  );\n}\n\nfunction AccordionContent({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n  return (\n    <AccordionPrimitive.Content\n      data-slot=\"accordion-content\"\n      className=\"overflow-hidden text-button leading-relaxed text-fg-muted motion-safe:data-[state=closed]:animate-accordion-up data-[state=closed]:[animation-duration:var(--ds-duration-base)] motion-safe:data-[state=open]:animate-accordion-down motion-reduce:animate-none\"\n      {...props}\n    >\n      <div className={cn(\"max-w-xl pb-6 transition-[opacity,translate] duration-200 ease-out starting:-translate-y-1 starting:opacity-0 motion-reduce:transition-[opacity]\", className)}>{children}</div>\n    </AccordionPrimitive.Content>\n  );\n}\n\nexport { Accordion, AccordionContent, AccordionItem, AccordionMark, AccordionTrigger };\n"
    }
  ]
}
