{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "faq-searchable-accordion-workbench",
  "title": "Faq Searchable Accordion Workbench",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/faq-searchable-accordion-workbench/FaqSearchableAccordionWorkbench.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { ChevronDown, HelpCircle, MessageSquare, Search, Terminal } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { cn } from '@/lib/utils'\n\ntype FaqCategory = 'all' | 'architecture' | 'parity' | 'licensing'\n\ninterface FaqItem {\n  id: string\n  category: 'architecture' | 'parity' | 'licensing'\n  question: string\n  answer: string\n  tag: string\n}\n\nconst faqItems: FaqItem[] = [\n  {\n    id: '1',\n    category: 'architecture',\n    question: 'How is UIPKGE different from standard component packages on npm?',\n    answer:\n      'UIPKGE does not publish monolithic npm packages. When you run our CLI command, raw Vue 3.5 SFCs or React 19 TSX files are copied directly into your repository. You own 100% of the code, have zero semver breaking risks, and can customize any token, prop, or micro-interaction without waiting on maintainers.',\n    tag: 'Unbundled AST',\n  },\n  {\n    id: '2',\n    category: 'parity',\n    question: 'How does dual-framework parity work between Vue and React?',\n    answer:\n      'Every primitive and block in UIPKGE is authored with identical class tokens, CVA variant definitions, and OKLCH color palettes across both Vue (Reka UI) and React (Radix UI). Automated parity check scripts in CI ensure 100% token consistency across frameworks.',\n    tag: 'Dual-Framework',\n  },\n  {\n    id: '3',\n    category: 'architecture',\n    question: 'Can I customize the Tailwind CSS v4 design tokens?',\n    answer:\n      'Yes. All design tokens are declared using standard Tailwind CSS v4 `@theme inline` CSS custom properties in `styles/tailwind.css`. You can change primary colors, border radii, or spring curves globally in one file.',\n    tag: 'Tailwind v4',\n  },\n  {\n    id: '4',\n    category: 'licensing',\n    question: 'What is the licensing model for commercial projects?',\n    answer:\n      'All UIPKGE components and blocks are 100% MIT-licensed. You can use them freely in commercial applications, client projects, and internal tools without paying per-seat subscriptions or attribution fees.',\n    tag: 'MIT License',\n  },\n  {\n    id: '5',\n    category: 'parity',\n    question: 'Which headless primitives power UIPKGE components?',\n    answer:\n      'In Vue 3.5, primitives use Reka UI for keyboard ergonomics and ARIA compliance. In React 19, primitives utilize Radix UI and standard headless primitives, ensuring complete accessibility compliance (WCAG AA).',\n    tag: 'Headless A11y',\n  },\n  {\n    id: '6',\n    category: 'licensing',\n    question: 'Do you offer custom enterprise component design engineering?',\n    answer:\n      'Yes. Our enterprise tier includes dedicated engineering syncs, bespoke block authoring, private organizational registry hubs, and priority architectural audits.',\n    tag: 'Enterprise SLA',\n  },\n]\n\nexport interface FaqSearchableAccordionWorkbenchProps {\n  className?: string\n}\n\nexport function FaqSearchableAccordionWorkbench({ className }: FaqSearchableAccordionWorkbenchProps) {\n  const [searchQuery, setSearchQuery] = React.useState('')\n  const [selectedCategory, setSelectedCategory] = React.useState<FaqCategory>('all')\n  const [openItemIds, setOpenItemIds] = React.useState<Record<string, boolean>>({ '1': true })\n\n  const toggleItem = (id: string) => {\n    setOpenItemIds((prev) => ({\n      ...prev,\n      [id]: !prev[id],\n    }))\n  }\n\n  const filteredFaqs = React.useMemo(() => {\n    return faqItems.filter((item) => {\n      const matchesCategory = selectedCategory === 'all' || item.category === selectedCategory\n      const query = searchQuery.toLowerCase().trim()\n      const matchesQuery =\n        query === '' ||\n        item.question.toLowerCase().includes(query) ||\n        item.answer.toLowerCase().includes(query) ||\n        item.tag.toLowerCase().includes(query)\n\n      return matchesCategory && matchesQuery\n    })\n  }, [searchQuery, selectedCategory])\n\n  return (\n    <section\n      data-slot=\"faq-searchable-accordion-workbench\"\n      className={cn('bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8', className)}\n    >\n      <div className=\"mx-auto max-w-4xl space-y-12\">\n        {/* Section Header */}\n        <div className=\"space-y-4 text-center\">\n          <Badge variant=\"secondary\" className=\"gap-1.5 px-3 py-1 font-mono text-xs shadow-xs\">\n            <HelpCircle className=\"text-primary size-3.5\" />\n            Technical FAQ Workbench\n          </Badge>\n          <h2 className=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">\n            Frequently asked architectural questions.\n          </h2>\n          <p className=\"text-muted-foreground text-base\">\n            Everything you need to know about our unbundled registry distribution model.\n          </p>\n\n          {/* Search & Filter Bar */}\n          <div className=\"mx-auto max-w-xl space-y-3 pt-4\">\n            <div className=\"relative\">\n              <Search className=\"text-muted-foreground absolute top-1/2 left-3.5 size-4 -translate-y-1/2\" />\n              <Input\n                value={searchQuery}\n                onChange={(e) => setSearchQuery(e.target.value)}\n                placeholder=\"Search architecture, tokens, licensing, or parity...\"\n                className=\"bg-card border-border h-11 rounded-xl pl-10 font-mono text-xs shadow-sm\"\n              />\n            </div>\n\n            {/* Category Filter Pills */}\n            <div className=\"flex flex-wrap items-center justify-center gap-1.5\">\n              <button\n                type=\"button\"\n                className={cn(\n                  'rounded-lg border px-3 py-1 font-mono text-xs transition-colors',\n                  selectedCategory === 'all'\n                    ? 'border-primary bg-primary text-primary-foreground font-semibold shadow-xs'\n                    : 'border-border bg-card text-muted-foreground hover:text-foreground',\n                )}\n                onClick={() => setSelectedCategory('all')}\n              >\n                All ({faqItems.length})\n              </button>\n              <button\n                type=\"button\"\n                className={cn(\n                  'rounded-lg border px-3 py-1 font-mono text-xs transition-colors',\n                  selectedCategory === 'architecture'\n                    ? 'border-primary bg-primary text-primary-foreground font-semibold shadow-xs'\n                    : 'border-border bg-card text-muted-foreground hover:text-foreground',\n                )}\n                onClick={() => setSelectedCategory('architecture')}\n              >\n                Architecture\n              </button>\n              <button\n                type=\"button\"\n                className={cn(\n                  'rounded-lg border px-3 py-1 font-mono text-xs transition-colors',\n                  selectedCategory === 'parity'\n                    ? 'border-primary bg-primary text-primary-foreground font-semibold shadow-xs'\n                    : 'border-border bg-card text-muted-foreground hover:text-foreground',\n                )}\n                onClick={() => setSelectedCategory('parity')}\n              >\n                Dual-Framework Parity\n              </button>\n              <button\n                type=\"button\"\n                className={cn(\n                  'rounded-lg border px-3 py-1 font-mono text-xs transition-colors',\n                  selectedCategory === 'licensing'\n                    ? 'border-primary bg-primary text-primary-foreground font-semibold shadow-xs'\n                    : 'border-border bg-card text-muted-foreground hover:text-foreground',\n                )}\n                onClick={() => setSelectedCategory('licensing')}\n              >\n                Licensing &amp; SLA\n              </button>\n            </div>\n          </div>\n        </div>\n\n        {/* FAQ Accordion List */}\n        <div className=\"space-y-3\">\n          {filteredFaqs.map((faq) => {\n            const isOpen = Boolean(openItemIds[faq.id])\n            return (\n              <div\n                key={faq.id}\n                className={cn(\n                  'border-border bg-card/95 overflow-hidden rounded-2xl border text-left shadow-xs transition-colors',\n                  isOpen ? 'ring-primary/20 shadow-md ring-1' : 'hover:border-border/80',\n                )}\n              >\n                <button\n                  type=\"button\"\n                  className=\"flex w-full items-center justify-between gap-4 p-5 text-left font-mono\"\n                  onClick={() => toggleItem(faq.id)}\n                >\n                  <div className=\"flex min-w-0 items-center gap-3\">\n                    <Badge variant=\"outline\" className=\"shrink-0 font-mono text-xs\">\n                      {faq.tag}\n                    </Badge>\n                    <h3 className=\"text-foreground truncate text-sm font-bold sm:text-base\">{faq.question}</h3>\n                  </div>\n                  <ChevronDown\n                    className={cn(\n                      'text-muted-foreground size-4 shrink-0 transition-transform duration-200',\n                      isOpen && 'text-primary rotate-180',\n                    )}\n                  />\n                </button>\n\n                {/* Answer Body */}\n                {isOpen && (\n                  <div className=\"text-muted-foreground border-border/40 border-t px-5 pt-1 pb-5 text-xs leading-relaxed sm:text-sm\">\n                    {faq.answer}\n                  </div>\n                )}\n              </div>\n            )\n          })}\n\n          {/* Empty Results */}\n          {filteredFaqs.length === 0 && (\n            <div className=\"border-border rounded-2xl border border-dashed p-12 text-center\">\n              <p className=\"text-muted-foreground font-mono text-xs\">No questions match your query \"{searchQuery}\".</p>\n            </div>\n          )}\n        </div>\n\n        {/* Live Support Footer Card */}\n        <Card className=\"border-border bg-card/50 flex flex-col items-center justify-between gap-4 rounded-2xl p-6 text-center sm:flex-row sm:text-left\">\n          <div className=\"space-y-1\">\n            <h4 className=\"text-foreground font-mono text-sm font-bold\">Have a unique technical requirement?</h4>\n            <p className=\"text-muted-foreground text-xs\">Chat with the core design engineering team in real time.</p>\n          </div>\n          <div className=\"flex shrink-0 items-center gap-2\">\n            <Button size=\"sm\" variant=\"outline\" className=\"h-9 gap-1.5 font-mono text-xs\">\n              <MessageSquare className=\"size-3.5\" />\n              <span>Join Discord</span>\n            </Button>\n            <Button size=\"sm\" className=\"h-9 gap-1.5 font-mono text-xs\">\n              <Terminal className=\"size-3.5\" />\n              <span>GitHub Discussions</span>\n            </Button>\n          </div>\n        </Card>\n      </div>\n    </section>\n  )\n}\nexport default FaqSearchableAccordionWorkbench\n",
      "type": "registry:block",
      "target": "~/components/blocks/FaqSearchableAccordionWorkbench.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json"
  ],
  "description": "Searchable FAQ workbench with real-time query filtering, category switcher, collapsible accordions, and community support links.",
  "categories": [
    "marketing"
  ]
}