{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "faq-accordion",
  "type": "registry:block",
  "title": "FAQ accordion",
  "description": "Five questions, one open at a time, with a still-have-questions contact card beside it on desktop.",
  "author": "StoreKit <hello@storekit.dev>",
  "categories": [
    "marketing",
    "any"
  ],
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "registryDependencies": [
    "https://storekit-eight.vercel.app/r/cn.json",
    "https://storekit-eight.vercel.app/r/button.json",
    "https://storekit-eight.vercel.app/r/sk-analytics.json"
  ],
  "files": [
    {
      "path": "marketing/faq-accordion.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\"\nimport { ChevronDown, MessageCircle } from \"lucide-react\"\nimport { cn } from \"@/components/storekit/lib/cn\"\nimport { Button } from \"@/components/storekit/ui/button\"\nimport { useSkBlock } from \"@/components/storekit/lib/sk-analytics\"\n\n/* FAQ with one row open at a time. Each row is a real button with\n   aria-expanded and a labelled region. A contact card sits beside it on\n   desktop and below it on mobile. */\n\ntype Faq = { q: string; a: string }\n\nconst SAMPLE: Faq[] = [\n  { q: \"How do I know what is in it?\", a: \"Every batch is tested by an independent lab for ingredient amounts, heavy metals and microbes. The results are on each product page, and the code on your pouch links to your batch.\" },\n  { q: \"How fast do orders ship?\", a: \"Orders placed before 2pm ET ship the same business day. Standard delivery takes 3 to 5 business days in the US.\" },\n  { q: \"How does subscribe and save work?\", a: \"You save 15% on every delivery and pick how often it ships. Skip, swap or cancel any time from your account, no calls needed.\" },\n  { q: \"What if my order arrives damaged?\", a: \"Send a photo within 7 days and we reship at no cost. Unopened products can be returned within 30 days.\" },\n  { q: \"Which payment methods do you accept?\", a: \"Major cards, Shop Pay and PayPal. Every checkout is encrypted end to end and we never store card numbers.\" },\n]\n\nexport function FaqAccordion({\n  items = SAMPLE,\n  eyebrow = \"FAQ\",\n  title = \"Questions, answered.\",\n  contactTitle = \"Still have questions?\",\n  contactBody = \"A real person on our team replies within four hours on business days.\",\n  contactLabel = \"Contact us\",\n  onContact,\n  defaultOpen = 0,\n  className,\n}: {\n  items?: Faq[]\n  eyebrow?: string\n  title?: string\n  contactTitle?: string\n  contactBody?: string\n  contactLabel?: string\n  onContact?: () => void\n  /** Index open on mount, or -1 for none. */\n  defaultOpen?: number\n  className?: string\n}) {\n  const reduce = useReducedMotion()\n  const sk = useSkBlock(\"marketing\", \"faq-accordion\")\n  const [open, setOpen] = React.useState(defaultOpen)\n  const uid = React.useId()\n  return (\n    <section ref={sk.ref as React.Ref<HTMLElement>} {...sk.attrs} className={cn(\"w-full py-16 sm:py-24\", className)}>\n      <div className=\"mx-auto grid max-w-6xl gap-10 px-4 sm:px-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:gap-16\">\n        <div>\n          <p className=\"font-sk-mono text-[11px] uppercase tracking-[0.14em] text-sk-muted\">{eyebrow}</p>\n          <h2 className=\"mt-3 font-sk-display text-3xl font-semibold leading-[1.1] tracking-[-0.02em] sm:text-4xl\">{title}</h2>\n          <div className=\"mt-8 border-t border-sk-line\">\n            {items.map((item, i) => {\n              const isOpen = open === i\n              const btn = `${uid}-b${i}`\n              const panel = `${uid}-p${i}`\n              return (\n                <div key={item.q} className=\"border-b border-sk-line\">\n                  <h3>\n                    <button\n                      id={btn}\n                      type=\"button\"\n                      aria-expanded={isOpen}\n                      aria-controls={panel}\n                      onClick={() => {\n                        if (!isOpen) sk.emit(\"interact\", `faq_open_${i + 1}`)\n                        setOpen(isOpen ? -1 : i)\n                      }}\n                      className=\"group flex min-h-14 w-full items-center justify-between gap-4 py-4 text-left text-[15px] font-medium text-sk-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sk-accent focus-visible:ring-offset-2 focus-visible:ring-offset-sk-paper\"\n                    >\n                      {item.q}\n                      <span className={cn(\"grid h-8 w-8 shrink-0 place-items-center rounded-sk-chip border border-sk-line transition-[transform,background-color] duration-300 ease-sk-out group-hover:bg-sk-ink/[0.04]\", isOpen && \"rotate-180\")}>\n                        <ChevronDown size={16} />\n                      </span>\n                    </button>\n                  </h3>\n                  <AnimatePresence initial={false}>\n                    {isOpen ? (\n                      <motion.div\n                        id={panel}\n                        role=\"region\"\n                        aria-labelledby={btn}\n                        initial={{ height: 0, opacity: 0 }}\n                        animate={{ height: \"auto\", opacity: 1 }}\n                        exit={{ height: 0, opacity: 0 }}\n                        transition={{ duration: reduce ? 0 : 0.32, ease: [0.16, 1, 0.3, 1] }}\n                        className=\"overflow-hidden\"\n                      >\n                        <p className=\"max-w-2xl pb-5 pr-12 text-[15px] leading-[1.5] text-sk-muted\">{item.a}</p>\n                      </motion.div>\n                    ) : null}\n                  </AnimatePresence>\n                </div>\n              )\n            })}\n          </div>\n        </div>\n\n        <aside className=\"lg:pt-[88px]\">\n          <div className=\"rounded-sk-card border border-sk-line bg-sk-card p-6\">\n            <span className=\"grid h-10 w-10 place-items-center rounded-sk-chip bg-sk-accent/10 text-sk-accent\">\n              <MessageCircle size={18} />\n            </span>\n            <p className=\"mt-4 font-sk-display text-xl font-semibold leading-[1.1] tracking-[-0.02em]\">{contactTitle}</p>\n            <p className=\"mt-2 text-[15px] leading-[1.5] text-sk-muted\">{contactBody}</p>\n            <Button\n              className=\"mt-5 w-full\"\n              onClick={() => {\n                sk.emit(\"convert\", \"contact\")\n                onContact?.()\n              }}\n            >\n              {contactLabel}\n            </Button>\n          </div>\n        </aside>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:block",
      "target": "components/storekit/marketing/faq-accordion.tsx"
    }
  ],
  "meta": {
    "section": "marketing",
    "variant": "accordion",
    "niche": [
      "any"
    ],
    "commerce": [
      "faq",
      "support"
    ],
    "previewHeight": 640
  }
}