{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "feature-matrix-table-dense",
  "title": "Feature Matrix Table Dense",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/feature-matrix-table-dense/FeatureMatrixTableDense.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { ArrowRight, Check, CheckCircle2, ChevronDown, ChevronRight, Filter, Minus, Search } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface MatrixFeature {\n  name: string\n  description: string\n  uipkge: boolean | string\n  npmMonolith: boolean | string\n  inHouse: boolean | string\n}\n\nexport interface MatrixCategory {\n  id: string\n  title: string\n  features: MatrixFeature[]\n}\n\nexport interface FeatureMatrixTableDenseProps {\n  title?: string\n  description?: string\n  categories?: MatrixCategory[]\n  className?: string\n}\n\nconst DEFAULT_CATEGORIES: MatrixCategory[] = [\n  {\n    id: 'architecture',\n    title: 'Architecture & Runtime Ownership',\n    features: [\n      {\n        name: 'Zero NPM Runtime Dependency',\n        description: 'Source code copied directly into your repository with 100% ownership.',\n        uipkge: true,\n        npmMonolith: false,\n        inHouse: true,\n      },\n      {\n        name: 'Dual Framework 1:1 Parity',\n        description: 'Synchronized Vue 3.5 and React 19 primitives with identical token bindings.',\n        uipkge: true,\n        npmMonolith: false,\n        inHouse: 'High Cost',\n      },\n      {\n        name: 'Deterministic Tree-Shaking',\n        description: 'Zero dead code in final production bundles; only imported components compile.',\n        uipkge: true,\n        npmMonolith: 'Partial',\n        inHouse: true,\n      },\n      {\n        name: 'Tailwind CSS v4 Native Tokens',\n        description: 'Direct @theme inline OKLCH bindings without legacy tailwind.config.js overhead.',\n        uipkge: true,\n        npmMonolith: false,\n        inHouse: 'Manual',\n      },\n    ],\n  },\n  {\n    id: 'developer-experience',\n    title: 'Developer Experience & Tooling',\n    features: [\n      {\n        name: 'Headless Primitive Foundation',\n        description: 'Powered by battle-tested Reka UI and Radix UI accessible state machines.',\n        uipkge: true,\n        npmMonolith: 'Proprietary',\n        inHouse: 'Custom',\n      },\n      {\n        name: 'CLI Direct Add Workflow',\n        description: 'Install via npx shadcn add @uipkge/<name> with automated dependency resolution.',\n        uipkge: true,\n        npmMonolith: false,\n        inHouse: false,\n      },\n      {\n        name: 'Automated Parity Check Suite',\n        description: 'Built-in AST parity verification scripts guarding against framework drift.',\n        uipkge: true,\n        npmMonolith: false,\n        inHouse: false,\n      },\n    ],\n  },\n  {\n    id: 'enterprise',\n    title: 'Enterprise & Security Compliance',\n    features: [\n      {\n        name: 'Zero Supply-Chain Vulnerabilities',\n        description: 'No third-party registry packages or compromised transitive semver updates.',\n        uipkge: true,\n        npmMonolith: false,\n        inHouse: true,\n      },\n      {\n        name: 'Full Customization Freedom',\n        description: 'Modify any CSS class, DOM attribute, or internal logic without breaking upstream.',\n        uipkge: true,\n        npmMonolith: 'Limited',\n        inHouse: true,\n      },\n      {\n        name: 'WCAG 2.1 AA Accessibility',\n        description: 'Keyboard ergonomics, focus rings, ARIA roles, and screen-reader audited.',\n        uipkge: true,\n        npmMonolith: 'Partial',\n        inHouse: 'Manual',\n      },\n    ],\n  },\n]\n\nexport function FeatureMatrixTableDense({\n  title = 'Engineered for teams who demand complete source code control.',\n  description = 'Compare how unbundled registry components stack up against traditional monolithic npm packages and bespoke in-house design systems.',\n  categories = DEFAULT_CATEGORIES,\n  className,\n}: FeatureMatrixTableDenseProps) {\n  const [searchQuery, setSearchQuery] = React.useState('')\n  const [onlyDifferences, setOnlyDifferences] = React.useState(false)\n  const [collapsedCategories, setCollapsedCategories] = React.useState<Record<string, boolean>>({})\n\n  function toggleCategory(catId: string) {\n    setCollapsedCategories((prev) => ({\n      ...prev,\n      [catId]: !prev[catId],\n    }))\n  }\n\n  const filteredCategories = React.useMemo(() => {\n    const query = searchQuery.toLowerCase().trim()\n\n    return categories\n      .map((cat) => {\n        const filteredFeatures = cat.features.filter((f) => {\n          const matchesQuery =\n            !query || f.name.toLowerCase().includes(query) || f.description.toLowerCase().includes(query)\n\n          if (!matchesQuery) return false\n\n          if (onlyDifferences) {\n            const isSame = f.uipkge === f.npmMonolith && f.npmMonolith === f.inHouse\n            if (isSame) return false\n          }\n\n          return true\n        })\n\n        return {\n          ...cat,\n          features: filteredFeatures,\n        }\n      })\n      .filter((cat) => cat.features.length > 0)\n  }, [categories, searchQuery, onlyDifferences])\n\n  return (\n    <section\n      data-slot=\"feature-matrix-table-dense\"\n      className={cn('bg-background relative overflow-hidden py-16 sm:py-24', className)}\n    >\n      <div className=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n        {/* Section Header */}\n        <div className=\"mx-auto max-w-3xl space-y-4 text-center\">\n          <a\n            href=\"#technical-matrix\"\n            className=\"group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors\"\n          >\n            <CheckCircle2 className=\"text-primary size-3.5\" />\n            <span>Technical Architecture Comparison</span>\n            <ArrowRight className=\"text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5\" />\n          </a>\n\n          <h2 className=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">{title}</h2>\n\n          <p className=\"text-muted-foreground text-base sm:text-lg\">{description}</p>\n        </div>\n\n        {/* Controls Strip: Search & Filter Toggles */}\n        <div className=\"border-border mt-10 flex flex-col gap-3 border-b pb-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"relative w-full sm:w-72\">\n            <Search className=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n            <input\n              type=\"text\"\n              placeholder=\"Filter capabilities...\"\n              value={searchQuery}\n              onChange={(e) => setSearchQuery(e.target.value)}\n              className=\"border-border bg-muted/40 text-foreground placeholder:text-muted-foreground focus-visible:ring-primary h-8 w-full rounded-md border pr-3 pl-8 text-xs focus-visible:ring-1 focus-visible:outline-none\"\n            />\n          </div>\n\n          <div className=\"flex items-center gap-2\">\n            <button\n              type=\"button\"\n              className={cn(\n                'flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs font-medium transition-colors',\n                onlyDifferences\n                  ? 'border-primary bg-primary/10 text-primary'\n                  : 'border-border bg-card text-muted-foreground hover:text-foreground',\n              )}\n              onClick={() => setOnlyDifferences((prev) => !prev)}\n            >\n              <Filter className=\"size-3\" />\n              <span>Show Differences Only</span>\n            </button>\n          </div>\n        </div>\n\n        {/* Dense Comparison Matrix Table */}\n        <div className=\"border-border bg-card mt-6 overflow-x-auto rounded-lg border shadow-xs\">\n          <table className=\"w-full text-left text-xs\">\n            {/* Table Sticky Header */}\n            <thead className=\"border-border bg-muted/50 text-foreground border-b font-medium\">\n              <tr>\n                <th scope=\"col\" className=\"w-1/2 py-3.5 pr-3 pl-4 text-sm font-semibold sm:w-5/12 sm:pl-6\">\n                  Capability & Specification\n                </th>\n                <th\n                  scope=\"col\"\n                  className=\"text-primary bg-primary/5 border-border border-x px-3 py-3.5 text-center font-bold sm:w-3/12\"\n                >\n                  <div className=\"flex flex-col items-center\">\n                    <span>UIPKGE Registry</span>\n                    <span className=\"text-muted-foreground text-xs font-normal\">Unbundled Code Ownership</span>\n                  </div>\n                </th>\n                <th scope=\"col\" className=\"text-muted-foreground px-3 py-3.5 text-center sm:w-2/12\">\n                  <div className=\"flex flex-col items-center\">\n                    <span>NPM Monolith</span>\n                    <span className=\"text-muted-foreground text-xs font-normal\">e.g. MUI / AntD</span>\n                  </div>\n                </th>\n                <th scope=\"col\" className=\"text-muted-foreground px-3 py-3.5 text-center sm:w-2/12\">\n                  <div className=\"flex flex-col items-center\">\n                    <span>In-House Bespoke</span>\n                    <span className=\"text-muted-foreground text-xs font-normal\">Built from scratch</span>\n                  </div>\n                </th>\n              </tr>\n            </thead>\n\n            {/* Table Body with Collapsible Category Rows */}\n            <tbody className=\"divide-border/60 divide-y\">\n              {filteredCategories.map((category) => (\n                <React.Fragment key={category.id}>\n                  {/* Category Header Row */}\n                  <tr\n                    className=\"bg-muted/30 hover:bg-muted/50 cursor-pointer transition-colors select-none\"\n                    onClick={() => toggleCategory(category.id)}\n                  >\n                    <td colSpan={4} className=\"py-2.5 pr-3 pl-4 sm:pl-6\">\n                      <div className=\"text-foreground flex items-center gap-1.5 text-xs font-bold tracking-wider uppercase\">\n                        {!collapsedCategories[category.id] ? (\n                          <ChevronDown className=\"text-muted-foreground size-3.5\" />\n                        ) : (\n                          <ChevronRight className=\"text-muted-foreground size-3.5\" />\n                        )}\n                        <span>{category.title}</span>\n                        <span className=\"text-muted-foreground ml-1 text-xs font-normal\">\n                          ({category.features.length})\n                        </span>\n                      </div>\n                    </td>\n                  </tr>\n\n                  {/* Feature Items Rows */}\n                  {!collapsedCategories[category.id] &&\n                    category.features.map((feature, fIdx) => (\n                      <tr key={fIdx} className=\"hover:bg-muted/10 transition-colors\">\n                        {/* Feature Info (Col 1) */}\n                        <td className=\"space-y-0.5 py-3 pr-3 pl-4 sm:pl-6\">\n                          <div className=\"text-foreground font-semibold\">{feature.name}</div>\n                          <div className=\"text-muted-foreground text-xs\">{feature.description}</div>\n                        </td>\n\n                        {/* UIPKGE (Col 2 - Highlighted) */}\n                        <td className=\"bg-primary/5 border-border border-x px-3 py-3 text-center\">\n                          <div className=\"flex items-center justify-center\">\n                            {feature.uipkge === true ? (\n                              <span className=\"bg-success/10 text-success inline-flex size-5 items-center justify-center rounded-full font-bold\">\n                                <Check className=\"size-3.5 stroke-[2.5]\" />\n                              </span>\n                            ) : typeof feature.uipkge === 'string' ? (\n                              <span className=\"bg-muted text-foreground rounded px-1.5 py-0.5 font-mono text-xs font-medium\">\n                                {feature.uipkge}\n                              </span>\n                            ) : (\n                              <span className=\"text-muted-foreground\">\n                                <Minus className=\"size-3.5\" />\n                              </span>\n                            )}\n                          </div>\n                        </td>\n\n                        {/* NPM Monolith (Col 3) */}\n                        <td className=\"px-3 py-3 text-center\">\n                          <div className=\"flex items-center justify-center\">\n                            {feature.npmMonolith === true ? (\n                              <span className=\"bg-success/10 text-success inline-flex size-5 items-center justify-center rounded-full\">\n                                <Check className=\"size-3.5\" />\n                              </span>\n                            ) : typeof feature.npmMonolith === 'string' ? (\n                              <span className=\"bg-muted/60 text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs font-medium\">\n                                {feature.npmMonolith}\n                              </span>\n                            ) : (\n                              <span className=\"text-muted-foreground/60\">\n                                <Minus className=\"size-3.5\" />\n                              </span>\n                            )}\n                          </div>\n                        </td>\n\n                        {/* In-House Bespoke (Col 4) */}\n                        <td className=\"px-3 py-3 text-center\">\n                          <div className=\"flex items-center justify-center\">\n                            {feature.inHouse === true ? (\n                              <span className=\"bg-success/10 text-success inline-flex size-5 items-center justify-center rounded-full\">\n                                <Check className=\"size-3.5\" />\n                              </span>\n                            ) : typeof feature.inHouse === 'string' ? (\n                              <span className=\"bg-muted/60 text-muted-foreground rounded px-1.5 py-0.5 font-mono text-xs font-medium\">\n                                {feature.inHouse}\n                              </span>\n                            ) : (\n                              <span className=\"text-muted-foreground/60\">\n                                <Minus className=\"size-3.5\" />\n                              </span>\n                            )}\n                          </div>\n                        </td>\n                      </tr>\n                    ))}\n                </React.Fragment>\n              ))}\n            </tbody>\n          </table>\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/feature-matrix-table-dense/FeatureMatrixTableDense.tsx"
    },
    {
      "path": "packages/registry-react/blocks/feature-matrix-table-dense/index.ts",
      "content": "export { FeatureMatrixTableDense } from './FeatureMatrixTableDense'\nexport type { FeatureMatrixTableDenseProps, MatrixCategory, MatrixFeature } from './FeatureMatrixTableDense'\n",
      "type": "registry:block",
      "target": "~/components/blocks/feature-matrix-table-dense/index.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Dense Linear-style technical specification matrix table with collapsible sections and search filtering.",
  "categories": [
    "feature",
    "marketing"
  ]
}