{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "faq-tabs-card",
  "title": "FAQ Tabs Card",
  "description": "A tabbed FAQ card with animated accordion answers and a support footer.",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "files": [
    {
      "path": "app/registry/faq-tabs-card/faq-tabs-card.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport { ChevronDown } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport interface FaqItem {\n  question: string;\n  answer: string;\n}\n\nexport interface FaqTab {\n  label: string;\n  faqs: FaqItem[];\n}\n\nexport interface FAQTabsCardProps {\n  tabs?: FaqTab[];\n  /** Index of the tab selected initially. */\n  defaultTab?: number;\n  /** Index of the FAQ expanded initially (-1 for none). */\n  defaultOpenIndex?: number;\n  footerLabel?: string;\n  onFooterClick?: () => void;\n  className?: string;\n}\n\nconst DEFAULT_TABS: FaqTab[] = [\n  {\n    label: \"General\",\n    faqs: [\n      {\n        question: \"How secure is my financial data with Ledger?\",\n        answer:\n          \"We use bank-level AES-256 encryption, SOC 2 Type II certified infrastructure, and never store your credentials. All connections use read-only access tokens. We are a SEC registered investment advisor.\",\n      },\n      {\n        question: \"How do I connect my bank or investment accounts?\",\n        answer:\n          \"Open Settings → Connections and pick your institution. We support 12,000+ banks and brokerages through secure, read-only integrations.\",\n      },\n      {\n        question: \"Can I export my data for tax purposes?\",\n        answer:\n          \"Yes — export transactions, gains, and reports as CSV or PDF at any time from the Reports tab.\",\n      },\n    ],\n  },\n  {\n    label: \"Billing\",\n    faqs: [\n      {\n        question: \"What payment methods do you accept?\",\n        answer:\n          \"All major credit and debit cards, plus ACH transfers on annual plans.\",\n      },\n      {\n        question: \"Can I cancel my subscription anytime?\",\n        answer:\n          \"Yes, cancel from Settings → Billing. You keep access until the end of the current billing period.\",\n      },\n      {\n        question: \"Do you offer refunds?\",\n        answer:\n          \"We offer a full refund within 14 days of purchase, no questions asked.\",\n      },\n    ],\n  },\n  {\n    label: \"Goals\",\n    faqs: [\n      {\n        question: \"How do savings goals work?\",\n        answer:\n          \"Set a target amount and date — we track progress automatically across your linked accounts.\",\n      },\n      {\n        question: \"Can I share a goal with a partner?\",\n        answer:\n          \"Yes, invite a partner to any goal and you'll both see live progress and contributions.\",\n      },\n      {\n        question: \"What happens when I reach a goal?\",\n        answer:\n          \"We notify you and suggest next steps, like rolling the balance into a new goal or investing it.\",\n      },\n    ],\n  },\n];\n\nexport function FAQTabsCard({\n  tabs: tabsProp = DEFAULT_TABS,\n  defaultTab = 0,\n  defaultOpenIndex = 0,\n  footerLabel = \"Contact Support\",\n  onFooterClick,\n  className,\n}: FAQTabsCardProps) {\n  // Explicit `tabs={[]}` bypasses the default param — fall back so we never\n  // read `.faqs` off undefined.\n  const tabs = tabsProp.length > 0 ? tabsProp : DEFAULT_TABS;\n  const clampedDefaultTab = Math.min(\n    Math.max(defaultTab, 0),\n    tabs.length - 1,\n  );\n\n  const [activeTab, setActiveTab] = React.useState(clampedDefaultTab);\n  const [openIndex, setOpenIndex] = React.useState(defaultOpenIndex);\n\n  const safeActiveTab = Math.min(Math.max(activeTab, 0), tabs.length - 1);\n  const currentTab = tabs[safeActiveTab] ?? tabs[0];\n\n  return (\n    <div\n      className={cn(\n        \"flex w-full flex-col rounded-[26px] bg-white p-6 font-inter\",\n        \"shadow-[0_0_0_1px_rgba(10,10,10,0.05),0_2px_4px_0_rgba(0,0,0,0.1)]\",\n        \"dark:bg-neutral-950 dark:shadow-[0_0_0_1px_rgba(255,255,255,0.12),0_2px_4px_0_rgba(0,0,0,0.5)]\",\n        className,\n      )}\n    >\n      {/* Tabs */}\n      <div className=\"flex h-9 items-center rounded-full bg-neutral-100 p-1 dark:bg-neutral-900\">\n        {tabs.map((tab, index) => {\n          const active = index === safeActiveTab;\n          return (\n            <button\n              key={tab.label}\n              type=\"button\"\n              onClick={() => {\n                setActiveTab(index);\n                setOpenIndex(defaultOpenIndex);\n              }}\n              className=\"relative h-[27px] flex-1 rounded-full outline-hidden\"\n            >\n              {active ? (\n                <motion.span\n                  layoutId=\"faq-tab-pill\"\n                  className=\"absolute inset-0 rounded-full bg-white dark:bg-neutral-950\"\n                  transition={{ type: \"spring\", bounce: 0.2, duration: 0.5 }}\n                />\n              ) : null}\n              <span\n                className={cn(\n                  \"relative z-10 text-sm font-medium leading-5 transition-colors duration-200\",\n                  active\n                    ? \"text-foreground\"\n                    : \"text-foreground/60 hover:text-foreground/80\",\n                )}\n              >\n                {tab.label}\n              </span>\n            </button>\n          );\n        })}\n      </div>\n\n      {/* Accordion */}\n      <AnimatePresence mode=\"wait\" initial={false}>\n        <motion.div\n          key={safeActiveTab}\n          initial={{ opacity: 0, y: 6 }}\n          animate={{ opacity: 1, y: 0 }}\n          exit={{ opacity: 0, y: -6 }}\n          transition={{ duration: 0.18, ease: \"easeOut\" }}\n          className=\"mt-2 flex-1 overflow-hidden rounded-[18px] border border-border\"\n        >\n          {currentTab.faqs.map((faq, index) => {\n            const open = index === openIndex;\n            return (\n              <div\n                key={faq.question}\n                className={cn(\n                  \"transition-colors duration-300\",\n                  index > 0 && \"border-t border-border\",\n                  open && \"bg-neutral-100/50 dark:bg-neutral-900/50\",\n                )}\n              >\n                <button\n                  type=\"button\"\n                  onClick={() => setOpenIndex(open ? -1 : index)}\n                  aria-expanded={open}\n                  className=\"flex min-h-[56px] w-full items-start justify-between gap-4 p-4 text-left\"\n                >\n                  <span className=\"max-w-[248px] text-sm font-medium leading-5 text-foreground\">\n                    {faq.question}\n                  </span>\n                  <motion.span\n                    animate={{ rotate: open ? 180 : 0 }}\n                    transition={{ duration: 0.25, ease: \"easeOut\" }}\n                    className=\"flex shrink-0\"\n                  >\n                    <ChevronDown className=\"h-4 w-4 text-foreground\" />\n                  </motion.span>\n                </button>\n                <AnimatePresence initial={false}>\n                  {open ? (\n                    <motion.div\n                      key=\"answer\"\n                      initial={{ height: 0, opacity: 0 }}\n                      animate={{ height: \"auto\", opacity: 1 }}\n                      exit={{ height: 0, opacity: 0 }}\n                      transition={{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }}\n                      className=\"overflow-hidden\"\n                    >\n                      <p className=\"px-4 pb-[19px] text-sm leading-5 text-foreground\">\n                        {faq.answer}\n                      </p>\n                    </motion.div>\n                  ) : null}\n                </AnimatePresence>\n              </div>\n            );\n          })}\n        </motion.div>\n      </AnimatePresence>\n\n      {/* Footer */}\n      <motion.button\n        type=\"button\"\n        onClick={onFooterClick}\n        whileHover={{ scale: 1.015 }}\n        whileTap={{ scale: 0.97 }}\n        transition={{ type: \"spring\", bounce: 0.4, duration: 0.35 }}\n        className=\"mt-[25px] flex h-[34px] w-full shrink-0 items-center justify-center rounded-[26px] border border-border bg-white text-sm font-medium leading-5 text-foreground transition-colors hover:bg-neutral-50 dark:bg-neutral-950 dark:hover:bg-neutral-900\"\n      >\n        {footerLabel}\n      </motion.button>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/spectrumui/faq-tabs-card.tsx"
    }
  ],
  "type": "registry:component"
}
