{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "features-02",
  "type": "registry:block",
  "title": "Integration Bento Features",
  "description": "A four-card Bento feature section with integration, synchronization, developer and security details, adapted from Tailark.",
  "author": "Irung",
  "registryDependencies": [],
  "dependencies": [
    "cn@0.2.6",
    "lucide-react@0.577.0"
  ],
  "files": [
    {
      "path": "content/components/marketing/features-02.tsx",
      "type": "registry:component",
      "target": "@components/uiblocks/features-02/features-02.tsx",
      "content": "\"use client\";\n\n/**\n * Adapted from Tailark by Irung. Copyright (c) 2025 Irung. MIT licensed.\n * Source: https://github.com/tailark/blocks/blob/8139698115c1341bfd2e3e286c04bb4d8146f472/registry/bases/base/veil/blocks/features/one.tsx\n * Adaptations: local Card API; generic Lucide integration icons instead of brand\n * SVGs; typed host copy/visual slots; explicit demo mode; responsive content wrapping.\n */\nimport {\n  Cloud,\n  Database,\n  KeyRound,\n  Layers,\n  MessageSquare,\n  Shield,\n} from \"lucide-react\";\nimport { useId, type ReactNode } from \"react\";\nimport { Card } from \"./shared/components/ui/card\";\nimport { cn } from \"./shared/lib/utils\";\n\nexport type Feature02Visual =\n  | \"integrations\"\n  | \"sync\"\n  | \"developer\"\n  | \"security\";\nexport type Feature02Item = {\n  id: string;\n  title: string;\n  description: string;\n  visual?: Feature02Visual;\n  href?: string;\n  actionLabel?: string;\n};\nexport type Feature02Integration = {\n  id: string;\n  label: string;\n  icon?: ReactNode;\n};\nexport type Features02Props = {\n  mode?: \"controlled\" | \"demo\";\n  title?: string;\n  description?: string;\n  features?: readonly Feature02Item[];\n  integrations?: readonly Feature02Integration[];\n  visualSlots?: Partial<Record<Feature02Visual, ReactNode>>;\n  className?: string;\n};\n\nconst demoFeatures: readonly Feature02Item[] = [\n  {\n    id: \"demo-integrations\",\n    title: \"Everything, connected\",\n    description: \"An example canvas for the tools your team already uses.\",\n    visual: \"integrations\",\n  },\n  {\n    id: \"demo-sync\",\n    title: \"A shared rhythm\",\n    description:\n      \"Give real-time workflows a clear place in your product story.\",\n    visual: \"sync\",\n  },\n  {\n    id: \"demo-developer\",\n    title: \"Built to make it yours\",\n    description: \"A starting point for your API, SDK, and developer workflow.\",\n    visual: \"developer\",\n  },\n  {\n    id: \"demo-security\",\n    title: \"Room for trust\",\n    description:\n      \"Describe your verified security and governance capabilities here.\",\n    visual: \"security\",\n  },\n];\nconst demoIntegrations: readonly Feature02Integration[] = [\n  {\n    id: \"demo-workspace\",\n    label: \"Workspace\",\n    icon: <Layers className=\"size-3.5\" />,\n  },\n  {\n    id: \"demo-messages\",\n    label: \"Messages\",\n    icon: <MessageSquare className=\"size-3.5\" />,\n  },\n  {\n    id: \"demo-identity\",\n    label: \"Identity\",\n    icon: <KeyRound className=\"size-3.5\" />,\n  },\n  {\n    id: \"demo-storage\",\n    label: \"Storage\",\n    icon: <Database className=\"size-3.5\" />,\n  },\n  {\n    id: \"demo-projects\",\n    label: \"Projects\",\n    icon: <Layers className=\"size-3.5\" />,\n  },\n  { id: \"demo-deploy\", label: \"Deploy\", icon: <Cloud className=\"size-3.5\" /> },\n];\n\nfunction IntegrationCanvas({\n  integrations,\n}: {\n  integrations: readonly Feature02Integration[];\n}) {\n  if (!integrations.length)\n    return (\n      <p className=\"flex h-44 items-center text-sm text-muted-foreground\">\n        Supply your integration icons or a visual slot.\n      </p>\n    );\n  return (\n    <div className=\"flex h-44 flex-col justify-between pt-8\" aria-hidden=\"true\">\n      {[0, 1, 2].map((row) => (\n        <div\n          key={row}\n          className={cn(\n            \"relative flex h-10 items-center gap-12 px-6\",\n            row === 1 && \"justify-end pl-10 pr-4\",\n            row === 2 && \"gap-16 px-8\"\n          )}\n        >\n          <div className=\"absolute inset-0 my-auto h-px bg-border\" />\n          {integrations.slice(row * 2, row * 2 + 2).map((integration) => (\n            <span\n              key={integration.id}\n              title={integration.label}\n              className=\"relative flex h-8 min-w-9 shrink-0 items-center justify-center rounded-full bg-card px-3 shadow-sm shadow-black/5 ring-1 ring-border\"\n            >\n              {integration.icon ?? (\n                <span className=\"text-[10px] font-medium\">\n                  {Array.from(integration.label)[0] ?? \"+\"}\n                </span>\n              )}\n            </span>\n          ))}\n        </div>\n      ))}\n    </div>\n  );\n}\n\nfunction Decoration({\n  type,\n  integrations,\n}: {\n  type: Feature02Visual;\n  integrations: readonly Feature02Integration[];\n}) {\n  if (type === \"integrations\")\n    return <IntegrationCanvas integrations={integrations} />;\n  if (type === \"sync\")\n    return (\n      <div aria-hidden=\"true\" className=\"relative h-44 translate-y-6\">\n        <div className=\"absolute inset-0 mx-auto w-px bg-foreground/15\" />\n        <div className=\"absolute -inset-x-16 top-6 aspect-square rounded-full border border-border\" />\n        <div className=\"absolute -inset-x-16 top-6 aspect-square rounded-full border border-primary mask-l-from-50% mask-l-to-90% mask-r-from-50% mask-r-to-50%\" />\n        <div className=\"absolute -inset-x-8 top-24 aspect-square rounded-full border border-border\" />\n        <div className=\"absolute -inset-x-8 top-24 aspect-square rounded-full border border-lime-500 mask-r-from-50% mask-r-to-90% mask-l-from-50% mask-l-to-50%\" />\n      </div>\n    );\n  if (type === \"developer\")\n    return (\n      <div\n        aria-hidden=\"true\"\n        className=\"flex h-44 justify-between pb-6 pt-12 *:h-full *:w-px *:bg-foreground/15\"\n      >\n        {Array.from({ length: 32 }, (_, index) => (\n          <span\n            key={index}\n            className={\n              [4, 9, 13, 18, 23, 31].includes(index) ? \"bg-primary!\" : undefined\n            }\n          />\n        ))}\n      </div>\n    );\n  return (\n    <div\n      aria-hidden=\"true\"\n      className=\"pointer-events-none relative -ml-7 flex size-44 items-center justify-center pt-5\"\n    >\n      <Shield className=\"absolute inset-0 top-2.5 size-full stroke-[0.1px] opacity-15\" />\n      <Shield className=\"size-32 stroke-[0.1px]\" />\n    </div>\n  );\n}\n\nexport default function Features02({\n  mode = \"controlled\",\n  title = \"Product capabilities\",\n  description,\n  features,\n  integrations,\n  visualSlots,\n  className,\n}: Features02Props) {\n  const headingId = useId();\n  const items = features ?? (mode === \"demo\" ? demoFeatures : []);\n  const tools = integrations ?? (mode === \"demo\" ? demoIntegrations : []);\n  return (\n    <section\n      aria-labelledby={headingId}\n      className={cn(\n        \"@container bg-background py-16 text-foreground sm:py-24\",\n        className\n      )}\n      data-features-mode={mode}\n    >\n      <div className=\"mx-auto max-w-2xl px-6\">\n        <div>\n          <h2\n            id={headingId}\n            className=\"break-words text-balance font-serif text-3xl font-medium sm:text-4xl\"\n          >\n            {title}\n          </h2>\n          {description && (\n            <p className=\"mt-4 text-balance leading-7 text-muted-foreground [overflow-wrap:anywhere]\">\n              {description}\n            </p>\n          )}\n          {mode === \"demo\" && (\n            <p className=\"mt-3 text-xs leading-6 text-muted-foreground\">\n              Demo capabilities · Illustrative copy and generic integration\n              icons.\n            </p>\n          )}\n        </div>\n        {items.length ? (\n          <div className=\"mt-12 grid gap-3 @xl:grid-cols-2\">\n            {items.map((item) => (\n              <Card\n                key={item.id}\n                className=\"row-span-2 grid min-w-0 grid-rows-subgrid gap-6 overflow-hidden border border-border p-6 ring-0\"\n              >\n                <div className=\"min-w-0 space-y-2\">\n                  <h3 className=\"break-words font-medium [overflow-wrap:anywhere]\">\n                    {item.title}\n                  </h3>\n                  <p className=\"text-sm leading-6 text-muted-foreground [overflow-wrap:anywhere]\">\n                    {item.description}\n                  </p>\n                  {item.href && (\n                    <a\n                      href={item.href}\n                      className=\"inline-flex rounded-sm text-sm font-medium underline underline-offset-4 outline-offset-4 focus-visible:outline-2 focus-visible:outline-ring\"\n                    >\n                      {item.actionLabel ?? \"Learn more\"}\n                    </a>\n                  )}\n                </div>\n                {item.visual && (\n                  <div className=\"min-w-0\">\n                    {visualSlots && Object.hasOwn(visualSlots, item.visual) ? (\n                      visualSlots[item.visual]\n                    ) : (\n                      <Decoration type={item.visual} integrations={tools} />\n                    )}\n                  </div>\n                )}\n              </Card>\n            ))}\n          </div>\n        ) : (\n          <p className=\"mt-12 rounded-xl border border-dashed border-border p-8 text-sm leading-7 text-muted-foreground\">\n            No features supplied. Add verified product capabilities through the\n            features prop.\n          </p>\n        )}\n      </div>\n    </section>\n  );\n}\n"
    },
    {
      "path": "licenses/features-02/LICENSE.txt",
      "type": "registry:file",
      "target": "@components/uiblocks/features-02/LICENSE.txt",
      "content": "Includes source from Blocks.so and its bundled primitives.\nSource: https://github.com/ephraimduncan/blocks\nRevision: 3f759d5171c2391253ec4c772e9e5b3db2bc7c7f\nUIBlocks modifications (block v0.1.0):\n- Replaced upstream brand-logo SVG dependencies with generic Lucide icons and host content slots.\n- Added typed feature and integration content, portable host links, and explicit demo mode.\n- Retained the four-card composition while adapting theme primitives and mobile spacing.\n\nMIT License\n\nCopyright (c) 2025 Ephraim Duncan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nThird-party design: Tailark\nBlock: features-02 (v0.1.0)\nSource: https://github.com/tailark/blocks\nAuthor: Irung\nRevision: 8139698115c1341bfd2e3e286c04bb4d8146f472\nOriginal files:\n- registry/bases/base/veil/blocks/features/one.tsx\nUIBlocks modifications:\n- Replaced upstream brand-logo SVG dependencies with generic Lucide icons and host content slots.\n- Added typed feature and integration content, portable host links, and explicit demo mode.\n- Retained the four-card composition while adapting theme primitives and mobile spacing.\n\nMIT License\n\nCopyright (c) 2025 Irung\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
    },
    {
      "path": "components/ui/card.tsx",
      "type": "registry:component",
      "target": "@components/uiblocks/features-02/shared/components/ui/card.tsx",
      "content": "import type * as React from 'react';\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Card({\n  className,\n  size = 'default',\n  ...props\n}: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) {\n  return (\n    <div\n      className={cn(\n        'group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-card-foreground text-sm ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-[>img:first-child]:pt-0 has-data-[slot=card-footer]:pb-0 data-[size=sm]:has-data-[slot=card-footer]:pb-0 data-[size=sm]:[--card-spacing:--spacing(3)] *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl',\n        className\n      )}\n      data-size={size}\n      data-slot=\"card\"\n      {...props}\n    />\n  );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      className={cn(\n        'group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)',\n        className\n      )}\n      data-slot=\"card-header\"\n      {...props}\n    />\n  );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      className={cn(\n        'font-medium text-base leading-snug group-data-[size=sm]/card:text-sm',\n        className\n      )}\n      data-slot=\"card-title\"\n      {...props}\n    />\n  );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      className={cn('text-muted-foreground text-sm', className)}\n      data-slot=\"card-description\"\n      {...props}\n    />\n  );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      className={cn(\n        'col-start-2 row-span-2 row-start-1 self-start justify-self-end',\n        className\n      )}\n      data-slot=\"card-action\"\n      {...props}\n    />\n  );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      className={cn('px-(--card-spacing)', className)}\n      data-slot=\"card-content\"\n      {...props}\n    />\n  );\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      className={cn(\n        'flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)',\n        className\n      )}\n      data-slot=\"card-footer\"\n      {...props}\n    />\n  );\n}\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardAction,\n  CardDescription,\n  CardContent,\n};\n"
    },
    {
      "path": "lib/utils.ts",
      "type": "registry:component",
      "target": "@components/uiblocks/features-02/shared/lib/utils.ts",
      "content": "export { cn } from \"cn\";\n"
    }
  ],
  "categories": [
    "marketing",
    "marketing",
    "clean-saas"
  ],
  "docs": "Import the default component from @components/uiblocks/features-02/features-02.tsx. React 19, Tailwind CSS 4, and the standard shadcn CSS theme variables are required. This block is framework-independent React and works in TanStack Start, Vite, and Next.js projects. Connect links or navigation callbacks to your host application. The live preview opts into mode='demo'; the installed component defaults to controlled data and actions. Supply the host's records and callbacks before enabling service actions. Original design: Tailark by Irung, commit 8139698115c1341bfd2e3e286c04bb4d8146f472, source https://github.com/tailark/blocks. Original paths and local adaptations are recorded in meta.source. The complete upstream MIT notice is bundled in LICENSE.txt; retain it when adapting the component. See https://uiblocks.org/marketing/features-02 for content guidelines and source attribution.",
  "meta": {
    "kind": "block",
    "previewProps": {
      "mode": "demo"
    },
    "defaultMode": "controlled",
    "demoMode": "explicit",
    "includesBackend": false,
    "version": "0.1.0",
    "source": {
      "name": "Tailark",
      "url": "https://github.com/tailark/blocks",
      "license": "MIT",
      "author": "Irung",
      "revision": "8139698115c1341bfd2e3e286c04bb4d8146f472",
      "licenseFile": "licenses/third-party/tailark-MIT.txt",
      "files": [
        "registry/bases/base/veil/blocks/features/one.tsx"
      ],
      "modifications": [
        "Replaced upstream brand-logo SVG dependencies with generic Lucide icons and host content slots.",
        "Added typed feature and integration content, portable host links, and explicit demo mode.",
        "Retained the four-card composition while adapting theme primitives and mobile spacing."
      ]
    },
    "license": "MIT",
    "style": "clean-saas",
    "pageType": "marketing",
    "featured": true,
    "tags": [
      "features",
      "bento",
      "integrations",
      "sync",
      "developer",
      "security",
      "功能",
      "功能网格",
      "集成",
      "同步",
      "安全"
    ],
    "contentGuidelines": [
      "Replace illustrative capabilities with product features you actually provide.",
      "Supply integration labels or visualSlots for your actual product content; generic icons do not assert third-party partnerships.",
      "Keep headings short and allow descriptions to wrap on narrow screens."
    ],
    "recommendedWith": [
      "hero-01",
      "testimonials-01",
      "pricing-02"
    ],
    "entry": "@components/uiblocks/features-02/features-02.tsx",
    "exportName": "default",
    "frameworkIndependent": true,
    "frameworkDependencies": [],
    "compatibleHosts": [
      "react",
      "vite",
      "tanstack-start",
      "nextjs"
    ],
    "requirements": {
      "react": ">=19",
      "tailwind": ">=4"
    },
    "previewUrl": "https://uiblocks.org/preview/features-02"
  }
}
